@leemour/cli-core 0.6.1 → 0.8.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 (49) hide show
  1. package/README.md +31 -0
  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/config.d.ts.map +1 -1
  39. package/dist/config.js +14 -5
  40. package/dist/config.js.map +1 -1
  41. package/dist/index.d.ts +1 -1
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +1 -1
  44. package/dist/index.js.map +1 -1
  45. package/dist/sanitize.d.ts +12 -0
  46. package/dist/sanitize.d.ts.map +1 -1
  47. package/dist/sanitize.js +21 -4
  48. package/dist/sanitize.js.map +1 -1
  49. package/package.json +21 -16
@@ -0,0 +1,38 @@
1
+ /**
2
+ * What generated Valibot schemas call at run time. Kept apart from the generator so a CLI loads
3
+ * these few functions, not the code that writes code.
4
+ *
5
+ * Numbers arrive from a lossless JSON parser (`lossless-json` or anything shaped like its
6
+ * `LosslessNumber`), because a 64-bit id read as a JS number is silently a different id.
7
+ */
8
+ import * as v from "valibot";
9
+ const isLossless = (input) => typeof input === "object" &&
10
+ input !== null &&
11
+ input.isLosslessNumber === true &&
12
+ typeof input.value === "string";
13
+ const INTEGER = /^-?\d+$/;
14
+ const INT64_MIN = -(2n ** 63n);
15
+ const INT64_MAX = 2n ** 63n - 1n;
16
+ const digitsOf = (input) => {
17
+ if (isLossless(input))
18
+ return INTEGER.test(input.value) ? input.value : undefined;
19
+ if (typeof input === "bigint")
20
+ return input.toString();
21
+ if (typeof input === "number" && Number.isSafeInteger(input))
22
+ return String(input);
23
+ return undefined;
24
+ };
25
+ const inRange = (value, { minimum, maximum }) => (minimum === undefined || value >= minimum) && (maximum === undefined || value <= maximum);
26
+ /** A 64-bit integer, handed on as its exact decimal string. */
27
+ export const int64 = (range = {}) => v.pipe(v.custom((input) => digitsOf(input) !== undefined, "expected an integer"), v.transform((input) => digitsOf(input)), v.check((digits) => {
28
+ const value = BigInt(digits);
29
+ return value >= INT64_MIN && value <= INT64_MAX && inRange(value, range);
30
+ }, "integer out of range"));
31
+ /** An integer that must fit a JS number exactly; one that does not fails instead of rounding. */
32
+ export const integer = (range = {}) => v.pipe(v.custom((input) => {
33
+ const digits = digitsOf(input);
34
+ return digits !== undefined && Number.isSafeInteger(Number(digits));
35
+ }, "expected an integer within ±2^53"), v.transform((input) => Number(digitsOf(input))), v.check((value) => inRange(value, range), "integer out of range"));
36
+ export const number = (range = {}) => v.pipe(v.custom((input) => (isLossless(input) ? Number.isFinite(Number(input.value)) : Number.isFinite(input)), "expected a number"), v.transform((input) => (isLossless(input) ? Number(input.value) : input)), v.check((value) => inRange(value, range), "number out of range"));
37
+ export const unique = (items) => new Set(items.map((item) => JSON.stringify(item))).size === items.length;
38
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/codegen/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAO5B,MAAM,UAAU,GAAG,CAAC,KAAc,EAAyB,EAAE,CAC3D,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACb,KAAwC,CAAC,gBAAgB,KAAK,IAAI;IACnE,OAAQ,KAA6B,CAAC,KAAK,KAAK,QAAQ,CAAA;AAE1D,MAAM,OAAO,GAAG,SAAS,CAAA;AACzB,MAAM,SAAS,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAA;AAC9B,MAAM,SAAS,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,CAAA;AAEhC,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAsB,EAAE;IACtD,IAAI,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;IACjF,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAA;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IAClF,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAOD,MAAM,OAAO,GAAG,CAAC,KAAsB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAS,EAAW,EAAE,CAC/E,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,IAAI,OAAO,CAAC,CAAA;AAE5F,+DAA+D;AAC/D,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAK,GAAU,EAAE,EAAE,EAAE,CACzC,CAAC,CAAC,IAAI,CACJ,CAAC,CAAC,MAAM,CAAiC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,qBAAqB,CAAC,EACzG,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAW,CAAC,EACjD,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE;IACjB,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5B,OAAO,KAAK,IAAI,SAAS,IAAI,KAAK,IAAI,SAAS,IAAI,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC1E,CAAC,EAAE,sBAAsB,CAAC,CAC3B,CAAA;AAEH,iGAAiG;AACjG,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAK,GAAU,EAAE,EAAE,EAAE,CAC3C,CAAC,CAAC,IAAI,CACJ,CAAC,CAAC,MAAM,CAAiC,CAAC,KAAK,EAAE,EAAE;IACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC9B,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;AACrE,CAAC,EAAE,kCAAkC,CAAC,EACtC,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAC/C,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAClE,CAAA;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAK,GAAU,EAAE,EAAE,EAAE,CAC1C,CAAC,CAAC,IAAI,CACJ,CAAC,CAAC,MAAM,CACN,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAC9F,mBAAmB,CACpB,EACD,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAgB,CAAC,CAAC,EACrF,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,qBAAqB,CAAC,CACjE,CAAA;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAyB,EAAW,EAAE,CAC3D,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAA"}
@@ -0,0 +1,29 @@
1
+ import type { ApiModel, ApiSchema, SchemaNode } from "./model.js";
2
+ type ObjectNode = Extract<SchemaNode, {
3
+ type: "object";
4
+ }>;
5
+ export interface NamedSchema {
6
+ name: string;
7
+ schema: ApiSchema;
8
+ }
9
+ /**
10
+ * The schema index generators share: named components, inline request and response bodies given a
11
+ * name of their own, and which subtype each discriminator value selects.
12
+ */
13
+ export declare class SchemaTree {
14
+ #private;
15
+ readonly named: NamedSchema[];
16
+ constructor(model: ApiModel);
17
+ schema(id: string): ApiSchema;
18
+ requestName(operationId: string): string | undefined;
19
+ responseName(operationId: string): string | undefined;
20
+ /** The value a subtype's discriminator property must hold, if the schema is a subtype. */
21
+ literalFor(id: string): {
22
+ property: string;
23
+ value: string;
24
+ } | undefined;
25
+ /** Merges inheritance into one object. A member that is not an object stops generation. */
26
+ flatten(node: SchemaNode, where: string): ObjectNode;
27
+ }
28
+ export {};
29
+ //# sourceMappingURL=tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/codegen/tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAIjE,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAA;AAEzD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,SAAS,CAAA;CAClB;AAED;;;GAGG;AACH,qBAAa,UAAU;;IACrB,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,CAAA;IAM7B,YAAY,KAAK,EAAE,QAAQ,EA8B1B;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAI5B;IAED,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnD;IAED,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEpD;IAED,0FAA0F;IAC1F,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAEtE;IAED,2FAA2F;IAC3F,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAiBnD;CACF"}
@@ -0,0 +1,87 @@
1
+ import { identifier } from "./names.js";
2
+ import { CodegenError } from "./pipeline.js";
3
+ /**
4
+ * The schema index generators share: named components, inline request and response bodies given a
5
+ * name of their own, and which subtype each discriminator value selects.
6
+ */
7
+ export class SchemaTree {
8
+ named;
9
+ #byId;
10
+ #literals = new Map();
11
+ #requests = new Map();
12
+ #responses = new Map();
13
+ constructor(model) {
14
+ this.#byId = new Map(model.schemas.map((schema) => [schema.id, schema]));
15
+ this.named = model.schemas.map((schema) => ({ name: identifier(schema.id), schema }));
16
+ const taken = new Set(this.named.map((entry) => entry.name));
17
+ const nameInline = (operationId, suffix, node) => {
18
+ if (!node)
19
+ return undefined;
20
+ if (node.type === "ref")
21
+ return identifier(node.ref);
22
+ const name = identifier(`${operationId} ${suffix}`);
23
+ if (taken.has(name))
24
+ throw new CodegenError([`inline ${suffix.toLowerCase()} of "${operationId}" collides with ${name}`]);
25
+ taken.add(name);
26
+ this.named.push({ name, schema: { id: name, schema: node } });
27
+ return name;
28
+ };
29
+ for (const operation of model.operations) {
30
+ const request = nameInline(operation.id, "Request", operation.requestBody?.schema);
31
+ const response = nameInline(operation.id, "Response", operation.response?.schema);
32
+ if (request)
33
+ this.#requests.set(operation.id, request);
34
+ if (response)
35
+ this.#responses.set(operation.id, response);
36
+ }
37
+ for (const schema of model.schemas) {
38
+ for (const [value, target] of Object.entries(schema.discriminator?.mapping ?? {})) {
39
+ if (this.#literals.has(target)) {
40
+ throw new CodegenError([`schema "${target}" is a subtype of two discriminated schemas`]);
41
+ }
42
+ this.#literals.set(target, { property: schema.discriminator?.property ?? "", value });
43
+ }
44
+ }
45
+ }
46
+ schema(id) {
47
+ const schema = this.#byId.get(id);
48
+ if (!schema)
49
+ throw new CodegenError([`unknown schema "${id}"`]);
50
+ return schema;
51
+ }
52
+ requestName(operationId) {
53
+ return this.#requests.get(operationId);
54
+ }
55
+ responseName(operationId) {
56
+ return this.#responses.get(operationId);
57
+ }
58
+ /** The value a subtype's discriminator property must hold, if the schema is a subtype. */
59
+ literalFor(id) {
60
+ return this.#literals.get(id);
61
+ }
62
+ /** Merges inheritance into one object. A member that is not an object stops generation. */
63
+ flatten(node, where) {
64
+ if (node.type === "object")
65
+ return node;
66
+ if (node.type === "ref")
67
+ return this.flatten(this.schema(node.ref).schema, `${where} → ${node.ref}`);
68
+ if (node.type !== "allOf") {
69
+ throw new CodegenError([`${where}: allOf member of type "${node.type}" cannot be merged into an object`]);
70
+ }
71
+ const merged = {
72
+ properties: {},
73
+ required: [],
74
+ };
75
+ for (const member of node.of) {
76
+ const part = this.flatten(member, where);
77
+ Object.assign(merged.properties, part.properties);
78
+ for (const name of part.required)
79
+ if (!merged.required.includes(name))
80
+ merged.required.push(name);
81
+ if (part.additionalProperties)
82
+ merged.additionalProperties = part.additionalProperties;
83
+ }
84
+ return { type: "object", description: node.description, nullable: node.nullable, ...merged };
85
+ }
86
+ }
87
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/codegen/tree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { CodeGenerator } from "./model.js";
2
+ /** TypeScript types for every schema: what a caller holds after the response has been validated. */
3
+ export declare const typesGenerator: (options: {
4
+ path: string;
5
+ }) => CodeGenerator;
6
+ //# sourceMappingURL=typescript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/codegen/typescript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,aAAa,EAAc,MAAM,YAAY,CAAA;AAmErE,oGAAoG;AACpG,eAAO,MAAM,cAAc,YACf;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,KAAG,aAY5B,CAAA"}
@@ -0,0 +1,76 @@
1
+ import { identifier } from "./names.js";
2
+ import { SchemaTree } from "./tree.js";
3
+ const doc = (text, indent) => {
4
+ const line = text?.replace(/\s+/g, " ").replace(/\*\//g, "*\\/").trim();
5
+ return line ? `${indent}/** ${line} */\n` : "";
6
+ };
7
+ const key = (name) => (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name));
8
+ class TypeWriter {
9
+ tree;
10
+ constructor(tree) {
11
+ this.tree = tree;
12
+ }
13
+ node(node, where, literal) {
14
+ const base = this.#bare(node, where, literal);
15
+ return node.nullable ? `${base} | null` : base;
16
+ }
17
+ #bare(node, where, literal) {
18
+ switch (node.type) {
19
+ case "ref":
20
+ return identifier(node.ref);
21
+ case "string":
22
+ return node.enum ? node.enum.map((value) => JSON.stringify(value)).join(" | ") : "string";
23
+ case "integer":
24
+ if (node.format === "int64")
25
+ return "string";
26
+ return node.enum ? node.enum.map(String).join(" | ") : "number";
27
+ case "number":
28
+ return "number";
29
+ case "boolean":
30
+ return "boolean";
31
+ case "unknown":
32
+ return "unknown";
33
+ case "array": {
34
+ return `Array<${this.node(node.items, `${where}[]`)}>`;
35
+ }
36
+ case "allOf":
37
+ if (node.of.length === 1 && node.of[0] && !literal)
38
+ return this.#bare(node.of[0], where);
39
+ return this.#object(this.tree.flatten(node, where), where, literal);
40
+ case "object":
41
+ return this.#object(node, where, literal);
42
+ }
43
+ }
44
+ #object(node, where, literal) {
45
+ const names = Object.keys(node.properties);
46
+ if (literal && !names.includes(literal.property))
47
+ names.unshift(literal.property);
48
+ const rest = node.additionalProperties
49
+ ? `Record<string, ${this.node(node.additionalProperties, where)}>`
50
+ : undefined;
51
+ if (names.length === 0)
52
+ return rest ?? "Record<string, unknown>";
53
+ const fields = names.map((name) => {
54
+ const property = node.properties[name] ?? { type: "string" };
55
+ const optional = node.required.includes(name) || literal?.property === name ? "" : "?";
56
+ const type = literal?.property === name ? JSON.stringify(literal.value) : this.node(property, `${where}.${name}`);
57
+ return `${doc(property.description, " ")} ${key(name)}${optional}: ${type}`;
58
+ });
59
+ const body = `{\n${fields.join("\n")}\n}`;
60
+ return rest ? `${body} & ${rest}` : body;
61
+ }
62
+ }
63
+ /** TypeScript types for every schema: what a caller holds after the response has been validated. */
64
+ export const typesGenerator = (options) => (model) => {
65
+ const tree = new SchemaTree(model);
66
+ const writer = new TypeWriter(tree);
67
+ const declarations = tree.named.map(({ name, schema }) => {
68
+ const union = schema.discriminator
69
+ ? Object.values(schema.discriminator.mapping).map(identifier).join(" | ")
70
+ : undefined;
71
+ const type = union ?? writer.node(schema.schema, schema.id, tree.literalFor(schema.id));
72
+ return `${doc(schema.schema.description, "")}export type ${name} = ${type}\n`;
73
+ });
74
+ return [{ path: options.path, content: declarations.join("\n") }];
75
+ };
76
+ //# sourceMappingURL=typescript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript.js","sourceRoot":"","sources":["../../src/codegen/typescript.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEtC,MAAM,GAAG,GAAG,CAAC,IAAwB,EAAE,MAAc,EAAU,EAAE;IAC/D,MAAM,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;IACvE,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;AAChD,CAAC,CAAA;AAED,MAAM,GAAG,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;AAE7G,MAAM,UAAU;IACO,IAAI;IAAzB,YAAqB,IAAgB;oBAAhB,IAAI;IAAe,CAAC;IAEzC,IAAI,CAAC,IAAgB,EAAE,KAAa,EAAE,OAA6C;QACjF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA;IAChD,CAAC;IAED,KAAK,CAAC,IAAgB,EAAE,KAAa,EAAE,OAA6C;QAClF,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,KAAK;gBACR,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC7B,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;YAC3F,KAAK,SAAS;gBACZ,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO;oBAAE,OAAO,QAAQ,CAAA;gBAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;YACjE,KAAK,QAAQ;gBACX,OAAO,QAAQ,CAAA;YACjB,KAAK,SAAS;gBACZ,OAAO,SAAS,CAAA;YAClB,KAAK,SAAS;gBACZ,OAAO,SAAS,CAAA;YAClB,KAAK,OAAO,EAAE,CAAC;gBACb,OAAO,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC,GAAG,CAAA;YACxD,CAAC;YACD,KAAK,OAAO;gBACV,IAAI,IAAI,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO;oBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;gBACxF,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;YACrE,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;IAED,OAAO,CACL,IAA6C,EAC7C,KAAa,EACb,OAA6C;QAE7C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC1C,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QACjF,MAAM,IAAI,GAAG,IAAI,CAAC,oBAAoB;YACpC,CAAC,CAAC,kBAAkB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,GAAG;YAClE,CAAC,CAAC,SAAS,CAAA;QACb,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,IAAI,yBAAyB,CAAA;QAChE,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAChC,MAAM,QAAQ,GAAe,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;YACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;YACtF,MAAM,IAAI,GAAG,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC,CAAA;YACjH,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,KAAK,IAAI,EAAE,CAAA;QAC/E,CAAC,CAAC,CAAA;QACF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAA;QACzC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAC1C,CAAC;CACF;AAED,oGAAoG;AACpG,MAAM,CAAC,MAAM,cAAc,GACzB,CAAC,OAAyB,EAAiB,EAAE,CAC7C,CAAC,KAAe,EAAE,EAAE;IAClB,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAClC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAA;IACnC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QACvD,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa;YAChC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACzE,CAAC,CAAC,SAAS,CAAA;QACb,MAAM,IAAI,GAAG,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QACvF,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,eAAe,IAAI,MAAM,IAAI,IAAI,CAAA;IAC/E,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACnE,CAAC,CAAA"}
@@ -0,0 +1,10 @@
1
+ import type { CodeGenerator } from "./model.js";
2
+ export interface ValibotOptions {
3
+ path: string;
4
+ /** Module the types come from, relative to `path`. */
5
+ typesImport: string;
6
+ runtimeImport?: string;
7
+ }
8
+ /** Valibot schemas that keep the source's constraints at run time, which plain generated types lose. */
9
+ export declare const valibotGenerator: (options: ValibotOptions) => CodeGenerator;
10
+ //# sourceMappingURL=valibot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valibot.d.ts","sourceRoot":"","sources":["../../src/codegen/valibot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,aAAa,EAAc,MAAM,YAAY,CAAA;AA8FrE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wGAAwG;AACxG,eAAO,MAAM,gBAAgB,YACjB,cAAc,KAAG,aAqB1B,CAAA"}
@@ -0,0 +1,121 @@
1
+ import { identifier } from "./names.js";
2
+ import { CodegenError } from "./pipeline.js";
3
+ import { SchemaTree } from "./tree.js";
4
+ const key = (name) => (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name));
5
+ const piped = (base, actions) => actions.length === 0 ? base : `v.pipe(${base}, ${actions.join(", ")})`;
6
+ const range = (node) => {
7
+ const parts = [];
8
+ if (node.minimum !== undefined)
9
+ parts.push(`minimum: ${node.minimum}`);
10
+ if (node.maximum !== undefined)
11
+ parts.push(`maximum: ${node.maximum}`);
12
+ return parts.length === 0 ? "" : `{ ${parts.join(", ")} }`;
13
+ };
14
+ class SchemaWriter {
15
+ tree;
16
+ helpers = new Set();
17
+ constructor(tree) {
18
+ this.tree = tree;
19
+ }
20
+ node(node, where, literal) {
21
+ const base = this.#bare(node, where, literal);
22
+ return node.nullable ? `v.nullable(${base})` : base;
23
+ }
24
+ #bare(node, where, literal) {
25
+ switch (node.type) {
26
+ case "ref":
27
+ return `v.lazy(() => ${identifier(node.ref)})`;
28
+ case "string": {
29
+ if (node.enum)
30
+ return `v.picklist(${JSON.stringify(node.enum)})`;
31
+ const actions = [];
32
+ if (node.minLength !== undefined)
33
+ actions.push(`v.minLength(${node.minLength})`);
34
+ if (node.maxLength !== undefined)
35
+ actions.push(`v.maxLength(${node.maxLength})`);
36
+ if (node.pattern !== undefined) {
37
+ try {
38
+ new RegExp(node.pattern);
39
+ }
40
+ catch {
41
+ throw new CodegenError([`${where}: pattern ${JSON.stringify(node.pattern)} is not a JS regular expression`]);
42
+ }
43
+ actions.push(`v.regex(new RegExp(${JSON.stringify(node.pattern)}))`);
44
+ }
45
+ return piped("v.string()", actions);
46
+ }
47
+ case "integer": {
48
+ const helper = node.format === "int64" ? "int64" : "integer";
49
+ this.helpers.add(helper);
50
+ const call = `${helper}(${range(node)})`;
51
+ return node.enum ? piped(call, [`v.picklist(${JSON.stringify(node.enum)})`]) : call;
52
+ }
53
+ case "number":
54
+ this.helpers.add("number");
55
+ return `number(${range(node)})`;
56
+ case "boolean":
57
+ return "v.boolean()";
58
+ case "unknown":
59
+ return "v.unknown()";
60
+ case "array": {
61
+ const actions = [];
62
+ if (node.minItems !== undefined)
63
+ actions.push(`v.minLength(${node.minItems})`);
64
+ if (node.maxItems !== undefined)
65
+ actions.push(`v.maxLength(${node.maxItems})`);
66
+ if (node.uniqueItems)
67
+ this.helpers.add("unique");
68
+ if (node.uniqueItems)
69
+ actions.push(`v.check((items) => unique(items), "items must be unique")`);
70
+ return piped(`v.array(${this.node(node.items, `${where}[]`)})`, actions);
71
+ }
72
+ case "allOf":
73
+ if (node.of.length === 1 && node.of[0] && !literal)
74
+ return this.#bare(node.of[0], where);
75
+ return this.#object(this.tree.flatten(node, where), where, literal);
76
+ case "object":
77
+ return this.#object(node, where, literal);
78
+ }
79
+ }
80
+ // Loose on purpose: MAX adds fields, and a response with a field we have never seen is still valid.
81
+ #object(node, where, literal) {
82
+ const names = Object.keys(node.properties);
83
+ if (literal && !names.includes(literal.property))
84
+ names.unshift(literal.property);
85
+ const rest = node.additionalProperties ? this.node(node.additionalProperties, where) : undefined;
86
+ if (names.length === 0)
87
+ return rest ? `v.record(v.string(), ${rest})` : "v.looseObject({})";
88
+ const entries = names.map((name) => {
89
+ if (literal?.property === name)
90
+ return ` ${key(name)}: v.literal(${JSON.stringify(literal.value)}),`;
91
+ const property = node.properties[name];
92
+ const schema = this.node(property, `${where}.${name}`);
93
+ return ` ${key(name)}: ${node.required.includes(name) ? schema : `v.optional(${schema})`},`;
94
+ });
95
+ const body = `{\n${entries.join("\n")}\n}`;
96
+ return rest ? `v.objectWithRest(${body}, ${rest})` : `v.looseObject(${body})`;
97
+ }
98
+ }
99
+ /** Valibot schemas that keep the source's constraints at run time, which plain generated types lose. */
100
+ export const valibotGenerator = (options) => (model) => {
101
+ const tree = new SchemaTree(model);
102
+ const writer = new SchemaWriter(tree);
103
+ const declarations = tree.named.map(({ name, schema }) => {
104
+ const expression = schema.discriminator
105
+ ? `v.union([${Object.values(schema.discriminator.mapping)
106
+ .map((target) => `v.lazy(() => ${identifier(target)})`)
107
+ .join(", ")}])`
108
+ : writer.node(schema.schema, schema.id, tree.literalFor(schema.id));
109
+ return `export const ${name}: v.GenericSchema<unknown, T.${name}> = ${expression}\n`;
110
+ });
111
+ const helpers = [...writer.helpers].sort();
112
+ const runtime = options.runtimeImport ?? "@leemour/cli-core/codegen/runtime";
113
+ const packages = [
114
+ `import * as v from "valibot"`,
115
+ ...(helpers.length > 0 ? [`import { ${helpers.join(", ")} } from "${runtime}"`] : []),
116
+ ].sort((a, b) => (a.split(" from ")[1] ?? "").localeCompare(b.split(" from ")[1] ?? ""));
117
+ const header = [...packages, `import type * as T from "${options.typesImport}"`, ""];
118
+ const registry = `export const schemas = {\n${tree.named.map(({ name }) => ` ${name},`).join("\n")}\n} as const\n`;
119
+ return [{ path: options.path, content: `${header.join("\n")}\n${declarations.join("\n")}\n${registry}` }];
120
+ };
121
+ //# sourceMappingURL=valibot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valibot.js","sourceRoot":"","sources":["../../src/codegen/valibot.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,SAAU,MAAM,YAAY,MAAM,QAAQ,MAAM,KAAG,IAQ5E,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,SAAS,CAAC,CAAC,aAAa,QACtD,MAAM,UACJ,OAAO,YACL,MAAM,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,KACrC,CAAC,CAAC,WAAW,CAAC,OAAO,CAqBvB,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,cAAc,SAAU,MAAM,UAAU,OAAO,KAAG,IAE9D,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,SAAU,MAAM,YAAY,MAAM,QAAQ,MAAM,KAAG,IAe5E,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,SAAS,CAAC,CAAC,aAAa,QACtD,MAAM,UACJ,OAAO,YACL,MAAM,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,KACrC,CAAC,CAAC,WAAW,CAAC,OAAO,CAqBvB,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,cAAc,SAAU,MAAM,UAAU,OAAO,KAAG,IAE9D,CAAA"}
package/dist/config.js CHANGED
@@ -1,4 +1,5 @@
1
- import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
1
+ import { randomBytes } from "node:crypto";
2
+ import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
2
3
  import { dirname, join } from "node:path";
