@game-infra/valibot-to-csharp 0.0.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.
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Options accepted by {@link generate} and {@link generateToFile}.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import type { GenerateOptions } from "@game-infra/valibot-to-csharp";
7
+ *
8
+ * const opts: GenerateOptions = {
9
+ * inputs: ["./schemas/events.ts"],
10
+ * outputDir: "./Generated",
11
+ * namespace: "MyGame.Events",
12
+ * };
13
+ * ```
14
+ */
15
+ export interface GenerateOptions {
16
+ /** Absolute or cwd-relative `.ts` files containing valibot schemas. */
17
+ inputs: string[];
18
+ /** Absolute or cwd-relative directory to write C# output into. */
19
+ outputDir: string;
20
+ /** C# namespace for emitted types. */
21
+ namespace: string;
22
+ /** When true, write a single bundled `.cs` file instead of one per input. */
23
+ bundle?: boolean;
24
+ /** Bundled file name (used when `bundle` is true). Default: 'Schemas.cs'. */
25
+ bundleName?: string;
26
+ /** Optional source-const → C# type name overrides (union/variant renames). */
27
+ unionRenames?: Record<string, string>;
28
+ }
29
+ /**
30
+ * One generated C# file: target path plus full file content.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * import { generate } from "@game-infra/valibot-to-csharp";
35
+ * import type { GeneratedFile } from "@game-infra/valibot-to-csharp";
36
+ *
37
+ * const result = await generate({
38
+ * inputs: ["./schemas/events.ts"],
39
+ * outputDir: "./Generated",
40
+ * namespace: "MyGame.Events",
41
+ * });
42
+ * const file: GeneratedFile = result.files[0]!;
43
+ * console.log(file.path, file.content.length);
44
+ * ```
45
+ */
46
+ export interface GeneratedFile {
47
+ path: string;
48
+ content: string;
49
+ }
50
+ /**
51
+ * Result of {@link generate} / {@link generateToFile}.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import { generate } from "@game-infra/valibot-to-csharp";
56
+ * import type { GenerateResult } from "@game-infra/valibot-to-csharp";
57
+ *
58
+ * const result: GenerateResult = await generate({
59
+ * inputs: ["./schemas/events.ts"],
60
+ * outputDir: "./Generated",
61
+ * namespace: "MyGame.Events",
62
+ * });
63
+ * ```
64
+ */
65
+ export interface GenerateResult {
66
+ files: GeneratedFile[];
67
+ }
68
+ /**
69
+ * Parse the given TypeScript files, build the IR, and emit C# source. Returns
70
+ * the list of files that would be written (caller can inspect or persist via
71
+ * {@link generateToFile}).
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import { generate } from "@game-infra/valibot-to-csharp";
76
+ *
77
+ * const result = await generate({
78
+ * inputs: ["./schemas/events.ts"],
79
+ * outputDir: "./Generated",
80
+ * namespace: "MyGame.Events",
81
+ * });
82
+ * for (const file of result.files) console.log(file.path);
83
+ * ```
84
+ */
85
+ export declare function generate(opts: GenerateOptions): Promise<GenerateResult>;
86
+ /**
87
+ * Run {@link generate} and write every returned file to disk.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * import { generateToFile } from "@game-infra/valibot-to-csharp";
92
+ *
93
+ * await generateToFile({
94
+ * inputs: ["./schemas/events.ts"],
95
+ * outputDir: "./Generated",
96
+ * namespace: "MyGame.Events",
97
+ * });
98
+ * ```
99
+ */
100
+ export declare function generateToFile(opts: GenerateOptions): Promise<GenerateResult>;
101
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAyC7E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAOnF"}
@@ -0,0 +1,99 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { emitFileHeader, emitModule } from "./emitter.js";
4
+ import { parseFiles } from "./parser.js";
5
+ /**
6
+ * Parse the given TypeScript files, build the IR, and emit C# source. Returns
7
+ * the list of files that would be written (caller can inspect or persist via
8
+ * {@link generateToFile}).
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { generate } from "@game-infra/valibot-to-csharp";
13
+ *
14
+ * const result = await generate({
15
+ * inputs: ["./schemas/events.ts"],
16
+ * outputDir: "./Generated",
17
+ * namespace: "MyGame.Events",
18
+ * });
19
+ * for (const file of result.files) console.log(file.path);
20
+ * ```
21
+ */
22
+ export async function generate(opts) {
23
+ const inputs = opts.inputs.map((f) => path.resolve(f));
24
+ const unionRenames = new Map(Object.entries(opts.unionRenames ?? {}));
25
+ if (opts.bundle) {
26
+ const module = parseFiles(inputs);
27
+ const emit = emitModule(module, {
28
+ namespace: opts.namespace,
29
+ unionRenames,
30
+ });
31
+ const header = emitFileHeader(module.notes);
32
+ const bundleName = opts.bundleName ?? "Schemas.cs";
33
+ return {
34
+ files: [
35
+ {
36
+ path: path.resolve(opts.outputDir, bundleName),
37
+ content: header + emit.source,
38
+ },
39
+ ],
40
+ };
41
+ }
42
+ // File-per-input mode: parse each entry (including its transitively imported
43
+ // local files) and emit all reachable schemas into a single .cs file named
44
+ // after the entry. Per the spec, cross-file references get pulled into the
45
+ // same output file so the resulting C# compiles standalone.
46
+ const files = [];
47
+ for (const input of inputs) {
48
+ const module = parseFiles([input]);
49
+ const emit = emitModule(module, {
50
+ namespace: opts.namespace,
51
+ unionRenames,
52
+ });
53
+ const header = emitFileHeader(module.notes);
54
+ const csFileName = toCsFileName(input);
55
+ files.push({
56
+ path: path.resolve(opts.outputDir, csFileName),
57
+ content: header + emit.source,
58
+ });
59
+ }
60
+ return { files };
61
+ }
62
+ /**
63
+ * Run {@link generate} and write every returned file to disk.
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * import { generateToFile } from "@game-infra/valibot-to-csharp";
68
+ *
69
+ * await generateToFile({
70
+ * inputs: ["./schemas/events.ts"],
71
+ * outputDir: "./Generated",
72
+ * namespace: "MyGame.Events",
73
+ * });
74
+ * ```
75
+ */
76
+ export async function generateToFile(opts) {
77
+ const result = await generate(opts);
78
+ for (const f of result.files) {
79
+ fs.mkdirSync(path.dirname(f.path), { recursive: true });
80
+ fs.writeFileSync(f.path, f.content, "utf8");
81
+ }
82
+ return result;
83
+ }
84
+ function toCsFileName(tsInput) {
85
+ const base = path.basename(tsInput).replace(/\.(ts|tsx)$/i, "");
86
+ // Mirror C# convention: PascalCase filename, and normalise DTO → Dto so
87
+ // the output file doesn't scream the acronym.
88
+ const parts = base
89
+ .replace(/[^A-Za-z0-9]+/g, " ")
90
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
91
+ .trim()
92
+ .split(/\s+/);
93
+ const pascal = parts
94
+ .map((p) => (p.length === 0 ? "" : p[0].toUpperCase() + p.slice(1)))
95
+ .join("")
96
+ .replace(/DTO/g, "Dto");
97
+ return `${pascal}.cs`;
98
+ }
99
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Public entry point for `@game-infra/valibot-to-csharp`.
3
+ *
4
+ * High-level API: {@link generate} / {@link generateToFile}. Lower-level
5
+ * building blocks ({@link parseFiles}, {@link emitModule}, the IR types) are
6
+ * exported for consumers embedding the generator into their own pipelines.
7
+ */
8
+ export { generate, generateToFile } from "./generate.js";
9
+ export type { GeneratedFile, GenerateOptions, GenerateResult } from "./generate.js";
10
+ export { emitFileHeader, emitModule } from "./emitter.js";
11
+ export type { EmitOptions, EmitResult } from "./emitter.js";
12
+ export { parseFiles } from "./parser.js";
13
+ export type { ArrayNode, LiteralNode, NamedSchema, NullableNode, ObjectField, ObjectNode, OptionalNode, PicklistNode, PrimitiveNode, RecordNode, RefNode, SchemaModule, SchemaNode, UnionNode, UnknownNode, VariantNode, } from "./ir.js";
14
+ export { csStringLiteral, indent, stripSchemaSuffix, toPascalCase } from "./naming.js";
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,UAAU,EACV,OAAO,EACP,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Public entry point for `@game-infra/valibot-to-csharp`.
3
+ *
4
+ * High-level API: {@link generate} / {@link generateToFile}. Lower-level
5
+ * building blocks ({@link parseFiles}, {@link emitModule}, the IR types) are
6
+ * exported for consumers embedding the generator into their own pipelines.
7
+ */
8
+ export { generate, generateToFile } from "./generate.js";
9
+ export { emitFileHeader, emitModule } from "./emitter.js";
10
+ export { parseFiles } from "./parser.js";
11
+ export { csStringLiteral, indent, stripSchemaSuffix, toPascalCase } from "./naming.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAmBzC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
package/dist/ir.d.ts ADDED
@@ -0,0 +1,292 @@
1
+ /**
2
+ * Intermediate representation produced by the parser and consumed by the
3
+ * emitter.
4
+ *
5
+ * A valibot source file is reduced to a list of named schemas that each
6
+ * describe an object/record, a picklist/enum, a discriminated union, or a
7
+ * plain type alias. The shape is intentionally closed: if a new valibot
8
+ * feature is needed, extend {@link SchemaNode} and teach the emitter how to
9
+ * handle it.
10
+ */
11
+ /**
12
+ * Union of every schema node the parser can produce. Narrow on `kind`.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import type { SchemaNode } from "@game-infra/valibot-to-csharp";
17
+ *
18
+ * function describe(node: SchemaNode): string {
19
+ * return node.kind === "array" ? `array of ${node.inner.kind}` : node.kind;
20
+ * }
21
+ * ```
22
+ */
23
+ export type SchemaNode = PrimitiveNode | UnknownNode | ArrayNode | RecordNode | ObjectNode | LiteralNode | PicklistNode | UnionNode | VariantNode | RefNode | NullableNode | OptionalNode;
24
+ /**
25
+ * A valibot `string()`, `number()`, or `boolean()` call.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * import type { PrimitiveNode } from "@game-infra/valibot-to-csharp";
30
+ *
31
+ * const node: PrimitiveNode = { kind: "primitive", type: "string" };
32
+ * ```
33
+ */
34
+ export interface PrimitiveNode {
35
+ kind: "primitive";
36
+ type: "string" | "number" | "boolean";
37
+ }
38
+ /**
39
+ * A valibot `unknown()` call. Emitted as `JsonElement` in C#.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import type { UnknownNode } from "@game-infra/valibot-to-csharp";
44
+ *
45
+ * const node: UnknownNode = { kind: "unknown" };
46
+ * ```
47
+ */
48
+ export interface UnknownNode {
49
+ kind: "unknown";
50
+ }
51
+ /**
52
+ * A valibot `array(inner)` call. Emitted as `IReadOnlyList<T>` in C#.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * import type { ArrayNode } from "@game-infra/valibot-to-csharp";
57
+ *
58
+ * const node: ArrayNode = {
59
+ * kind: "array",
60
+ * inner: { kind: "primitive", type: "string" },
61
+ * };
62
+ * ```
63
+ */
64
+ export interface ArrayNode {
65
+ kind: "array";
66
+ inner: SchemaNode;
67
+ }
68
+ /**
69
+ * A valibot `record(string(), value)` call. Only string keys are supported.
70
+ * Emitted as `IReadOnlyDictionary<string, T>` in C#.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * import type { RecordNode } from "@game-infra/valibot-to-csharp";
75
+ *
76
+ * const node: RecordNode = { kind: "record", value: { kind: "unknown" } };
77
+ * ```
78
+ */
79
+ export interface RecordNode {
80
+ kind: "record";
81
+ value: SchemaNode;
82
+ }
83
+ /**
84
+ * A single field of an {@link ObjectNode}. `optional`/`nullable` wrappers are
85
+ * peeled off the field schema and tracked here as flags.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * import type { ObjectField } from "@game-infra/valibot-to-csharp";
90
+ *
91
+ * const field: ObjectField = {
92
+ * name: "title",
93
+ * schema: { kind: "primitive", type: "string" },
94
+ * optional: false,
95
+ * nullable: false,
96
+ * };
97
+ * ```
98
+ */
99
+ export interface ObjectField {
100
+ name: string;
101
+ schema: SchemaNode;
102
+ optional: boolean;
103
+ nullable: boolean;
104
+ }
105
+ /**
106
+ * A valibot `object({...})` call. Emitted as a `public sealed record` in C#.
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * import type { ObjectNode } from "@game-infra/valibot-to-csharp";
111
+ *
112
+ * const node: ObjectNode = {
113
+ * kind: "object",
114
+ * fields: [
115
+ * {
116
+ * name: "id",
117
+ * schema: { kind: "primitive", type: "string" },
118
+ * optional: false,
119
+ * nullable: false,
120
+ * },
121
+ * ],
122
+ * };
123
+ * ```
124
+ */
125
+ export interface ObjectNode {
126
+ kind: "object";
127
+ fields: ObjectField[];
128
+ }
129
+ /**
130
+ * A valibot `literal("a")` call. Only string literals are supported; they get
131
+ * merged into enums or variant discriminator tags.
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * import type { LiteralNode } from "@game-infra/valibot-to-csharp";
136
+ *
137
+ * const node: LiteralNode = { kind: "literal", value: "ShowMessage" };
138
+ * ```
139
+ */
140
+ export interface LiteralNode {
141
+ kind: "literal";
142
+ value: string;
143
+ }
144
+ /**
145
+ * A valibot `picklist(["a", "b"])` call. Emitted as a string-serialised C#
146
+ * enum.
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * import type { PicklistNode } from "@game-infra/valibot-to-csharp";
151
+ *
152
+ * const node: PicklistNode = { kind: "picklist", values: ["common", "rare"] };
153
+ * ```
154
+ */
155
+ export interface PicklistNode {
156
+ kind: "picklist";
157
+ values: string[];
158
+ }
159
+ /**
160
+ * A valibot `union([...])` call. The emitter classifies the members into an
161
+ * enum, a string-or-string-list helper, a discriminated union, or a
162
+ * `JsonElement` fallback.
163
+ *
164
+ * @example
165
+ * ```ts
166
+ * import type { UnionNode } from "@game-infra/valibot-to-csharp";
167
+ *
168
+ * const node: UnionNode = {
169
+ * kind: "union",
170
+ * members: [
171
+ * { kind: "literal", value: "a" },
172
+ * { kind: "literal", value: "b" },
173
+ * ],
174
+ * };
175
+ * ```
176
+ */
177
+ export interface UnionNode {
178
+ kind: "union";
179
+ members: SchemaNode[];
180
+ }
181
+ /**
182
+ * A valibot `variant("type", [...])` call. Emitted as a `[JsonPolymorphic]`
183
+ * abstract record with one derived record per member.
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * import type { VariantNode } from "@game-infra/valibot-to-csharp";
188
+ *
189
+ * const node: VariantNode = {
190
+ * kind: "variant",
191
+ * discriminator: "type",
192
+ * members: [{ kind: "ref", name: "ShowMessageSchema" }],
193
+ * };
194
+ * ```
195
+ */
196
+ export interface VariantNode {
197
+ kind: "variant";
198
+ discriminator: string;
199
+ members: SchemaNode[];
200
+ }
201
+ /**
202
+ * A bare identifier referencing another named schema, e.g. `RaritySchema`
203
+ * used inside an `object({...})`.
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * import type { RefNode } from "@game-infra/valibot-to-csharp";
208
+ *
209
+ * const node: RefNode = { kind: "ref", name: "RaritySchema" };
210
+ * ```
211
+ */
212
+ export interface RefNode {
213
+ kind: "ref";
214
+ name: string;
215
+ }
216
+ /**
217
+ * A valibot `nullable(inner)` call. On object fields this is peeled into the
218
+ * {@link ObjectField} `nullable` flag.
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * import type { NullableNode } from "@game-infra/valibot-to-csharp";
223
+ *
224
+ * const node: NullableNode = {
225
+ * kind: "nullable",
226
+ * inner: { kind: "primitive", type: "number" },
227
+ * };
228
+ * ```
229
+ */
230
+ export interface NullableNode {
231
+ kind: "nullable";
232
+ inner: SchemaNode;
233
+ }
234
+ /**
235
+ * A valibot `optional(inner)` call. On object fields this is peeled into the
236
+ * {@link ObjectField} `optional` flag.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * import type { OptionalNode } from "@game-infra/valibot-to-csharp";
241
+ *
242
+ * const node: OptionalNode = {
243
+ * kind: "optional",
244
+ * inner: { kind: "primitive", type: "string" },
245
+ * };
246
+ * ```
247
+ */
248
+ export interface OptionalNode {
249
+ kind: "optional";
250
+ inner: SchemaNode;
251
+ }
252
+ /**
253
+ * One parsed `export const XSchema = ...` declaration.
254
+ *
255
+ * @example
256
+ * ```ts
257
+ * import type { NamedSchema } from "@game-infra/valibot-to-csharp";
258
+ *
259
+ * const named: NamedSchema = {
260
+ * name: "RaritySchema",
261
+ * sourceFile: "/abs/path/schemas.ts",
262
+ * schema: { kind: "picklist", values: ["common", "rare"] },
263
+ * };
264
+ * ```
265
+ */
266
+ export interface NamedSchema {
267
+ /** Source const name, e.g. "EventDefinitionDTOSchema". */
268
+ name: string;
269
+ /** Source file this schema came from (absolute). */
270
+ sourceFile: string;
271
+ schema: SchemaNode;
272
+ }
273
+ /**
274
+ * The parse result for a set of input files: every named schema found, plus
275
+ * notes surfaced by parser heuristics.
276
+ *
277
+ * @example
278
+ * ```ts
279
+ * import { parseFiles } from "@game-infra/valibot-to-csharp";
280
+ * import type { SchemaModule } from "@game-infra/valibot-to-csharp";
281
+ *
282
+ * const module: SchemaModule = parseFiles(["./schemas/events.ts"]);
283
+ * console.log([...module.schemas.keys()]);
284
+ * ```
285
+ */
286
+ export interface SchemaModule {
287
+ /** Map of source const name to parsed schema. */
288
+ schemas: Map<string, NamedSchema>;
289
+ /** Flags surfaced by parser heuristics (e.g. the string('x') as literal hack). */
290
+ notes: string[];
291
+ }
292
+ //# sourceMappingURL=ir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAClB,aAAa,GACb,WAAW,GACX,SAAS,GACT,UAAU,GACV,UAAU,GACV,WAAW,GACX,YAAY,GACZ,SAAS,GACT,WAAW,GACX,OAAO,GACP,YAAY,GACZ,YAAY,CAAC;AAEjB;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;CACvC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,kFAAkF;IAClF,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB"}
package/dist/ir.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Intermediate representation produced by the parser and consumed by the
3
+ * emitter.
4
+ *
5
+ * A valibot source file is reduced to a list of named schemas that each
6
+ * describe an object/record, a picklist/enum, a discriminated union, or a
7
+ * plain type alias. The shape is intentionally closed: if a new valibot
8
+ * feature is needed, extend {@link SchemaNode} and teach the emitter how to
9
+ * handle it.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=ir.js.map
package/dist/ir.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir.js","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Small naming helpers shared by the parser and the emitter.
3
+ */
4
+ /**
5
+ * Convert arbitrary identifiers / string enum values into PascalCase.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { toPascalCase } from "@game-infra/valibot-to-csharp";
10
+ *
11
+ * toPascalCase("fooBar"); // "FooBar"
12
+ * toPascalCase("foo_bar-baz"); // "FooBarBaz"
13
+ * toPascalCase("EventDTO"); // "EventDto"
14
+ * ```
15
+ */
16
+ export declare function toPascalCase(input: string): string;
17
+ /**
18
+ * Strip the trailing "Schema" suffix from a valibot const name and normalise
19
+ * common acronyms (DTO → Dto). Returns a PascalCase C# type name.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { stripSchemaSuffix } from "@game-infra/valibot-to-csharp";
24
+ *
25
+ * stripSchemaSuffix("FooSchema"); // "Foo"
26
+ * stripSchemaSuffix("EventDefinitionDTOSchema"); // "EventDefinitionDto"
27
+ * stripSchemaSuffix("fooBarSchema"); // "FooBar"
28
+ * ```
29
+ */
30
+ export declare function stripSchemaSuffix(name: string): string;
31
+ /**
32
+ * Escape a C# string literal (for JsonPropertyName values etc.).
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * import { csStringLiteral } from "@game-infra/valibot-to-csharp";
37
+ *
38
+ * csStringLiteral('a"b\\c'); // '"a\\"b\\\\c"'
39
+ * ```
40
+ */
41
+ export declare function csStringLiteral(value: string): string;
42
+ /**
43
+ * Indent every non-empty line of `text` by `spaces` spaces.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * import { indent } from "@game-infra/valibot-to-csharp";
48
+ *
49
+ * indent("a\nb", 4); // " a\n b"
50
+ * ```
51
+ */
52
+ export declare function indent(text: string, spaces: number): string;
53
+ //# sourceMappingURL=naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYlD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAatD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAM3D"}