Small, fast TypeScript runtime for the Blue Language: parse YAML/JSON into BlueNode graphs, preprocess (directives & mappings), resolve/merge types and references, and compute stable Blue IDs (Base58-SHA256) with first-class Zod interop.
npm install @blue-labs/languageSmall, fast TypeScript runtime for the Blue Language: parse YAML/JSON into BlueNode graphs, preprocess (directives & mappings), resolve/merge types and references, and compute stable Blue IDs (Base58-SHA256) with first-class Zod interop.
- BlueNode graph: single, list, map, typed values, metadata (name/description), contracts, and references by blueId.
- Preprocessing: blue: directive (aliases, BlueId, or URL fetch with allow-list), inline-type mappings, implicit type inference for primitives.
- Resolution/Merge: deterministic resolver with a pluggable MergingProcessor pipeline (value propagation, type checking, list/dict validators, metadata propagation, basic-type guard).
- BlueId: canonical JSON → SHA-256 → Base58; sync/async, lists supported; CIDv1 conversion.
- Providers: resolve by BlueId from memory, repositories or built-in bootstrap content; sequential composition.
- Zod mapping: convert nodes to typed objects with schema extensions & Blue annotations; serialize objects back to Blue-shaped JSON.
- Limits & paths: restrict extension/merge by path or depth; compose limits.
- Patching & transforms: RFC-6902-style patch ops for BlueNode; recursive transform utilities.
- URL fetching: pluggable strategy + caching + domain allow-list (opt-in).
``bash`
npm i @blue-labs/language zodor
yarn add @blue-labs/language zod
`ts
import { Blue, BasicNodeProvider, PathLimits } from '@blue-labs/language';
import { z } from 'zod';
// 1) Construct runtime (uses bootstrap types + your provider chain)
const blue = new Blue({
nodeProvider: new BasicNodeProvider(),
});
// 2) Parse YAML (or JSON) into a BlueNode
const yaml =
name: Greeting
value: Hello, Blue!;
const node = blue.yamlToNode(yaml);
// 3) Resolve (merge types/references), optionally with limits
const resolved = blue.resolve(node, PathLimits.withMaxDepth(10));
// 4) Compute BlueId
const blueId = blue.calculateBlueIdSync(resolved);
// 5) Map to a Zod schema (with annotations supported)
const Greeting = z.object({
name: z.string().optional(),
value: z.string(),
});
const asObject = blue.nodeToSchemaOutput(resolved, Greeting);
// 6) Convert back to JSON (choose strategy)
const official = blue.nodeToJson(resolved, 'official');
`
Register a generated repository package to resolve types and aliases. Historical type BlueIds are normalized by the ingestion helpers (yamlToNode/jsonValueToNode) after preprocessing; when you create nodes manually, ensure they already use current type BlueIds before type checks or schema output.
`ts
import { Blue } from '@blue-labs/language';
import { repository } from '@blue-repository/types';
const blue = new Blue({ repositories: [repository] });
const node = blue.jsonValueToNode({
type: { blueId: '...historical-blue-id...' },
value: 'hello',
});
// For manually constructed nodes, ensure current type BlueIds are used.
`
Serialize to a specific repository version with BlueContext:
`ts`
const json = blue.nodeToJson(node, {
format: 'official',
blueContext: {
repositories: {
myos: '...repo-blue-id...',
},
},
});
- BlueNode – node model (name, description, type, itemType, keyType, valueType, value, items, properties, blueId, blue directive).ResolvedBlueNode
- – wrapper for resolved nodes; includes getMinimalNode() and getMinimalBlueId().
- class BlueyamlToNode(_)/jsonValueToNode(_)
- Parsing: (+ async variants), which preprocess and normalize.BlueDirectivePreprocessor
- Preprocess: blue directive () + default pipeline (Preprocessor).resolve(node, limits)
- Resolve: → ResolvedBlueNode.calculateBlueId(_)/calculateBlueIdSync(_)
- IDs: .nodeToJson(node, 'official'|'simple'|'original'|{ format, blueContext })
- Mapping: , nodeToSchemaOutput(node, zod).isTypeOf(node, zod)
- Type checks: , isTypeOfNode(node, typeNode), isTypeOfBlueId(node, blueId).extend(node, limits)
- Helpers: , transform(node, fn), reverse(node), restoreInlineTypes(node).enablePreprocessingDirectivesFetchForDomains([...])
- Config: URL fetch allow-list (), global limits, repositories.
- Merger + MergingProcessor pipeline: value → types → lists/dicts → metadata → basic checks.createDefaultMergingProcessor()
- exports the default pipeline.
- NodeProvider, SequentialNodeProvider, BootstrapProvider, InMemoryNodeProvider, BasicNodeProvider, RepositoryBasedNodeProvider.NodeProviderWrapper.wrap(...)
- composes bootstrap, repositories, and your provider.
- BlueDirectivePreprocessor: resolves blue: directive (alias, BlueId, or URL).Preprocessor
- : runs transformations declared under blue: (replace inline type strings → BlueIds; infer basic types; validate inline types removed).BlueIdsMappingGenerator
- : accumulate BlueId mappings (repositories, custom, core).
- NodeToObjectConverter + converters for primitives/arrays/tuples/sets/maps/objects; supports schema extension resolution via TypeSchemaResolver.withTypeBlueId
- Schema annotations: , withBlueId, withBlueName, withBlueDescription, blueIdField, blueNodeField.
- BlueIdCalculator (sync/async); Base58Sha256Provider.BlueIds
- validator; BlueIdToCid and CidToBlueId converters.
- PathLimits, CompositeLimits, and NO_LIMITS. Build from node shape or explicit patterns.
- Nodes, NodeTransformer, NodePathAccessor (/path getter), patching via applyBlueNodePatch(es) implementing RFC-6902.UrlContentFetcher
- URL fetching: with pluggable { fetchUrl } and domain allow-list.
- docs/resolve.md – resolver & merging pipeline.docs/preprocessor.md
- – blue directive, inference & mappings.docs/blue-id.md
- – BlueId algorithm and APIs.docs/mapping.md
- – Zod mapping and serialization.docs/architecture.md` – end-to-end architecture.
-
The Changelog is regularly updated to reflect what's changed in each new release.
We welcome contributions! Please read our Contributing Guide to learn about how you can contribute.
This project is licensed under the MIT License. See the LICENSE file for more details.