@pajecawav/json2code 0.0.0-stage → 0.2.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 (82) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +180 -2
  3. package/dist/cli.d.mts +1 -0
  4. package/dist/cli.mjs +131 -0
  5. package/dist/cli.mjs.map +1 -0
  6. package/dist/core/config.mjs +53 -0
  7. package/dist/core/config.mjs.map +1 -0
  8. package/dist/core/discovery/index.d.mts +10 -0
  9. package/dist/core/discovery/index.d.mts.map +1 -0
  10. package/dist/core/discovery/index.mjs +83 -0
  11. package/dist/core/discovery/index.mjs.map +1 -0
  12. package/dist/core/generate.d.mts +11 -0
  13. package/dist/core/generate.d.mts.map +1 -0
  14. package/dist/core/generate.mjs +89 -0
  15. package/dist/core/generate.mjs.map +1 -0
  16. package/dist/core/ir/types.d.mts +100 -0
  17. package/dist/core/ir/types.d.mts.map +1 -0
  18. package/dist/core/ir/visit.d.mts +8 -0
  19. package/dist/core/ir/visit.d.mts.map +1 -0
  20. package/dist/core/ir/visit.mjs +38 -0
  21. package/dist/core/ir/visit.mjs.map +1 -0
  22. package/dist/core/linker/index.d.mts +32 -0
  23. package/dist/core/linker/index.d.mts.map +1 -0
  24. package/dist/core/linker/index.mjs +104 -0
  25. package/dist/core/linker/index.mjs.map +1 -0
  26. package/dist/core/printer/abstract.d.mts +26 -0
  27. package/dist/core/printer/abstract.d.mts.map +1 -0
  28. package/dist/core/types.d.mts +76 -0
  29. package/dist/core/types.d.mts.map +1 -0
  30. package/dist/core/types.mjs +28 -0
  31. package/dist/core/types.mjs.map +1 -0
  32. package/dist/core/walker/abstract.d.mts +18 -0
  33. package/dist/core/walker/abstract.d.mts.map +1 -0
  34. package/dist/core/walker/json-schema.d.mts +10 -0
  35. package/dist/core/walker/json-schema.d.mts.map +1 -0
  36. package/dist/core/walker/json-schema.mjs +311 -0
  37. package/dist/core/walker/json-schema.mjs.map +1 -0
  38. package/dist/core/walker/ref-resolver.d.mts +22 -0
  39. package/dist/core/walker/ref-resolver.d.mts.map +1 -0
  40. package/dist/core/walker/ref-resolver.mjs +66 -0
  41. package/dist/core/walker/ref-resolver.mjs.map +1 -0
  42. package/dist/core/writer/index.d.mts +19 -0
  43. package/dist/core/writer/index.d.mts.map +1 -0
  44. package/dist/core/writer/index.mjs +84 -0
  45. package/dist/core/writer/index.mjs.map +1 -0
  46. package/dist/diagnostics/errors.d.mts +39 -0
  47. package/dist/diagnostics/errors.d.mts.map +1 -0
  48. package/dist/diagnostics/errors.mjs +50 -0
  49. package/dist/diagnostics/errors.mjs.map +1 -0
  50. package/dist/diagnostics/logger.d.mts +10 -0
  51. package/dist/diagnostics/logger.d.mts.map +1 -0
  52. package/dist/diagnostics/logger.mjs +18 -0
  53. package/dist/diagnostics/logger.mjs.map +1 -0
  54. package/dist/index.d.mts +24 -0
  55. package/dist/index.d.mts.map +1 -0
  56. package/dist/index.mjs +26 -0
  57. package/dist/index.mjs.map +1 -0
  58. package/dist/package.mjs +6 -0
  59. package/dist/package.mjs.map +1 -0
  60. package/dist/targets/index.d.mts +9 -0
  61. package/dist/targets/index.d.mts.map +1 -0
  62. package/dist/targets/index.mjs +30 -0
  63. package/dist/targets/index.mjs.map +1 -0
  64. package/dist/targets/shared.mjs +137 -0
  65. package/dist/targets/shared.mjs.map +1 -0
  66. package/dist/targets/typescript/printer.d.mts +13 -0
  67. package/dist/targets/typescript/printer.d.mts.map +1 -0
  68. package/dist/targets/typescript/printer.mjs +47 -0
  69. package/dist/targets/typescript/printer.mjs.map +1 -0
  70. package/dist/targets/valibot/printer.d.mts +21 -0
  71. package/dist/targets/valibot/printer.d.mts.map +1 -0
  72. package/dist/targets/valibot/printer.mjs +198 -0
  73. package/dist/targets/valibot/printer.mjs.map +1 -0
  74. package/dist/targets/zod/lazy.d.mts +29 -0
  75. package/dist/targets/zod/lazy.d.mts.map +1 -0
  76. package/dist/targets/zod/lazy.mjs +100 -0
  77. package/dist/targets/zod/lazy.mjs.map +1 -0
  78. package/dist/targets/zod/printer.d.mts +21 -0
  79. package/dist/targets/zod/printer.d.mts.map +1 -0
  80. package/dist/targets/zod/printer.mjs +193 -0
  81. package/dist/targets/zod/printer.mjs.map +1 -0
  82. package/package.json +71 -3