3
4
  import * as v from "valibot";
4
5
  /**
@@ -12,10 +13,18 @@ import * as v from "valibot";
12
13
  export const writeSecurely = (path, contents, mode) => {
13
14
  const dir = dirname(path);
14
15
  mkdirSync(dir, { recursive: true, mode: 0o700 });
15
- const temp = join(dir, `.${Date.now()}-${process.pid}.tmp`);
16
- writeFileSync(temp, contents, { mode });
17
- // A rename within one directory is atomic on every platform we target.
18
- renameSync(temp, path);
16
+ // An unguessable name opened with `wx` fails on anything already there, a planted symlink
17
+ // included, instead of writing through it.
18
+ const temp = join(dir, `.${randomBytes(8).toString("hex")}.tmp`);
19
+ try {
20
+ writeFileSync(temp, contents, { mode, flag: "wx" });
21
+ // A rename within one directory is atomic on every platform we target.
22
+ renameSync(temp, path);
23
+ }
24
+ catch (error) {
25
+ rmSync(temp, { force: true });
26
+ throw error;
27
+ }
19
28
  };
20
29
  /**
21
30
  * Reads and validates a JSON config. A missing file is not an error — it is a program that has not
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAE,IAAY,EAAQ,EAAE;IAClF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAEhD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC,CAAA;IAC3D,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IACvC,uEAAuE;IACvE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AACxB,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,IAAY,EACZ,MAAe,EACf,QAAsC,EACd,EAAE;IAC1B,IAAI,IAAY,CAAA;IAChB,IAAI,CAAC;QACH,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,EAAE,CAAA;IACnB,CAAC;IAED,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAA;IAC9C,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACrG,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,8BAA8B,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAA;AACtB,CAAC,CAAA;AAED,sFAAsF;AACtF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,MAAe,EAAQ,EAAE;IACpE,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACpE,CAAC,CAAA"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACpF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAE,IAAY,EAAQ,EAAE;IAClF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAEhD,0FAA0F;IAC1F,2CAA2C;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAChE,IAAI,CAAC;QACH,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QACnD,uEAAuE;QACvE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7B,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,IAAY,EACZ,MAAe,EACf,QAAsC,EACd,EAAE;IAC1B,IAAI,IAAY,CAAA;IAChB,IAAI,CAAC;QACH,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,EAAE,CAAA;IACnB,CAAC;IAED,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAA;IAC9C,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACrG,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,8BAA8B,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAA;AACtB,CAAC,CAAA;AAED,sFAAsF;AACtF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,MAAe,EAAQ,EAAE;IACpE,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACpE,CAAC,CAAA"}
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export { configFilePath, type Paths, type PathsOptions, pathsAreOverridden, reso
10
10
  export { type PrettyOptions, renderPretty } from "./pretty.js";
11
11
  export { createRenderer, RENDER_FORMATS, type Renderer, type RendererOptions, type RenderFormat, } from "./renderer.js";
12
12
  export { backoffMs, DEFAULT_RETRY, isTransportFailure, type RetryConfig } from "./retry.js";
13
- export { visibleControls } from "./sanitize.js";
13
+ export { singleLine, visibleControls } from "./sanitize.js";
14
14
  export { captureStreams, processStreams, type Streams } from "./streams.js";
15
15
  export { abortError, type MonotonicClock, monotonic, realSleep, type SleepLike, type SleepReason, type WallClock, wallClock, } from "./time.js";
16
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3E,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACjH,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAClF,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC7F,OAAO,EAAE,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACzG,OAAO,EAAE,cAAc,EAAE,KAAK,KAAK,EAAE,KAAK,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5G,OAAO,EAAE,KAAK,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAC3F,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EACL,UAAU,EACV,KAAK,cAAc,EACnB,SAAS,EACT,SAAS,EACT,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,SAAS,GACV,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3E,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACjH,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAClF,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC7F,OAAO,EAAE,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACzG,OAAO,EAAE,cAAc,EAAE,KAAK,KAAK,EAAE,KAAK,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5G,OAAO,EAAE,KAAK,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAC3F,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EACL,UAAU,EACV,KAAK,cAAc,EACnB,SAAS,EACT,SAAS,EACT,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,SAAS,GACV,MAAM,WAAW,CAAA"}
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ export { configFilePath, pathsAreOverridden, resolvePaths } from "./paths.js";
9
9
  export { renderPretty } from "./pretty.js";
10
10
  export { createRenderer, RENDER_FORMATS, } from "./renderer.js";
11
11
  export { backoffMs, DEFAULT_RETRY, isTransportFailure } from "./retry.js";
12
- export { visibleControls } from "./sanitize.js";
12
+ export { singleLine, visibleControls } from "./sanitize.js";
13
13
  export { captureStreams, processStreams } from "./streams.js";
14
14
  export { abortError, monotonic, realSleep, wallClock, } from "./time.js";
15
15
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3E,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAClF,OAAO,EAAE,QAAQ,EAAwC,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAqB,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC7F,OAAO,EAAe,UAAU,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAA2C,eAAe,EAAE,MAAM,cAAc,CAAA;AACzG,OAAO,EAAE,cAAc,EAAiC,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5G,OAAO,EAAsB,YAAY,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EACL,cAAc,EACd,cAAc,GAIf,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,kBAAkB,EAAoB,MAAM,YAAY,CAAA;AAC3F,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAgB,MAAM,cAAc,CAAA;AAC3E,OAAO,EACL,UAAU,EAEV,SAAS,EACT,SAAS,EAIT,SAAS,GACV,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3E,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAClF,OAAO,EAAE,QAAQ,EAAwC,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAqB,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC7F,OAAO,EAAe,UAAU,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAA2C,eAAe,EAAE,MAAM,cAAc,CAAA;AACzG,OAAO,EAAE,cAAc,EAAiC,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5G,OAAO,EAAsB,YAAY,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EACL,cAAc,EACd,cAAc,GAIf,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,kBAAkB,EAAoB,MAAM,YAAY,CAAA;AAC3F,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAgB,MAAM,cAAc,CAAA;AAC3E,OAAO,EACL,UAAU,EAEV,SAAS,EACT,SAAS,EAIT,SAAS,GACV,MAAM,WAAW,CAAA"}
@@ -9,5 +9,17 @@
9
9
  * **Machine modes need none of this** — `JSON.stringify` already escapes control characters, and
10
10
  * those bytes are a contract with scripts. Only what a person reads goes through here.
11
11
  */
12
+ /**
13
+ * Control characters become visible rather than disappearing. A reader has to know the value
14
+ * contained something strange; an audit that silently drops bytes is worse than one that shows
15
+ * them.
16
+ *
17
+ * `\t` and `\n` survive, because a table and a multi-line field are built out of them.
18
+ */
12
19
  export declare const visibleControls: (text: string) => string;
20
+ /**
21
+ * For a value that must stay on one line: a name, a title, a file name, a URL. A newline in a
22
+ * sender's name would otherwise print as a line of its own, indistinguishable from real output.
23
+ */
24
+ export declare const singleLine: (text: string) => string;
13
25
  //# sourceMappingURL=sanitize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,eAAO,MAAM,eAAe,SAAU,MAAM,KAAG,MACsC,CAAA"}
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAoBH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,SAAU,MAAM,KAAG,MAAwC,CAAA;AAEvF;;;GAGG;AACH,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,MAA6D,CAAA"}
package/dist/sanitize.js CHANGED
@@ -9,6 +9,21 @@
9
9
  * **Machine modes need none of this** — `JSON.stringify` already escapes control characters, and
10
10
  * those bytes are a contract with scripts. Only what a person reads goes through here.
11
11
  */
12
+ /**
13
+ * C0 minus tab and newline, DEL, and C1 — which xterm honours as escapes in its 8-bit form. Then
14
+ * the direction overrides and isolates, which reorder what follows them (`invoice\u202efdp.exe`
15
+ * reads as a PDF), and the invisible zero-width space and direction marks.
16
+ *
17
+ * U+200C and U+200D stay: Persian and Indic text need the non-joiner, and every multi-person emoji
18
+ * is built with the joiner.
19
+ */
20
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: matching them is the whole point
21
+ const CONTROL = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u200B\u200E\u200F\u202A-\u202E\u2066-\u2069]/g;
22
+ const LINE_BREAKS = /[\t\n\u2028\u2029]/g;
23
+ const escaped = (c) => {
24
+ const code = c.charCodeAt(0);
25
+ return code > 0xff ? `\\u${code.toString(16).padStart(4, "0")}` : `\\x${code.toString(16).padStart(2, "0")}`;
26
+ };
12
27
  /**
13
28
  * Control characters become visible rather than disappearing. A reader has to know the value
14
29
  * contained something strange; an audit that silently drops bytes is worse than one that shows
@@ -16,8 +31,10 @@
16
31
  *
17
32
  * `\t` and `\n` survive, because a table and a multi-line field are built out of them.
18
33
  */
