@abapify/ts-xsd 0.3.6 → 0.4.1

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 @@
1
+ export { };
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+ import { t as runCodegen } from "../runner-CRhT3smd.mjs";
3
+ import { t as generateSchemaFile } from "../generate-DnX2dJZe.mjs";
4
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
+ import { basename, dirname, resolve } from "node:path";
6
+ import { pathToFileURL } from "node:url";
7
+
8
+ //#region src/codegen/cli.ts
9
+ /**
10
+ * ts-xsd Codegen CLI
11
+ *
12
+ * Usage:
13
+ * ts-xsd codegen [--config=ts-xsd.config.ts] [--verbose]
14
+ * ts-xsd codegen <input.xsd> [output.ts] [--name=SchemaName]
15
+ *
16
+ * Config-based (recommended):
17
+ * ts-xsd codegen # Uses ts-xsd.config.ts in cwd
18
+ * ts-xsd codegen --config=my-config.ts # Uses custom config
19
+ * ts-xsd codegen --verbose # Verbose output
20
+ *
21
+ * Single-file (legacy):
22
+ * ts-xsd codegen person.xsd
23
+ * ts-xsd codegen person.xsd ./generated/person-schema.ts
24
+ * ts-xsd codegen person.xsd --name=PersonSchema
25
+ */
26
+ function parseArgs(args) {
27
+ const positional = [];
28
+ let config;
29
+ let verbose = false;
30
+ let name;
31
+ for (const arg of args) if (arg.startsWith("--config=")) config = arg.slice(9);
32
+ else if (arg === "--verbose" || arg === "-v") verbose = true;
33
+ else if (arg.startsWith("--name=")) name = arg.slice(7);
34
+ else if (!arg.startsWith("-")) positional.push(arg);
35
+ if (positional[0]?.endsWith(".xsd")) {
36
+ const input = positional[0];
37
+ const defaultOutput = input.replace(/\.xsd$/i, "-schema.ts");
38
+ const output = positional[1] || defaultOutput;
39
+ const defaultName = basename(input, ".xsd").replaceAll(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : "").replace(/^./, (s) => s.toLowerCase()) + "Schema";
40
+ return {
41
+ mode: "single",
42
+ input: resolve(input),
43
+ output: resolve(output),
44
+ name: name || defaultName,
45
+ verbose
46
+ };
47
+ }
48
+ return {
49
+ mode: "config",
50
+ config: config || "ts-xsd.config.ts",
51
+ verbose
52
+ };
53
+ }
54
+ async function runConfigMode(options) {
55
+ const configPath = resolve(options.config);
56
+ if (!existsSync(configPath)) {
57
+ console.error(`āŒ Config file not found: ${configPath}`);
58
+ console.error("\nCreate a ts-xsd.config.ts file or specify --config=path/to/config.ts");
59
+ process.exit(1);
60
+ }
61
+ console.log(`šŸ“¦ Loading config: ${configPath}\n`);
62
+ const config = (await import(pathToFileURL(configPath).href)).default;
63
+ const result = await runCodegen(config, {
64
+ rootDir: dirname(configPath),
65
+ verbose: options.verbose
66
+ });
67
+ console.log(`\nšŸ“Š Summary:`);
68
+ console.log(` - Schemas processed: ${result.schemas.length}`);
69
+ console.log(` - Files generated: ${result.files.length}`);
70
+ console.log(` - Errors: ${result.errors.length}`);
71
+ if (result.errors.length > 0) {
72
+ console.error("\nāŒ Errors:");
73
+ for (const err of result.errors) console.error(` - ${err.schema || "unknown"}: ${err.error.message}`);
74
+ process.exit(1);
75
+ }
76
+ console.log("\nāœ… Codegen complete!");
77
+ }
78
+ function runSingleFileMode(options) {
79
+ console.log(`Reading: ${options.input}`);
80
+ const xsdContent = readFileSync(options.input, "utf-8");
81
+ console.log(`Generating schema: ${options.name}`);
82
+ const tsContent = generateSchemaFile(xsdContent, {
83
+ name: options.name,
84
+ comment: `Source: ${basename(options.input)}`
85
+ });
86
+ mkdirSync(dirname(options.output), { recursive: true });
87
+ console.log(`Writing: ${options.output}`);
88
+ writeFileSync(options.output, tsContent);
89
+ console.log(`Done! Generated ${tsContent.length} characters`);
90
+ console.log(`\nUsage in TypeScript:`);
91
+ console.log(` import { ${options.name} } from './${basename(options.output, ".ts")}';`);
92
+ console.log(` import type { InferSchema } from '@abapify/ts-xsd';`);
93
+ console.log(` type MyType = InferSchema<typeof ${options.name}>;`);
94
+ }
95
+ function showHelp() {
96
+ console.log(`
97
+ ts-xsd Codegen CLI
98
+
99
+ Usage:
100
+ ts-xsd codegen [options] Config-based generation (recommended)
101
+ ts-xsd codegen <input.xsd> [output] Single-file generation (legacy)
102
+
103
+ Options:
104
+ --config=FILE Config file path (default: ts-xsd.config.ts)
105
+ --verbose, -v Verbose output
106
+ --name=NAME Schema variable name (single-file mode only)
107
+ --help, -h Show this help
108
+
109
+ Examples:
110
+ # Config-based (recommended)
111
+ ts-xsd codegen # Uses ts-xsd.config.ts
112
+ ts-xsd codegen --config=my-config.ts # Custom config
113
+ ts-xsd codegen --verbose # With verbose output
114
+
115
+ # Single-file (legacy)
116
+ ts-xsd codegen person.xsd
117
+ ts-xsd codegen person.xsd ./out/person.ts --name=PersonSchema
118
+ `);
119
+ }
120
+ async function main() {
121
+ const args = process.argv.slice(2);
122
+ if (args.includes("--help") || args.includes("-h")) {
123
+ showHelp();
124
+ process.exit(0);
125
+ }
126
+ const options = parseArgs(args);
127
+ if (options.mode === "config") await runConfigMode(options);
128
+ else runSingleFileMode(options);
129
+ }
130
+ main().catch((err) => {
131
+ console.error("Fatal error:", err);
132
+ process.exit(1);
133
+ });
134
+
135
+ //#endregion
136
+ export { };
137
+ //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../../src/codegen/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * ts-xsd Codegen CLI\n *\n * Usage:\n * ts-xsd codegen [--config=ts-xsd.config.ts] [--verbose]\n * ts-xsd codegen <input.xsd> [output.ts] [--name=SchemaName]\n *\n * Config-based (recommended):\n * ts-xsd codegen # Uses ts-xsd.config.ts in cwd\n * ts-xsd codegen --config=my-config.ts # Uses custom config\n * ts-xsd codegen --verbose # Verbose output\n *\n * Single-file (legacy):\n * ts-xsd codegen person.xsd\n * ts-xsd codegen person.xsd ./generated/person-schema.ts\n * ts-xsd codegen person.xsd --name=PersonSchema\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { dirname, basename, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { generateSchemaFile } from './generate';\nimport { runCodegen } from './runner';\nimport type { CodegenConfig } from './types';\n\ninterface ConfigModeOptions {\n mode: 'config';\n config: string;\n verbose?: boolean;\n}\n\ninterface SingleFileModeOptions {\n mode: 'single';\n input: string;\n output: string;\n name: string;\n verbose?: boolean;\n}\n\ntype CliOptions = ConfigModeOptions | SingleFileModeOptions;\n\nfunction parseArgs(args: string[]): CliOptions {\n const positional: string[] = [];\n let config: string | undefined;\n let verbose = false;\n let name: string | undefined;\n\n for (const arg of args) {\n if (arg.startsWith('--config=')) {\n config = arg.slice(9);\n } else if (arg === '--verbose' || arg === '-v') {\n verbose = true;\n } else if (arg.startsWith('--name=')) {\n name = arg.slice(7);\n } else if (!arg.startsWith('-')) {\n positional.push(arg);\n }\n }\n\n // If first positional arg is an XSD file, use single-file mode\n if (positional[0]?.endsWith('.xsd')) {\n const input = positional[0];\n const defaultOutput = input.replace(/\\.xsd$/i, '-schema.ts');\n const output = positional[1] || defaultOutput;\n const defaultName =\n basename(input, '.xsd')\n .replaceAll(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^./, (s) => s.toLowerCase()) + 'Schema';\n\n return {\n mode: 'single',\n input: resolve(input),\n output: resolve(output),\n name: name || defaultName,\n verbose,\n };\n }\n\n // Config-based mode\n return {\n mode: 'config',\n config: config || 'ts-xsd.config.ts',\n verbose,\n };\n}\n\nasync function runConfigMode(options: ConfigModeOptions) {\n const configPath = resolve(options.config);\n\n if (!existsSync(configPath)) {\n console.error(`āŒ Config file not found: ${configPath}`);\n console.error(\n '\\nCreate a ts-xsd.config.ts file or specify --config=path/to/config.ts',\n );\n process.exit(1);\n }\n\n console.log(`šŸ“¦ Loading config: ${configPath}\\n`);\n\n // Dynamic import of config file\n const configUrl = pathToFileURL(configPath).href;\n const configModule = await import(configUrl);\n const config: CodegenConfig = configModule.default;\n\n const result = await runCodegen(config, {\n rootDir: dirname(configPath),\n verbose: options.verbose,\n });\n\n console.log(`\\nšŸ“Š Summary:`);\n console.log(` - Schemas processed: ${result.schemas.length}`);\n console.log(` - Files generated: ${result.files.length}`);\n console.log(` - Errors: ${result.errors.length}`);\n\n if (result.errors.length > 0) {\n console.error('\\nāŒ Errors:');\n for (const err of result.errors) {\n console.error(` - ${err.schema || 'unknown'}: ${err.error.message}`);\n }\n process.exit(1);\n }\n\n console.log('\\nāœ… Codegen complete!');\n}\n\nfunction runSingleFileMode(options: SingleFileModeOptions) {\n console.log(`Reading: ${options.input}`);\n const xsdContent = readFileSync(options.input, 'utf-8');\n\n console.log(`Generating schema: ${options.name}`);\n const tsContent = generateSchemaFile(xsdContent, {\n name: options.name,\n comment: `Source: ${basename(options.input)}`,\n });\n\n mkdirSync(dirname(options.output), { recursive: true });\n\n console.log(`Writing: ${options.output}`);\n writeFileSync(options.output, tsContent);\n\n console.log(`Done! Generated ${tsContent.length} characters`);\n console.log(`\\nUsage in TypeScript:`);\n console.log(\n ` import { ${options.name} } from './${basename(options.output, '.ts')}';`,\n );\n console.log(` import type { InferSchema } from '@abapify/ts-xsd';`);\n console.log(` type MyType = InferSchema<typeof ${options.name}>;`);\n}\n\nfunction showHelp() {\n console.log(`\nts-xsd Codegen CLI\n\nUsage:\n ts-xsd codegen [options] Config-based generation (recommended)\n ts-xsd codegen <input.xsd> [output] Single-file generation (legacy)\n\nOptions:\n --config=FILE Config file path (default: ts-xsd.config.ts)\n --verbose, -v Verbose output\n --name=NAME Schema variable name (single-file mode only)\n --help, -h Show this help\n\nExamples:\n # Config-based (recommended)\n ts-xsd codegen # Uses ts-xsd.config.ts\n ts-xsd codegen --config=my-config.ts # Custom config\n ts-xsd codegen --verbose # With verbose output\n\n # Single-file (legacy)\n ts-xsd codegen person.xsd\n ts-xsd codegen person.xsd ./out/person.ts --name=PersonSchema\n`);\n}\n\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.includes('--help') || args.includes('-h')) {\n showHelp();\n process.exit(0);\n }\n\n const options = parseArgs(args);\n\n if (options.mode === 'config') {\n await runConfigMode(options);\n } else {\n runSingleFileMode(options);\n }\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n});\n"],"mappings":"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"}
@@ -0,0 +1,262 @@
1
+ import { g as parseXsd } from "./runner-CRhT3smd.mjs";
2
+
3
+ //#region src/codegen/generate.ts
4
+ /**
5
+ * Schema Literal Generator
6
+ *
7
+ * Transforms a parsed Schema object into a TypeScript literal string
8
+ * that preserves type information for InferSchema<T>.
9
+ */
10
+ /**
11
+ * Generate a TypeScript literal string from XSD content.
12
+ *
13
+ * @param xsdContent - XSD file content as string
14
+ * @param options - Generation options
15
+ * @returns TypeScript code with schema as const literal
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const xsd = `<xs:schema>...</xs:schema>`;
20
+ * const code = generateSchemaLiteral(xsd, { name: 'PersonSchema' });
21
+ * // export const PersonSchema = { ... } as const;
22
+ * ```
23
+ */
24
+ function generateSchemaLiteral(xsdContent, options = {}) {
25
+ const schema = parseXsd(xsdContent);
26
+ const features = options.features ?? {};
27
+ const exclude = new Set(options.exclude ?? []);
28
+ let outputSchema = { ...schema };
29
+ if (features.$filename && options.name) outputSchema = {
30
+ $filename: `${options.name}.xsd`,
31
+ ...outputSchema
32
+ };
33
+ outputSchema = applyTransforms(outputSchema, features, exclude);
34
+ return schemaToLiteral(outputSchema, options);
35
+ }
36
+ /**
37
+ * Apply transformations: features ($xmlns, $imports) and exclude filter.
38
+ * Used by generateSchemaLiteral (without imports).
39
+ */
40
+ function applyTransforms(schema, features, exclude) {
41
+ return applyTransformsWithImports(schema, features, exclude, []);
42
+ }
43
+ /**
44
+ * Special marker for schema references (not serialized as strings).
45
+ */
46
+ var SchemaRef = class {
47
+ constructor(name) {
48
+ this.name = name;
49
+ }
50
+ };
51
+ /**
52
+ * Apply transformations with schema imports as references.
53
+ */
54
+ function applyTransformsWithImports(schema, features, exclude, importedSchemaNames) {
55
+ const result = {};
56
+ for (const [key, value] of Object.entries(schema)) {
57
+ if (exclude.has(key)) continue;
58
+ if (key === "$xmlns") {
59
+ if (features.$xmlns) result[key] = value;
60
+ } else if (key === "import") {
61
+ if (features.$imports && importedSchemaNames.length > 0) result["$imports"] = importedSchemaNames.map((name) => new SchemaRef(name));
62
+ } else result[key] = filterDeep(value, exclude);
63
+ }
64
+ return result;
65
+ }
66
+ /**
67
+ * Recursively filter excluded properties from nested structures.
68
+ */
69
+ function filterDeep(value, exclude) {
70
+ if (Array.isArray(value)) return value.map((item) => filterDeep(item, exclude));
71
+ if (value !== null && typeof value === "object") {
72
+ const result = {};
73
+ for (const [k, v] of Object.entries(value)) if (!exclude.has(k)) result[k] = filterDeep(v, exclude);
74
+ return result;
75
+ }
76
+ return value;
77
+ }
78
+ /**
79
+ * Generate a complete TypeScript file from XSD content.
80
+ *
81
+ * @param xsdContent - XSD file content as string
82
+ * @param options - Generation options
83
+ * @returns Complete TypeScript file content
84
+ */
85
+ function generateSchemaFile(xsdContent, options = {}) {
86
+ const { name = "schema", comment, features = {}, importResolver, isolatedDeclarations = false } = options;
87
+ const xsdImports = parseXsd(xsdContent).import ?? [];
88
+ const tsImports = [];
89
+ const importedSchemaNames = [];
90
+ if (isolatedDeclarations) tsImports.push("import type { Schema } from '@abapify/ts-xsd';");
91
+ if (features.$imports && importResolver) {
92
+ for (const imp of xsdImports) if (imp.schemaLocation) {
93
+ const modulePath = importResolver(imp.schemaLocation);
94
+ if (modulePath) {
95
+ const schemaName = imp.schemaLocation.replace(/\.xsd$/, "").replace(/^.*\//, "");
96
+ tsImports.push(`import ${schemaName} from '${modulePath}';`);
97
+ importedSchemaNames.push(schemaName);
98
+ }
99
+ }
100
+ }
101
+ return [
102
+ "/**",
103
+ " * Auto-generated schema literal from XSD",
104
+ " * ",
105
+ " * DO NOT EDIT - Generated by ts-xsd codegen",
106
+ comment ? ` * ${comment}` : null,
107
+ " */",
108
+ "",
109
+ ...tsImports,
110
+ tsImports.length > 0 ? "" : null,
111
+ generateSchemaLiteralWithImports(xsdContent, options, importedSchemaNames),
112
+ "",
113
+ `export type ${pascalCase(name)}Type = typeof ${name};`,
114
+ ""
115
+ ].filter((line) => line !== null).join("\n");
116
+ }
117
+ /**
118
+ * Generate schema literal with $imports as schema references.
119
+ */
120
+ function generateSchemaLiteralWithImports(xsdContent, options, importedSchemaNames) {
121
+ const schema = parseXsd(xsdContent);
122
+ const features = options.features ?? {};
123
+ const exclude = new Set(options.exclude ?? []);
124
+ let outputSchema = { ...schema };
125
+ if (features.$filename && options.name) outputSchema = {
126
+ $filename: `${options.name}.xsd`,
127
+ ...outputSchema
128
+ };
129
+ outputSchema = applyTransformsWithImports(outputSchema, features, exclude, importedSchemaNames);
130
+ return schemaToLiteral(outputSchema, options);
131
+ }
132
+ /**
133
+ * Escape reserved words by adding underscore suffix.
134
+ */
135
+ function escapeReservedWord(name) {
136
+ return RESERVED_WORDS.has(name) ? `${name}_` : name;
137
+ }
138
+ /**
139
+ * Convert a Schema object to a TypeScript literal string.
140
+ */
141
+ function schemaToLiteral(schema, options = {}) {
142
+ const { name = "schema", pretty = true, indent = " ", isolatedDeclarations = false, singleQuote = false } = options;
143
+ return `export const ${escapeReservedWord(name)} = ${objectToLiteral(schema, pretty, indent, 0, singleQuote)} ${isolatedDeclarations ? "satisfies Schema as const" : "as const"};`;
144
+ }
145
+ /**
146
+ * Format a string value as a single-quoted literal, unescaping JSON double quotes
147
+ * and escaping any single quotes.
148
+ */
149
+ function toSingleQuoteLiteral(jsonStr) {
150
+ return `'${jsonStr.slice(1, -1).replaceAll("\\\"", "\"").replaceAll("'", "\\'")}'`;
151
+ }
152
+ /**
153
+ * Convert any value to a TypeScript literal string.
154
+ */
155
+ function objectToLiteral(value, pretty, indent, depth, singleQuote = false) {
156
+ if (value === null || value === void 0) return "undefined";
157
+ if (value instanceof SchemaRef) return value.name;
158
+ if (typeof value === "string") {
159
+ const json = JSON.stringify(value);
160
+ if (singleQuote) return toSingleQuoteLiteral(json);
161
+ return json;
162
+ }
163
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
164
+ if (Array.isArray(value)) {
165
+ if (value.length === 0) return "[]";
166
+ const items = value.map((item) => objectToLiteral(item, pretty, indent, depth + 1, singleQuote));
167
+ if (pretty) {
168
+ const itemIndent = indent.repeat(depth + 1);
169
+ const closeIndent = indent.repeat(depth);
170
+ return `[\n${items.map((item) => `${itemIndent}${item}`).join(",\n")},\n${closeIndent}]`;
171
+ }
172
+ return `[${items.join(", ")}]`;
173
+ }
174
+ if (typeof value === "object") {
175
+ const obj = value;
176
+ const entries = Object.entries(obj).filter(([, v]) => v !== void 0);
177
+ if (entries.length === 0) return "{}";
178
+ const props = entries.map(([key, val]) => {
179
+ let keyStr = key;
180
+ if (!isValidIdentifier(key)) {
181
+ const json = JSON.stringify(key);
182
+ keyStr = singleQuote ? toSingleQuoteLiteral(json) : json;
183
+ }
184
+ const valStr = objectToLiteral(val, pretty, indent, depth + 1, singleQuote);
185
+ return `${keyStr}: ${valStr}`;
186
+ });
187
+ if (pretty) {
188
+ const propIndent = indent.repeat(depth + 1);
189
+ const closeIndent = indent.repeat(depth);
190
+ return `{\n${props.map((prop) => `${propIndent}${prop}`).join(",\n")},\n${closeIndent}}`;
191
+ }
192
+ return `{ ${props.join(", ")} }`;
193
+ }
194
+ return "undefined";
195
+ }
196
+ /**
197
+ * JavaScript reserved words that cannot be used as variable names.
198
+ */
199
+ const RESERVED_WORDS = new Set([
200
+ "break",
201
+ "case",
202
+ "catch",
203
+ "continue",
204
+ "debugger",
205
+ "default",
206
+ "delete",
207
+ "do",
208
+ "else",
209
+ "finally",
210
+ "for",
211
+ "function",
212
+ "if",
213
+ "in",
214
+ "instanceof",
215
+ "new",
216
+ "return",
217
+ "switch",
218
+ "this",
219
+ "throw",
220
+ "try",
221
+ "typeof",
222
+ "var",
223
+ "void",
224
+ "while",
225
+ "with",
226
+ "class",
227
+ "const",
228
+ "enum",
229
+ "export",
230
+ "extends",
231
+ "import",
232
+ "super",
233
+ "implements",
234
+ "interface",
235
+ "let",
236
+ "package",
237
+ "private",
238
+ "protected",
239
+ "public",
240
+ "static",
241
+ "yield",
242
+ "await",
243
+ "null",
244
+ "true",
245
+ "false"
246
+ ]);
247
+ /**
248
+ * Check if a string is a valid JavaScript identifier.
249
+ */
250
+ function isValidIdentifier(str) {
251
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str) && !RESERVED_WORDS.has(str);
252
+ }
253
+ /**
254
+ * Convert string to PascalCase.
255
+ */
256
+ function pascalCase(str) {
257
+ return str.replaceAll(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : "").replace(/^./, (s) => s.toUpperCase());
258
+ }
259
+
260
+ //#endregion
261
+ export { generateSchemaLiteral as n, generateSchemaFile as t };
262
+ //# sourceMappingURL=generate-DnX2dJZe.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-DnX2dJZe.mjs","names":[],"sources":["../src/codegen/generate.ts"],"sourcesContent":["/**\n * Schema Literal Generator\n *\n * Transforms a parsed Schema object into a TypeScript literal string\n * that preserves type information for InferSchema<T>.\n */\n\nimport { parseXsd } from '../xsd';\nimport type { Schema } from '../xsd/types';\n\nexport interface GenerateOptions {\n /** Variable name for the exported schema */\n name?: string;\n /** Add JSDoc comment */\n comment?: string;\n /** Pretty print with indentation */\n pretty?: boolean;\n /** Indentation string (default: ' ') */\n indent?: string;\n /**\n * Enable specific $ metadata features in output.\n * - `$xmlns`: Keep `$xmlns` in output (already parsed as $xmlns)\n * - `$imports`: Rename `import` → `$imports` for schema linking\n * - `$filename`: Include `$filename` (uses `name` option + '.xsd')\n *\n * @example\n * ```typescript\n * features: { $xmlns: true, $imports: true, $filename: true }\n * ```\n */\n features?: {\n /** Keep `$xmlns` in output */\n $xmlns?: boolean;\n /** Rename `import` → `$imports` for schema linking */\n $imports?: boolean;\n /** Include `$filename` (uses `name` + '.xsd') */\n $filename?: boolean;\n };\n /**\n * Property names to exclude from output.\n * Useful for removing annotations, documentation, etc.\n *\n * @example\n * ```typescript\n * exclude: ['annotation'] // Remove all annotation elements\n * ```\n */\n exclude?: string[];\n /** Resolver for import paths (schemaLocation -> module path) */\n importResolver?: (schemaLocation: string) => string | null;\n /**\n * Generate isolatedDeclarations-compatible output.\n * Uses `satisfies Schema as const` instead of just `as const`.\n */\n isolatedDeclarations?: boolean;\n /** Use single quotes for string literals and property names */\n singleQuote?: boolean;\n}\n\n/**\n * Generate a TypeScript literal string from XSD content.\n *\n * @param xsdContent - XSD file content as string\n * @param options - Generation options\n * @returns TypeScript code with schema as const literal\n *\n * @example\n * ```typescript\n * const xsd = `<xs:schema>...</xs:schema>`;\n * const code = generateSchemaLiteral(xsd, { name: 'PersonSchema' });\n * // export const PersonSchema = { ... } as const;\n * ```\n */\nexport function generateSchemaLiteral(\n xsdContent: string,\n options: GenerateOptions = {},\n): string {\n const schema = parseXsd(xsdContent);\n const features = options.features ?? {};\n const exclude = new Set(options.exclude ?? []);\n\n // Transform schema\n let outputSchema: Record<string, unknown> = { ...schema };\n\n // Add $filename when enabled (uses name option)\n if (features.$filename && options.name) {\n outputSchema = { $filename: `${options.name}.xsd`, ...outputSchema };\n }\n\n // Apply transformations (features + exclude)\n outputSchema = applyTransforms(outputSchema, features, exclude);\n\n return schemaToLiteral(outputSchema as Schema, options);\n}\n\n/**\n * Apply transformations: features ($xmlns, $imports) and exclude filter.\n * Used by generateSchemaLiteral (without imports).\n */\nfunction applyTransforms(\n schema: Record<string, unknown>,\n features: NonNullable<GenerateOptions['features']>,\n exclude: Set<string>,\n): Record<string, unknown> {\n return applyTransformsWithImports(schema, features, exclude, []);\n}\n\n/**\n * Special marker for schema references (not serialized as strings).\n */\nclass SchemaRef {\n constructor(public readonly name: string) {}\n}\n\n/**\n * Apply transformations with schema imports as references.\n */\nfunction applyTransformsWithImports(\n schema: Record<string, unknown>,\n features: NonNullable<GenerateOptions['features']>,\n exclude: Set<string>,\n importedSchemaNames: string[],\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(schema)) {\n // Skip excluded properties\n if (exclude.has(key)) {\n continue;\n }\n\n if (key === '$xmlns') {\n // $xmlns is already parsed - keep only if feature enabled\n if (features.$xmlns) {\n result[key] = value;\n }\n } else if (key === 'import') {\n // Convert import to $imports with schema references\n if (features.$imports && importedSchemaNames.length > 0) {\n result['$imports'] = importedSchemaNames.map(\n (name) => new SchemaRef(name),\n );\n }\n // If no imports resolved, skip the import property entirely\n } else {\n // Recursively filter nested objects/arrays for exclude\n result[key] = filterDeep(value, exclude);\n }\n }\n\n return result;\n}\n\n/**\n * Recursively filter excluded properties from nested structures.\n */\nfunction filterDeep(value: unknown, exclude: Set<string>): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => filterDeep(item, exclude));\n }\n\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n if (!exclude.has(k)) {\n result[k] = filterDeep(v, exclude);\n }\n }\n return result;\n }\n\n return value;\n}\n\n/**\n * Generate a complete TypeScript file from XSD content.\n *\n * @param xsdContent - XSD file content as string\n * @param options - Generation options\n * @returns Complete TypeScript file content\n */\nexport function generateSchemaFile(\n xsdContent: string,\n options: GenerateOptions = {},\n): string {\n const {\n name = 'schema',\n comment,\n features = {},\n importResolver,\n isolatedDeclarations = false,\n } = options;\n\n // Parse to extract imports\n const schema = parseXsd(xsdContent);\n const xsdImports = (schema.import ?? []) as Array<{\n schemaLocation?: string;\n namespace?: string;\n }>;\n\n // Generate TypeScript import statements if $imports feature enabled\n const tsImports: string[] = [];\n const importedSchemaNames: string[] = [];\n\n // Add Schema type import for isolatedDeclarations mode\n if (isolatedDeclarations) {\n tsImports.push(\"import type { Schema } from '@abapify/ts-xsd';\");\n }\n\n if (features.$imports && importResolver) {\n for (const imp of xsdImports) {\n if (imp.schemaLocation) {\n const modulePath = importResolver(imp.schemaLocation);\n if (modulePath) {\n // Derive schema name from schemaLocation basename (e.g., \"../sap/adtcore.xsd\" → \"adtcore\")\n const schemaName = imp.schemaLocation\n .replace(/\\.xsd$/, '')\n .replace(/^.*\\//, '');\n tsImports.push(`import ${schemaName} from '${modulePath}';`);\n importedSchemaNames.push(schemaName);\n }\n }\n }\n }\n\n const lines: string[] = [\n '/**',\n ' * Auto-generated schema literal from XSD',\n ' * ',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n comment ? ` * ${comment}` : null,\n ' */',\n '',\n // Add TypeScript imports\n ...tsImports,\n tsImports.length > 0 ? '' : null,\n // Generate schema with $imports as array of schema references\n generateSchemaLiteralWithImports(xsdContent, options, importedSchemaNames),\n '',\n `export type ${pascalCase(name)}Type = typeof ${name};`,\n '',\n ].filter((line): line is string => line !== null);\n\n return lines.join('\\n');\n}\n\n/**\n * Generate schema literal with $imports as schema references.\n */\nfunction generateSchemaLiteralWithImports(\n xsdContent: string,\n options: GenerateOptions,\n importedSchemaNames: string[],\n): string {\n const schema = parseXsd(xsdContent);\n const features = options.features ?? {};\n const exclude = new Set(options.exclude ?? []);\n\n // Transform schema\n let outputSchema: Record<string, unknown> = { ...schema };\n\n // Add $filename when enabled (uses name option)\n if (features.$filename && options.name) {\n outputSchema = { $filename: `${options.name}.xsd`, ...outputSchema };\n }\n\n // Apply transformations (features + exclude), passing imported schema names\n outputSchema = applyTransformsWithImports(\n outputSchema,\n features,\n exclude,\n importedSchemaNames,\n );\n\n return schemaToLiteral(outputSchema as Schema, options);\n}\n\n/**\n * Escape reserved words by adding underscore suffix.\n */\nfunction escapeReservedWord(name: string): string {\n return RESERVED_WORDS.has(name) ? `${name}_` : name;\n}\n\n/**\n * Convert a Schema object to a TypeScript literal string.\n */\nfunction schemaToLiteral(\n schema: Schema,\n options: GenerateOptions = {},\n): string {\n const {\n name = 'schema',\n pretty = true,\n indent = ' ',\n isolatedDeclarations = false,\n singleQuote = false,\n } = options;\n\n const safeName = escapeReservedWord(name);\n const literal = objectToLiteral(schema, pretty, indent, 0, singleQuote);\n\n // For isolatedDeclarations compatibility, use `satisfies Schema as const`\n // This makes the type explicit so TypeScript can emit declarations\n const typeAssertion = isolatedDeclarations\n ? 'satisfies Schema as const'\n : 'as const';\n\n return `export const ${safeName} = ${literal} ${typeAssertion};`;\n}\n\n/**\n * Format a string value as a single-quoted literal, unescaping JSON double quotes\n * and escaping any single quotes.\n */\nfunction toSingleQuoteLiteral(jsonStr: string): string {\n const inner = jsonStr\n .slice(1, -1)\n .replaceAll('\\\\\"', '\"')\n .replaceAll(\"'\", \"\\\\'\");\n return `'${inner}'`;\n}\n\n/**\n * Convert any value to a TypeScript literal string.\n */\nfunction objectToLiteral(\n value: unknown,\n pretty: boolean,\n indent: string,\n depth: number,\n singleQuote = false,\n): string {\n if (value === null || value === undefined) {\n return 'undefined';\n }\n\n // Handle SchemaRef - output as bare identifier (not quoted)\n if (value instanceof SchemaRef) {\n return value.name;\n }\n\n if (typeof value === 'string') {\n const json = JSON.stringify(value);\n if (singleQuote) {\n return toSingleQuoteLiteral(json);\n }\n return json;\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return '[]';\n }\n\n const items = value.map((item) =>\n objectToLiteral(item, pretty, indent, depth + 1, singleQuote),\n );\n\n if (pretty) {\n const itemIndent = indent.repeat(depth + 1);\n const closeIndent = indent.repeat(depth);\n return `[\\n${items\n .map((item) => `${itemIndent}${item}`)\n .join(',\\n')},\\n${closeIndent}]`;\n }\n\n return `[${items.join(', ')}]`;\n }\n\n if (typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const entries = Object.entries(obj).filter(([, v]) => v !== undefined);\n\n if (entries.length === 0) {\n return '{}';\n }\n\n const props = entries.map(([key, val]) => {\n let keyStr = key;\n if (!isValidIdentifier(key)) {\n const json = JSON.stringify(key);\n keyStr = singleQuote ? toSingleQuoteLiteral(json) : json;\n }\n const valStr = objectToLiteral(\n val,\n pretty,\n indent,\n depth + 1,\n singleQuote,\n );\n return `${keyStr}: ${valStr}`;\n });\n\n if (pretty) {\n const propIndent = indent.repeat(depth + 1);\n const closeIndent = indent.repeat(depth);\n return `{\\n${props\n .map((prop) => `${propIndent}${prop}`)\n .join(',\\n')},\\n${closeIndent}}`;\n }\n\n return `{ ${props.join(', ')} }`;\n }\n\n return 'undefined';\n}\n\n/**\n * JavaScript reserved words that cannot be used as variable names.\n */\nconst RESERVED_WORDS = new Set([\n 'break',\n 'case',\n 'catch',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'else',\n 'finally',\n 'for',\n 'function',\n 'if',\n 'in',\n 'instanceof',\n 'new',\n 'return',\n 'switch',\n 'this',\n 'throw',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'while',\n 'with',\n 'class',\n 'const',\n 'enum',\n 'export',\n 'extends',\n 'import',\n 'super',\n 'implements',\n 'interface',\n 'let',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'static',\n 'yield',\n 'await',\n 'null',\n 'true',\n 'false',\n]);\n\n/**\n * Check if a string is a valid JavaScript identifier.\n */\nfunction isValidIdentifier(str: string): boolean {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str) && !RESERVED_WORDS.has(str);\n}\n\n/**\n * Convert string to PascalCase.\n */\nfunction pascalCase(str: string): string {\n return str\n .replaceAll(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^./, (s) => s.toUpperCase());\n}\n"],"mappings":"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"}
@@ -0,0 +1,198 @@
1
+ import { _ as TransformContext, c as CodegenConfig, d as GeneratorPlugin, f as HookContext, g as SourceInfo, h as SourceConfig, i as ResolveOptions, l as FinalizeContext, m as SetupContext, n as RunnerResult, p as SchemaInfo, r as runCodegen, s as AfterAllContext, t as RunnerOptions, u as GeneratedFile, v as defineConfig } from "../runner-C4_p2y5e.mjs";
2
+
3
+ //#region src/generators/raw-schema.d.ts
4
+ interface RawSchemaOptions {
5
+ /** Use default export (default: true) */
6
+ defaultExport?: boolean;
7
+ /** Use named export with this name (alternative to default export) */
8
+ namedExport?: string;
9
+ /** Include $xmlns in output (default: true) */
10
+ $xmlns?: boolean;
11
+ /** Include $imports in output for xs:import (default: true) */
12
+ $imports?: boolean;
13
+ /** Include $includes in output for xs:include (default: true) */
14
+ $includes?: boolean;
15
+ /** Include $filename in output (default: false) */
16
+ $filename?: boolean;
17
+ /** Properties to exclude from output */
18
+ exclude?: string[];
19
+ /** Add file header comment */
20
+ header?: boolean;
21
+ /**
22
+ * Resolve schema - merge imports, expand extensions and substitution groups.
23
+ * When enabled, produces a self-contained schema with no $imports dependencies.
24
+ * Can be boolean (true = all options) or ResolveOptions for fine control.
25
+ */
26
+ resolve?: boolean | ResolveOptions;
27
+ /**
28
+ * Resolve includes - merge included schema content directly into the main schema.
29
+ * When enabled, xs:include content is merged recursively and no $includes or include
30
+ * properties appear in the output. The schema becomes self-contained.
31
+ */
32
+ resolveIncludes?: boolean;
33
+ /**
34
+ * Resolve ALL dependencies - merge both $includes AND $imports into a single schema.
35
+ * Creates a fully self-contained schema with all elements and types from the entire
36
+ * dependency tree. Useful for generating a schema that can parse the complete XML
37
+ * document structure (e.g., abapGit root element + asx:abap + values).
38
+ *
39
+ * When enabled, no $includes, $imports, include, or import properties appear in output.
40
+ */
41
+ resolveAll?: boolean;
42
+ /**
43
+ * Generate isolatedDeclarations-compatible output.
44
+ * Uses `satisfies Schema as const` instead of just `as const`.
45
+ * Also adds `import type { Schema } from '@abapify/ts-xsd';`
46
+ */
47
+ isolatedDeclarations?: boolean;
48
+ /** Use single quotes for string literals and property names */
49
+ singleQuote?: boolean;
50
+ }
51
+ /**
52
+ * Create a raw schema generator plugin
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * import { rawSchema } from '@abapify/ts-xsd/generators';
57
+ *
58
+ * export default defineConfig({
59
+ * generators: [
60
+ * rawSchema(), // default export
61
+ * rawSchema({ namedExport: 'mySchema' }), // named export
62
+ * ],
63
+ * });
64
+ * ```
65
+ */
66
+ declare function rawSchema(options?: RawSchemaOptions): GeneratorPlugin;
67
+ //#endregion
68
+ //#region src/generators/inferred-types.d.ts
69
+ interface InferredTypesOptions {
70
+ /** Import path for InferSchema (default: 'ts-xsd') */
71
+ inferSchemaImport?: string;
72
+ /** Type name pattern. Use {Name} for PascalCase schema name (default: '{Name}') */
73
+ typeNamePattern?: string;
74
+ /** Schema variable name to infer from (default: 'schema' for default export) */
75
+ schemaVariable?: string;
76
+ }
77
+ /**
78
+ * Create an inferred types generator plugin
79
+ *
80
+ * This generator should be used AFTER rawSchema() in the pipeline.
81
+ * It modifies the generated schema file to add type exports.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * import { rawSchema, inferredTypes } from '@abapify/ts-xsd/generators';
86
+ *
87
+ * export default defineConfig({
88
+ * generators: [
89
+ * rawSchema(),
90
+ * inferredTypes(), // Adds: export type Intf = InferSchema<typeof schema>;
91
+ * ],
92
+ * });
93
+ * ```
94
+ */
95
+ declare function inferredTypes(options?: InferredTypesOptions): GeneratorPlugin;
96
+ //#endregion
97
+ //#region src/generators/interfaces.d.ts
98
+ interface InterfacesOptions {
99
+ /** Output file name pattern. Use {name} for schema name, {source} for source name */
100
+ filePattern?: string;
101
+ /** Add file header comment */
102
+ header?: boolean;
103
+ /**
104
+ * If true, generates a single flattened type with all nested types inlined.
105
+ * If false (default), generates interfaces with imports and extends.
106
+ */
107
+ flatten?: boolean;
108
+ /** Custom root type name pattern. Use {name} for schema name (default: '{Name}Schema') */
109
+ rootTypePattern?: string;
110
+ /** Add JSDoc comments to generated types */
111
+ addJsDoc?: boolean;
112
+ }
113
+ /**
114
+ * Create an interfaces generator plugin
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * import { interfaces } from '@abapify/ts-xsd/generators';
119
+ *
120
+ * export default defineConfig({
121
+ * generators: [
122
+ * interfaces(), // interfaces with imports
123
+ * interfaces({ flatten: true }), // fully flattened types
124
+ * ],
125
+ * });
126
+ * ```
127
+ */
128
+ declare function interfaces(options?: InterfacesOptions): GeneratorPlugin;
129
+ //#endregion
130
+ //#region src/generators/index-barrel.d.ts
131
+ interface IndexBarrelOptions {
132
+ /** File name for the barrel (default: 'index.ts') */
133
+ filename?: string;
134
+ /** Use named re-exports instead of star exports */
135
+ namedExports?: boolean;
136
+ /** Export types from .typed.ts files if they exist */
137
+ includeTypedExports?: boolean;
138
+ /** Add file header comment */
139
+ header?: boolean;
140
+ /** Import extension to use: '.ts' for Node.js native, '' for bundlers (default: '' for bundler compatibility) */
141
+ importExtension?: '.ts' | '';
142
+ }
143
+ /**
144
+ * Create an index barrel generator plugin
145
+ *
146
+ * This generator runs in finalize() after all schemas are processed.
147
+ * It generates an index.ts that re-exports all schemas.
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * import { rawSchema, indexBarrel } from '@abapify/ts-xsd/generators';
152
+ *
153
+ * export default defineConfig({
154
+ * generators: [
155
+ * rawSchema(),
156
+ * indexBarrel(), // Generates index.ts with all exports
157
+ * ],
158
+ * });
159
+ * ```
160
+ */
161
+ declare function indexBarrel(options?: IndexBarrelOptions): GeneratorPlugin;
162
+ //#endregion
163
+ //#region src/generators/typed-schemas.d.ts
164
+ interface TypedSchemasOptions {
165
+ /** Output file path relative to package root (default: 'src/schemas/generated/index.ts') */
166
+ outputPath?: string;
167
+ /** Path to ts-xsd module from output file (default: 'ts-xsd') */
168
+ tsXsdPath?: string;
169
+ /** Path prefix to schemas from output file (default: './schemas') */
170
+ schemasPath?: string;
171
+ /** Path prefix to types from output file (default: './types') */
172
+ typesPath?: string;
173
+ /** Add file header comment */
174
+ header?: boolean;
175
+ }
176
+ /**
177
+ * Create a typed schemas generator plugin
178
+ *
179
+ * This generator runs in finalize() after all schemas are processed.
180
+ * It generates a single index file that exports typed schema wrappers.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * import { rawSchema, interfaces, typedSchemas } from '@abapify/ts-xsd/generators';
185
+ *
186
+ * export default defineConfig({
187
+ * generators: [
188
+ * rawSchema(),
189
+ * interfaces(),
190
+ * typedSchemas(), // Generates typed wrappers
191
+ * ],
192
+ * });
193
+ * ```
194
+ */
195
+ declare function typedSchemas(options?: TypedSchemasOptions): GeneratorPlugin;
196
+ //#endregion
197
+ export { type AfterAllContext, type CodegenConfig, type FinalizeContext, type GeneratedFile, type GeneratorPlugin, type HookContext, type IndexBarrelOptions, type InferredTypesOptions, type InterfacesOptions, type RawSchemaOptions, type RunnerOptions, type RunnerResult, type SchemaInfo, type SetupContext, type SourceConfig, type SourceInfo, type TransformContext, type TypedSchemasOptions, defineConfig, indexBarrel, inferredTypes, interfaces, rawSchema, runCodegen, typedSchemas };
198
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/generators/raw-schema.ts","../../src/generators/inferred-types.ts","../../src/generators/interfaces.ts","../../src/generators/index-barrel.ts","../../src/generators/typed-schemas.ts"],"mappings":";;;UAmBiB,gBAAA;EAQf;EANA,aAAA;EAUA;EARA,WAAA;EAYA;EAVA,MAAA;EAgBoB;EAdpB,QAAA;EA6BA;EA3BA,SAAA;EAmCA;EAjCA,SAAA;EAiCW;EA/BX,OAAA;EAqDuB;EAnDvB,MAAA;EAmDwE;;;;;EA7CxE,OAAA,aAAoB,cAAA;;;;ACtBtB;;ED4BE,eAAA;EC5BmC;;;;;;AA+BrC;;EDME,UAAA;ECJgB;;;;;EDUhB,oBAAA;;EAEA,WAAA;AAAA;AEzCF;;;;;;;;;;;AAqDA;;;;AArDA,iBF+DgB,SAAA,CAAU,OAAA,GAAS,gBAAA,GAAwB,eAAA;;;UCnE1C,oBAAA;EDQf;ECNA,iBAAA;EDUA;ECRA,eAAA;EDYA;ECVA,cAAA;AAAA;;;;;;;AD6DF;;;;;;;;;;;;iBCpCgB,aAAA,CACd,OAAA,GAAS,oBAAA,GACR,eAAA;;;UC7Bc,iBAAA;EFQf;EENA,WAAA;EFUA;EERA,MAAA;EFcoB;;;;EETpB,OAAA;EFgCW;EE9BX,eAAA;EFoDc;EElDd,QAAA;AAAA;;;;;;;;;;ADjBF;;;;;;iBCyDgB,UAAA,CAAW,OAAA,GAAS,iBAAA,GAAyB,eAAA;;;UC1D5C,kBAAA;EHOf;EGLA,QAAA;EHSA;EGPA,YAAA;EHWA;EGTA,mBAAA;EHiBA;EGfA,MAAA;EHqBA;EGnBA,eAAA;AAAA;;;;AH0DF;;;;;;;;;;;;ACnEA;;;iBEkCgB,WAAA,CAAY,OAAA,GAAS,kBAAA,GAA0B,eAAA;;;UCvB9C,mBAAA;EJkCf;EIhCA,UAAA;EJgCW;EI9BX,SAAA;EJoDuB;EIlDvB,WAAA;EJkDwE;EIhDxE,SAAA;EJgDwB;EI9CxB,MAAA;AAAA;;;;;AHrBF;;;;;;;;;AA+BA;;;;;;iBGgBgB,YAAA,CACd,OAAA,GAAS,mBAAA,GACR,eAAA"}