@domoinc/ryuu-proxy
v5.1.1
Published
a middleware that provides a proxy for local domo app development
Readme
@domoinc/ryuu-proxy
Middleware for local Domo App development. It intercepts calls to Domo data/API endpoints and proxies authenticated requests to your Domo instance, so you can develop against real data from your local dev server.
Table of Contents
Features
- Intercepts and proxies Domo API traffic:
/data/v{d},/sql/v{d},/dql/v{d},/domo/.../v{d},/api/... - Drop-in Express / Connect middleware via
proxy.express() - Framework-agnostic
proxy.stream(req)for Koa, Nodehttp, Fastify, etc. - Handles multipart/form-data uploads (file streams via
busboy) - Injects OAuth access/refresh tokens for apps using DQL, writeback, or OAuth features
- Reads auth from your existing Domo CLI login session — no extra config
- Ships with TypeScript types
- ESM package
Requirements
- Node.js 18+
- An active Domo CLI session (
domo login) — see@ryuu - A project
manifest.jsonthat has been published at least once (domo publish) - Peer:
express ^4.17.0 || ^5.0.0(only required if you useproxy.express())
Installation
pnpm add -D @domoinc/ryuu-proxy
# or
npm install --save-dev @domoinc/ryuu-proxy
# or
yarn add -D @domoinc/ryuu-proxyUsage
This library leverages the last login session from your Domo CLI. If that session is no longer active or doesn't exist, the proxy won't work. Log in before starting your dev server:
domo loginConfiguration
import { Proxy } from '@domoinc/ryuu-proxy';
import manifest from './path/to/app/manifest.json' with { type: 'json' };
const proxy = new Proxy({ manifest });The Proxy constructor accepts a config object.
Required
manifest— parsed contents of your project'smanifest.json.domo publishmust have been run at least once so the manifest has anid.
Optional
manifest.proxyId— required for apps using DQL, writebacks, or OAuth. If you're unsure, you probably don't need it. See Getting a proxyId.
With Express / Connect
import express from 'express';
const app = express();
app.use(proxy.express());With Other Frameworks
For other frameworks, stream() returns a readable stream you can pipe back to your response. It accepts a standard Node IncomingMessage, which most frameworks extend.
// koa
app.use(async (ctx, next) => {
await proxy
.stream(ctx.req)
.then((data) => (ctx.body = ctx.req.pipe(data)))
.catch(next);
});// express
app.use((req, res, next) => {
proxy
.stream(req)
.then((stream) => stream.pipe(res))
.catch(() => next());
});// node http
import http from 'node:http';
const server = http.createServer((req, res) => {
if (req.url === '/') {
loadHomePage(res);
} else {
proxy.stream(req).then((stream) => stream.pipe(res));
}
});Error Handling
Ignoring errors causes the proxy to fail silently and the request returns 404. To expose errors, catch DomoException and forward the status:
// koa
app.use(async (ctx, next) => {
await proxy
.stream(ctx.req)
.then((data) => (ctx.body = ctx.req.pipe(data)))
.catch((err) => {
if (err.name === 'DomoException') {
ctx.status = err.status || err.statusCode || 500;
ctx.body = err;
} else {
next();
}
});
});// express / connect
app.use((req, res, next) => {
proxy
.stream(req)
.then((stream) => stream.pipe(res))
.catch((err) => {
if (err.name === 'DomoException') {
res.status(err.status || err.statusCode || 500).json(err);
} else {
next();
}
});
});// node http
const server = http.createServer((req, res) => {
if (req.url === '/') {
loadHomePage();
} else {
proxy
.stream(req)
.then((stream) => stream.pipe(res))
.catch((err) => {
if (err.name === 'DomoException') {
res.writeHead(err.status || err.statusCode || 500);
res.end(JSON.stringify(err));
}
});
}
});DomoException shape:
| Field | Description |
| ----------------------- | ------------------------ |
| name | Always "DomoException" |
| status / statusCode | HTTP status code |
| statusMessage | Error description |
HTTP Proxy Support
If you sit behind a corporate HTTP proxy, set any of the following environment variables. REACT_APP_-prefixed variants are also honored for Create React App projects.
| Variable | Purpose |
| --------------------------------------------- | ------------------------------ |
| PROXY_HOST / REACT_APP_PROXY_HOST | Proxy hostname |
| PROXY_PORT / REACT_APP_PROXY_PORT | Proxy port |
| PROXY_USERNAME / REACT_APP_PROXY_USERNAME | Basic auth username (optional) |
| PROXY_PASSWORD / REACT_APP_PROXY_PASSWORD | Basic auth password (optional) |
Getting a proxyId (Advanced)
Apps using DQL, writeback, or OAuth features must supply a proxyId in the proxy configuration so the proxy can route requests correctly. A proxyId is of the form XXXXXXXX-XXXX-4XXX-XXXX-XXXXXXXXXXXX. To find it:
- Ensure the app has been published at least once with
domo publish. - Publish a new card from your app design, or open an existing card built from it.
- Right-click the card and choose Inspect element.
- Find the
<iframe>containing your app. Its URL looks like//{HASH}.domoapps.prodX.domo.com?userId=.... - Copy the hash between
//and.domoapps— that is yourproxyId.
proxyIds tie apps to cards. If you delete the card you pulled the ID from, you'll need a new one from another card created from the same app design.
Related Packages
ryuu— the Domo CLI (domo login,domo publish, etc.)ryuu-client— underlying Domo API client
Contributing
Workflow
- Create a branch (e.g.
DOMO-XXXXXX) - Make and commit changes
- Test — optionally publish an alpha/beta for integration testing
- Open a pull request
- After merge to
master, bump the version and release to npm
Scripts
| Script | Description |
| ----------------------------- | --------------------------------------- |
| pnpm run build | Compile TypeScript to dist/ |
| pnpm test | Run the test suite (vitest) |
| pnpm run test:watch | Run vitest in watch mode |
| pnpm run test:coverage | Run tests with coverage |
| pnpm run format | Format source with Prettier |
| pnpm run release:production | Build and publish to npm |
| pnpm run release:beta | Build and publish under the beta tag |
| pnpm run release:alpha | Build and publish under the alpha tag |
Versioning
This project uses standard-version with conventional commits to determine version bumps.
