@leemour/cli-core 0.7.0 → 0.9.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.
Files changed (47) hide show
  1. package/README.md +73 -11
  2. package/dist/codegen/index.d.ts +12 -0
  3. package/dist/codegen/index.d.ts.map +1 -0
  4. package/dist/codegen/index.js +11 -0
  5. package/dist/codegen/index.js.map +1 -0
  6. package/dist/codegen/manifest.d.ts +41 -0
  7. package/dist/codegen/manifest.d.ts.map +1 -0
  8. package/dist/codegen/manifest.js +59 -0
  9. package/dist/codegen/manifest.js.map +1 -0
  10. package/dist/codegen/model.d.ts +139 -0
  11. package/dist/codegen/model.d.ts.map +1 -0
  12. package/dist/codegen/model.js +7 -0
  13. package/dist/codegen/model.js.map +1 -0
  14. package/dist/codegen/names.d.ts +4 -0
  15. package/dist/codegen/names.d.ts.map +1 -0
  16. package/dist/codegen/names.js +46 -0
  17. package/dist/codegen/names.js.map +1 -0
  18. package/dist/codegen/pipeline.d.ts +24 -0
  19. package/dist/codegen/pipeline.d.ts.map +1 -0
  20. package/dist/codegen/pipeline.js +134 -0
  21. package/dist/codegen/pipeline.js.map +1 -0
  22. package/dist/codegen/runtime.d.ts +24 -0
  23. package/dist/codegen/runtime.d.ts.map +1 -0
  24. package/dist/codegen/runtime.js +38 -0
  25. package/dist/codegen/runtime.js.map +1 -0
  26. package/dist/codegen/tree.d.ts +29 -0
  27. package/dist/codegen/tree.d.ts.map +1 -0
  28. package/dist/codegen/tree.js +87 -0
  29. package/dist/codegen/tree.js.map +1 -0
  30. package/dist/codegen/typescript.d.ts +6 -0
  31. package/dist/codegen/typescript.d.ts.map +1 -0
  32. package/dist/codegen/typescript.js +76 -0
  33. package/dist/codegen/typescript.js.map +1 -0
  34. package/dist/codegen/valibot.d.ts +10 -0
  35. package/dist/codegen/valibot.d.ts.map +1 -0
  36. package/dist/codegen/valibot.js +121 -0
  37. package/dist/codegen/valibot.js.map +1 -0
  38. package/dist/logger.d.ts +1 -1
  39. package/dist/release/index.d.ts +37 -0
  40. package/dist/release/index.d.ts.map +1 -0
  41. package/dist/release/index.js +90 -0
  42. package/dist/release/index.js.map +1 -0
  43. package/dist/release/markdown.d.ts +35 -0
  44. package/dist/release/markdown.d.ts.map +1 -0
  45. package/dist/release/markdown.js +150 -0
  46. package/dist/release/markdown.js.map +1 -0
  47. package/package.json +32 -13
