@noego/stitch
v1.0.1
Published
Stitch merges multiple YAML files into a single, validated artifact. It’s ideal for modular OpenAPI specs and other structured YAML, with CLI, Node, and browser support — plus VSCode schema integration for real‑time validation.
Readme
Stitch — Modular YAML Merging and Validation
Stitch merges multiple YAML files into a single, validated artifact. It’s ideal for modular OpenAPI specs and other structured YAML, with CLI, Node, and browser support — plus VSCode schema integration for real‑time validation.
Note: OpenAPI is used throughout as a familiar example, but Stitch is schema‑agnostic and works with any YAML configuration.
Core Features
- Deterministic ordering: Globs expand to files sorted alphabetically; the order in
stitch.yamldecides precedence (later wins). - Deep merge for objects: Keys are joined recursively; later files override earlier values for the same key.
- Arrays replace, not concatenate: When a key maps to an array, the array from the later file fully replaces the earlier one.
- Flexible validation: Lightweight OpenAPI shape checks or full JSON Schema validation via AJV.
- Multi-environment: Same engine for CLI/Node, plus browser helpers for Vite.
- Watch + output: Rebuild on changes; write YAML/JSON to file with a generated-file header.
How merging works (keys and arrays)
Given two files merged in order: base.yaml, then override.yaml.
Objects (keys are joined, later overrides):
# base.yaml
info:
title: My API
version: 1.0.0
contact:
name: Team A
# override.yaml
info:
version: 1.1.0
contact:
email: [email protected]Result:
info:
title: My API # from base
version: 1.1.0 # overridden by override
contact:
name: Team A # preserved from base
email: [email protected]Arrays (later replaces earlier, no concat):
# base.yaml
servers:
- url: https://api.example.com
- url: https://staging.example.com
# override.yaml
servers:
- url: http://localhost:3000Result:
servers:
- url: http://localhost:3000Primitives (later replaces earlier):
# base.yaml
openapi: 3.0.3
# override.yaml
openapi: 3.1.0Result: openapi: 3.1.0
Works With Any YAML
- Schema‑agnostic: Stitch performs generic YAML deep merges; it is not tied to OpenAPI.
- Validation choices: For non‑OpenAPI configs, either skip
--validateor provide your own JSON Schema path.
Config File (stitch.yaml)
Stitch expects a YAML config whose top-level key is stitch, an array of file paths and/or glob patterns. Paths are resolved relative to the config file’s directory. Files are merged in the order listed; glob matches are sorted alphabetically.
Minimal example:
# stitch.yaml
stitch:
- openapi/base.yaml
- openapi/components/**/*.yaml
- openapi/paths/**/*.yaml
- overrides/*.yamlNotes
- Required key:
stitchmust be an array. - Relative base: paths/globs are resolved relative to the config file location.
- Ordering: list order decides precedence; later files override earlier ones.
- Globs:
*,**,?, and character classes are supported. - JSON is fine too: JSON is a subset of YAML, so a
.jsonconfig with the same shape works. - OpenAPI is just an example here: use any YAML file layout and names for your domain.
Using a different config file
- CLI: pass the config file as a positional argument, e.g.
stitch build my-config.yamlorstitch watch my-config.yaml. - Programmatic:
stitch.build({ input: 'my-config.yaml', ... })orengine.build('my-config.yaml', ...).
Why Stitch
- Modularize YAML: Keep specs split across files and folders without losing clarity.
- Validate output: Use JSON Schema (AJV) or basic structure checks.
- Watch and rebuild: Fast dev feedback when files change.
- Run anywhere: Same engine for CLI, Node, and browser (Vite).
- IDE assistance: Auto‑configure VSCode to validate YAML as you type.
Key Capabilities
- Merge: Ordered deep‑merge of YAML files and globs; later files override earlier keys.
- Validate: AJV JSON Schema or basic OpenAPI structure checks.
- Output: YAML or JSON to stdout or file (with generated‑file headers when writing files).
- Watch: Rebuild on changes with chokidar.
- VSCode: Install yaml.schemas mapping into
.vscode/settings.json. - Browser: Merge content via
import.meta.globor raw strings (Vite).
Quick Start
CLI
stitch [command] [input-file] [options]
# Build and print to stdout (defaults to stitch.yaml)
stitch build
# Build specific config
stitch build my-config.yaml
# Output to a file (adds generated-file header)
stitch build --output dist/openapi.yaml
# Output JSON instead of YAML
stitch build --format json
# Validate (basic) or with a schema
stitch build --validate
stitch build --validate schemas/schema.json
# Watch for changes and rebuild
stitch watch --validate schemas/schema.jsonOptions
--output <file>: write to a file instead of stdout--format <json|yaml>: output format (default: yaml)--validate [schema]: basic validation or path to JSON Schema--quiet: build/validate but don’t print content
Programmatic (Node)
import { stitch, StitchEngine } from 'stitch';
// Convenience API
await stitch.build({
input: 'stitch.yaml',
output: 'dist/openapi.yaml',
format: 'yaml',
validate: 'schemas/schema.json',
});
// Direct engine usage
const engine = new StitchEngine();
const result = engine.buildSync('stitch.yaml', { format: 'json' });
await engine.watch('stitch.yaml', { validate: true });
// VSCode schema installation
engine.install({
schemaPath: 'schemas/schema.json',
targets: ['*.yaml', 'openapi/*.yaml'],
vscodeSettingsPath: '.vscode/settings.json',
});Browser / Vite
import { stitchFromViteImports, stitchFromContent } from 'stitch/browser';
// Vite import.meta.glob integration
const imports = import.meta.glob('./openapi/*.yaml', { as: 'raw' });
const merged = await stitchFromViteImports(imports);
// Direct content merging
const result = stitchFromContent([
{ content: baseYaml, name: 'base.yaml' },
{ content: pathsYaml, name: 'paths.yaml' },
]);Merge Rules
- Objects: deep‑merge — later files override keys.
- Arrays: later arrays replace earlier arrays (no concatenation).
- Primitives: later values replace earlier values.
Validation
- Basic:
--validateenables lightweight OpenAPI shape checks (openapi,info). If your content is not OpenAPI, skip this flag. - JSON Schema:
--validate schemas/schema.jsonenables full AJV validation against your schema (works for any YAML domain).
VSCode Integration
Install a JSON Schema mapping so VSCode validates YAML in real‑time:
stitch install schemas/schema.json --target "**/*.yaml"Manual configuration example (.vscode/settings.json):
{
"yaml.schemas": {
"./schemas/schema.json": ["**/*.yaml"]
},
"yaml.validate": true
}Example Project Structure
project/
├── stitch.yaml
├── openapi/
│ ├── base.yaml
│ ├── paths/
│ │ ├── users.yaml
│ │ └── posts.yaml
│ └── components/
│ └── schemas/
└── schemas/
└── schema.jsonFramework Integrations (Optional)
If you use framework‑specific schemas, you can install them too:
stitch install @noego/forge/schema.json --target "openapi/*.yaml"
stitch install @noego/dinner/schema.json --target "**/*.yaml"License
MIT
