zopia 0.3.0
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/CHANGELOG.md +354 -0
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/bin/zopia.js +20 -0
- package/docs/01-overview.md +94 -0
- package/docs/02-targets.md +55 -0
- package/docs/03-roadmap.md +205 -0
- package/docs/04-architecture.md +345 -0
- package/docs/05-concepts.md +239 -0
- package/docs/06-conversions.md +493 -0
- package/docs/07-api-docs.md +337 -0
- package/docs/08-components.md +223 -0
- package/docs/09-configuration.md +167 -0
- package/docs/10-usage.md +208 -0
- package/docs/11-testing.md +267 -0
- package/docs/12-standards.md +242 -0
- package/docs/README.md +42 -0
- package/docs/publish-workflow.yml.example +48 -0
- package/package.json +77 -0
- package/src/api-docs-navigation.ts +353 -0
- package/src/cli-command.ts +537 -0
- package/src/cli.ts +4 -0
- package/src/config.ts +190 -0
- package/src/conversions/api-docs-facade.ts +42 -0
- package/src/conversions/api-docs-generate.ts +567 -0
- package/src/conversions/api-docs-layout.ts +39 -0
- package/src/conversions/api-docs-plan.ts +130 -0
- package/src/conversions/api-docs-presets.ts +246 -0
- package/src/conversions/json-schema-to-zod.ts +931 -0
- package/src/conversions/manifest-staleness.ts +211 -0
- package/src/conversions/manifest-to-openapi.ts +1861 -0
- package/src/conversions/manifest-writer.ts +778 -0
- package/src/conversions/openapi-contracts.ts +333 -0
- package/src/conversions/openapi-external-ref.ts +233 -0
- package/src/conversions/openapi-ir.ts +74 -0
- package/src/conversions/openapi-ref.ts +38 -0
- package/src/conversions/openapi-to-api-docs-public.ts +466 -0
- package/src/conversions/openapi-to-api-docs.ts +203 -0
- package/src/conversions/openapi.ts +80 -0
- package/src/conversions/reverse-security.ts +68 -0
- package/src/conversions/yaml.ts +876 -0
- package/src/conversions/zod-to-json-schema.ts +536 -0
- package/src/diff.ts +353 -0
- package/src/errors.ts +114 -0
- package/src/index.ts +80 -0
- package/src/validation.ts +299 -0
- package/src/warnings.ts +164 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# ๐งญ Overview
|
|
2
|
+
|
|
3
|
+
zopia is a **type-safe OpenAPI โ Zod toolkit** for generating, validating, and
|
|
4
|
+
transforming API schemas. It converts between the four formats an API team
|
|
5
|
+
lives in โ **Swagger 2.0**, **OpenAPI 3.x**, **JSON Schema**, and **Zod v4** โ
|
|
6
|
+
and turns any of them into a tree of **type-safe `km-api` endpoint files** that
|
|
7
|
+
drop straight into a TypeScript codebase.
|
|
8
|
+
|
|
9
|
+
## ๐ฉ๏ธ The problem
|
|
10
|
+
|
|
11
|
+
API teams keep the same knowledge in many places, and every copy drifts:
|
|
12
|
+
|
|
13
|
+
| ๐ Pain | ๐ Consequence |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| The spec (`swagger.json`) describes the API | โฆbut the validation code is written by hand |
|
|
16
|
+
| Zod schemas validate at runtime | โฆbut they are re-typed from the spec, field by field |
|
|
17
|
+
| Components (`$ref`) keep the DRY spec | โฆbut the generated code duplicates the same shapes |
|
|
18
|
+
| Swagger 2.0 and OpenAPI 3.x differ subtly | โฆand both must be supported to read legacy specs |
|
|
19
|
+
|
|
20
|
+
**Every copy is a source of bugs. Every re-typing is a waste of time.**
|
|
21
|
+
|
|
22
|
+
## ๐ ๏ธ The solution
|
|
23
|
+
|
|
24
|
+
zopia makes the spec and the code **two views of one fact**:
|
|
25
|
+
|
|
26
|
+
```mermaid
|
|
27
|
+
flowchart LR
|
|
28
|
+
A["๐ swagger.json<br/>(v2 / v3)"] -->|"โข openapi โ api docs"| B["๐ api_docs/**<br/>(.ts ยท km-api ยท zod v4)"]
|
|
29
|
+
B -->|"โฃ api docs โ openapi"| A
|
|
30
|
+
C["โ๏ธ Zod v4 schemas"] -->|"โ zod โ JSON Schema"| D["๐ JSON Schema"]
|
|
31
|
+
D -->|"โก JSON Schema โ zod"| C
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- **โข** reads a spec, resolves every `$ref`, and renders one **`index.ts` per
|
|
35
|
+
endpoint** โ each built with `makeApiConfig()` from **km-api** (0.4.x), with
|
|
36
|
+
request/response/params/query/headers/cookies validated by **Zod v4** schemas.
|
|
37
|
+
- **โฃ** reads that tree back and regenerates a complete OpenAPI document โ so
|
|
38
|
+
developer edits to the generated code become the new spec.
|
|
39
|
+
- **โ / โก** are the two primitive schema converters the other engines are built on.
|
|
40
|
+
|
|
41
|
+
## ๐ฏ The promise
|
|
42
|
+
|
|
43
|
+
> **Fast and valid developing.** A developer gets **valid, documented,
|
|
44
|
+
> type-safe** endpoint code **in seconds**, from a spec they already trust โ
|
|
45
|
+
> and can always get the spec back.
|
|
46
|
+
|
|
47
|
+
## ๐งฐ The stack (fixed, by standard)
|
|
48
|
+
|
|
49
|
+
| ๐งฉ Piece | Version | Role in zopia |
|
|
50
|
+
| --- | --- | --- |
|
|
51
|
+
| โ๏ธ [Zod](https://zod.dev/) | **v4** (`^4`) | Runtime validation + static types; built-in `z.toJSONSchema()` |
|
|
52
|
+
| ๐งฑ [km-api](https://www.npmjs.com/package/km-api) | **0.4.x** (`^0.4` from npm) | The "make function" โ `makeApiConfig()` builds every generated endpoint |
|
|
53
|
+
| ๐ฃ [Bun](https://bun.sh/) | `โฅ 1.1` | Primary runtime & toolchain (runs the package, tests, and generated code) |
|
|
54
|
+
| ๐งช [Vitest](https://vitest.dev/) | latest stable | Test runner for the full scenario matrix |
|
|
55
|
+
| ๐ท TypeScript | `5.9+`, `strict` | Language of the package and of every generated file |
|
|
56
|
+
|
|
57
|
+
## ๐ฅ Who is this for?
|
|
58
|
+
|
|
59
|
+
- ๐งโ๐ป **TypeScript backend teams** that maintain a Swagger/OpenAPI spec and
|
|
60
|
+
want the validation layer generated, not hand-written
|
|
61
|
+
- ๐ **Legacy teams** still on Swagger 2.0 who need a path to OpenAPI 3.x
|
|
62
|
+
- ๐ค **Full-stack teams** that want one artifact (`api_docs/**`) shared between
|
|
63
|
+
server validation and client code
|
|
64
|
+
|
|
65
|
+
## ๐ซ Non-goals (Phase 1)
|
|
66
|
+
|
|
67
|
+
Being explicit about what zopia **does not do** keeps the scope honest:
|
|
68
|
+
|
|
69
|
+
- ๐ It is **not a runtime** โ no HTTP server, no client, no hosting of specs.
|
|
70
|
+
(km-api already provides client adapters; zopia generates the definitions.)
|
|
71
|
+
- โ๏ธ It is **not a spec editor** โ it never edits your original spec file.
|
|
72
|
+
- ๐งฎ It does **not execute user code** except through the documented,
|
|
73
|
+
trusted-input contract of engine โฃ (see [Standards โ Safety](12-standards.md#-safety)).
|
|
74
|
+
- ๐ **YAML input** โ v0.1.0 accepted JSON only; v0.2.x lifts that limit
|
|
75
|
+
(D-16): JSON/YAML objects, JSON/YAML text, and `spec.json` / `spec.yaml` /
|
|
76
|
+
`spec.yml` all enter the same normalized model through zopia's owned
|
|
77
|
+
deterministic YAML parser.
|
|
78
|
+
|
|
79
|
+
## ๐ Core principles
|
|
80
|
+
|
|
81
|
+
| # | Principle | Meaning |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| P-1 | ๐ฏ **Deterministic** | Same input + same options โ **byte-identical** output. No timestamps, no random order, no environment leakage. |
|
|
84
|
+
| P-2 | ๐ **Lossless by design** | Every conversion is reversible; what cannot be represented in the target format is recorded (manifest + warnings), never silently dropped. |
|
|
85
|
+
| P-3 | ๐งผ **Pure core** | In-memory transforms stay pure; documented file reads, generated-tree writes/imports, and CLI process access live at explicit adapter boundaries. |
|
|
86
|
+
| P-4 | ๐ก๏ธ **Safe** | Fail loudly with typed, actionable errors; never write outside the configured output directory; never hide lossy conversions. |
|
|
87
|
+
| P-5 | ๐ **Documented** | Every public symbol has JSDoc; every rule is numbered; every decision is recorded. |
|
|
88
|
+
| P-6 | ๐ฆ **Dependency-light** | Zero bundled runtime dependencies; `zod` and `km-api` remain explicit peers (`zod` powers engines โ /โก and generated schemas; km-api powers generated endpoints and their reverse imports). |
|
|
89
|
+
|
|
90
|
+
## ๐ Next
|
|
91
|
+
|
|
92
|
+
- ๐ฏ The completed public targets โ [Targets](02-targets.md)
|
|
93
|
+
- ๐บ๏ธ Release phases and deferred breadth โ [Roadmap](03-roadmap.md)
|
|
94
|
+
- ๐งฉ Words you will keep seeing โ [Concepts](05-concepts.md)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# ๐ฏ Targets
|
|
2
|
+
|
|
3
|
+
These are the **explicit, testable targets** of zopia. Every Phase 1 target maps
|
|
4
|
+
to its governing document and automated release-gate coverage โ see
|
|
5
|
+
[Testing โ Scenario matrix](11-testing.md).
|
|
6
|
+
|
|
7
|
+
> โ
**Complete** = implemented, documented, and covered by the release gate.
|
|
8
|
+
> Deferred work is listed explicitly under [Roadmap โ Phase 2](03-roadmap.md#-phase-2--breadth-v02x-).
|
|
9
|
+
|
|
10
|
+
## ๐ Conversion targets
|
|
11
|
+
|
|
12
|
+
| # | ๐ฏ Target | Spec | Status |
|
|
13
|
+
| --- | --- | --- | --- |
|
|
14
|
+
| T-1 | **Convert Zod โ JSON Schema** | [Conversions โ Engine โ ](06-conversions.md) | โ
|
|
|
15
|
+
| T-2 | **Convert JSON Schema โ Zod** | [Conversions โ Engine โก](06-conversions.md) | โ
|
|
|
16
|
+
| T-3 | **Convert OpenAPI โ api docs** โ Swagger 2.0 *and* OpenAPI 3.0/3.1 | [Conversions โ Engine โข](06-conversions.md) | โ
|
|
|
17
|
+
| T-4 | **Convert api docs โ OpenAPI** (the reverse direction) | [Conversions โ Engine โฃ](06-conversions.md) | โ
|
|
|
18
|
+
|
|
19
|
+
## ๐ API docs targets
|
|
20
|
+
|
|
21
|
+
| # | ๐ฏ Target | Spec | Status |
|
|
22
|
+
| --- | --- | --- | --- |
|
|
23
|
+
| T-5 | **Layout mode `directory`** โ `api_docs/` + path segments as nested directories + a method-named directory at the last level + `index` file | [API docs format โ directory mode](07-api-docs.md) | โ
|
|
|
24
|
+
| T-6 | **Layout mode `flat`** โ `api_docs/` + one directory per API + method directory + `index` file | [API docs format โ flat mode](07-api-docs.md#-mode--flat) | โ
|
|
|
25
|
+
| T-7 | **`index.ts` files are TypeScript** and fill **all practical content** of the endpoint (method, path, operationId, summary, description, tags, auth, content types, request, response, examples) using **`makeApiConfig()` from km-api** (the package's make function) | [API docs format โ `index.ts` contract](07-api-docs.md#-the-indexts-contract) | โ
|
|
|
26
|
+
| T-8 | **Option `insertComponents: boolean`** โ when `true`, components are written into `api_docs` as their own schema files; **default `false`** | [Components](08-components.md) ยท [Configuration](09-configuration.md) | โ
|
|
|
27
|
+
| T-9 | **Option `useComponentAsReference: boolean`** โ endpoints import emitted components recursively; requires `insertComponents: true`; **default `false`** | [Components โ option matrix](08-components.md) | โ
|
|
|
28
|
+
|
|
29
|
+
## ๐ Reverse-conversion targets
|
|
30
|
+
|
|
31
|
+
| # | ๐ฏ Target | Spec | Status |
|
|
32
|
+
| --- | --- | --- | --- |
|
|
33
|
+
| T-10 | **Reversible output** โ the generated tree contains everything needed to regenerate the spec (paths, methods, schemas, metadata), guaranteed by the manifest | [API docs format โ manifest](07-api-docs.md) | โ
|
|
|
34
|
+
| T-11 | **Round-trip stability** โ `openapi โ api docs โ openapi` and `zod โ JSON Schema โ zod` converge: re-running the pipeline on its own output is a no-op (idempotent) | [Testing โ round-trip tests](11-testing.md#-round-trip-property-tests) | โ
|
|
|
35
|
+
|
|
36
|
+
## ๐๏ธ Engineering targets
|
|
37
|
+
|
|
38
|
+
| # | ๐ฏ Target | Spec | Status |
|
|
39
|
+
| --- | --- | --- | --- |
|
|
40
|
+
| T-12 | **JSDoc everywhere** โ every exported function, type, constant, and class is documented (template + rules fixed) | [Standards โ JSDoc standard](12-standards.md) | โ
|
|
|
41
|
+
| T-13 | **Tests in all scenarios** โ Vitest suite covering the full scenario matrix (spec versions, ref graphs, modes, option combinations, zod features, edge cases), run with Bun | [Testing](11-testing.md) | โ
|
|
|
42
|
+
| T-14 | **Bun runs the project** โ install, typecheck, test, coverage, CLI, and generated-TypeScript imports all work through one pinned-Bun gate | [Standards โ Bun gate](12-standards.md#-bun-gate) | โ
|
|
|
43
|
+
| T-15 | **Standard documentation** โ `docs/` directory with targets, roadmap, architecture, conventions; README links into it; beautiful, icon-based markdown | this document set ยท [Standards โ Docs convention](12-standards.md#-docs-convention) | โ
|
|
|
44
|
+
| T-16 | **Quality bar** โ pure, safe, clean code with descriptions; deterministic output; typed errors; no silent lossy conversions | [Standards](12-standards.md) | โ
|
|
|
45
|
+
| T-17 | **Changelog after commits** โ `CHANGELOG.md` updated by every user-facing commit under `Unreleased` | [Standards โ Changelog convention](12-standards.md#-changelog-convention) | โ
|
|
|
46
|
+
|
|
47
|
+
## ๐บ๏ธ Out of scope for the first phase
|
|
48
|
+
|
|
49
|
+
> ๐ The reverse-conversion *capability* (T-4/T-10/T-11) **is** in the first
|
|
50
|
+
> phase โ it is part of the four targets above. What is deferred:
|
|
51
|
+
|
|
52
|
+
- ~~๐ YAML spec input~~ โ shipped in v0.2.x (D-16; `.yaml`/`.yml` files and inline YAML text reach the same normalized model as JSON)
|
|
53
|
+
- ๐ External (multi-file) `$ref`s โ [Roadmap Phase 2](03-roadmap.md)
|
|
54
|
+
- ๐งฉ Reusable **parameters / responses** as emitted components (Phase 1 emits `components.schemas` only) โ [Roadmap Phase 2](03-roadmap.md)
|
|
55
|
+
- ~~๐ฅ๏ธ `zopia validate` (spec linting)~~ โ shipped in v0.3.x (S-89; [Roadmap Phase 3](03-roadmap.md)); incremental regeneration remains deferred
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# ๐บ๏ธ Roadmap
|
|
2
|
+
|
|
3
|
+
zopia ships in phases. **Phase 0 is this documentation set** โ the contracts
|
|
4
|
+
are fixed before a line of code is written, so implementation never re-decides
|
|
5
|
+
anything.
|
|
6
|
+
|
|
7
|
+
## ๐ฆ Phase 0 โ Documentation & standards โ
|
|
8
|
+
|
|
9
|
+
The standard documentation of the project:
|
|
10
|
+
|
|
11
|
+
- ๐ `docs/` โ overview, targets, roadmap, architecture, concepts, conversions,
|
|
12
|
+
api-docs format, components, configuration, usage, testing, standards
|
|
13
|
+
- ๐ `README.md` โ project home with the documentation map
|
|
14
|
+
- ๐ `CHANGELOG.md` โ Keep-a-Changelog format + the "changelog after commits" rule
|
|
15
|
+
- ๐ `LICENSE` (MIT) ยท ๐งน `.gitignore`
|
|
16
|
+
- ๐ Key decisions **D-01 โฆ D-15** recorded in [Standards](12-standards.md#-key-decisions)
|
|
17
|
+
|
|
18
|
+
**Completed:** the documentation fixed the Phase 1 contracts before
|
|
19
|
+
implementation; it now describes the implemented v0.1.0 behavior and deferred scope.
|
|
20
|
+
|
|
21
|
+
## ๐ Phase 1 โ The four engines (v0.1.0) โ
|
|
22
|
+
|
|
23
|
+
**Released:** 2026-09-28. Everything in [Targets](02-targets.md) is marked โ
:
|
|
24
|
+
|
|
25
|
+
- [x] โ๏ธ Package scaffold โ ESM `package.json` (Bun-first, zero direct runtime
|
|
26
|
+
dependencies; `zod` + `km-api ^0.4.1` peers from npm โ D-15), strict `tsconfig`,
|
|
27
|
+
Vitest/V8, pinned Bun, and checked-in `bun.lock`
|
|
28
|
+
- [x] โ **Engine 1** โ `zodToJsonSchema()` on top of `z.toJSONSchema()`
|
|
29
|
+
([rules](06-conversions.md))
|
|
30
|
+
- [x] โก **Engine 2** โ `jsonSchemaToZod()` recursive emitter
|
|
31
|
+
([rules](06-conversions.md))
|
|
32
|
+
- [x] โข **Engine 3** โ `openApiToApiDocs()` โ normalize v2/v3 โ operation IR
|
|
33
|
+
โ render `directory` / `flat` trees of `index.ts` files
|
|
34
|
+
([rules](06-conversions.md),
|
|
35
|
+
[format](07-api-docs.md))
|
|
36
|
+
- [x] โฃ **Engine 4** โ `apiDocsToOpenApi()` โ manifest-driven reverse
|
|
37
|
+
conversion to OpenAPI 3.0/3.1
|
|
38
|
+
([rules](06-conversions.md))
|
|
39
|
+
- [x] ๐งฑ Component options โ `insertComponents`, `useComponentAsReference`,
|
|
40
|
+
nested references, and direct/mutual cycles ([rules](08-components.md))
|
|
41
|
+
- [x] ๐ **YAML input** โ owned deterministic YAML 1.2 core-schema parser,
|
|
42
|
+
`.yaml`/`.yml` paths and inline YAML text, anchors/aliases/merge keys,
|
|
43
|
+
stable `ZOPIA_SPEC_INVALID_YAML` ([rules](06-conversions.md#engine-โข--openapi--api-docs), D-16)
|
|
44
|
+
- [x] ๐ **External `$ref`s** โ same-folder references bundled inline for
|
|
45
|
+
spec file paths, byte-identical to inline twins ([rules](06-conversions.md#engine-โข--openapi--api-docs), D-17)
|
|
46
|
+
- [x] ๐ฆ Manifest writer/reader โ `.zopia-manifest.json` (D-06)
|
|
47
|
+
- [x] โ ๏ธ **Warnings pipeline** โ stable typed codes, exact JSON Pointer locations,
|
|
48
|
+
deterministic collection/callbacks, generated-code markers, and CLI stderr
|
|
49
|
+
reporting across engines โ โโฃ (R-144/R-408/D-12)
|
|
50
|
+
- [x] โป๏ธ **Manifest staleness** โ canonical source/config comparison, invalid and
|
|
51
|
+
incomplete-tree detection, source-located warnings, safe obsolete-artifact
|
|
52
|
+
pruning, and symlink-safe regeneration (R-741โฆR-743)
|
|
53
|
+
- [x] ๐ **Reverse security fallback** โ manifest-authoritative requirements,
|
|
54
|
+
validated metadata, collision-safe deterministic bearer synthesis,
|
|
55
|
+
OpenAPI/Swagger representations, and operation-located warnings (R-656)
|
|
56
|
+
- [x] ๐ **Typed errors** โ one immutable stable-code catalogue and `ZopiaError`
|
|
57
|
+
boundary across engines, manifests, generated-module imports, filesystem
|
|
58
|
+
operations, warnings, and CLI validation, with locations, hints, and causes
|
|
59
|
+
(R-141โฆR-143/R-404)
|
|
60
|
+
- [x] ๐ **Round-trip contract** โ fixture-backed source-dialect identity across
|
|
61
|
+
Swagger 2.0 and OpenAPI 3.0/3.1, every layout/component mode, refs/cycles,
|
|
62
|
+
lossy-keyword overlays, path-item metadata, and byte-identical regeneration;
|
|
63
|
+
supported Zod โ JSON Schema pipelines converge after canonicalization
|
|
64
|
+
(T-10/T-11/R-409)
|
|
65
|
+
- [x] โจ๏ธ **CLI contract** โ strict `generate` / `reverse` grammar, complete option
|
|
66
|
+
mapping and help, isolated stdout/stderr channels, stable exit statuses,
|
|
67
|
+
trusted-tree disclosure, and direct/package execution ([usage](10-usage.md#-cli))
|
|
68
|
+
- [x] ๐ธ **Golden generated-tree contract** โ deliberate reproducible updates,
|
|
69
|
+
complete byte-for-byte tree comparisons in all canonical layouts, and
|
|
70
|
+
strict compilation against installed published `km-api@0.4.1`, including
|
|
71
|
+
`trace`, custom/default statuses, and extension media types (R-112/R-126)
|
|
72
|
+
- [x] ๐ **Coverage gates** โ V8 measures every source file; overall line/function
|
|
73
|
+
coverage is gated at 90%, branches at 85%, conversion engines at 95% lines,
|
|
74
|
+
and every source file at 80% lines, with omitted-file detection
|
|
75
|
+
- [x] ๐ฃ **Bun gate** โ pinned Bun 1.2.21, frozen `bun.lock` installation,
|
|
76
|
+
typecheck, Vitest, coverage, direct/package CLI smoke tests, and Bun-native
|
|
77
|
+
generated-TypeScript reverse imports run through one command (T-14/D-01)
|
|
78
|
+
- [x] ๐งช **Vitest suite** โ unit, integration, round-trip, golden-tree, JSDoc,
|
|
79
|
+
CLI, and package-release contracts run in the pinned Bun gate
|
|
80
|
+
([testing](11-testing.md))
|
|
81
|
+
- [x] ๐ **JSDoc audit** โ every exported declaration and exposed interface/class
|
|
82
|
+
member has a useful summary; public callables document parameters and return
|
|
83
|
+
values; optional configuration fields state defaults; examples and links are
|
|
84
|
+
checked; and named-only exports are enforced by an AST contract suite (T-12,
|
|
85
|
+
R-131โฆR-135/R-1003)
|
|
86
|
+
- [x] ๐ฆ **Package/release readiness** โ public npm metadata, an allowlisted
|
|
87
|
+
source archive, executable CLI, isolated packed-consumer import and CLI
|
|
88
|
+
smoke tests, and a mandatory prepublish gate (R-191โฆR-193)
|
|
89
|
+
- [x] ๐ **Documentation status sync** โ current module/test layouts, generated
|
|
90
|
+
examples, Phase 1 completion labels, and deferred boundaries agree with
|
|
91
|
+
the implementation and are guarded by a documentation contract test
|
|
92
|
+
- [x] ๐ First versioned entry in `CHANGELOG.md` โ **v0.1.0**
|
|
93
|
+
|
|
94
|
+
### โ
Definition of done โ Phase 1 (met)
|
|
95
|
+
|
|
96
|
+
The v0.1.0 release satisfies all of the following:
|
|
97
|
+
|
|
98
|
+
1. ๐ `bun run test` is green โ unit + integration + round-trip suites
|
|
99
|
+
2. ๐ Coverage gates are met (see [Testing โ Coverage gates](11-testing.md#-coverage-gates))
|
|
100
|
+
3. ๐ Round-trip: for every fixture spec, `openapi(docs(spec))` equals `spec` after canonicalization
|
|
101
|
+
4. ๐งฉ All four engine docs sections are implemented exactly as specified (mapping tables are the contract)
|
|
102
|
+
5. ๐ Every public symbol has JSDoc; `tsc --noEmit` (strict) passes
|
|
103
|
+
6. ๐ `CHANGELOG.md` v0.1.0 entry exists and `README` status banner is updated
|
|
104
|
+
7. โ
**km-api dependency gate** (D-15) โ `km-api@0.4.1` is published and zopia
|
|
105
|
+
uses `km-api: ^0.4.1` from npm; no Git submodule or unpublished commit remains.
|
|
106
|
+
The dependency remains installed and type-checkable in every release gate.
|
|
107
|
+
|
|
108
|
+
## ๐งฐ Phase 2 โ Breadth (v0.2.x) โ
|
|
109
|
+
|
|
110
|
+
- ๐ **YAML input** โ โ
accept `swagger.yaml` / `openapi.yaml` (D-13 lifts โ D-16)
|
|
111
|
+
- ๐ **External `$ref`s** โ โ
resolve references to other files in the same folder (D-17)
|
|
112
|
+
- ๐งฉ **Reusable parameters & responses** โ โ
emitted as their own component
|
|
113
|
+
files `components/parameters/<Name>/index.ts` and
|
|
114
|
+
`components/responses/<Name>/index.ts` with `<Name>Parameter` / `<Name>Response`
|
|
115
|
+
exports, kind barrels, manifest `kind` entries, and a reverse conversion that
|
|
116
|
+
refreshes declarations from the modules while restoring every use-site `$ref`
|
|
117
|
+
verbatim (D-18; km-api has no standalone-parameter concept, so modules hold the
|
|
118
|
+
derived schema only โ name/location/`required` remain operation data)
|
|
119
|
+
- ๐งพ **`zopia.config.ts`** โ โ
project-level config file with working-directory
|
|
120
|
+
discovery, explicit `--config` paths, validated `{ generate, reverse }` defaults,
|
|
121
|
+
and stable precedence CLI flag > config value > built-in default (D-19);
|
|
122
|
+
CLI flags stay available
|
|
123
|
+
- ๐ค **OpenAPI 2.0 output** โ โ
engine โฃ accepts `version: '2.0'` (CLI
|
|
124
|
+
`--version 2.0`, config `reverse.version`) and downgrades 3.x-sourced
|
|
125
|
+
manifests into Swagger 2.0 documents: `nullable` becomes `x-nullable`,
|
|
126
|
+
`requestBody` becomes `body`/`formData` parameters, `components` becomes
|
|
127
|
+
top-level `definitions`/`parameters`/`responses`, `servers` decomposes into
|
|
128
|
+
`host`/`basePath`/`schemes`, and unrepresentable 3.x features (webhooks,
|
|
129
|
+
`jsonSchemaDialect`, cookie params, `links`, multi-flow OAuth2, โฆ) drop with
|
|
130
|
+
deterministic `ZOPIA_WARN_DIALECT_DOWNGRADE` warnings (D-20)
|
|
131
|
+
- ๐งช **More JSON Schema keywords** โ โ
`propertyNames` graduates from the D-12
|
|
132
|
+
approximation to native conversion: the exact
|
|
133
|
+
`{ type: 'object', propertyNames: { type: 'string', <pattern/length constraints> }, additionalProperties: <schema> }`
|
|
134
|
+
form now converts to `z.record(key, value)` (and back) with no warning or
|
|
135
|
+
frozen overlay (D-22); every other listed keyword keeps its runtime-refinement
|
|
136
|
+
+ frozen-overlay round-trip (`patternProperties`, `if/then/else`,
|
|
137
|
+
`minProperties/maxProperties`, non-native `propertyNames` forms, `contains`) (Phase 1: documented approximation + warning, D-12)
|
|
138
|
+
- ๐ช **3.1 webhook endpoint generation** โ โ
`document.webhooks` operations now
|
|
139
|
+
generate real endpoint files under `webhooks/<name>/<method>/index.ts`
|
|
140
|
+
alongside path operations (D-23). The manifest records `webhooks[]` entries
|
|
141
|
+
with the same reference/overlay/security metadata as path endpoints plus
|
|
142
|
+
`webhookOrder` and a `webhooksOverlay` (item-level metadata, `x-` names, and
|
|
143
|
+
operation-less items stay verbatim), so engine โฃ reassembles webhooks in exact
|
|
144
|
+
source order for 3.1 output and omits them with source-located
|
|
145
|
+
`ZOPIA_WARN_WEBHOOKS` warnings for 3.0/2.0 output. Operation-less webhook maps
|
|
146
|
+
keep the Phase 1 manifest-only behavior (no endpoint files, forward warning)
|
|
147
|
+
- ๐ **Watch mode** โ โ
`zopia generate --watch` regenerates whenever the spec
|
|
148
|
+
file changes (S-88): an immediate initial run, 50 ms-coalesced re-runs that
|
|
149
|
+
serialize against in-flight generation, run errors printed to stderr while
|
|
150
|
+
watching continues, and abort/cleanup on exit. Uses `fs.watch` with the
|
|
151
|
+
existing stale-tree/prune pipeline, so spec edits refresh owned files in place
|
|
152
|
+
|
|
153
|
+
## ๐ Phase 3 โ Ecosystem (v0.3+) โ
|
|
154
|
+
|
|
155
|
+
- ๐งน **`zopia validate`** โ โ
CLI command + `validateZopia()` API lint specs
|
|
156
|
+
and generated trees (S-89): specs are checked for dialect validity, broken
|
|
157
|
+
local `$ref`s, endpoint-planning failures (name collisions, cross-namespace
|
|
158
|
+
duplicate operationIds), and components unreachable from any operation
|
|
159
|
+
(transitive; Swagger `definitions` included). Generated trees are checked for
|
|
160
|
+
manifest presence/validity, a successful reverse dry-run, and km-api peer
|
|
161
|
+
drift. Findings are deterministic sorted diagnostics with stable
|
|
162
|
+
`ZOPIA_VALIDATE_*` lint codes; the CLI prints them on stdout and exits `1`
|
|
163
|
+
when any error-severity finding exists
|
|
164
|
+
- โป๏ธ **Incremental regeneration** โ โ
unchanged generated files keep their
|
|
165
|
+
mtimes (byte-identical regeneration writes nothing); the opt-in merge-safe
|
|
166
|
+
custom layer (D-24, S-90) exports a `custom` companion namespace per
|
|
167
|
+
endpoint/webhook scaffolded once and never overwritten (`--custom`,
|
|
168
|
+
`generate.custom`, or the `custom` generate option)
|
|
169
|
+
- ๐ **Diff tool** โ โ
`zopia diff old.json new.json` + `diffOpenApiSpecs()`
|
|
170
|
+
API (S-91): semantic comparison of dialect, info, endpoints (with
|
|
171
|
+
parameter/request-body/response details), webhooks, schema components,
|
|
172
|
+
document fields, and `x-` extensions; key order is ignored; deterministic
|
|
173
|
+
`+`/`-`/`~` human-readable lines with a summary; differences are data on
|
|
174
|
+
stdout, so the CLI exits `0` for changed pairs
|
|
175
|
+
- ๐งฉ **Presets** โ โ
split-generation layouts (S-92): `--preset multi-tag`
|
|
176
|
+
routes each operation by its primary tag, `--preset multi-server` by the
|
|
177
|
+
effective first server (repeatedly), producing one independently
|
|
178
|
+
reverse-convertible api-docs sub-tree per bucket; untagged/default-server
|
|
179
|
+
operations land in `untagged`/`https-default-server`-style buckets; nothing
|
|
180
|
+
to split โ the normal single tree. Programmatic `preset` option plus
|
|
181
|
+
`generate.preset` configuration; `planPresetBuckets()` exposes the pure
|
|
182
|
+
deterministic planner (collision-safe slugs, `ZOPIA_WARN_PRESET_PRIMARY_TAG`
|
|
183
|
+
on multi-tagged operations) and results report `trees[]`
|
|
184
|
+
- ๐งโ๐ป **VS Code extension** โ โ
navigate spec โ generated code both ways
|
|
185
|
+
(S-93): manifest-driven navigation core (`loadNavigationIndex`,
|
|
186
|
+
`specToLocations`/`treeToSpecLocation`, one-pass JSON
|
|
187
|
+
`specPointersToLines`/`specPointerAtLine` cursor resolution, YAML
|
|
188
|
+
operationId fallback) plus the `zopia navigate` CLI (`--to-code` /
|
|
189
|
+
`--to-spec`) and a plain-JS extension package under `editors/vscode/`
|
|
190
|
+
resolving the workspace's own zopia install
|
|
191
|
+
|
|
192
|
+
## ๐งฎ Versioning
|
|
193
|
+
|
|
194
|
+
SemVer, strictly:
|
|
195
|
+
|
|
196
|
+
| ๐ Bump | When |
|
|
197
|
+
| --- | --- |
|
|
198
|
+
| `MAJOR` | A generated-file format or manifest format breaks (`zopia:manifest@1` โ `@2`) |
|
|
199
|
+
| `MINOR` | New option, new engine feature, new CLI flag โ backward compatible |
|
|
200
|
+
| `PATCH` | Bug fixes, doc corrections, mapping-table clarifications |
|
|
201
|
+
|
|
202
|
+
## ๐ Next
|
|
203
|
+
|
|
204
|
+
- ๐ฏ The exact list of what Phase 1 builds โ [Targets](02-targets.md)
|
|
205
|
+
- ๐๏ธ How the pieces fit โ [Architecture](04-architecture.md)
|