npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ecode-sdk

v0.1.6

Published

TypeScript SDK for Ecology 9 ecode APIs

Readme

ecode-sdk

JavaScript SDK for Ecology 9 ecode APIs.

API

EcodeClient

const { EcodeClient } = require('ecode-sdk');

const client = new EcodeClient({
  baseUrl: 'http://your-ecology-server',
  username: 'sysadmin',
  password: 'your-password',
});

await client.login();
const tree = await client.listTree();
const result = await client.download('/path/to/project');
await client.uploadResource('/local/path.js', 'remote-folder-id');

Download

client.download(outputRoot) loads the complete remote tree, downloads source files to <outputRoot>/src, and generates <outputRoot>/.ecode/ecode-tree.json.

Existing source files are kept by default. Pass { overwrite: true } to replace them. Integrations can use prepareTree to merge the new remote tree with local metadata before selecting the remote paths that should be materialized:

const result = await client.download('/path/to/project', {
  prepareTree: async (remoteTree) => {
    const filePaths = await mergeWithLocalTree(remoteTree);
    return { filePaths };
  },
});

console.log(result.downloaded, result.skipped, result.failed);

App configuration files

The SDK can derive application metadata from an eCode tree and synchronize one JSON file per app under .ecode/apps:

const path = require('node:path');
const { collectEcodeAppConfigs, synchronizeEcodeAppConfigs } = require('ecode-sdk');

const apps = collectEcodeAppConfigs(tree);

await synchronizeEcodeAppConfigs(path.resolve('/path/to/project/.ecode/ecode-tree.json'));
// Writes .ecode/apps/<id>.json and removes stale generated app JSON files.

Upgrade packages

The SDK builds Ecology app upload archives with buildAppUpgradePackage. Pass the exact app IDs to include; the project must contain src/, .ecode/apps/, and .ecode/ecode-tree.json:

const { buildAppUpgradePackage } = require('ecode-sdk');

const result = await buildAppUpgradePackage({
  projectRoot: '/path/to/project',
  outputDirectory: '/path/to/project/dist/app-upgrade',
  apps: ['11111111111111111111111111111111', '22222222222222222222222222222222'],
});

console.log(result.archivePath);

The caller owns outputDirectory; the SDK writes the current ZIP, plan, and checksum there without removing existing files. The archive layout matches the Ecology app export format: <timestamp><uuid>/ecode.json plus one direct <timestamp><uuid>/<appId>/ source directory for every selected app. The merged ecode.json contains all selected apps and their shared type tree. The generated plan records each app's appId and appStatus for deployment.

Callers that already hold app metadata can pass appConfigs; in that case the builder does not read .ecode/apps/.

Import apps

Build and publish a package with the shared upload/import workflow:

const { publishAppUpgradePackage } = require('ecode-sdk');

const published = await publishAppUpgradePackage(client, result.archivePath, result.plan.apps);
console.log(published.fileId);

For lower-level integrations, an already uploaded package can still be imported with per-app options:

await client.importApps(fileId, {
  '11111111111111111111111111111111': {
    cover: 'y',
    autoRelease: 'y',
    coverConfig: 'n',
  },
});

JavaScript compiler

The SDK compiles browser-side JavaScript and JSX with the legacy eCode Babel toolchain (Babel standalone 7.5.5). It uses the classic JSX runtime, so the generated code continues to use the global React.createElement.

const path = require('node:path');
const { compileJavaScript, compileJavaScriptFile } = require('ecode-sdk');

const code = compileJavaScript('const view = <div>Hello</div>;');

const fileCode = compileJavaScriptFile(path.resolve('index.test.js'), path.resolve('dist/compiled_index.test.js'));
// Returns the compiled content after synchronously writing the output file.

The compiler uses the legacy es2015, react, decorators, class-properties, and transform-instanceof configuration. Decorators use legacy mode, including decorated class properties. Pass sourceType, comments, compact, minified, or retainLines to override output options. Project Babel configuration files do not affect the standalone compiler, so output stays deterministic.

Notes

The SDK uses the modern Node.js global fetch, FormData, and Blob APIs for requests and uploads. It maintains a cookie jar automatically, so login() stores the session cookie and subsequent requests carry it automatically.