package/README.md CHANGED
@@ -7,8 +7,9 @@ keyring behind a testable seam, and injectable clocks.
7
7
  Extracted from [`brazecli`](https://github.com/leemour/brazecli), where each piece earned its
8
8
  shape, and shared with [`max-cli`](https://github.com/leemour/max-cli).
9
9
 
10
- **Status: 0.5.0.** Published on npm, used by `max-cli`. Both extraction steps have landed: the
11
- files that move unchanged, and the ones that needed a parameter threaded through. 75 tests.
10
+ Published on npm and used by `max-cli`, `cli-messaging`, `tg-cli` and `brazecli`. What changed in
11
+ each version is in [`CHANGELOG.md`](CHANGELOG.md); how the package is put together and released is in
12
+ [`docs/dev/`](docs/dev/ARCHITECTURE.md).
12
13
 
13
14
  ## The rule this package exists to keep
14
15
 
@@ -46,6 +47,8 @@ streams.stderr // []
46
47
  | `/commands` | the command registry: `describeProgram`, `annotate`, `flatten` — see below |
47
48
  | `/completion` | shell completion over the registry: `suggest`, `formatSuggestions` — see below |
48
49
  | `/update` | keeping an install current: `installerOf`, `updateCommand`, `latestVersion`, `mayNotify`, `updateNotice`, `runUpdate` — see below |
50
+ | `/codegen` | build time: an official API description → types, Valibot schemas, an operation manifest and a coverage page — see below |
51
+ | `/release` | release time: `releaseCheck` and the checks it runs — changelog shape, links, package contents, version in step — see below |
49
52
 
50
53
  **Nothing in the root export is HTTP.** Status classification, `Retry-After` parsing and the fetch
51
54
  seam live in `@leemour/cli-core/http`, so a CLI that speaks a socket never depends on a stack it
@@ -95,9 +98,40 @@ a throwaway config directory silently overwrites the real secret unless you pass
95
98
  And a secret should never be handed to a logger in the first place — redaction by field name is the
96
99
  second line of defence, not the first.
97
100
 
98
- **Everything the environment knows is passed in.** No `process.env` reads, no config file paths,
99
- no ambient clock. That is what makes a timeout test finish instantly and a keyring test incapable
100
- of reaching a real keychain.
101
+ **Everything the environment knows can be passed in**: the clock, the sleep, the keyring, `env`,
102
+ `fetch` and the streams. The real ones are only defaults — `Credentials` without a `keyring` uses the
103
+ system keychain, `resolvePaths` without `env` reads `process.env`. Passing them is what makes a
104
+ timeout test finish instantly and a keyring test incapable of reaching a real keychain.
105
+
106
+ **Generating an API catalog is `@leemour/cli-core/codegen`**, a build-time tool. It reads a
107
+ format-neutral `ApiModel` — operations with a transport binding (`http` method and path, or `rpc`
108
+ name), an `effect` (`read`, `write`, `destructive`) and how far the source can be trusted
109
+ (`contract`, `example`, `inferred`, `override`) — and writes committed files. It parses no file
110
+ format: the adapter from OpenAPI, Postman or anything else lives in the CLI that has that source,
111
+ so this adds no dependency. Generation stops, naming the problem, when two operations collide, an
112
+ operation is not classified as a read or a write, an override matches nothing, a reference points
113
+ nowhere or a construct cannot be expressed; it never drops an operation or falls back to `any`.
114
+
115
+ ```ts
116
+ import { generate, manifestGenerator, typesGenerator, valibotGenerator, writeArtifacts } from "@leemour/cli-core/codegen"
117
+
118
+ const artifacts = generate(model, [typesGenerator({ path }), valibotGenerator({ path, typesImport }), manifestGenerator({ path })], {
119
+ overrides: { answerOnCallback: { effect: "write", reason: "a POST that edits a message" } },
120
+ banner: ["Source: spec/bot/schema.yaml", "Run: pnpm bot:generate"],
121
+ })
122
+ const stale = writeArtifacts(artifacts, { root, check: process.argv.includes("--check") })
123
+ ```
124
+
125
+ The generated schemas import `@leemour/cli-core/codegen/runtime` at run time — a few number
126
+ helpers, not the generator. Numbers are expected from a lossless JSON parser (`lossless-json`): a
127
+ 64-bit integer comes out as its exact decimal string, and any other integer that does not fit a JS
128
+ number fails instead of rounding. Objects are loose, so a field the API added later passes through.
129
+ Enums and discriminated unions are **strict**: a value or subtype the snapshot does not know fails,
130
+ so decode a live stream (updates, webhooks) only where that is what you want.
131
+
132
+ **The schemas decode; they do not encode.** Their output carries an `int64` as a string, so sending
133
+ it back would put a string where the API expects a number. Validate a request with the schema, then
134
+ send the original lossless value.
101
135
 
102
136
  **Keeping an install current is `@leemour/cli-core/update`.** `installerOf(realpath(script))` says
103
137
  which package manager put the CLI there — pnpm, npm or bun, measured on real installs — and
@@ -110,6 +144,30 @@ sentence or `undefined` — it never throws. `runUpdate` starts the package mana
110
144
  stderr (`spawnPlan` is the Windows `.cmd` rule). Nothing here updates or prints by itself — a CLI
111
145
  holding somebody's credentials must not change itself unasked.
112
146
 
147
+ **The release checks are `@leemour/cli-core/release`** — everything about a release that a program
148
+ can decide. A check is `{ name, run }`, and `run` returns the problems it found, one line each; an
149
+ empty list is a pass. `releaseCheck(checks, { version, log })` runs them all, even after a failure,
150
+ prints `ok` or `FAIL` per check and returns how many failed — the caller exits. The checks every CLI
151
+ shares: `command(root, "pnpm", "lint")` for anything that passes by exiting 0, `notOnNpm`,
152
+ `packContents` against a list of what may ship, `changelogProblems` for the fixed headings and the
153
+ dated top section, `docsProblems` for dead links and anchors and the rules of the pages a user reads,
154
+ and `versionScript` — the whole of a `version:check` / `version:sync` script. Each CLI passes its
155
+ own headings, id prefixes and pages; the checks that belong to one messenger stay in that CLI.
156
+
157
+ ```ts
158
+ import { command, notOnNpm, packageVersion, releaseCheck } from "@leemour/cli-core/release"
159
+
160
+ const version = packageVersion(root)
161
+ const failed = releaseCheck(
162
+ [
163
+ { name: "version not on npm", run: notOnNpm(root, "@leemour/tg-cli", version) },
164
+ { name: "lint", run: command(root, "pnpm", "lint") },
165
+ ],
166
+ { version, log: console.log },
167
+ )
168
+ process.exit(failed === 0 ? 0 : 1)
169
+ ```
170
+
113
171
  ## Where secrets actually go, per platform
114
172
 
115
173
  The keyring is real on every desktop and absent on most servers, so the fallback is not an edge
@@ -149,19 +207,23 @@ pnpm typecheck
149
207
  pnpm build
150
208
  ```
151
209
 
210
+ The rest of the checks, and what each is for, are in [`docs/dev/TESTING.md`](docs/dev/TESTING.md).
211
+
152
212
  ## Releasing
153
213
 
154
- Raise `version` in `package.json` through a pull request, merge it, then on `main`:
214
+ Raise `version` in `package.json` and date the `## Unreleased` section of
215
+ [`CHANGELOG.md`](CHANGELOG.md) as that version, through a pull request; merge it, then on `main`:
155
216
 
156
217
  ```sh
157
218
  bin/release
158
219
  ```
159
220
 
160
- It refuses a dirty tree, a branch other than `main`, a `main` that is not pushed and a version npm
161
- already has, then starts [`release.yml`](.github/workflows/release.yml) and follows it. The workflow
162
- runs every check, publishes through npm's
163
- [trusted publishing](https://docs.npmjs.com/trusted-publishers/) — no npm token in GitHub, and npm
164
- attaches provenance — and tags `v<version>` only once npm shows the new version.
221
+ It refuses a dirty tree, a branch other than `main` and a `main` that is not pushed. When npm already
222
+ has the version, or a higher one, it commits the next free version to `main` — the next minor for
223
+ `x.y.0`, the next patch otherwise — renames the changelog heading to match, and publishes that. Then it starts
224
+ [`release.yml`](.github/workflows/release.yml) and follows it. The workflow runs every check,
225
+ publishes through npm's [trusted publishing](https://docs.npmjs.com/trusted-publishers/) — no npm
226
+ token in GitHub, and npm attaches provenance — and tags `v<version>` only once npm shows the new version.
165
227
 
166
228
  npm trusts the workflow **by file name**: the package's Trusted Publisher settings on npmjs.com name
167
229
  `leemour` / `cli-core` / `release.yml`. Rename the file and publishing stops until they are updated.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Turns an official API description into committed code: types, Valibot schemas, an operation
3
+ * manifest and a coverage page. Build-time only, and format-neutral: it parses no file format and
4
+ * adds no dependency. The adapter from OpenAPI, Postman or anything else lives in the consumer.
5
+ */
6
+ export { type CoverageOptions, coverageGenerator, type ManifestOperation, manifestGenerator } from "./manifest.js";
7
+ export type { ApiBody, ApiModel, ApiOperation, ApiParameter, ApiSchema, Binding, CodeGenerator, Confidence, Discriminator, Effect, GeneratedArtifact, HttpBinding, HttpMethod, Override, RpcBinding, SchemaNode, SourceInfo, SourceReference, } from "./model.js";
8
+ export { identifier, kebab } from "./names.js";
9
+ export { applyOverrides, CodegenError, type GenerateOptions, generate, validateModel, type WriteOptions, writeArtifacts, } from "./pipeline.js";
10
+ export { typesGenerator } from "./typescript.js";
11
+ export { type ValibotOptions, valibotGenerator } from "./valibot.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,KAAK,eAAe,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAClH,YAAY,EACV,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,OAAO,EACP,aAAa,EACb,UAAU,EACV,aAAa,EACb,MAAM,EACN,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EACL,cAAc,EACd,YAAY,EACZ,KAAK,eAAe,EACpB,QAAQ,EACR,aAAa,EACb,KAAK,YAAY,EACjB,cAAc,GACf,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,KAAK,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Turns an official API description into committed code: types, Valibot schemas, an operation
3
+ * manifest and a coverage page. Build-time only, and format-neutral: it parses no file format and
4
+ * adds no dependency. The adapter from OpenAPI, Postman or anything else lives in the consumer.
5
+ */
6
+ export { coverageGenerator, manifestGenerator } from "./manifest.js";
7
+ export { identifier, kebab } from "./names.js";
8
+ export { applyOverrides, CodegenError, generate, validateModel, writeArtifacts, } from "./pipeline.js";
9
+ export { typesGenerator } from "./typescript.js";
10
+ export { valibotGenerator } from "./valibot.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAwB,iBAAiB,EAA0B,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAqBlH,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EACL,cAAc,EACd,YAAY,EAEZ,QAAQ,EACR,aAAa,EAEb,cAAc,GACf,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAuB,gBAAgB,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,41 @@
1
+ import type { Binding, CodeGenerator, Confidence, Effect, SchemaNode } from "./model.js";
2
+ /** One operation as a CLI reads it at run time: enough to build a command, validate input and guard a write. */
3
+ export interface ManifestOperation {
4
+ id: string;
5
+ command: string;
6
+ binding: Binding;
7
+ effect: Effect;
8
+ summary?: string;
9
+ description?: string;
10
+ tags: readonly string[];
11
+ deprecated?: boolean;
12
+ parameters: readonly {
13
+ name: string;
14
+ in: "path" | "query" | "header";
15
+ required: boolean;
16
+ description?: string;
17
+ schema: SchemaNode;
18
+ }[];
19
+ request?: {
20
+ required: boolean;
21
+ confidence: Confidence;
22
+ schema?: string;
23
+ };
24
+ response?: {
25
+ confidence: Confidence;
26
+ schema?: string;
27
+ };
28
+ }
29
+ export declare const manifestGenerator: (options: {
30
+ path: string;
31
+ coreImport?: string;
32
+ }) => CodeGenerator;
33
+ export interface CoverageOptions {
34
+ path: string;
35
+ title: string;
36
+ /** How a user reaches the operation, e.g. `max bot api get-my-info`. */
37
+ command: (operation: ManifestOperation) => string;
38
+ }
39
+ /** Every operation the source has, and how it is reached — the page a reviewer diffs after a sync. */
40
+ export declare const coverageGenerator: (options: CoverageOptions) => CodeGenerator;
41
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/codegen/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA0B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAIhH,gHAAgH;AAChH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,EAAE,SAAS;QACnB,IAAI,EAAE,MAAM,CAAA;QACZ,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;QAC/B,QAAQ,EAAE,OAAO,CAAA;QACjB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,MAAM,EAAE,UAAU,CAAA;KACnB,EAAE,CAAA;IACH,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,UAAU,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxE,QAAQ,CAAC,EAAE;QAAE,UAAU,EAAE,UAAU,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACvD;AA4BD,eAAO,MAAM,iBAAiB,YAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,aAWjD,CAAA;AAIH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,wEAAwE;IACxE,OAAO,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,MAAM,CAAA;CAClD;AAED,sGAAsG;AACtG,eAAO,MAAM,iBAAiB,YAClB,eAAe,KAAG,aAwB3B,CAAA"}
@@ -0,0 +1,59 @@
1
+ import { kebab } from "./names.js";
2
+ import { SchemaTree } from "./tree.js";
3
+ const withoutUndefined = (value) => Object.fromEntries(Object.entries(value).filter(([, field]) => field !== undefined));
4
+ const toManifest = (operation, tree) => withoutUndefined({
5
+ id: operation.id,
6
+ command: kebab(operation.id),
7
+ binding: operation.binding,
8
+ effect: operation.effect,
9
+ summary: operation.summary,
10
+ description: operation.description,
11
+ tags: operation.tags,
12
+ deprecated: operation.deprecated,
13
+ parameters: operation.parameters.map((parameter) => withoutUndefined({ ...parameter })),
14
+ request: operation.requestBody
15
+ ? withoutUndefined({
16
+ required: operation.requestBody.required,
17
+ confidence: operation.requestBody.confidence,
18
+ schema: tree.requestName(operation.id),
19
+ })
20
+ : undefined,
21
+ response: operation.response
22
+ ? withoutUndefined({ confidence: operation.response.confidence, schema: tree.responseName(operation.id) })
23
+ : undefined,
24
+ });
25
+ export const manifestGenerator = (options) => (model) => {
26
+ const tree = new SchemaTree(model);
27
+ const operations = model.operations.map((operation) => toManifest(operation, tree));
28
+ const content = [
29
+ `import type { ManifestOperation } from "${options.coreImport ?? "@leemour/cli-core/codegen"}"`,
30
+ "",
31
+ `export const operations: readonly ManifestOperation[] = ${JSON.stringify(operations, null, 2)}`,
32
+ "",
33
+ ].join("\n");
34
+ return [{ path: options.path, content }];
35
+ };
36
+ const cell = (text) => (text ?? "").replace(/\s+/g, " ").replace(/\|/g, "\\|").trim();
37
+ /** Every operation the source has, and how it is reached — the page a reviewer diffs after a sync. */
38
+ export const coverageGenerator = (options) => (model) => {
39
+ const tree = new SchemaTree(model);
40
+ const rows = model.operations.map((operation) => {
41
+ const entry = toManifest(operation, tree);
42
+ const binding = entry.binding.kind === "http" ? `${entry.binding.method} ${entry.binding.path}` : entry.binding.name;
43
+ const status = entry.deprecated ? "deprecated" : "generated";
44
+ return `| \`${entry.id}\` | \`${binding}\` | \`${options.command(entry)}\` | ${entry.effect} | ${entry.request?.confidence ?? "—"} | ${status} | ${cell(entry.summary)} |`;
45
+ });
46
+ const version = model.source.version ? ` ${model.source.version}` : "";
47
+ const content = [
48
+ `# ${options.title}`,
49
+ "",
50
+ `${model.operations.length} operations from ${model.source.kind}${version}.`,
51
+ "",
52
+ "| Operation | Call | Command | Effect | Request source | Status | Summary |",
53
+ "|---|---|---|---|---|---|---|",
54
+ ...rows,
55
+ "",
56
+ ].join("\n");
57
+ return [{ path: options.path, content }];
58
+ };
59
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/codegen/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * The model every generator reads, whatever the source was: an OpenAPI file, a Postman collection,
3
+ * a scraped reference page. A source adapter lives in the consumer and produces this; nothing here
4
+ * parses a file format.
5
+ */
6
+ export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD";
7
+ /** How much the source promises. A Postman example is not a contract and must never become one. */
8
+ export type Confidence = "contract" | "example" | "inferred" | "override";
9
+ /**
10
+ * `undefined` in an adapter's output means "the source did not say". Generation refuses to run
11
+ * until an override classifies it — a write mistaken for a read is the expensive mistake.
12
+ */
13
+ export type Effect = "read" | "write" | "destructive";
14
+ export interface HttpBinding {
15
+ kind: "http";
16
+ method: HttpMethod;
17
+ path: string;
18
+ }
19
+ /** Every call is the same HTTP shape and only the name differs, as in the Telegram Bot API. */
20
+ export interface RpcBinding {
21
+ kind: "rpc";
22
+ name: string;
23
+ }
24
+ export type Binding = HttpBinding | RpcBinding;
25
+ interface SchemaCommon {
26
+ description?: string;
27
+ nullable?: boolean;
28
+ deprecated?: boolean;
29
+ default?: unknown;
30
+ }
31
+ export type SchemaNode = SchemaCommon & ({
32
+ type: "ref";
33
+ ref: string;
34
+ } | {
35
+ type: "string";
36
+ enum?: readonly string[];
37
+ minLength?: number;
38
+ maxLength?: number;
39
+ pattern?: string;
40
+ } | {
41
+ type: "integer";
42
+ format?: "int32" | "int64";
43
+ minimum?: number;
44
+ maximum?: number;
45
+ enum?: readonly number[];
46
+ } | {
47
+ type: "number";
48
+ minimum?: number;
49
+ maximum?: number;
50
+ } | {
51
+ type: "boolean";
52
+ } | {
53
+ type: "array";
54
+ items: SchemaNode;
55
+ minItems?: number;
56
+ maxItems?: number;
57
+ uniqueItems?: boolean;
58
+ } | {
59
+ type: "object";
60
+ properties: Readonly<Record<string, SchemaNode>>;
61
+ required: readonly string[];
62
+ additionalProperties?: SchemaNode;
63
+ }
64
+ /** Inheritance: every member must resolve to an object, and the fields are merged. */
65
+ | {
66
+ type: "allOf";
67
+ of: readonly SchemaNode[];
68
+ }
69
+ /** Only where the source itself says "anything". An adapter never falls back to this. */
70
+ | {
71
+ type: "unknown";
72
+ });
73
+ /**
74
+ * A base type with subtypes chosen by one property, OpenAPI's `discriminator`. Referenced from
75
+ * inside an `allOf` it means the base's own fields; referenced anywhere else, one of the subtypes.
76
+ */
77
+ export interface Discriminator {
78
+ property: string;
79
+ mapping: Readonly<Record<string, string>>;
80
+ }
81
+ export interface ApiSchema {
82
+ id: string;
83
+ schema: SchemaNode;
84
+ discriminator?: Discriminator;
85
+ }
86
+ export interface ApiParameter {
87
+ name: string;
88
+ in: "path" | "query" | "header";
89
+ required: boolean;
90
+ description?: string;
91
+ schema: SchemaNode;
92
+ }
93
+ export interface ApiBody {
94
+ confidence: Confidence;
95
+ required: boolean;
96
+ schema?: SchemaNode;
97
+ example?: unknown;
98
+ }
99
+ export interface SourceReference {
100
+ /** Where in the source this came from, for a reviewer: a JSON pointer, a folder path. */
101
+ location: string;
102
+ }
103
+ export interface ApiOperation {
104
+ /** The source's own id where it has one. Never re-derived when it does. */
105
+ id: string;
106
+ binding: Binding;
107
+ summary?: string;
108
+ description?: string;
109
+ tags: readonly string[];
110
+ parameters: readonly ApiParameter[];
111
+ requestBody?: ApiBody;
112
+ response?: ApiBody;
113
+ effect?: Effect;
114
+ deprecated?: boolean;
115
+ source: SourceReference;
116
+ }
117
+ export interface SourceInfo {
118
+ kind: "openapi" | "postman" | "other";
119
+ version?: string;
120
+ sourceUrl?: string;
121
+ sourceRevision?: string;
122
+ }
123
+ export interface ApiModel {
124
+ source: SourceInfo;
125
+ operations: readonly ApiOperation[];
126
+ schemas: readonly ApiSchema[];
127
+ }
128
+ export interface Override {
129
+ effect?: Effect;
130
+ /** Required: an override nobody can explain is one nobody dares remove. */
131
+ reason: string;
132
+ }
133
+ export interface GeneratedArtifact {
134
+ path: string;
135
+ content: string;
136
+ }
137
+ export type CodeGenerator = (model: ApiModel) => GeneratedArtifact[];
138
+ export {};
139
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/codegen/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The model every generator reads, whatever the source was: an OpenAPI file, a Postman collection,
3
+ * a scraped reference page. A source adapter lives in the consumer and produces this; nothing here
4
+ * parses a file format.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/codegen/model.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,4 @@
1
+ export declare const identifier: (id: string) => string;
2
+ /** `getMyInfo` → `get-my-info`. */
3
+ export declare const kebab: (id: string) => string;
4
+ //# sourceMappingURL=names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../src/codegen/names.ts"],"names":[],"mappings":"AAoCA,eAAO,MAAM,UAAU,OAAQ,MAAM,KAAG,MAIvC,CAAA;AAED,mCAAmC;AACnC,eAAO,MAAM,KAAK,OAAQ,MAAM,KAAG,MAKjB,CAAA"}
@@ -0,0 +1,46 @@
1
+ const pascal = (text) => text
2
+ .split(/[^A-Za-z0-9]+/)
3
+ .filter(Boolean)
4
+ .map((word) => word[0]?.toUpperCase() + word.slice(1))
5
+ .join("");
6
+ // A generated `export const Error` compiles, and then every `new Error()` in that module builds a schema.
7
+ const GLOBALS = new Set([
8
+ "Array",
9
+ "BigInt",
10
+ "Boolean",
11
+ "Date",
12
+ "Error",
13
+ "Function",
14
+ "Intl",
15
+ "JSON",
16
+ "Map",
17
+ "Math",
18
+ "Number",
19
+ "Object",
20
+ "Partial",
21
+ "Promise",
22
+ "Proxy",
23
+ "Record",
24
+ "Reflect",
25
+ "RegExp",
26
+ "Required",
27
+ "Set",
28
+ "String",
29
+ "Symbol",
30
+ "URL",
31
+ "WeakMap",
32
+ "WeakSet",
33
+ ]);
34
+ export const identifier = (id) => {
35
+ const name = pascal(id);
36
+ if (!/^[A-Za-z]/.test(name))
37
+ return `Schema${name}`;
38
+ return GLOBALS.has(name) ? `Api${name}` : name;
39
+ };
40
+ /** `getMyInfo` → `get-my-info`. */
41
+ export const kebab = (id) => id
42
+ .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
43
+ .replace(/[^A-Za-z0-9]+/g, "-")
44
+ .replace(/^-|-$/g, "")
45
+ .toLowerCase();
46
+ //# sourceMappingURL=names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.js","sourceRoot":"","sources":["../../src/codegen/names.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,CAAC,IAAY,EAAU,EAAE,CACtC,IAAI;KACD,KAAK,CAAC,eAAe,CAAC;KACtB,MAAM,CAAC,OAAO,CAAC;KACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACrD,IAAI,CAAC,EAAE,CAAC,CAAA;AAEb,0GAA0G;AAC1G,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC;IACtB,OAAO;IACP,QAAQ;IACR,SAAS;IACT,MAAM;IACN,OAAO;IACP,UAAU;IACV,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,SAAS;IACT,OAAO;IACP,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,UAAU;IACV,KAAK;IACL,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,SAAS;IACT,SAAS;CACV,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAU,EAAU,EAAE;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAA;IACvB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,IAAI,EAAE,CAAA;IACnD,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AAChD,CAAC,CAAA;AAED,mCAAmC;AACnC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EAAU,EAAU,EAAE,CAC1C,EAAE;KACC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;KACtC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;KAC9B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;KACrB,WAAW,EAAE,CAAA"}
@@ -0,0 +1,24 @@
1
+ import type { ApiModel, CodeGenerator, GeneratedArtifact, Override } from "./model.js";
2
+ export declare class CodegenError extends Error {
3
+ readonly problems: readonly string[];
4
+ constructor(problems: readonly string[]);
5
+ }
6
+ export declare const applyOverrides: (model: ApiModel, overrides: Readonly<Record<string, Override>>) => ApiModel;
7
+ /** Everything that would otherwise make an operation vanish or turn into a guess. */
8
+ export declare const validateModel: (model: ApiModel) => void;
9
+ export interface GenerateOptions {
10
+ overrides?: Readonly<Record<string, Override>>;
11
+ /** Lines under "GENERATED. DO NOT EDIT." — the source and the command. Nothing that changes by itself. */
12
+ banner: readonly string[];
13
+ }
14
+ export declare const generate: (model: ApiModel, generators: readonly CodeGenerator[], options: GenerateOptions) => GeneratedArtifact[];
15
+ export interface WriteOptions {
16
+ root: string;
17
+ /** Compare only: report what is out of date and write nothing. */
18
+ check?: boolean;
19
+ /** The consumer's formatter, so a check compares what would actually be committed. */
20
+ format?: (path: string, content: string) => string;
21
+ }
22
+ /** Paths whose committed content differs from what was generated — written, or with `check`, only reported. */
23
+ export declare const writeArtifacts: (artifacts: readonly GeneratedArtifact[], options: WriteOptions) => string[];
24
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/codegen/pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAgB,aAAa,EAAE,iBAAiB,EAAE,QAAQ,EAAc,MAAM,YAAY,CAAA;AAGhH,qBAAa,YAAa,SAAQ,KAAK;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE;IAAhD,YAAqB,QAAQ,EAAE,SAAS,MAAM,EAAE,EAG/C;CACF;AAED,eAAO,MAAM,cAAc,UAAW,QAAQ,aAAa,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAG,QAc/F,CAAA;AA6BD,qFAAqF;AACrF,eAAO,MAAM,aAAa,UAAW,QAAQ,KAAG,IAyC/C,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;IAC9C,0GAA0G;IAC1G,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAC1B;AAOD,eAAO,MAAM,QAAQ,UACZ,QAAQ,cACH,SAAS,aAAa,EAAE,WAC3B,eAAe,KACvB,iBAAiB,EAQnB,CAAA;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,sFAAsF;IACtF,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;CACnD;AAED,+GAA+G;AAC/G,eAAO,MAAM,cAAc,cAAe,SAAS,iBAAiB,EAAE,WAAW,YAAY,KAAG,MAAM,EAarG,CAAA"}