@flowget/registry-loader
v0.2.1
Published
Shared registry loader for Flowget — parses REGISTRY_DIR specifiers, resolves npm subpaths and brace expansions, walks the on-disk node/decorator/decider layout, validates each node.json against the canonical @flowget/types schema at load time, and projec
Maintainers
Readme
@flowget/registry-loader
The shared loader for the Flowget REGISTRY_DIR contract. It parses
REGISTRY_DIR specifiers, resolves filesystem paths and npm subpaths,
walks the on-disk node/decorator/decider layout, validates each
<name>.json against the canonical @flowget/types node-metadata schema
at load time, and projects catalog JSON into typed node metadata. The
worker side imports executors; the web/builder side reads catalog
metadata.
Install
npm i @flowget/registry-loaderUsage
Worker side — walk discovery records and import each executor:
import {
parseRegistryEnv,
expandBraces,
resolveRegistrySpecifier,
discoverRegistry,
} from "@flowget/registry-loader";
const entries = parseRegistryEnv(process.env.REGISTRY_DIR).flatMap(expandBraces);
const paths = entries.map((e) => resolveRegistrySpecifier(e));
const records = await discoverRegistry({ paths });
for (const record of records) {
const mod = await import(record.executorPath);
registerNode(record.name, mod.default);
}Web side — project each <name>.json into typed NodeMetadata. The
JSON is validated against the canonical node-metadata schema at load
time (an illegal type / valueType, a malformed handle, or a stray
top-level key fails loud with a RegistryScanError naming the node),
and each config field is enriched with its resolved FieldValueType:
import { loadCatalogJson } from "@flowget/registry-loader";
const catalog = await Promise.all(
records.map((r) => loadCatalogJson(r.jsonPath)),
);Custom TExtensions catalogs
The canonical schema is closed (additionalProperties: false), so it
rejects any top-level key it does not know. A catalog that attaches a
custom extension block via a different TExtensions type (e.g. a
decider's hitl) declares just that additive key — it is merged into
the canonical schema, which keeps its closed floor, so canonical fields
and stray typos are still validated:
const catalog = await Promise.all(
records.map((r) =>
loadCatalogJson(r.jsonPath, {
extensionProperties: { hitl: { type: "object" } },
}),
),
);REGISTRY_DIR is a comma-separated list. Each entry is a filesystem
path, an npm package subpath (resolved through the package's exports
field), or a brace expansion (<base>/nodes/{log,delay}). Duplicate
node ids across entries fail loud with a RegistryScanError.
⚠️ 0.x is unstable
The surface is unstable until v1 — breaking changes ship as minor
bumps. Pin exact versions in consumers ("@flowget/registry-loader":
"0.2.0", not "^0.2.0").
Links
- Full documentation: https://docs.flowget.io
- Security policy: SECURITY.md
- License: FSL-1.1-ALv2 (see LICENSE)
