Skip to content

DomoApps/ryuu-proxy

Repository files navigation

@domoinc/ryuu-proxy

npm version install size npm downloads types license Known Vulnerabilities

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, Node http, 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.json that has been published at least once (domo publish)
  • Peer: express ^4.17.0 || ^5.0.0 (only required if you use proxy.express())

Installation

pnpm add -D @domoinc/ryuu-proxy
# or
npm install --save-dev @domoinc/ryuu-proxy
# or
yarn add -D @domoinc/ryuu-proxy

Usage

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 login

Configuration

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's manifest.json. domo publish must have been run at least once so the manifest has an id.

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.
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:

  1. Ensure the app has been published at least once with domo publish.
  2. Publish a new card from your app design, or open an existing card built from it.
  3. Right-click the card and choose Inspect element.
  4. Find the <iframe> containing your app. Its URL looks like //{HASH}.domoapps.prodX.domo.com?userId=....
  5. Copy the hash between // and .domoapps — that is your proxyId.

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

  1. Create a branch (e.g. DOMO-XXXXXX)
  2. Make and commit changes
  3. Test — optionally publish an alpha/beta for integration testing
  4. Open a pull request
  5. 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.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors