@nekostack/schema 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -128
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,10 +8,9 @@
|
|
|
8
8
|
|---|---|
|
|
9
9
|
| **Build tier** | Foundation primitive — build first |
|
|
10
10
|
| **Depends on** | (none — foundational). External: TypeScript (dev/build). Peer: Zod (for runtime validation; not required at IR level). |
|
|
11
|
-
| **Used by** | `
|
|
11
|
+
| **Used by** | `@nekostack/cli` (published); `api`, `form`, `auth`, `config`, `events`, `telemetry`, and others (planned) |
|
|
12
12
|
| **Status** | **v1.0 — released.** Canonical IR + Zod / JSON Schema / OpenAPI / TypeScript generators + runtime validation. 1,294 tests; public surface frozen. |
|
|
13
13
|
| **Released** | [`schema-v1.0.0`](./CHANGELOG.md) — API frozen. Reserved-but-unbuilt IR capacity (unions, lazy/recursive refs, transforms, dates) lands in post-1.0 minors. |
|
|
14
|
-
| **Sellable?** | Not as the package itself. It's the **technical substrate** for a future registry/governance product. Schema-as-a-service requires registry + diffing + history + governance + CI integration on top — see [Product potential](#product-potential). |
|
|
15
14
|
|
|
16
15
|
## Why this exists
|
|
17
16
|
|
|
@@ -22,9 +21,8 @@ Every non-trivial app defines the same data shape in multiple places: TypeScript
|
|
|
22
21
|
Building this rather than adopting Zod is justified because:
|
|
23
22
|
|
|
24
23
|
1. **Zod is one output target, not the source.** A Zod-as-source architecture forces every non-Zod consumer to glue through adapters that drift.
|
|
25
|
-
2. **
|
|
26
|
-
3. **
|
|
27
|
-
4. **No vendor coupling.** Zod 4 introduces a breaking change? The generator emits Zod 3 syntax until you choose to migrate.
|
|
24
|
+
2. **Outputs target NekoStack's specific consumers** — the Zod output knows about NekoStack's normalized `Issue` shape; the OpenAPI output knows how NekoStack APIs version themselves.
|
|
25
|
+
3. **No vendor coupling.** Zod 4 introduces a breaking change? The generator emits Zod 3 syntax until you choose to migrate.
|
|
28
26
|
|
|
29
27
|
## Scope
|
|
30
28
|
|
|
@@ -50,7 +48,7 @@ Building this rather than adopting Zod is justified because:
|
|
|
50
48
|
|
|
51
49
|
## Boundary
|
|
52
50
|
|
|
53
|
-
> See
|
|
51
|
+
> See BOUNDARIES.md §7 in the NekoStack repository for the full capability map.
|
|
54
52
|
|
|
55
53
|
### Owns
|
|
56
54
|
- Canonical IR (`SchemaNode` AST)
|
|
@@ -407,36 +405,14 @@ The package can *generate* Zod without *requiring* Zod at runtime; consumers wan
|
|
|
407
405
|
|
|
408
406
|
---
|
|
409
407
|
|
|
410
|
-
## Competitors and adjacent tools
|
|
411
|
-
|
|
412
|
-
| Tool | What they do well | Where they fall short for us |
|
|
413
|
-
|---|---|---|
|
|
414
|
-
| **Zod** | Excellent runtime validator, great TS inference, large ecosystem; ~all NekoStack consumers will run *generated* Zod at runtime. | Zod-as-source forces every non-Zod consumer through adapters that drift. We emit Zod as one output target; we don't make Zod the source format. |
|
|
415
|
-
| **TypeBox** | JSON-Schema-first, fast, multi-target. | DSL is verbose and less TS-native; closer in spirit to our approach but with different priorities. |
|
|
416
|
-
| **Effect-Schema** | Extremely powerful, principled, multi-output. | Steep learning curve, deep Effect ecosystem coupling, overkill for solo dev. |
|
|
417
|
-
| **io-ts** | Mature, principled. | Verbose, weaker TS inference than Zod, declining ecosystem. |
|
|
418
|
-
| **Valibot** | Tree-shakeable Zod alternative. | Same single-output limitation as Zod. |
|
|
419
|
-
| **JSON Schema (raw)** | Universal interchange format. | Hand-written JSON is hostile to author and review. |
|
|
420
|
-
| **TypeBox + zod-from-json-schema** | Multi-tool stack. | Toolchain becomes the spec — fragile, hard to evolve consistently. |
|
|
421
|
-
|
|
422
|
-
The right framing — corrected from the original audit critique:
|
|
423
|
-
|
|
424
|
-
> NekoStack is not "better Zod." It is a **schema IR + generator system** that emits Zod as one target alongside JSON Schema, OpenAPI, and TypeScript. The unique value is multi-output semantic consistency, not DSL ergonomics.
|
|
425
|
-
|
|
426
408
|
## How this fits the NekoStack
|
|
427
409
|
|
|
428
410
|
**Depends on:** Nothing within NekoStack. This is foundational — every other package may depend on it.
|
|
429
411
|
|
|
430
|
-
**
|
|
431
|
-
- `@nekostack/
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
- `@nekostack/codex` — validates entity shape definitions.
|
|
435
|
-
- `@nekostack/auth` — typifies token claims + `AccessDecision` shapes.
|
|
436
|
-
- `@nekostack/config` — boot-time env + runtime config validation.
|
|
437
|
-
- `@nekostack/events` — event payload shapes.
|
|
438
|
-
- `@nekostack/telemetry` — typed event catalog shapes.
|
|
439
|
-
- Effectively everything that crosses a system boundary.
|
|
412
|
+
**Published packages that consume schema:**
|
|
413
|
+
- `@nekostack/cli` — schema validation, codegen, and diff commands.
|
|
414
|
+
|
|
415
|
+
**Planned:** `@nekostack/api`, `@nekostack/form`, `@nekostack/auth`, `@nekostack/config`, `@nekostack/events`, `@nekostack/telemetry`, and others in the NekoStack ecosystem all plan to consume this package as their data-shape substrate.
|
|
440
416
|
|
|
441
417
|
## Design philosophy
|
|
442
418
|
|
|
@@ -500,56 +476,12 @@ export type User = s.infer<typeof User>;
|
|
|
500
476
|
|
|
501
477
|
## Roadmap
|
|
502
478
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
- `
|
|
507
|
-
|
|
508
|
-
-
|
|
509
|
-
- Metadata: id, version, description, deprecated flag.
|
|
510
|
-
- Basic `Issue` shape, normalized codes.
|
|
511
|
-
- TypeScript type inference (`s.infer<T>`).
|
|
512
|
-
- Builder unit tests + type inference tests.
|
|
513
|
-
|
|
514
|
-
### v0.2 — TypeScript + Zod generation
|
|
515
|
-
- TS generator (`.d.ts` output).
|
|
516
|
-
- Zod generator (Zod 3.x target initially).
|
|
517
|
-
- Deterministic header.
|
|
518
|
-
- Snapshot tests for generator output.
|
|
519
|
-
- Zod-execution tests (generated validator runs and matches fixtures).
|
|
520
|
-
|
|
521
|
-
### v0.3 — JSON Schema generation
|
|
522
|
-
- JSON Schema draft 2020-12 output.
|
|
523
|
-
- `$id` / `$defs` / `$ref` per identity rules.
|
|
524
|
-
- Portable constraint mapping (min/max/regex/format/etc.).
|
|
525
|
-
- Semantic-loss metadata for runtime-only refinements (`x-nekostack-runtime-refinement`).
|
|
526
|
-
- JSON Schema test-suite conformance.
|
|
527
|
-
|
|
528
|
-
### v0.4 — OpenAPI 3.1 generation
|
|
529
|
-
- OpenAPI 3.1 component schemas.
|
|
530
|
-
- Integration fixtures for `@nekostack/api`.
|
|
531
|
-
- Nullable / required mapping per the Absence Semantics table.
|
|
532
|
-
- Round-trip tests with `@redocly/openapi-core`.
|
|
533
|
-
|
|
534
|
-
### v0.5 — Composition
|
|
535
|
-
- `extend`, `pick`, `omit`, `partial`, `required`.
|
|
536
|
-
- Conflict-safe `merge` with explicit `override`.
|
|
537
|
-
- Composition tests covering conflict cases.
|
|
538
|
-
|
|
539
|
-
### v0.6 — Runtime validation
|
|
540
|
-
- `validate(schema, input)` returning `Result<T, Issue[]>`.
|
|
541
|
-
- Unknown-key handling (strict / stripUnknown / passthrough).
|
|
542
|
-
- Zod-backed execution (runtime delegates to generated Zod).
|
|
543
|
-
- Issue normalization (raw Zod issues → NekoStack `Issue` codes).
|
|
544
|
-
- Semantic-parity tests: same fixture validated against Neko runtime, generated Zod, JSON Schema validator, OpenAPI-compatible schema — expected failures match.
|
|
545
|
-
|
|
546
|
-
### v0.7 — Registry-lite
|
|
547
|
-
- Local schema registry (lookup by id + version).
|
|
548
|
-
- Schema diffing between two versions.
|
|
549
|
-
- Breaking-change detection per the matrix below.
|
|
550
|
-
- `neko schema check` (freshness) and `neko schema diff` (changes).
|
|
551
|
-
|
|
552
|
-
**Breaking-change matrix** (v0.7 implementation target):
|
|
479
|
+
v1.0 is the stable, API-frozen baseline. Post-v1.0 work:
|
|
480
|
+
|
|
481
|
+
- **Reserved IR capacity** — `s.union()`, `s.lazy()` (recursive), `s.transform()`, and full date typing are in the IR type system; generator support for the full surface lands in post-v1.0 minors.
|
|
482
|
+
- **Registry-lite** — local schema registry, schema diffing between versions, and breaking-change detection (`neko schema diff`).
|
|
483
|
+
|
|
484
|
+
**Breaking-change matrix** (registry-lite target):
|
|
553
485
|
|
|
554
486
|
| Change | Compatibility |
|
|
555
487
|
|---|---|
|
|
@@ -566,21 +498,9 @@ Revised after the design-audit pass. Migrations pushed from v0.5 to v0.8+ becaus
|
|
|
566
498
|
| Rename field | **breaking** in all directions unless explicitly aliased |
|
|
567
499
|
| Add discriminated-union branch | non-breaking for consumers using fallback; breaking otherwise |
|
|
568
500
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
- Migration registry with version graph.
|
|
573
|
-
- Forward migrations between versioned schemas.
|
|
574
|
-
- Pre/post migration validation.
|
|
575
|
-
- Migration provenance and audit.
|
|
576
|
-
- Failure behavior + downgrade policy.
|
|
577
|
-
- Fixture tests per version pair.
|
|
578
|
-
|
|
579
|
-
### v1.0 — Stable API
|
|
580
|
-
- Full documentation site.
|
|
581
|
-
- Migration guide from Zod-as-source.
|
|
582
|
-
- Performance benchmarks vs Zod and TypeBox.
|
|
583
|
-
- Companion spec docs (deferred from v0.x): full Issue code catalog, generated-artifact policy details, testing strategy.
|
|
501
|
+
- **Schema migrations** — forward migration registry, version graph, migration provenance + audit.
|
|
502
|
+
- **Generator plugin contract** — stable contract for third-party generators (Prisma DDL, GraphQL SDL, etc.).
|
|
503
|
+
- **Performance benchmarks** — vs Zod and TypeBox.
|
|
584
504
|
|
|
585
505
|
## Testing strategy
|
|
586
506
|
|
|
@@ -602,30 +522,9 @@ Revised after the design-audit pass. Migrations pushed from v0.5 to v0.8+ becaus
|
|
|
602
522
|
|
|
603
523
|
Semantic parity is the load-bearing test category. Where the four outputs cannot match (runtime-only refinements being the prime case), the test asserts the *expected gap*, not equality.
|
|
604
524
|
|
|
605
|
-
## Product potential
|
|
606
|
-
|
|
607
|
-
**Internal use:** Mandatory. The whole stack rests on this.
|
|
608
|
-
|
|
609
|
-
**Open-source release:** Strong candidate. The multi-output semantic-consistency angle is genuinely undersupplied. MIT-licensed release with good docs could attract real users — particularly TS teams running multi-language stacks (TS frontend + Python backend, or generating SDKs for non-TS consumers).
|
|
610
|
-
|
|
611
|
-
**Commercial product (corrected from the original brief):** `@nekostack/schema` is **not the commercial product by itself**. It is the technical substrate for a future registry/governance product. A schema package becomes commercially interesting only when paired with:
|
|
612
|
-
|
|
613
|
-
- Hosted schema registry with version history
|
|
614
|
-
- Cross-version diffing + breaking-change detection
|
|
615
|
-
- SDK / codegen integration (à la Speakeasy / Stainless, but one layer earlier)
|
|
616
|
-
- Schema governance + team permissions
|
|
617
|
-
- CI integration (PR-level schema-change review)
|
|
618
|
-
- Changelog generation
|
|
619
|
-
- Compliance export
|
|
620
|
-
- Migration tracking
|
|
621
|
-
|
|
622
|
-
That commercial product would be a separate offering (e.g., `@nekostack/schema-cloud` or NekoSystems' enterprise tier consuming this) — built on top of this primitive. Not a near-term focus, but the path is real.
|
|
623
|
-
|
|
624
|
-
**Estimated effort to v1.0:** 6–12 weeks of focused work; more realistically 4–8 months at solo-dev cadence. Revised up from the original 4–8 / 3–6 because the IR + semantic-loss + identity + parity-test work added scope.
|
|
625
|
-
|
|
626
525
|
## Locked Design Decisions (v1.0 Freeze)
|
|
627
526
|
|
|
628
|
-
These
|
|
527
|
+
These are stable API contracts guaranteed not to change in v1.x.
|
|
629
528
|
|
|
630
529
|
- **No Async Refinements.** `refineAsync` is explicitly rejected. Validation must remain a pure, synchronous, CPU-bound operation. If a check requires I/O (e.g., querying a database to see if a username is taken), it is **Business Logic**, not **Shape Validation**, and belongs in a Controller or Service.
|
|
631
530
|
- **Recursive Schema Cycles (`A → B → A`).** `s.lazy()` MUST take a string ID representing the target schema (e.g., `s.lazy("com.nekostack.User")`). The compiler does not attempt to resolve this during definition. It is resolved safely at runtime by querying the `schemaRegistry`. If the ID doesn't exist, it throws `recursive_reference_unresolved`.
|
|
@@ -645,12 +544,4 @@ Items here should graduate into the Implementation contracts section once decide
|
|
|
645
544
|
|
|
646
545
|
## Status
|
|
647
546
|
|
|
648
|
-
|
|
649
|
-
- **Owner:** Cody (solo dev project).
|
|
650
|
-
- **Priority tier:** Foundation primitive.
|
|
651
|
-
- **Estimated learning return:** Very high. Schema-system design, type-level TypeScript, code-gen architecture, JSON Schema semantics, OpenAPI 3.1 internals, semantic-loss management, deterministic output discipline — all in one project.
|
|
652
|
-
- **Source thinking:**
|
|
653
|
-
- Initial audit: [`references/schema/design-audit-2026-05.md`](../../references/schema/design-audit-2026-05.md) — drove the IR / semantic-loss / identity / strict-by-default / migration-deferral additions.
|
|
654
|
-
- Follow-up audit: [`references/schema/design-audit-2026-05-followup.md`](../../references/schema/design-audit-2026-05-followup.md) — drove the Transform input/output split, Union policy, validate-vs-parse, coercion policy, IR hash, breaking-change matrix, and the Still-open section.
|
|
655
|
-
|
|
656
|
-
Future significant design changes should generate a similar audit document and link from here. The pattern is: audit → revise → preserve source thinking → label open decisions → repeat as design matures.
|
|
547
|
+
v1.0 — public API frozen. 1,294 tests passing. See the [CHANGELOG](./CHANGELOG.md) for release history.
|