@@ -0,0 +1,50 @@
1
+ //#region src/diagnostics/errors.ts
2
+ const DiagnosticCode = {
3
+ FileNotFound: "J2C_FILE_NOT_FOUND",
4
+ InvalidJson: "J2C_INVALID_JSON",
5
+ InvalidRef: "J2C_INVALID_REF",
6
+ ExternalRef: "J2C_EXTERNAL_REF",
7
+ NameCollision: "J2C_NAME_COLLISION",
8
+ UnknownKeyword: "J2C_UNKNOWN_KEYWORD",
9
+ OutputDirty: "J2C_OUTPUT_DIRTY"
10
+ };
11
+ function createDiagnostic(code, severity, message, location) {
12
+ return {
13
+ code,
14
+ severity,
15
+ message,
16
+ ...location
17
+ };
18
+ }
19
+ /** Format a single diagnostic as `[docId] → [$ref] → message`. */
20
+ function formatDiagnostic(diag) {
21
+ const parts = [];
22
+ if (diag.docId) parts.push(`[${diag.docId}]`);
23
+ if (diag.ref) parts.push(`[${diag.ref}]`);
24
+ parts.push(diag.message);
25
+ return parts.join(" → ");
26
+ }
27
+ /** Aggregated error carrying all collected diagnostics. Thrown once at the end of a run. */
28
+ var Json2CodeError = class extends Error {
29
+ diagnostics;
30
+ constructor(diagnostics) {
31
+ super(diagnostics.map(formatDiagnostic).join("\n"));
32
+ this.name = "Json2CodeError";
33
+ this.diagnostics = diagnostics;
34
+ }
35
+ };
36
+ /** Separate error-level from warning-level diagnostics. */
37
+ function partitionDiagnostics(diagnostics) {
38
+ const errors = [];
39
+ const warnings = [];
40
+ for (const diag of diagnostics) if (diag.severity === "error") errors.push(diag);
41
+ else warnings.push(diag);
42
+ return {
43
+ errors,
44
+ warnings
45
+ };
46
+ }
47
+ //#endregion
48
+ export { DiagnosticCode, Json2CodeError, createDiagnostic, formatDiagnostic, partitionDiagnostics };
49
+
50
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../../src/diagnostics/errors.ts"],"sourcesContent":["export const DiagnosticCode = {\n\tFileNotFound: \"J2C_FILE_NOT_FOUND\",\n\tInvalidJson: \"J2C_INVALID_JSON\",\n\tInvalidRef: \"J2C_INVALID_REF\",\n\tExternalRef: \"J2C_EXTERNAL_REF\",\n\tNameCollision: \"J2C_NAME_COLLISION\",\n\tUnknownKeyword: \"J2C_UNKNOWN_KEYWORD\",\n\tOutputDirty: \"J2C_OUTPUT_DIRTY\",\n} as const;\n\nexport type DiagnosticCode = (typeof DiagnosticCode)[keyof typeof DiagnosticCode];\n\nexport type DiagnosticSeverity = \"error\" | \"warning\";\n\nexport interface Diagnostic {\n\treadonly code: DiagnosticCode;\n\treadonly severity: DiagnosticSeverity;\n\treadonly message: string;\n\t/** doc id (path relative to input root) for display. */\n\treadonly docId?: string;\n\t/** the $ref string that caused the diagnostic. */\n\treadonly ref?: string;\n}\n\nexport function createDiagnostic(\n\tcode: DiagnosticCode,\n\tseverity: DiagnosticSeverity,\n\tmessage: string,\n\tlocation?: { docId?: string; ref?: string },\n): Diagnostic {\n\treturn { code, severity, message, ...location };\n}\n\n/** Format a single diagnostic as `[docId] → [$ref] → message`. */\nexport function formatDiagnostic(diag: Diagnostic): string {\n\tconst parts: string[] = [];\n\tif (diag.docId) {\n\t\tparts.push(`[${diag.docId}]`);\n\t}\n\tif (diag.ref) {\n\t\tparts.push(`[${diag.ref}]`);\n\t}\n\tparts.push(diag.message);\n\treturn parts.join(\" → \");\n}\n\n/** Aggregated error carrying all collected diagnostics. Thrown once at the end of a run. */\nexport class Json2CodeError extends Error {\n\tpublic readonly diagnostics: Diagnostic[];\n\n\tpublic constructor(diagnostics: Diagnostic[]) {\n\t\tsuper(diagnostics.map(formatDiagnostic).join(\"\\n\"));\n\t\tthis.name = \"Json2CodeError\";\n\t\tthis.diagnostics = diagnostics;\n\t}\n}\n\n/** Separate error-level from warning-level diagnostics. */\nexport function partitionDiagnostics(diagnostics: readonly Diagnostic[]): {\n\terrors: Diagnostic[];\n\twarnings: Diagnostic[];\n} {\n\tconst errors: Diagnostic[] = [];\n\tconst warnings: Diagnostic[] = [];\n\tfor (const diag of diagnostics) {\n\t\tif (diag.severity === \"error\") {\n\t\t\terrors.push(diag);\n\t\t} else {\n\t\t\twarnings.push(diag);\n\t\t}\n\t}\n\treturn { errors, warnings };\n}\n"],"mappings":";AAAA,MAAa,iBAAiB;CAC7B,cAAc;CACd,aAAa;CACb,YAAY;CACZ,aAAa;CACb,eAAe;CACf,gBAAgB;CAChB,aAAa;AACd;AAgBA,SAAgB,iBACf,MACA,UACA,SACA,UACa;CACb,OAAO;EAAE;EAAM;EAAU;EAAS,GAAG;CAAS;AAC/C;;AAGA,SAAgB,iBAAiB,MAA0B;CAC1D,MAAM,QAAkB,CAAC;CACzB,IAAI,KAAK,OACR,MAAM,KAAK,IAAI,KAAK,MAAM,EAAE;CAE7B,IAAI,KAAK,KACR,MAAM,KAAK,IAAI,KAAK,IAAI,EAAE;CAE3B,MAAM,KAAK,KAAK,OAAO;CACvB,OAAO,MAAM,KAAK,KAAK;AACxB;;AAGA,IAAa,iBAAb,cAAoC,MAAM;CACzC;CAEA,YAAmB,aAA2B;EAC7C,MAAM,YAAY,IAAI,gBAAgB,CAAC,CAAC,KAAK,IAAI,CAAC;EAClD,KAAK,OAAO;EACZ,KAAK,cAAc;CACpB;AACD;;AAGA,SAAgB,qBAAqB,aAGnC;CACD,MAAM,SAAuB,CAAC;CAC9B,MAAM,WAAyB,CAAC;CAChC,KAAK,MAAM,QAAQ,aAClB,IAAI,KAAK,aAAa,SACrB,OAAO,KAAK,IAAI;MAEhB,SAAS,KAAK,IAAI;CAGpB,OAAO;EAAE;EAAQ;CAAS;AAC3B"}
@@ -0,0 +1,10 @@
1
+ //#region src/diagnostics/logger.d.ts
2
+ export interface Logger {
3
+ readonly debug: (message: string, ...args: unknown[]) => void;
4
+ readonly info: (message: string, ...args: unknown[]) => void;
5
+ readonly warn: (message: string, ...args: unknown[]) => void;
6
+ readonly error: (message: string, ...args: unknown[]) => void;
7
+ }
8
+ export declare function createLogger(verbose?: boolean): Logger;
9
+ //#endregion
10
+ //# sourceMappingURL=logger.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.mts","names":[],"sources":["../../src/diagnostics/logger.ts"],"mappings":";iBAEiB;WACP,QAAQ,oBAAoB;WAC5B,OAAO,oBAAoB;WAC3B,OAAO,oBAAoB;WAC3B,QAAQ,oBAAoB;;wBAGtB,aAAa,oBAAkB"}
@@ -0,0 +1,18 @@
1
+ import { createConsola } from "consola";
2
+ //#region src/diagnostics/logger.ts
3
+ function createLogger(verbose = false) {
4
+ const consola = createConsola({
5
+ level: verbose ? 4 : 3,
6
+ fancy: true
7
+ });
8
+ return {
9
+ debug: (message, ...args) => consola.debug(message, ...args),
10
+ info: (message, ...args) => consola.info(message, ...args),
11
+ warn: (message, ...args) => consola.warn(message, ...args),
12
+ error: (message, ...args) => consola.error(message, ...args)
13
+ };
14
+ }
15
+ //#endregion
16
+ export { createLogger };
17
+
18
+ //# sourceMappingURL=logger.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.mjs","names":[],"sources":["../../src/diagnostics/logger.ts"],"sourcesContent":["import { createConsola } from \"consola\";\n\nexport interface Logger {\n\treadonly debug: (message: string, ...args: unknown[]) => void;\n\treadonly info: (message: string, ...args: unknown[]) => void;\n\treadonly warn: (message: string, ...args: unknown[]) => void;\n\treadonly error: (message: string, ...args: unknown[]) => void;\n}\n\nexport function createLogger(verbose = false): Logger {\n\tconst consola = createConsola({ level: verbose ? 4 : 3, fancy: true });\n\treturn {\n\t\tdebug: (message, ...args) => consola.debug(message, ...args),\n\t\tinfo: (message, ...args) => consola.info(message, ...args),\n\t\twarn: (message, ...args) => consola.warn(message, ...args),\n\t\terror: (message, ...args) => consola.error(message, ...args),\n\t};\n}\n"],"mappings":";;AASA,SAAgB,aAAa,UAAU,OAAe;CACrD,MAAM,UAAU,cAAc;EAAE,OAAO,UAAU,IAAI;EAAG,OAAO;CAAK,CAAC;CACrE,OAAO;EACN,QAAQ,SAAS,GAAG,SAAS,QAAQ,MAAM,SAAS,GAAG,IAAI;EAC3D,OAAO,SAAS,GAAG,SAAS,QAAQ,KAAK,SAAS,GAAG,IAAI;EACzD,OAAO,SAAS,GAAG,SAAS,QAAQ,KAAK,SAAS,GAAG,IAAI;EACzD,QAAQ,SAAS,GAAG,SAAS,QAAQ,MAAM,SAAS,GAAG,IAAI;CAC5D;AACD"}
@@ -0,0 +1,24 @@
1
+ import { Diagnostic, DiagnosticCode, DiagnosticSeverity, Json2CodeError, createDiagnostic, formatDiagnostic, partitionDiagnostics } from "./diagnostics/errors.mjs";
2
+ import { Logger, createLogger } from "./diagnostics/logger.mjs";
3
+ import { IRKind, IRMeta, IRType, Ref, SourceDoc } from "./core/ir/types.mjs";
4
+ import { AbstractPrinter, PrintContext } from "./core/printer/abstract.mjs";
5
+ import { AbstractWalker, WalkerContext } from "./core/walker/abstract.mjs";
6
+ import { DEFAULT_OPTIONS, GenerateConfig, GenerateOptions, GeneratorDefinition, ImportExtension, ImportPaths, PrintedFile, ResolvedOptions, SchemaFile, TargetName, TargetSpec } from "./core/types.mjs";
7
+ import { GenerateResult, generate } from "./core/generate.mjs";
8
+ import { discover } from "./core/discovery/index.mjs";
9
+ import { Linker } from "./core/linker/index.mjs";
10
+ import { writeFiles } from "./core/writer/index.mjs";
11
+ import { TsPrinter } from "./targets/typescript/printer.mjs";
12
+ import { ValibotPrinter } from "./targets/valibot/printer.mjs";
13
+ import { ZodPrinter } from "./targets/zod/printer.mjs";
14
+ import { resolveTarget } from "./targets/index.mjs";
15
+ import { JsonSchemaWalker } from "./core/walker/json-schema.mjs";
16
+ import { RefResolution, resolveRef } from "./core/walker/ref-resolver.mjs";
17
+ import { LazyGraph, NodeId, buildLazyGraph, nodeId } from "./targets/zod/lazy.mjs";
18
+ import { referencedDocs, visitRefs } from "./core/ir/visit.mjs";
19
+ //#region src/index.d.ts
20
+ export declare function defineGenerator(def: GeneratorDefinition): GeneratorDefinition;
21
+ export declare function defineConfig(config: GenerateConfig): GenerateConfig;
22
+ //#endregion
23
+ export { type AbstractPrinter, type AbstractWalker, DEFAULT_OPTIONS, type Diagnostic, DiagnosticCode, type DiagnosticSeverity, type GenerateConfig, type GenerateOptions, type GenerateResult, type GeneratorDefinition, type IRKind, type IRMeta, type IRType, type ImportExtension, type ImportPaths, Json2CodeError, JsonSchemaWalker, type LazyGraph, Linker, type Logger, type NodeId, type PrintContext, type PrintedFile, type Ref, type RefResolution, type ResolvedOptions, type SchemaFile, type SourceDoc, type TargetName, type TargetSpec, TsPrinter, ValibotPrinter, type WalkerContext, ZodPrinter, buildLazyGraph, createDiagnostic, createLogger, discover, formatDiagnostic, generate, nodeId, partitionDiagnostics, referencedDocs, resolveRef, resolveTarget, visitRefs, writeFiles };
24
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;wBAwDgB,gBAAgB,KAAK,sBAAsB;wBAI3C,aAAa,QAAQ,iBAAiB"}
package/dist/index.mjs ADDED
@@ -0,0 +1,26 @@
1
+ import { DiagnosticCode, Json2CodeError, createDiagnostic, formatDiagnostic, partitionDiagnostics } from "./diagnostics/errors.mjs";
2
+ import { createLogger } from "./diagnostics/logger.mjs";
3
+ import { referencedDocs, visitRefs } from "./core/ir/visit.mjs";
4
+ import { TsPrinter } from "./targets/typescript/printer.mjs";
5
+ import { buildLazyGraph, nodeId } from "./targets/zod/lazy.mjs";
6
+ import { ValibotPrinter } from "./targets/valibot/printer.mjs";
7
+ import { ZodPrinter } from "./targets/zod/printer.mjs";
8
+ import { resolveTarget } from "./targets/index.mjs";
9
+ import { discover } from "./core/discovery/index.mjs";
10
+ import { Linker } from "./core/linker/index.mjs";
11
+ import { DEFAULT_OPTIONS } from "./core/types.mjs";
12
+ import { resolveRef } from "./core/walker/ref-resolver.mjs";
13
+ import { JsonSchemaWalker } from "./core/walker/json-schema.mjs";
14
+ import { writeFiles } from "./core/writer/index.mjs";
15
+ import { generate } from "./core/generate.mjs";
16
+ //#region src/index.ts
17
+ function defineGenerator(def) {
18
+ return def;
19
+ }
20
+ function defineConfig(config) {
21
+ return config;
22
+ }
23
+ //#endregion
24
+ export { DEFAULT_OPTIONS, DiagnosticCode, Json2CodeError, JsonSchemaWalker, Linker, TsPrinter, ValibotPrinter, ZodPrinter, buildLazyGraph, createDiagnostic, createLogger, defineConfig, defineGenerator, discover, formatDiagnostic, generate, nodeId, partitionDiagnostics, referencedDocs, resolveRef, resolveTarget, visitRefs, writeFiles };
25
+
26
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["// ── Core pipeline ──────────────────────────────────────────────────────────\nexport { generate } from \"./core/generate.js\";\nexport type { GenerateResult } from \"./core/generate.js\";\nexport { discover } from \"./core/discovery/index.js\";\nexport { Linker } from \"./core/linker/index.js\";\nexport { writeFiles } from \"./core/writer/index.js\";\nexport { resolveTarget } from \"./targets/index.js\";\n\n// ── Built-in targets & walker ───────────────────────────────────────────────\nexport { JsonSchemaWalker } from \"./core/walker/json-schema.js\";\nexport { resolveRef } from \"./core/walker/ref-resolver.js\";\nexport type { RefResolution } from \"./core/walker/ref-resolver.js\";\nexport { TsPrinter } from \"./targets/typescript/printer.js\";\nexport { ZodPrinter } from \"./targets/zod/printer.js\";\nexport { ValibotPrinter } from \"./targets/valibot/printer.js\";\nexport { buildLazyGraph, nodeId } from \"./targets/zod/lazy.js\";\nexport type { LazyGraph, NodeId } from \"./targets/zod/lazy.js\";\nexport { visitRefs, referencedDocs } from \"./core/ir/visit.js\";\n\n// ── Public contracts ───────────────────────────────────────────────────────\nexport type {\n\tGenerateConfig,\n\tGenerateOptions,\n\tResolvedOptions,\n\tGeneratorDefinition,\n\tTargetSpec,\n\tTargetName,\n\tImportExtension,\n\tImportPaths,\n\tSchemaFile,\n\tPrintedFile,\n} from \"./core/types.js\";\nexport { DEFAULT_OPTIONS } from \"./core/types.js\";\n\n// ── Abstract extension points ──────────────────────────────────────────────\nexport type { AbstractWalker, WalkerContext } from \"./core/walker/abstract.js\";\nexport type { AbstractPrinter, PrintContext } from \"./core/printer/abstract.js\";\n\n// ── IR ─────────────────────────────────────────────────────────────────────\nexport type { IRType, IRKind, IRMeta, Ref, SourceDoc } from \"./core/ir/types.js\";\n\n// ── Diagnostics ────────────────────────────────────────────────────────────\nexport {\n\tDiagnosticCode,\n\tJson2CodeError,\n\tcreateDiagnostic,\n\tformatDiagnostic,\n\tpartitionDiagnostics,\n} from \"./diagnostics/errors.js\";\nexport type { Diagnostic, DiagnosticSeverity } from \"./diagnostics/errors.js\";\nexport { createLogger } from \"./diagnostics/logger.js\";\nexport type { Logger } from \"./diagnostics/logger.js\";\n\n// ── Ergonomic helpers for config files ────────────────────────────────────\nimport type { GenerateConfig, GeneratorDefinition } from \"./core/types.js\";\n\nexport function defineGenerator(def: GeneratorDefinition): GeneratorDefinition {\n\treturn def;\n}\n\nexport function defineConfig(config: GenerateConfig): GenerateConfig {\n\treturn config;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAwDA,SAAgB,gBAAgB,KAA+C;CAC9E,OAAO;AACR;AAEA,SAAgB,aAAa,QAAwC;CACpE,OAAO;AACR"}
@@ -0,0 +1,6 @@
1
+ //#region package.json
2
+ var version = "0.2.0";
3
+ //#endregion
4
+ export { version };
5
+
6
+ //# sourceMappingURL=package.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.mjs","names":[],"sources":["../package.json"],"sourcesContent":[""],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import { GeneratorDefinition, TargetSpec } from "../core/types.mjs";
2
+ import { TsPrinter } from "./typescript/printer.mjs";
3
+ import { ValibotPrinter } from "./valibot/printer.mjs";
4
+ import { ZodPrinter } from "./zod/printer.mjs";
5
+ //#region src/targets/index.d.ts
6
+ /** Resolve a {@link TargetSpec} into a concrete {@link GeneratorDefinition}. */
7
+ export declare function resolveTarget(spec: TargetSpec): GeneratorDefinition;
8
+ //#endregion
9
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/targets/index.ts"],"mappings":";;;;;;wBAUgB,cAAc,MAAM,aAAa"}
@@ -0,0 +1,30 @@
1
+ import { TsPrinter } from "./typescript/printer.mjs";
2
+ import { ValibotPrinter } from "./valibot/printer.mjs";
3
+ import { ZodPrinter } from "./zod/printer.mjs";
4
+ //#region src/targets/index.ts
5
+ const TYPESCRIPT_TARGET = {
6
+ name: "typescript",
7
+ printer: new TsPrinter()
8
+ };
9
+ const ZOD_TARGET = {
10
+ name: "zod",
11
+ printer: new ZodPrinter()
12
+ };
13
+ const VALIBOT_TARGET = {
14
+ name: "valibot",
15
+ printer: new ValibotPrinter()
16
+ };
17
+ /** Resolve a {@link TargetSpec} into a concrete {@link GeneratorDefinition}. */
18
+ function resolveTarget(spec) {
19
+ if (typeof spec !== "string") return spec;
20
+ switch (spec) {
21
+ case "typescript": return TYPESCRIPT_TARGET;
22
+ case "zod": return ZOD_TARGET;
23
+ case "valibot": return VALIBOT_TARGET;
24
+ default: throw new Error(`Unknown target: ${String(spec)}. Available: typescript, zod, valibot.`);
25
+ }
26
+ }
27
+ //#endregion
28
+ export { TsPrinter, ValibotPrinter, ZodPrinter, resolveTarget };
29
+
30
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/targets/index.ts"],"sourcesContent":["import type { GeneratorDefinition, TargetSpec } from \"../core/types.js\";\nimport { TsPrinter } from \"./typescript/printer.js\";\nimport { ValibotPrinter } from \"./valibot/printer.js\";\nimport { ZodPrinter } from \"./zod/printer.js\";\n\nconst TYPESCRIPT_TARGET: GeneratorDefinition = { name: \"typescript\", printer: new TsPrinter() };\nconst ZOD_TARGET: GeneratorDefinition = { name: \"zod\", printer: new ZodPrinter() };\nconst VALIBOT_TARGET: GeneratorDefinition = { name: \"valibot\", printer: new ValibotPrinter() };\n\n/** Resolve a {@link TargetSpec} into a concrete {@link GeneratorDefinition}. */\nexport function resolveTarget(spec: TargetSpec): GeneratorDefinition {\n\tif (typeof spec !== \"string\") {\n\t\treturn spec;\n\t}\n\tswitch (spec) {\n\t\tcase \"typescript\":\n\t\t\treturn TYPESCRIPT_TARGET;\n\t\tcase \"zod\":\n\t\t\treturn ZOD_TARGET;\n\t\tcase \"valibot\":\n\t\t\treturn VALIBOT_TARGET;\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t`Unknown target: ${String(spec)}. Available: typescript, zod, valibot.`,\n\t\t\t);\n\t}\n}\n\nexport { TsPrinter, ValibotPrinter, ZodPrinter };\n"],"mappings":";;;;AAKA,MAAM,oBAAyC;CAAE,MAAM;CAAc,SAAS,IAAI,UAAU;AAAE;AAC9F,MAAM,aAAkC;CAAE,MAAM;CAAO,SAAS,IAAI,WAAW;AAAE;AACjF,MAAM,iBAAsC;CAAE,MAAM;CAAW,SAAS,IAAI,eAAe;AAAE;;AAG7F,SAAgB,cAAc,MAAuC;CACpE,IAAI,OAAO,SAAS,UACnB,OAAO;CAER,QAAQ,MAAR;EACC,KAAK,cACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK,WACJ,OAAO;EACR,SACC,MAAM,IAAI,MACT,mBAAmB,OAAO,IAAI,EAAE,uCACjC;CACF;AACD"}
@@ -0,0 +1,137 @@
1
+ import { visitRefs } from "../core/ir/visit.mjs";
2
+ //#region src/targets/shared.ts
3
+ /** Collect cross-file imports of a document: target doc id → import path + exported names used. */
4
+ function collectImports(doc, ctx, byId) {
5
+ const imports = /* @__PURE__ */ new Map();
6
+ for (const [, ir] of doc.exports) visitRefs(ir, (ref) => {
7
+ if (ref.docId === doc.docId) return;
8
+ const target = byId.get(ref.docId);
9
+ if (!target) return;
10
+ const name = ctx.resolveExportName(target, ref.exportName);
11
+ let info = imports.get(ref.docId);
12
+ if (!info) {
13
+ info = {
14
+ path: ctx.resolveImport(doc.docId, ref.docId),
15
+ names: /* @__PURE__ */ new Set()
16
+ };
17
+ imports.set(ref.docId, info);
18
+ }
19
+ info.names.add(name);
20
+ });
21
+ return imports;
22
+ }
23
+ /** Quote an object key if it is not a valid identifier. */
24
+ function quoteKey(key) {
25
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
26
+ }
27
+ const TAB = " ";
28
+ /** Render a primitive literal as a JSON value. */
29
+ function literal(value) {
30
+ if (value === null) return "null";
31
+ if (typeof value === "string") return JSON.stringify(value);
32
+ return String(value);
33
+ }
34
+ /** Render a regex pattern as a literal, falling back to `new RegExp` when it embeds `/`. */
35
+ function regexLiteral(pattern) {
36
+ if (/[/\n\r\u2028\u2029]/.test(pattern)) return `new RegExp(${JSON.stringify(pattern)})`;
37
+ return `/${pattern}/`;
38
+ }
39
+ /** Whether a JSON Schema `default` value is type-compatible with the schema it belongs to. */
40
+ function defaultMatches(ir, value) {
41
+ switch (ir.kind) {
42
+ case "string": return typeof value === "string";
43
+ case "integer": return typeof value === "number" && Number.isInteger(value);
44
+ case "number": return typeof value === "number";
45
+ case "boolean": return typeof value === "boolean";
46
+ case "null": return value === null;
47
+ case "literal": return value === ir.value;
48
+ case "union": return ir.variants.some((v) => defaultMatches(v, value));
49
+ case "array": return Array.isArray(value);
50
+ case "tuple": return Array.isArray(value);
51
+ case "object":
52
+ case "record": return typeof value === "object" && value !== null && !Array.isArray(value);
53
+ default: return true;
54
+ }
55
+ }
56
+ /** Render JSDoc from IR meta, if there is anything to render. */
57
+ function renderJSDoc(meta) {
58
+ if (!meta) return;
59
+ const lines = [];
60
+ if (meta.description) lines.push(meta.description);
61
+ if (meta.deprecated) lines.push("@deprecated");
62
+ if (lines.length === 0) return;
63
+ if (lines.length === 1) return `/** ${lines[0]} */`;
64
+ return `/**\n${lines.map((l) => ` * ${l}`).join("\n")}\n */`;
65
+ }
66
+ function indentedJSDoc(meta, indent) {
67
+ const doc = renderJSDoc(meta);
68
+ if (!doc) return;
69
+ return doc.split("\n").map((l) => `${indent}${l}`).join("\n");
70
+ }
71
+ /**
72
+ * Render an IR node as a TypeScript type expression.
73
+ * References are resolved through the `renderRef` callback, so both
74
+ * type-level (TS target) and schema-alias (zod target) rendering share this logic.
75
+ */
76
+ function renderTsType(ir, renderRef, opts) {
77
+ switch (ir.kind) {
78
+ case "ref": return renderRef(ir.ref);
79
+ case "string":
80
+ if (ir.const !== void 0) return JSON.stringify(ir.const);
81
+ if (ir.enum) return ir.enum.map((v) => JSON.stringify(v)).join(" | ") || "string";
82
+ return "string";
83
+ case "integer":
84
+ case "number":
85
+ if (ir.const !== void 0) return String(ir.const);
86
+ if (ir.enum) return ir.enum.map((v) => String(v)).join(" | ") || "number";
87
+ return "number";
88
+ case "boolean": return ir.const !== void 0 ? String(ir.const) : "boolean";
89
+ case "null": return "null";
90
+ case "literal": return literal(ir.value);
91
+ case "array": {
92
+ const inner = ir.items ? renderTsType(ir.items, renderRef, opts) : "unknown";
93
+ return opts.readonlyArrays ? `ReadonlyArray<${inner}>` : `Array<${inner}>`;
94
+ }
95
+ case "tuple": {
96
+ let inner = ir.items.map((i) => renderTsType(i, renderRef, opts)).join(", ");
97
+ if (ir.additionalItems) {
98
+ const rest = renderTsType(ir.additionalItems, renderRef, opts);
99
+ inner = `${inner}${inner ? ", " : ""}...${rest}[]`;
100
+ }
101
+ return `[${inner}]`;
102
+ }
103
+ case "object": return renderObject(ir, renderRef, opts);
104
+ case "record": return `Record<string, ${renderTsType(ir.values, renderRef, opts)}>`;
105
+ case "union": return ir.variants.map((v) => renderWrapped(v, renderRef, opts)).join(" | ") || "never";
106
+ case "intersection": return ir.variants.map((v) => renderWrapped(v, renderRef, opts)).join(" & ") || "unknown";
107
+ case "unknown": return "unknown";
108
+ }
109
+ }
110
+ function renderObject(ir, renderRef, opts) {
111
+ if (ir.properties.size === 0 && !ir.additionalProperties) return "{}";
112
+ const indent = opts.indent ?? "";
113
+ const inner = `${indent}${TAB}`;
114
+ const childOpts = {
115
+ ...opts,
116
+ indent: inner
117
+ };
118
+ const required = new Set(ir.required);
119
+ const lines = [];
120
+ for (const [key, val] of ir.properties) {
121
+ const jsdoc = indentedJSDoc(val.meta, inner);
122
+ if (jsdoc) lines.push(jsdoc);
123
+ const opt = required.has(key) ? "" : "?";
124
+ lines.push(`${inner}${quoteKey(key)}${opt}: ${renderTsType(val, renderRef, childOpts)};`);
125
+ }
126
+ if (ir.additionalProperties) lines.push(`${inner}[key: string]: ${renderTsType(ir.additionalProperties, renderRef, childOpts)};`);
127
+ return `{\n${lines.join("\n")}\n${indent}}`;
128
+ }
129
+ function renderWrapped(ir, renderRef, opts) {
130
+ const inner = renderTsType(ir, renderRef, opts);
131
+ if (ir.kind === "union" || ir.kind === "intersection") return `(${inner})`;
132
+ return inner;
133
+ }
134
+ //#endregion
135
+ export { collectImports, defaultMatches, literal, quoteKey, regexLiteral, renderJSDoc, renderTsType };
136
+
137
+ //# sourceMappingURL=shared.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.mjs","names":[],"sources":["../../src/targets/shared.ts"],"sourcesContent":["import type { IRType, Ref, SourceDoc } from \"../core/ir/types.js\";\nimport { visitRefs } from \"../core/ir/visit.js\";\nimport type { PrintContext } from \"../core/printer/abstract.js\";\n\nexport interface ImportInfo {\n\treadonly path: string;\n\treadonly names: Set<string>;\n}\n\n/** Collect cross-file imports of a document: target doc id → import path + exported names used. */\nexport function collectImports(\n\tdoc: SourceDoc,\n\tctx: PrintContext,\n\tbyId: Map<string, SourceDoc>,\n): Map<string, ImportInfo> {\n\tconst imports = new Map<string, ImportInfo>();\n\tfor (const [, ir] of doc.exports) {\n\t\tvisitRefs(ir, ref => {\n\t\t\tif (ref.docId === doc.docId) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst target = byId.get(ref.docId);\n\t\t\tif (!target) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst name = ctx.resolveExportName(target, ref.exportName);\n\t\t\tlet info = imports.get(ref.docId);\n\t\t\tif (!info) {\n\t\t\t\tinfo = { path: ctx.resolveImport(doc.docId, ref.docId), names: new Set<string>() };\n\t\t\t\timports.set(ref.docId, info);\n\t\t\t}\n\t\t\tinfo.names.add(name);\n\t\t});\n\t}\n\treturn imports;\n}\n\n/** Quote an object key if it is not a valid identifier. */\nexport function quoteKey(key: string): string {\n\treturn /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);\n}\n\nconst TAB = \"\\t\";\n\n/** Render a primitive literal as a JSON value. */\nexport function literal(value: string | number | boolean | null): string {\n\tif (value === null) {\n\t\treturn \"null\";\n\t}\n\tif (typeof value === \"string\") {\n\t\treturn JSON.stringify(value);\n\t}\n\treturn String(value);\n}\n\n/** Render a regex pattern as a literal, falling back to `new RegExp` when it embeds `/`. */\nexport function regexLiteral(pattern: string): string {\n\tif (/[/\\n\\r\\u2028\\u2029]/.test(pattern)) {\n\t\treturn `new RegExp(${JSON.stringify(pattern)})`;\n\t}\n\treturn `/${pattern}/`;\n}\n\n/** Whether a JSON Schema `default` value is type-compatible with the schema it belongs to. */\nexport function defaultMatches(ir: IRType, value: unknown): boolean {\n\tswitch (ir.kind) {\n\t\tcase \"string\":\n\t\t\treturn typeof value === \"string\";\n\t\tcase \"integer\":\n\t\t\treturn typeof value === \"number\" && Number.isInteger(value);\n\t\tcase \"number\":\n\t\t\treturn typeof value === \"number\";\n\t\tcase \"boolean\":\n\t\t\treturn typeof value === \"boolean\";\n\t\tcase \"null\":\n\t\t\treturn value === null;\n\t\tcase \"literal\":\n\t\t\treturn value === ir.value;\n\t\tcase \"union\":\n\t\t\treturn ir.variants.some(v => defaultMatches(v, value));\n\t\tcase \"array\":\n\t\t\treturn Array.isArray(value);\n\t\tcase \"tuple\":\n\t\t\treturn Array.isArray(value);\n\t\tcase \"object\":\n\t\tcase \"record\":\n\t\t\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n\t\tdefault:\n\t\t\treturn true;\n\t}\n}\n\n/** Render JSDoc from IR meta, if there is anything to render. */\nexport function renderJSDoc(\n\tmeta: { title?: string; description?: string; deprecated?: boolean } | undefined,\n): string | undefined {\n\tif (!meta) {\n\t\treturn undefined;\n\t}\n\tconst lines: string[] = [];\n\tif (meta.description) {\n\t\tlines.push(meta.description);\n\t}\n\tif (meta.deprecated) {\n\t\tlines.push(\"@deprecated\");\n\t}\n\tif (lines.length === 0) {\n\t\treturn undefined;\n\t}\n\tif (lines.length === 1) {\n\t\treturn `/** ${lines[0]} */`;\n\t}\n\treturn `/**\\n${lines.map(l => ` * ${l}`).join(\"\\n\")}\\n */`;\n}\n\nfunction indentedJSDoc(\n\tmeta: { title?: string; description?: string; deprecated?: boolean } | undefined,\n\tindent: string,\n): string | undefined {\n\tconst doc = renderJSDoc(meta);\n\tif (!doc) {\n\t\treturn undefined;\n\t}\n\treturn doc\n\t\t.split(\"\\n\")\n\t\t.map(l => `${indent}${l}`)\n\t\t.join(\"\\n\");\n}\n\nexport interface TsTypeRenderOptions {\n\treadonly readonlyArrays: boolean;\n\t/** Current indentation for multiline blocks (tabs); defaults to \"\". */\n\treadonly indent?: string;\n}\n\n/**\n * Render an IR node as a TypeScript type expression.\n * References are resolved through the `renderRef` callback, so both\n * type-level (TS target) and schema-alias (zod target) rendering share this logic.\n */\nexport function renderTsType(\n\tir: IRType,\n\trenderRef: (ref: Ref) => string,\n\topts: TsTypeRenderOptions,\n): string {\n\tswitch (ir.kind) {\n\t\tcase \"ref\":\n\t\t\treturn renderRef(ir.ref);\n\t\tcase \"string\": {\n\t\t\tif (ir.const !== undefined) {\n\t\t\t\treturn JSON.stringify(ir.const);\n\t\t\t}\n\t\t\tif (ir.enum) {\n\t\t\t\treturn ir.enum.map(v => JSON.stringify(v)).join(\" | \") || \"string\";\n\t\t\t}\n\t\t\treturn \"string\";\n\t\t}\n\t\tcase \"integer\":\n\t\tcase \"number\": {\n\t\t\tif (ir.const !== undefined) {\n\t\t\t\treturn String(ir.const);\n\t\t\t}\n\t\t\tif (ir.enum) {\n\t\t\t\treturn ir.enum.map(v => String(v)).join(\" | \") || \"number\";\n\t\t\t}\n\t\t\treturn \"number\";\n\t\t}\n\t\tcase \"boolean\":\n\t\t\treturn ir.const !== undefined ? String(ir.const) : \"boolean\";\n\t\tcase \"null\":\n\t\t\treturn \"null\";\n\t\tcase \"literal\":\n\t\t\treturn literal(ir.value);\n\t\tcase \"array\": {\n\t\t\tconst inner = ir.items ? renderTsType(ir.items, renderRef, opts) : \"unknown\";\n\t\t\treturn opts.readonlyArrays ? `ReadonlyArray<${inner}>` : `Array<${inner}>`;\n\t\t}\n\t\tcase \"tuple\": {\n\t\t\tconst elems = ir.items.map(i => renderTsType(i, renderRef, opts));\n\t\t\tlet inner = elems.join(\", \");\n\t\t\tif (ir.additionalItems) {\n\t\t\t\tconst rest = renderTsType(ir.additionalItems, renderRef, opts);\n\t\t\t\tinner = `${inner}${inner ? \", \" : \"\"}...${rest}[]`;\n\t\t\t}\n\t\t\treturn `[${inner}]`;\n\t\t}\n\t\tcase \"object\":\n\t\t\treturn renderObject(ir, renderRef, opts);\n\t\tcase \"record\":\n\t\t\treturn `Record<string, ${renderTsType(ir.values, renderRef, opts)}>`;\n\t\tcase \"union\":\n\t\t\treturn ir.variants.map(v => renderWrapped(v, renderRef, opts)).join(\" | \") || \"never\";\n\t\tcase \"intersection\":\n\t\t\treturn ir.variants.map(v => renderWrapped(v, renderRef, opts)).join(\" & \") || \"unknown\";\n\t\tcase \"unknown\":\n\t\t\treturn \"unknown\";\n\t}\n}\n\nfunction renderObject(\n\tir: Extract<IRType, { kind: \"object\" }>,\n\trenderRef: (ref: Ref) => string,\n\topts: TsTypeRenderOptions,\n): string {\n\tif (ir.properties.size === 0 && !ir.additionalProperties) {\n\t\treturn \"{}\";\n\t}\n\tconst indent = opts.indent ?? \"\";\n\tconst inner = `${indent}${TAB}`;\n\tconst childOpts: TsTypeRenderOptions = { ...opts, indent: inner };\n\tconst required = new Set(ir.required);\n\tconst lines: string[] = [];\n\tfor (const [key, val] of ir.properties) {\n\t\tconst jsdoc = indentedJSDoc(val.meta, inner);\n\t\tif (jsdoc) {\n\t\t\tlines.push(jsdoc);\n\t\t}\n\t\tconst opt = required.has(key) ? \"\" : \"?\";\n\t\tlines.push(`${inner}${quoteKey(key)}${opt}: ${renderTsType(val, renderRef, childOpts)};`);\n\t}\n\tif (ir.additionalProperties) {\n\t\tlines.push(\n\t\t\t`${inner}[key: string]: ${renderTsType(ir.additionalProperties, renderRef, childOpts)};`,\n\t\t);\n\t}\n\treturn `{\\n${lines.join(\"\\n\")}\\n${indent}}`;\n}\n\nfunction renderWrapped(\n\tir: IRType,\n\trenderRef: (ref: Ref) => string,\n\topts: TsTypeRenderOptions,\n): string {\n\tconst inner = renderTsType(ir, renderRef, opts);\n\tif (ir.kind === \"union\" || ir.kind === \"intersection\") {\n\t\treturn `(${inner})`;\n\t}\n\treturn inner;\n}\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { SourceDoc } from "../../core/ir/types.mjs";
2
+ import { AbstractPrinter, PrintContext } from "../../core/printer/abstract.mjs";
3
+ import { PrintedFile } from "../../core/types.mjs";
4
+ //#region src/targets/typescript/printer.d.ts
5
+ /** Generates TypeScript type declarations from IR documents. */
6
+ export declare class TsPrinter implements AbstractPrinter {
7
+ readonly name = "typescript";
8
+ print(docs: readonly SourceDoc[], ctx: PrintContext): Promise<PrintedFile[]>;
9
+ private printDoc;
10
+ private refName;
11
+ }
12
+ //#endregion
13
+ //# sourceMappingURL=printer.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"printer.d.mts","names":[],"sources":["../../../src/targets/typescript/printer.ts"],"mappings":";;;;;qBAMa,qBAAqB;WACjB;EAEhB,MAAmB,eAAe,aAAa,KAAK,eAAe,QAAQ;UASnE;UAiCA"}
@@ -0,0 +1,47 @@
1
+ import { collectImports, renderJSDoc, renderTsType } from "../shared.mjs";
2
+ //#region src/targets/typescript/printer.ts
3
+ /** Generates TypeScript type declarations from IR documents. */
4
+ var TsPrinter = class {
5
+ name = "typescript";
6
+ async print(docs, ctx) {
7
+ const byId = new Map(docs.map((d) => [d.docId, d]));
8
+ const files = [];
9
+ for (const doc of docs) files.push({
10
+ path: ctx.outputPath(doc.docId),
11
+ content: this.printDoc(doc, ctx, byId)
12
+ });
13
+ return files;
14
+ }
15
+ printDoc(doc, ctx, byId) {
16
+ const imports = collectImports(doc, ctx, byId);
17
+ const lines = [];
18
+ const sorted = [...imports.entries()].toSorted(([a], [b]) => a.localeCompare(b));
19
+ for (const [, info] of sorted) {
20
+ const names = [...info.names].toSorted();
21
+ lines.push(`import type { ${names.join(", ")} } from ${JSON.stringify(info.path)};`);
22
+ }
23
+ if (lines.length > 0) lines.push("");
24
+ const opts = { readonlyArrays: ctx.options.readonlyArrays };
25
+ const renderRef = (ref) => this.refName(ref, doc, ctx, byId);
26
+ for (const name of doc.exportOrder) {
27
+ const ir = doc.exports.get(name);
28
+ if (!ir) continue;
29
+ const exportName = ctx.resolveExportName(doc, name);
30
+ const jsdoc = renderJSDoc(ir.meta);
31
+ if (jsdoc) lines.push(jsdoc);
32
+ lines.push(`export type ${exportName} = ${renderTsType(ir, renderRef, opts)};`);
33
+ lines.push("");
34
+ }
35
+ return `${lines.join("\n").trimEnd()}\n`;
36
+ }
37
+ refName(ref, doc, ctx, byId) {
38
+ if (ref.docId === doc.docId) return ctx.resolveExportName(doc, ref.exportName);
39
+ const target = byId.get(ref.docId);
40
+ if (!target) return "unknown";
41
+ return ctx.resolveExportName(target, ref.exportName);
42
+ }
43
+ };
44
+ //#endregion
45
+ export { TsPrinter };
46
+
47
+ //# sourceMappingURL=printer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"printer.mjs","names":[],"sources":["../../../src/targets/typescript/printer.ts"],"sourcesContent":["import type { Ref, SourceDoc } from \"../../core/ir/types.js\";\nimport type { AbstractPrinter, PrintContext } from \"../../core/printer/abstract.js\";\nimport type { PrintedFile } from \"../../core/types.js\";\nimport { collectImports, renderJSDoc, renderTsType } from \"../shared.js\";\n\n/** Generates TypeScript type declarations from IR documents. */\nexport class TsPrinter implements AbstractPrinter {\n\tpublic readonly name = \"typescript\";\n\n\tpublic async print(docs: readonly SourceDoc[], ctx: PrintContext): Promise<PrintedFile[]> {\n\t\tconst byId = new Map<string, SourceDoc>(docs.map(d => [d.docId, d] as const));\n\t\tconst files: PrintedFile[] = [];\n\t\tfor (const doc of docs) {\n\t\t\tfiles.push({ path: ctx.outputPath(doc.docId), content: this.printDoc(doc, ctx, byId) });\n\t\t}\n\t\treturn files;\n\t}\n\n\tprivate printDoc(doc: SourceDoc, ctx: PrintContext, byId: Map<string, SourceDoc>): string {\n\t\tconst imports = collectImports(doc, ctx, byId);\n\t\tconst lines: string[] = [];\n\n\t\tconst sorted = [...imports.entries()].toSorted(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [, info] of sorted) {\n\t\t\tconst names = [...info.names].toSorted();\n\t\t\tlines.push(`import type { ${names.join(\", \")} } from ${JSON.stringify(info.path)};`);\n\t\t}\n\t\tif (lines.length > 0) {\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\tconst opts = { readonlyArrays: ctx.options.readonlyArrays };\n\t\tconst renderRef = (ref: Ref): string => this.refName(ref, doc, ctx, byId);\n\n\t\tfor (const name of doc.exportOrder) {\n\t\t\tconst ir = doc.exports.get(name);\n\t\t\tif (!ir) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst exportName = ctx.resolveExportName(doc, name);\n\t\t\tconst jsdoc = renderJSDoc(ir.meta);\n\t\t\tif (jsdoc) {\n\t\t\t\tlines.push(jsdoc);\n\t\t\t}\n\t\t\tlines.push(`export type ${exportName} = ${renderTsType(ir, renderRef, opts)};`);\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\treturn `${lines.join(\"\\n\").trimEnd()}\\n`;\n\t}\n\n\tprivate refName(\n\t\tref: Ref,\n\t\tdoc: SourceDoc,\n\t\tctx: PrintContext,\n\t\tbyId: Map<string, SourceDoc>,\n\t): string {\n\t\tif (ref.docId === doc.docId) {\n\t\t\treturn ctx.resolveExportName(doc, ref.exportName);\n\t\t}\n\t\tconst target = byId.get(ref.docId);\n\t\tif (!target) {\n\t\t\treturn \"unknown\";\n\t\t}\n\t\treturn ctx.resolveExportName(target, ref.exportName);\n\t}\n}\n"],"mappings":";;;AAMA,IAAa,YAAb,MAAkD;CACjD,OAAuB;CAEvB,MAAa,MAAM,MAA4B,KAA2C;EACzF,MAAM,OAAO,IAAI,IAAuB,KAAK,KAAI,MAAK,CAAC,EAAE,OAAO,CAAC,CAAU,CAAC;EAC5E,MAAM,QAAuB,CAAC;EAC9B,KAAK,MAAM,OAAO,MACjB,MAAM,KAAK;GAAE,MAAM,IAAI,WAAW,IAAI,KAAK;GAAG,SAAS,KAAK,SAAS,KAAK,KAAK,IAAI;EAAE,CAAC;EAEvF,OAAO;CACR;CAEA,SAAiB,KAAgB,KAAmB,MAAsC;EACzF,MAAM,UAAU,eAAe,KAAK,KAAK,IAAI;EAC7C,MAAM,QAAkB,CAAC;EAEzB,MAAM,SAAS,CAAC,GAAG,QAAQ,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;EAC/E,KAAK,MAAM,GAAG,SAAS,QAAQ;GAC9B,MAAM,QAAQ,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,SAAS;GACvC,MAAM,KAAK,iBAAiB,MAAM,KAAK,IAAI,EAAE,UAAU,KAAK,UAAU,KAAK,IAAI,EAAE,EAAE;EACpF;EACA,IAAI,MAAM,SAAS,GAClB,MAAM,KAAK,EAAE;EAGd,MAAM,OAAO,EAAE,gBAAgB,IAAI,QAAQ,eAAe;EAC1D,MAAM,aAAa,QAAqB,KAAK,QAAQ,KAAK,KAAK,KAAK,IAAI;EAExE,KAAK,MAAM,QAAQ,IAAI,aAAa;GACnC,MAAM,KAAK,IAAI,QAAQ,IAAI,IAAI;GAC/B,IAAI,CAAC,IACJ;GAED,MAAM,aAAa,IAAI,kBAAkB,KAAK,IAAI;GAClD,MAAM,QAAQ,YAAY,GAAG,IAAI;GACjC,IAAI,OACH,MAAM,KAAK,KAAK;GAEjB,MAAM,KAAK,eAAe,WAAW,KAAK,aAAa,IAAI,WAAW,IAAI,EAAE,EAAE;GAC9E,MAAM,KAAK,EAAE;EACd;EAEA,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,QAAQ,EAAE;CACtC;CAEA,QACC,KACA,KACA,KACA,MACS;EACT,IAAI,IAAI,UAAU,IAAI,OACrB,OAAO,IAAI,kBAAkB,KAAK,IAAI,UAAU;EAEjD,MAAM,SAAS,KAAK,IAAI,IAAI,KAAK;EACjC,IAAI,CAAC,QACJ,OAAO;EAER,OAAO,IAAI,kBAAkB,QAAQ,IAAI,UAAU;CACpD;AACD"}
@@ -0,0 +1,21 @@
1
+ import { SourceDoc } from "../../core/ir/types.mjs";
2
+ import { AbstractPrinter, PrintContext } from "../../core/printer/abstract.mjs";
3
+ import { PrintedFile } from "../../core/types.mjs";
4
+ //#region src/targets/valibot/printer.d.ts
5
+ /** Generates valibot v1 schemas from IR documents. */
6
+ export declare class ValibotPrinter implements AbstractPrinter {
7
+ readonly name = "valibot";
8
+ print(docs: readonly SourceDoc[], ctx: PrintContext): Promise<PrintedFile[]>;
9
+ private printDoc;
10
+ private exprOf;
11
+ private refExpr;
12
+ /** Ref renderer for structural aliases of cyclic exports. */
13
+ private aliasRefExpr;
14
+ private stringExpr;
15
+ private numberExpr;
16
+ private arrayExpr;
17
+ private tupleExpr;
18
+ private objectExpr;
19
+ }
20
+ //#endregion
21
+ //# sourceMappingURL=printer.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"printer.d.mts","names":[],"sources":["../../../src/targets/valibot/printer.ts"],"mappings":";;;;;qBAsBa,0BAA0B;WACtB;EAEhB,MAAmB,eAAe,aAAa,KAAK,eAAe,QAAQ;UAanE;UA+DA;UAkEA;;UAYA;UAsBA;UA8BA;UAmCA;UAuBA;UAeA"}