19
- /** C0 minus tab and newline, DEL, and C1 — which xterm honours as escapes in its 8-bit form. */
20
- // biome-ignore lint/suspicious/noControlCharactersInRegex: matching them is the whole point
21
- const CONTROL = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F]/g;
22
- export const visibleControls = (text) => text.replace(CONTROL, (c) => `\\x${c.charCodeAt(0).toString(16).padStart(2, "0")}`);
34
+ export const visibleControls = (text) => text.replace(CONTROL, escaped);
35
+ /**
36
+ * For a value that must stay on one line: a name, a title, a file name, a URL. A newline in a
37
+ * sender's name would otherwise print as a line of its own, indistinguishable from real output.
38
+ */
39
+ export const singleLine = (text) => visibleControls(text).replace(LINE_BREAKS, escaped);
23
40
  //# sourceMappingURL=sanitize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;GAMG;AACH,gGAAgG;AAChG,4FAA4F;AAC5F,MAAM,OAAO,GAAG,4CAA4C,CAAA;AAE5D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE,CACtD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA"}
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,4FAA4F;AAC5F,MAAM,OAAO,GAAG,wFAAwF,CAAA;AAExG,MAAM,WAAW,GAAG,qBAAqB,CAAA;AAEzC,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE;IACpC,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IAC5B,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAA;AAC9G,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAEvF;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA"}