@abapify/ts-xsd 0.4.34 → 0.4.36
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.
- package/README.md +17 -320
- package/dist/codegen/cli.mjs +6 -4
- package/dist/codegen/cli.mjs.map +1 -1
- package/dist/{generate-DQJ38rjv.mjs → generate-BWLnwHUW.mjs} +38 -33
- package/dist/generate-BWLnwHUW.mjs.map +1 -0
- package/dist/generators/index.d.mts +1 -1
- package/dist/generators/index.mjs +130 -116
- package/dist/generators/index.mjs.map +1 -1
- package/dist/index.d.mts +6 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +495 -368
- package/dist/index.mjs.map +1 -1
- package/dist/{runner-BGNA8Sl-.mjs → runner-BZNOc_YZ.mjs} +439 -334
- package/dist/runner-BZNOc_YZ.mjs.map +1 -0
- package/dist/{runner-CDEKB5AE.d.mts → runner-x86T9IvM.d.mts} +5 -5
- package/dist/{runner-CDEKB5AE.d.mts.map → runner-x86T9IvM.d.mts.map} +1 -1
- package/dist/{types-CySWjUcM.mjs → types-BAx8yQfm.mjs} +151 -115
- package/dist/types-BAx8yQfm.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/generate-DQJ38rjv.mjs.map +0 -1
- package/dist/runner-BGNA8Sl-.mjs.map +0 -1
- package/dist/types-CySWjUcM.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as resolveSchema, t as runCodegen } from "../runner-
|
|
2
|
-
import { r as generateInterfaces, t as defineConfig } from "../types-
|
|
1
|
+
import { l as resolveSchema, t as runCodegen } from "../runner-BZNOc_YZ.mjs";
|
|
2
|
+
import { r as generateInterfaces, t as defineConfig } from "../types-BAx8yQfm.mjs";
|
|
3
3
|
|
|
4
4
|
// src/generators/raw-schema.ts
|
|
5
5
|
/**
|
|
@@ -23,17 +23,7 @@ function rawSchema(options = {}) {
|
|
|
23
23
|
name: "raw-schema",
|
|
24
24
|
transform(ctx) {
|
|
25
25
|
const { schema, source } = ctx;
|
|
26
|
-
|
|
27
|
-
if (options.resolve) {
|
|
28
|
-
const resolveOpts = options.resolve === true ? {} : options.resolve;
|
|
29
|
-
schemaToProcess = resolveSchema(schema.schema, resolveOpts);
|
|
30
|
-
}
|
|
31
|
-
if (resolveAll) schemaToProcess = resolveSchema(schema.schema, { filterToRootElements: true });
|
|
32
|
-
else if (resolveIncludes) schemaToProcess = resolveSchema(schema.schema, {
|
|
33
|
-
resolveImports: false,
|
|
34
|
-
keepImportsRef: true
|
|
35
|
-
});
|
|
36
|
-
const outputSchema = buildOutputSchema(schemaToProcess, {
|
|
26
|
+
const outputSchema = buildOutputSchema(resolveSchemaToProcess(schema.schema, options.resolve, resolveIncludes, resolveAll), {
|
|
37
27
|
$xmlns,
|
|
38
28
|
$imports: resolveAll ? false : $imports,
|
|
39
29
|
$includes: resolveAll || resolveIncludes ? false : $includes,
|
|
@@ -46,25 +36,15 @@ function rawSchema(options = {}) {
|
|
|
46
36
|
if (header) lines.push("/**", " * Auto-generated schema from XSD", " * ", " * DO NOT EDIT - Generated by ts-xsd codegen", ` * Source: ${source.name}/${schema.name}.xsd`, " */", "");
|
|
47
37
|
if (isolatedDeclarations) lines.push("import type { Schema } from '@abapify/ts-xsd';");
|
|
48
38
|
const shouldGenerateImports = !options.resolve && !resolveIncludes && !resolveAll && ($imports || $includes);
|
|
49
|
-
if (shouldGenerateImports) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
});
|
|
54
|
-
if (imports.length > 0) for (const imp of imports) if (isolatedDeclarations) lines.push(`import { schema as ${imp.name} } from '${imp.path}';`);
|
|
55
|
-
else lines.push(`import ${imp.name} from '${imp.path}';`);
|
|
56
|
-
}
|
|
39
|
+
if (shouldGenerateImports) appendImportLines(lines, getSchemaImports(schema.schema, ctx.resolveImport, {
|
|
40
|
+
$imports,
|
|
41
|
+
$includes
|
|
42
|
+
}), isolatedDeclarations);
|
|
57
43
|
if (isolatedDeclarations || shouldGenerateImports && getSchemaImports(schema.schema, ctx.resolveImport, {
|
|
58
44
|
$imports,
|
|
59
45
|
$includes
|
|
60
46
|
}).length > 0) lines.push("");
|
|
61
|
-
|
|
62
|
-
if (isolatedDeclarations) {
|
|
63
|
-
const exportName = namedExport ?? "schema";
|
|
64
|
-
lines.push(`export const ${exportName} = ${literal} as const satisfies Schema;`);
|
|
65
|
-
if (defaultExport && !namedExport) lines.push(`export default ${exportName};`);
|
|
66
|
-
} else if (namedExport) lines.push(`export const ${namedExport} = ${literal} as const;`);
|
|
67
|
-
else if (defaultExport) lines.push(`export default ${literal} as const;`);
|
|
47
|
+
appendExportLines(lines, objectToLiteral(outputSchema, true, " ", 0, singleQuote), isolatedDeclarations, namedExport, defaultExport);
|
|
68
48
|
lines.push("");
|
|
69
49
|
return [{
|
|
70
50
|
path: `${schema.name}.ts`,
|
|
@@ -73,72 +53,107 @@ function rawSchema(options = {}) {
|
|
|
73
53
|
}
|
|
74
54
|
};
|
|
75
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Apply schema resolution according to the resolve/resolveAll/resolveIncludes options.
|
|
58
|
+
*/
|
|
59
|
+
function resolveSchemaToProcess(schema, resolveOption, resolveIncludes, resolveAll) {
|
|
60
|
+
let schemaToProcess = schema;
|
|
61
|
+
if (resolveOption) schemaToProcess = resolveSchema(schema, resolveOption === true ? {} : resolveOption);
|
|
62
|
+
if (resolveAll) schemaToProcess = resolveSchema(schema, { filterToRootElements: true });
|
|
63
|
+
else if (resolveIncludes) schemaToProcess = resolveSchema(schema, {
|
|
64
|
+
resolveImports: false,
|
|
65
|
+
keepImportsRef: true
|
|
66
|
+
});
|
|
67
|
+
return schemaToProcess;
|
|
68
|
+
}
|
|
69
|
+
/** Append one import statement per schema import. */
|
|
70
|
+
function appendImportLines(lines, imports, isolatedDeclarations) {
|
|
71
|
+
for (const imp of imports) if (isolatedDeclarations) lines.push(`import { schema as ${imp.name} } from '${imp.path}';`);
|
|
72
|
+
else lines.push(`import ${imp.name} from '${imp.path}';`);
|
|
73
|
+
}
|
|
74
|
+
/** Append the export statement(s) for the schema literal. */
|
|
75
|
+
function appendExportLines(lines, literal, isolatedDeclarations, namedExport, defaultExport) {
|
|
76
|
+
if (isolatedDeclarations) {
|
|
77
|
+
const exportName = namedExport ?? "schema";
|
|
78
|
+
lines.push(`export const ${exportName} = ${literal} as const satisfies Schema;`);
|
|
79
|
+
if (defaultExport && !namedExport) lines.push(`export default ${exportName};`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (namedExport) {
|
|
83
|
+
lines.push(`export const ${namedExport} = ${literal} as const;`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (defaultExport) lines.push(`export default ${literal} as const;`);
|
|
87
|
+
}
|
|
76
88
|
function buildOutputSchema(schema, options) {
|
|
77
89
|
const result = {};
|
|
78
90
|
const excludeSet = new Set(options.exclude);
|
|
79
91
|
if (options.$xmlns && schema.$xmlns) result.$xmlns = schema.$xmlns;
|
|
80
92
|
if (options.$imports && schema.import) {
|
|
81
|
-
const importRefs =
|
|
82
|
-
const imports = schema.import;
|
|
83
|
-
for (const imp of imports) if (imp.schemaLocation) {
|
|
84
|
-
if (!options.resolveImport(imp.schemaLocation)) throw new Error(`Cannot resolve xs:import schemaLocation: ${imp.schemaLocation} (in ${options.schemaName}.xsd)`);
|
|
85
|
-
const name = imp.schemaLocation.replace(/\.xsd$/, "").replace(/^.*\//, "");
|
|
86
|
-
importRefs.push(new SchemaRef(name));
|
|
87
|
-
}
|
|
93
|
+
const importRefs = buildSchemaRefs(schema.import, "xs:import", options);
|
|
88
94
|
if (importRefs.length > 0) result.$imports = importRefs;
|
|
89
95
|
}
|
|
90
96
|
if (options.$includes && schema.include) {
|
|
91
|
-
const includeRefs =
|
|
92
|
-
const includes = schema.include;
|
|
93
|
-
for (const inc of includes) if (inc.schemaLocation) {
|
|
94
|
-
if (!options.resolveImport(inc.schemaLocation)) throw new Error(`Cannot resolve xs:include schemaLocation: ${inc.schemaLocation} (in ${options.schemaName}.xsd)`);
|
|
95
|
-
const name = inc.schemaLocation.replace(/\.xsd$/, "").replace(/^.*\//, "");
|
|
96
|
-
includeRefs.push(new SchemaRef(name));
|
|
97
|
-
}
|
|
97
|
+
const includeRefs = buildSchemaRefs(schema.include, "xs:include", options);
|
|
98
98
|
if (includeRefs.length > 0) result.$includes = includeRefs;
|
|
99
99
|
}
|
|
100
100
|
if (options.$filename) result.$filename = `${options.schemaName}.xsd`;
|
|
101
|
+
copyRemainingProperties(schema, result, options, excludeSet);
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Build $imports/$includes refs from xs:import/xs:include schemaLocation
|
|
106
|
+
* entries. Unresolvable locations throw.
|
|
107
|
+
*/
|
|
108
|
+
function buildSchemaRefs(refs, kind, options) {
|
|
109
|
+
const schemaRefs = [];
|
|
110
|
+
for (const ref of refs) if (ref.schemaLocation) {
|
|
111
|
+
if (!options.resolveImport(ref.schemaLocation)) throw new Error(`Cannot resolve ${kind} schemaLocation: ${ref.schemaLocation} (in ${options.schemaName}.xsd)`);
|
|
112
|
+
const name = ref.schemaLocation.replace(/\.xsd$/, "").replace(/^.*\//, "");
|
|
113
|
+
schemaRefs.push(new SchemaRef(name));
|
|
114
|
+
}
|
|
115
|
+
return schemaRefs;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Copy schema properties that are not handled elsewhere,
|
|
119
|
+
* deep-filtering excluded keys.
|
|
120
|
+
*/
|
|
121
|
+
function copyRemainingProperties(schema, result, options, excludeSet) {
|
|
101
122
|
for (const [key, value] of Object.entries(schema)) {
|
|
102
|
-
if (key
|
|
103
|
-
if (key === "import" && options.$imports) continue;
|
|
104
|
-
if (key === "include" && options.$includes) continue;
|
|
123
|
+
if (shouldSkipProperty(key, options)) continue;
|
|
105
124
|
if (!excludeSet.has(key)) result[key] = filterDeep(value, excludeSet);
|
|
106
125
|
}
|
|
107
|
-
return result;
|
|
108
126
|
}
|
|
109
|
-
|
|
127
|
+
/** Whether a schema property is handled elsewhere and must not be copied. */
|
|
128
|
+
function shouldSkipProperty(key, options) {
|
|
129
|
+
if (key === "$xmlns" || key === "$imports" || key === "$includes" || key === "$filename") return true;
|
|
130
|
+
if (key === "import" && options.$imports) return true;
|
|
131
|
+
return key === "include" && options.$includes;
|
|
132
|
+
}
|
|
133
|
+
const DEFAULT_SCHEMA_IMPORT_OPTIONS = {
|
|
110
134
|
$imports: true,
|
|
111
135
|
$includes: true
|
|
112
|
-
}
|
|
136
|
+
};
|
|
137
|
+
function getSchemaImports(schema, resolveImport, options = DEFAULT_SCHEMA_IMPORT_OPTIONS) {
|
|
113
138
|
const imports = [];
|
|
114
|
-
if (options.$imports)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
for (const inc of xsdIncludes) if (inc.schemaLocation) {
|
|
133
|
-
const modulePath = resolveImport(inc.schemaLocation);
|
|
134
|
-
if (modulePath) {
|
|
135
|
-
const name = inc.schemaLocation.replace(/\.xsd$/, "").replace(/^.*\//, "");
|
|
136
|
-
imports.push({
|
|
137
|
-
name,
|
|
138
|
-
path: modulePath
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
}
|
|
139
|
+
if (options.$imports) imports.push(...collectSchemaImports(schema.import, resolveImport));
|
|
140
|
+
if (options.$includes) imports.push(...collectSchemaImports(schema.include, resolveImport));
|
|
141
|
+
return imports;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Resolve module imports from schemaLocation entries;
|
|
145
|
+
* unresolvable entries are skipped.
|
|
146
|
+
*/
|
|
147
|
+
function collectSchemaImports(refs, resolveImport) {
|
|
148
|
+
const imports = [];
|
|
149
|
+
for (const ref of refs ?? []) if (ref.schemaLocation) {
|
|
150
|
+
const modulePath = resolveImport(ref.schemaLocation);
|
|
151
|
+
if (modulePath) {
|
|
152
|
+
const name = ref.schemaLocation.replace(/\.xsd$/, "").replace(/^.*\//, "");
|
|
153
|
+
imports.push({
|
|
154
|
+
name,
|
|
155
|
+
path: modulePath
|
|
156
|
+
});
|
|
142
157
|
}
|
|
143
158
|
}
|
|
144
159
|
return imports;
|
|
@@ -155,7 +170,7 @@ var SchemaRef = class {
|
|
|
155
170
|
* and escaping any single quotes.
|
|
156
171
|
*/
|
|
157
172
|
function toSingleQuoteLiteral(jsonStr) {
|
|
158
|
-
return `'${jsonStr.slice(1, -1).replaceAll("
|
|
173
|
+
return `'${jsonStr.slice(1, -1).replaceAll(String.raw`\"`, "\"").replaceAll("'", String.raw`\'`)}'`;
|
|
159
174
|
}
|
|
160
175
|
function filterDeep(value, exclude) {
|
|
161
176
|
if (value instanceof SchemaRef) return value;
|
|
@@ -172,40 +187,45 @@ function objectToLiteral(value, pretty, indent, depth, singleQuote = false) {
|
|
|
172
187
|
if (value instanceof SchemaRef) return value.name;
|
|
173
188
|
if (typeof value === "string") {
|
|
174
189
|
const json = JSON.stringify(value);
|
|
175
|
-
|
|
176
|
-
return json;
|
|
190
|
+
return singleQuote ? toSingleQuoteLiteral(json) : json;
|
|
177
191
|
}
|
|
178
192
|
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
179
|
-
if (Array.isArray(value))
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
193
|
+
if (Array.isArray(value)) return arrayToLiteral(value, pretty, indent, depth, singleQuote);
|
|
194
|
+
if (typeof value === "object") return recordToLiteral(value, pretty, indent, depth, singleQuote);
|
|
195
|
+
return "undefined";
|
|
196
|
+
}
|
|
197
|
+
/** Render an array literal. */
|
|
198
|
+
function arrayToLiteral(value, pretty, indent, depth, singleQuote) {
|
|
199
|
+
if (value.length === 0) return "[]";
|
|
200
|
+
const items = value.map((item) => objectToLiteral(item, pretty, indent, depth + 1, singleQuote));
|
|
201
|
+
if (pretty) {
|
|
202
|
+
const itemIndent = indent.repeat(depth + 1);
|
|
203
|
+
const closeIndent = indent.repeat(depth);
|
|
204
|
+
return `[\n${items.map((item) => `${itemIndent}${item}`).join(",\n")},\n${closeIndent}]`;
|
|
188
205
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
});
|
|
201
|
-
if (pretty) {
|
|
202
|
-
const propIndent = indent.repeat(depth + 1);
|
|
203
|
-
const closeIndent = indent.repeat(depth);
|
|
204
|
-
return `{\n${props.map((prop) => `${propIndent}${prop}`).join(",\n")},\n${closeIndent}}`;
|
|
205
|
-
}
|
|
206
|
-
return `{ ${props.join(", ")} }`;
|
|
206
|
+
return `[${items.join(", ")}]`;
|
|
207
|
+
}
|
|
208
|
+
/** Render an object literal from record entries. */
|
|
209
|
+
function recordToLiteral(obj, pretty, indent, depth, singleQuote) {
|
|
210
|
+
const entries = Object.entries(obj).filter(([, v]) => v !== void 0);
|
|
211
|
+
if (entries.length === 0) return "{}";
|
|
212
|
+
const props = entries.map(([key, val]) => propertyToLiteral(key, val, pretty, indent, depth, singleQuote));
|
|
213
|
+
if (pretty) {
|
|
214
|
+
const propIndent = indent.repeat(depth + 1);
|
|
215
|
+
const closeIndent = indent.repeat(depth);
|
|
216
|
+
return `{\n${props.map((prop) => `${propIndent}${prop}`).join(",\n")},\n${closeIndent}}`;
|
|
207
217
|
}
|
|
208
|
-
return "
|
|
218
|
+
return `{ ${props.join(", ")} }`;
|
|
219
|
+
}
|
|
220
|
+
/** Render one `key: value` object property. */
|
|
221
|
+
function propertyToLiteral(key, val, pretty, indent, depth, singleQuote) {
|
|
222
|
+
let keyStr = key;
|
|
223
|
+
if (!isValidIdentifier(key)) {
|
|
224
|
+
const json = JSON.stringify(key);
|
|
225
|
+
keyStr = singleQuote ? toSingleQuoteLiteral(json) : json;
|
|
226
|
+
}
|
|
227
|
+
const valStr = objectToLiteral(val, pretty, indent, depth + 1, singleQuote);
|
|
228
|
+
return `${keyStr}: ${valStr}`;
|
|
209
229
|
}
|
|
210
230
|
const RESERVED_WORDS$2 = /* @__PURE__ */ new Set([
|
|
211
231
|
"break",
|
|
@@ -499,8 +519,7 @@ function typedSchemas(options = {}) {
|
|
|
499
519
|
finalize(ctx) {
|
|
500
520
|
const lines = [];
|
|
501
521
|
if (header) lines.push("/**", " * Auto-generated typed schema exports", " * ", " * DO NOT EDIT - Generated by ts-xsd codegen", " * ", " * These schemas have pre-computed types for full type inference.", " * Use these instead of raw schemas for type-safe parsing/building.", " * ", " * @example", " * import { classes } from '@abapify/adt-schemas';", " * const data = classes.parse(xml); // data is fully typed!", " */", "");
|
|
502
|
-
lines.push(`import { typedSchema, type TypedSchema } from '${tsXsdPath}'
|
|
503
|
-
lines.push("");
|
|
522
|
+
lines.push(`import { typedSchema, type TypedSchema } from '${tsXsdPath}';`, "");
|
|
504
523
|
const schemaExports = [];
|
|
505
524
|
for (const [sourceName, schemas] of ctx.processedSchemas) {
|
|
506
525
|
lines.push(`// ${sourceName.toUpperCase()} schemas`);
|
|
@@ -524,10 +543,7 @@ function typedSchemas(options = {}) {
|
|
|
524
543
|
}
|
|
525
544
|
lines.push("");
|
|
526
545
|
}
|
|
527
|
-
lines.push("// ============================================================================");
|
|
528
|
-
lines.push("// TYPED SCHEMA EXPORTS");
|
|
529
|
-
lines.push("// ============================================================================");
|
|
530
|
-
lines.push("");
|
|
546
|
+
lines.push("// ============================================================================", "// TYPED SCHEMA EXPORTS", "// ============================================================================", "");
|
|
531
547
|
for (const { name, rootTypes } of schemaExports) {
|
|
532
548
|
const exportName = toValidIdentifier(name);
|
|
533
549
|
if (rootTypes.length === 1) lines.push(`export const ${exportName}: TypedSchema<${rootTypes[0]}> = typedSchema<${rootTypes[0]}>(_${exportName});`);
|
|
@@ -536,9 +552,7 @@ function typedSchemas(options = {}) {
|
|
|
536
552
|
lines.push(`export const ${exportName}: TypedSchema<${unionType}> = typedSchema<${unionType}>(_${exportName});`);
|
|
537
553
|
}
|
|
538
554
|
}
|
|
539
|
-
lines.push("");
|
|
540
|
-
lines.push("// Types are internal - import directly from types/{source}/{schema}.types if needed");
|
|
541
|
-
lines.push("");
|
|
555
|
+
lines.push("", "// Types are internal - import directly from types/{source}/{schema}.types if needed", "");
|
|
542
556
|
return [{
|
|
543
557
|
path: outputPath,
|
|
544
558
|
content: lines.join("\n")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["obj","RESERVED_WORDS","pascalCase","generateInterfacesFromSchema","toValidIdentifier","RESERVED_WORDS"],"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"],"sourcesContent":["/**\n * Raw Schema Generator\n *\n * Generates raw schema literals with `as const` for type inference.\n *\n * Output: `export default { ... } as const;`\n */\n\nimport type {\n GeneratorPlugin,\n TransformContext,\n GeneratedFile,\n} from '../codegen/types';\nimport { resolveSchema, type ResolveOptions } from '../xsd/resolve';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface RawSchemaOptions {\n /** Use default export (default: true) */\n defaultExport?: boolean;\n /** Use named export with this name (alternative to default export) */\n namedExport?: string;\n /** Include $xmlns in output (default: true) */\n $xmlns?: boolean;\n /** Include $imports in output for xs:import (default: true) */\n $imports?: boolean;\n /** Include $includes in output for xs:include (default: true) */\n $includes?: boolean;\n /** Include $filename in output (default: false) */\n $filename?: boolean;\n /** Properties to exclude from output */\n exclude?: string[];\n /** Add file header comment */\n header?: boolean;\n /**\n * Resolve schema - merge imports, expand extensions and substitution groups.\n * When enabled, produces a self-contained schema with no $imports dependencies.\n * Can be boolean (true = all options) or ResolveOptions for fine control.\n */\n resolve?: boolean | ResolveOptions;\n /**\n * Resolve includes - merge included schema content directly into the main schema.\n * When enabled, xs:include content is merged recursively and no $includes or include\n * properties appear in the output. The schema becomes self-contained.\n */\n resolveIncludes?: boolean;\n /**\n * Resolve ALL dependencies - merge both $includes AND $imports into a single schema.\n * Creates a fully self-contained schema with all elements and types from the entire\n * dependency tree. Useful for generating a schema that can parse the complete XML\n * document structure (e.g., abapGit root element + asx:abap + values).\n *\n * When enabled, no $includes, $imports, include, or import properties appear in output.\n */\n resolveAll?: boolean;\n /**\n * Generate isolatedDeclarations-compatible output.\n * Uses `satisfies Schema as const` instead of just `as const`.\n * Also adds `import type { Schema } from '@abapify/ts-xsd';`\n */\n isolatedDeclarations?: boolean;\n /** Use single quotes for string literals and property names */\n singleQuote?: boolean;\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create a raw schema generator plugin\n *\n * @example\n * ```ts\n * import { rawSchema } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * rawSchema(), // default export\n * rawSchema({ namedExport: 'mySchema' }), // named export\n * ],\n * });\n * ```\n */\nexport function rawSchema(options: RawSchemaOptions = {}): GeneratorPlugin {\n const {\n defaultExport = true,\n namedExport,\n $xmlns = true,\n $imports = true,\n $includes = true,\n $filename = false,\n exclude = ['annotation'],\n header = true,\n resolveIncludes = false,\n resolveAll = false,\n isolatedDeclarations = false,\n singleQuote = false,\n } = options;\n\n return {\n name: 'raw-schema',\n\n transform(ctx: TransformContext): GeneratedFile[] {\n const { schema, source } = ctx;\n\n // Schema is already linked by runner.ts\n // Apply schema resolution if enabled\n let schemaToProcess = schema.schema as Record<string, unknown>;\n if (options.resolve) {\n const resolveOpts: ResolveOptions =\n options.resolve === true ? {} : options.resolve;\n schemaToProcess = resolveSchema(schema.schema, resolveOpts) as Record<\n string,\n unknown\n >;\n }\n\n // Resolve ALL - merge both $includes AND $imports into a single schema\n // This creates a fully self-contained schema with all elements and types\n if (resolveAll) {\n schemaToProcess = resolveSchema(schema.schema, {\n filterToRootElements: true,\n }) as Record<string, unknown>;\n }\n // Resolve includes only - merge included schema content recursively\n else if (resolveIncludes) {\n schemaToProcess = resolveSchema(schema.schema, {\n resolveImports: false,\n keepImportsRef: true,\n }) as Record<string, unknown>;\n }\n\n // When resolving all, disable both $includes and $imports in output\n const disableRefs = resolveAll || resolveIncludes;\n const outputSchema = buildOutputSchema(schemaToProcess, {\n $xmlns,\n $imports: resolveAll ? false : $imports,\n $includes: disableRefs ? false : $includes,\n $filename,\n exclude,\n schemaName: schema.name,\n resolveImport: ctx.resolveImport,\n });\n\n const lines: string[] = [];\n\n // Header\n if (header) {\n lines.push(\n '/**',\n ' * Auto-generated schema from XSD',\n ' * ',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ` * Source: ${source.name}/${schema.name}.xsd`,\n ' */',\n '',\n );\n }\n\n // Add Schema type import for isolatedDeclarations mode\n if (isolatedDeclarations) {\n lines.push(\"import type { Schema } from '@abapify/ts-xsd';\");\n }\n\n // Imports for $imports/$includes (skip if resolve/resolveIncludes/resolveAll is enabled - schema is self-contained)\n // Also skip if both $imports and $includes are disabled\n const shouldGenerateImports =\n !options.resolve &&\n !resolveIncludes &&\n !resolveAll &&\n ($imports || $includes);\n if (shouldGenerateImports) {\n const imports = getSchemaImports(schema.schema, ctx.resolveImport, {\n $imports,\n $includes,\n });\n if (imports.length > 0) {\n for (const imp of imports) {\n // For isolatedDeclarations, import the named 'schema' export and alias it\n // This is required because default exports can't be inferred with --isolatedDeclarations\n if (isolatedDeclarations) {\n lines.push(\n `import { schema as ${imp.name} } from '${imp.path}';`,\n );\n } else {\n lines.push(`import ${imp.name} from '${imp.path}';`);\n }\n }\n }\n }\n\n // Add blank line after imports if any were added\n if (\n isolatedDeclarations ||\n (shouldGenerateImports &&\n getSchemaImports(schema.schema, ctx.resolveImport, {\n $imports,\n $includes,\n }).length > 0)\n ) {\n lines.push('');\n }\n\n // Schema literal\n const literal = objectToLiteral(outputSchema, true, ' ', 0, singleQuote);\n\n // For isolatedDeclarations, use named export with `as const satisfies Schema`\n // This is required because default exports can't be inferred with --isolatedDeclarations\n if (isolatedDeclarations) {\n const exportName = namedExport ?? 'schema';\n lines.push(\n `export const ${exportName} = ${literal} as const satisfies Schema;`,\n );\n // Also add default export pointing to the named export\n if (defaultExport && !namedExport) {\n lines.push(`export default ${exportName};`);\n }\n } else if (namedExport) {\n lines.push(`export const ${namedExport} = ${literal} as const;`);\n } else if (defaultExport) {\n lines.push(`export default ${literal} as const;`);\n }\n\n lines.push('');\n\n return [\n {\n path: `${schema.name}.ts`,\n content: lines.join('\\n'),\n },\n ];\n },\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\ninterface BuildOptions {\n $xmlns: boolean;\n $imports: boolean;\n $includes: boolean;\n $filename: boolean;\n exclude: string[];\n schemaName: string;\n resolveImport: (schemaLocation: string) => string | null;\n}\n\nfunction buildOutputSchema(\n schema: Record<string, unknown>,\n options: BuildOptions,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const excludeSet = new Set(options.exclude);\n\n // Add $xmlns first if enabled\n if (options.$xmlns && schema.$xmlns) {\n result.$xmlns = schema.$xmlns;\n }\n\n // Add $imports if enabled (from xs:import - different namespace)\n if (options.$imports && schema.import) {\n const importRefs: SchemaRef[] = [];\n const imports = schema.import as Array<{ schemaLocation?: string }>;\n for (const imp of imports) {\n if (imp.schemaLocation) {\n const resolved = options.resolveImport(imp.schemaLocation);\n if (!resolved) {\n throw new Error(\n `Cannot resolve xs:import schemaLocation: ${imp.schemaLocation} (in ${options.schemaName}.xsd)`,\n );\n }\n const name = imp.schemaLocation\n .replace(/\\.xsd$/, '')\n .replace(/^.*\\//, '');\n importRefs.push(new SchemaRef(name));\n }\n }\n if (importRefs.length > 0) {\n result.$imports = importRefs;\n }\n }\n\n // Add $includes if enabled (from xs:include - same namespace)\n if (options.$includes && schema.include) {\n const includeRefs: SchemaRef[] = [];\n const includes = schema.include as Array<{ schemaLocation?: string }>;\n for (const inc of includes) {\n if (inc.schemaLocation) {\n const resolved = options.resolveImport(inc.schemaLocation);\n if (!resolved) {\n throw new Error(\n `Cannot resolve xs:include schemaLocation: ${inc.schemaLocation} (in ${options.schemaName}.xsd)`,\n );\n }\n // Use base name for valid JS identifier\n const name = inc.schemaLocation\n .replace(/\\.xsd$/, '')\n .replace(/^.*\\//, '');\n includeRefs.push(new SchemaRef(name));\n }\n }\n if (includeRefs.length > 0) {\n result.$includes = includeRefs;\n }\n }\n\n // Add $filename if enabled\n if (options.$filename) {\n result.$filename = `${options.schemaName}.xsd`;\n }\n\n // Copy remaining properties (excluding handled ones)\n for (const [key, value] of Object.entries(schema)) {\n // Skip extension properties\n if (\n key === '$xmlns' ||\n key === '$imports' ||\n key === '$includes' ||\n key === '$filename'\n ) {\n continue;\n }\n // Skip 'import' if $imports is enabled (we output $imports instead)\n if (key === 'import' && options.$imports) {\n continue;\n }\n // Skip 'include' if $includes is enabled (we output $includes instead)\n if (key === 'include' && options.$includes) {\n continue;\n }\n if (!excludeSet.has(key)) {\n result[key] = filterDeep(value, excludeSet);\n }\n }\n\n return result;\n}\n\nfunction getSchemaImports(\n schema: Record<string, unknown>,\n resolveImport: (schemaLocation: string) => string | null,\n options: { $imports?: boolean; $includes?: boolean } = {\n $imports: true,\n $includes: true,\n },\n): Array<{ name: string; path: string }> {\n const imports: Array<{ name: string; path: string }> = [];\n\n // Handle xs:import (only if $imports is enabled)\n if (options.$imports) {\n const xsdImports = schema.import as\n | Array<{ schemaLocation?: string }>\n | undefined;\n if (xsdImports) {\n for (const imp of xsdImports) {\n if (imp.schemaLocation) {\n const modulePath = resolveImport(imp.schemaLocation);\n if (modulePath) {\n const name = imp.schemaLocation\n .replace(/\\.xsd$/, '')\n .replace(/^.*\\//, '');\n imports.push({ name, path: modulePath });\n }\n }\n }\n }\n }\n\n // Handle xs:include (only if $includes is enabled)\n if (options.$includes) {\n const xsdIncludes = schema.include as\n | Array<{ schemaLocation?: string }>\n | undefined;\n if (xsdIncludes) {\n for (const inc of xsdIncludes) {\n if (inc.schemaLocation) {\n const modulePath = resolveImport(inc.schemaLocation);\n if (modulePath) {\n // Use base name for valid JS identifier\n const name = inc.schemaLocation\n .replace(/\\.xsd$/, '')\n .replace(/^.*\\//, '');\n imports.push({ name, path: modulePath });\n }\n }\n }\n }\n }\n\n return imports;\n}\n\n/** Marker class for schema references in $imports */\nclass SchemaRef {\n constructor(public readonly name: string) {}\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\nfunction filterDeep(value: unknown, exclude: Set<string>): unknown {\n if (value instanceof SchemaRef) {\n return value;\n }\n\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\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 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) return '[]';\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) return '{}';\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\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\nfunction isValidIdentifier(str: string): boolean {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str) && !RESERVED_WORDS.has(str);\n}\n","/**\n * Inferred Types Generator\n *\n * Generates TypeScript types using InferSchema<typeof schema>.\n * Appends type export to the schema file generated by rawSchema().\n *\n * Output: `export type Intf = InferSchema<typeof schema>;`\n */\n\nimport type {\n GeneratorPlugin,\n TransformContext,\n GeneratedFile,\n} from '../codegen/types';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface InferredTypesOptions {\n /** Import path for InferSchema (default: 'ts-xsd') */\n inferSchemaImport?: string;\n /** Type name pattern. Use {Name} for PascalCase schema name (default: '{Name}') */\n typeNamePattern?: string;\n /** Schema variable name to infer from (default: 'schema' for default export) */\n schemaVariable?: string;\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create an inferred types generator plugin\n *\n * This generator should be used AFTER rawSchema() in the pipeline.\n * It modifies the generated schema file to add type exports.\n *\n * @example\n * ```ts\n * import { rawSchema, inferredTypes } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * rawSchema(),\n * inferredTypes(), // Adds: export type Intf = InferSchema<typeof schema>;\n * ],\n * });\n * ```\n */\nexport function inferredTypes(\n options: InferredTypesOptions = {},\n): GeneratorPlugin {\n const { inferSchemaImport = 'ts-xsd', typeNamePattern = '{Name}' } = options;\n\n return {\n name: 'inferred-types',\n\n transform(ctx: TransformContext): GeneratedFile[] {\n const { schema } = ctx;\n const typeName = typeNamePattern.replace(\n '{Name}',\n pascalCase(schema.name),\n );\n\n // Store for later - we'll modify the file in finalize\n // For now, generate a separate types file that re-exports\n const lines: string[] = [\n '/**',\n ' * Auto-generated type from schema',\n ' * ',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ' */',\n '',\n `import type { InferSchema } from '${inferSchemaImport}';`,\n `import schema from './${schema.name}';`,\n '',\n `/** Inferred type for ${schema.name} schema */`,\n `export type ${typeName} = InferSchema<typeof schema>;`,\n '',\n `export default schema;`,\n '',\n ];\n\n // Generate a typed wrapper file instead of modifying the raw schema\n return [\n {\n path: `${schema.name}.typed.ts`,\n content: lines.join('\\n'),\n },\n ];\n },\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction pascalCase(str: string): string {\n return str\n .replaceAll(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^./, (s) => s.toUpperCase());\n}\n","/**\n * Interfaces Generator\n *\n * Generates TypeScript interfaces from XSD schemas.\n * Uses ts-morph for TypeScript code generation.\n *\n * Two modes:\n * 1. flatten: false (default) - Generates interfaces with imports and extends\n * 2. flatten: true - Generates a single flattened type with all nested types inlined\n */\n\nimport type {\n GeneratorPlugin,\n TransformContext,\n GeneratedFile,\n} from '../codegen/types';\nimport { generateInterfaces as generateInterfacesFromSchema } from '../codegen/interface-generator';\nimport { resolveSchema } from '../xsd/resolve';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface InterfacesOptions {\n /** Output file name pattern. Use {name} for schema name, {source} for source name */\n filePattern?: string;\n /** Add file header comment */\n header?: boolean;\n /**\n * If true, generates a single flattened type with all nested types inlined.\n * If false (default), generates interfaces with imports and extends.\n */\n flatten?: boolean;\n /** Custom root type name pattern. Use {name} for schema name (default: '{Name}Schema') */\n rootTypePattern?: string;\n /** Add JSDoc comments to generated types */\n addJsDoc?: boolean;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Extract base name from schema name (handles paths like 'sap/atom' -> 'atom')\n */\nfunction getBaseName(schemaName: string): string {\n const parts = schemaName.split('/');\n return parts.at(-1) ?? schemaName;\n}\n\nfunction deriveRootTypeName(schemaName: string, pattern: string): string {\n const baseName = getBaseName(schemaName);\n const capitalized = baseName.charAt(0).toUpperCase() + baseName.slice(1);\n return pattern.replace('{name}', baseName).replace('{Name}', capitalized);\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create an interfaces generator plugin\n *\n * @example\n * ```ts\n * import { interfaces } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * interfaces(), // interfaces with imports\n * interfaces({ flatten: true }), // fully flattened types\n * ],\n * });\n * ```\n */\nexport function interfaces(options: InterfacesOptions = {}): GeneratorPlugin {\n const {\n filePattern = options.flatten ? '{name}.flattened.ts' : '{name}.types.ts',\n header = true,\n flatten = false,\n rootTypePattern = '{Name}Schema',\n addJsDoc = true,\n } = options;\n\n return {\n name: 'interfaces',\n\n transform(ctx: TransformContext): GeneratedFile[] {\n const { schema, source } = ctx;\n\n const rootTypeName = deriveRootTypeName(schema.name, rootTypePattern);\n\n // Always resolve the schema to merge all imports into one flat schema\n // This ensures all types are available in a single source file\n // keepImportsRef preserves $imports so element refs from imported schemas can be resolved\n const targetSchema = resolveSchema(schema.schema, {\n keepImportsRef: true,\n });\n\n // Check if resolved schema has root elements (check AFTER resolution for imported elements)\n const hasRootElements =\n targetSchema.element && targetSchema.element.length > 0;\n\n // When flatten=true, skip dependency schemas (no root elements)\n // Their types are already inlined into the schemas that use them\n if (flatten && !hasRootElements) {\n return []; // Skip - no file generated\n }\n\n // Generate interfaces\n // When flatten=false, disable root type generation (just interfaces)\n // When flatten=true, generate root type for the primary element\n const { code } = generateInterfacesFromSchema(targetSchema, {\n rootTypeName: flatten && hasRootElements ? rootTypeName : null,\n addJsDoc,\n flatten,\n });\n\n // Build output\n const lines: string[] = [];\n\n if (header) {\n lines.push(\n '/**',\n ' * Auto-generated TypeScript interfaces from XSD',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ` * Source: ${source.name}/${schema.name}.xsd`,\n flatten ? ' * Mode: Flattened' : ' * Mode: Interfaces',\n ' */',\n '',\n );\n }\n\n lines.push(code);\n\n const fileName = filePattern\n .replace('{name}', schema.name)\n .replace('{source}', source.name);\n\n return [\n {\n path: fileName,\n content: lines.join('\\n'),\n },\n ];\n },\n };\n}\n","/**\n * Index Barrel Generator\n *\n * Generates index.ts files that re-export all schemas in a source.\n *\n * Output: `export * from './schema1'; export * from './schema2'; ...`\n */\n\nimport type {\n GeneratorPlugin,\n FinalizeContext,\n GeneratedFile,\n} from '../codegen/types';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface IndexBarrelOptions {\n /** File name for the barrel (default: 'index.ts') */\n filename?: string;\n /** Use named re-exports instead of star exports */\n namedExports?: boolean;\n /** Export types from .typed.ts files if they exist */\n includeTypedExports?: boolean;\n /** Add file header comment */\n header?: boolean;\n /** Import extension to use: '.ts' for Node.js native, '' for bundlers (default: '' for bundler compatibility) */\n importExtension?: '.ts' | '';\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create an index barrel generator plugin\n *\n * This generator runs in finalize() after all schemas are processed.\n * It generates an index.ts that re-exports all schemas.\n *\n * @example\n * ```ts\n * import { rawSchema, indexBarrel } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * rawSchema(),\n * indexBarrel(), // Generates index.ts with all exports\n * ],\n * });\n * ```\n */\nexport function indexBarrel(options: IndexBarrelOptions = {}): GeneratorPlugin {\n const {\n filename = 'index.ts',\n importExtension = '', // Default to extensionless for bundler compatibility\n namedExports = false,\n includeTypedExports = false,\n header = true,\n } = options;\n\n return {\n name: 'index-barrel',\n\n finalize(ctx: FinalizeContext): GeneratedFile[] {\n const files: GeneratedFile[] = [];\n\n // Generate one index per source\n for (const [sourceName, schemas] of ctx.processedSchemas) {\n const source = ctx.sources[sourceName];\n if (!source) continue;\n\n const lines: string[] = [];\n\n // Header\n if (header) {\n lines.push(\n '/**',\n ` * Auto-generated index for ${sourceName} schemas`,\n ' * ',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ' */',\n '',\n );\n }\n\n // Sort schemas alphabetically for consistent output\n const sortedSchemas = [...schemas].sort((a, b) =>\n a.name.localeCompare(b.name),\n );\n\n // Generate exports\n for (const schema of sortedSchemas) {\n if (namedExports) {\n const exportName = toValidIdentifier(schema.name);\n lines.push(\n `export { default as ${exportName} } from './${schema.name}${importExtension}';`,\n );\n } else {\n lines.push(`export * from './${schema.name}${importExtension}';`);\n }\n\n // Also export from typed files if requested\n if (includeTypedExports) {\n const typeName = pascalCase(schema.name);\n lines.push(\n `export type { ${typeName} } from './${schema.name}.typed${importExtension}';`,\n );\n }\n }\n\n lines.push('');\n\n files.push({\n path: filename,\n content: lines.join('\\n'),\n });\n }\n\n return files;\n },\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\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\nfunction toValidIdentifier(name: string): string {\n // Convert hyphens to camelCase\n let result = name.replaceAll(/-([a-zA-Z])/g, (_, c) => c.toUpperCase());\n // Escape reserved words\n if (RESERVED_WORDS.has(result)) {\n result = `${result}_`;\n }\n return result;\n}\n\nfunction pascalCase(str: string): string {\n return str\n .replaceAll(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^./, (s) => s.toUpperCase());\n}\n","/**\n * Typed Schemas Generator\n *\n * Generates typed schema wrappers that combine raw schemas with pre-computed types.\n * This enables full type inference without runtime overhead.\n *\n * Output: A single index file that exports typed schemas ready for use.\n *\n * @example\n * ```ts\n * // Generated output\n * import { typed } from '../../speci';\n * import _atom from './schemas/sap/atom';\n * import type { LinkType } from './types/sap/atom.types';\n *\n * export const atom = typed<LinkType>(_atom);\n * ```\n */\n\nimport type {\n GeneratorPlugin,\n FinalizeContext,\n GeneratedFile,\n SchemaInfo,\n} from '../codegen/types';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface TypedSchemasOptions {\n /** Output file path relative to package root (default: 'src/schemas/generated/index.ts') */\n outputPath?: string;\n /** Path to ts-xsd module from output file (default: 'ts-xsd') */\n tsXsdPath?: string;\n /** Path prefix to schemas from output file (default: './schemas') */\n schemasPath?: string;\n /** Path prefix to types from output file (default: './types') */\n typesPath?: string;\n /** Add file header comment */\n header?: boolean;\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create a typed schemas generator plugin\n *\n * This generator runs in finalize() after all schemas are processed.\n * It generates a single index file that exports typed schema wrappers.\n *\n * @example\n * ```ts\n * import { rawSchema, interfaces, typedSchemas } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * rawSchema(),\n * interfaces(),\n * typedSchemas(), // Generates typed wrappers\n * ],\n * });\n * ```\n */\nexport function typedSchemas(\n options: TypedSchemasOptions = {},\n): GeneratorPlugin {\n const {\n outputPath = 'src/schemas/generated/index.ts',\n tsXsdPath = 'ts-xsd',\n schemasPath = './schemas',\n typesPath = './types',\n header = true,\n } = options;\n\n return {\n name: 'typed-schemas',\n\n finalize(ctx: FinalizeContext): GeneratedFile[] {\n const lines: string[] = [];\n\n // Header\n if (header) {\n lines.push(\n '/**',\n ' * Auto-generated typed schema exports',\n ' * ',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ' * ',\n ' * These schemas have pre-computed types for full type inference.',\n ' * Use these instead of raw schemas for type-safe parsing/building.',\n ' * ',\n ' * @example',\n \" * import { classes } from '@abapify/adt-schemas';\",\n ' * const data = classes.parse(xml); // data is fully typed!',\n ' */',\n '',\n );\n }\n\n // Import typedSchema helper and TypedSchema type\n lines.push(\n `import { typedSchema, type TypedSchema } from '${tsXsdPath}';`,\n );\n lines.push('');\n\n // Collect all schemas with their root types\n const schemaExports: Array<{\n name: string;\n sourceName: string;\n rootTypes: string[];\n }> = [];\n\n // Process each source\n for (const [sourceName, schemas] of ctx.processedSchemas) {\n lines.push(`// ${sourceName.toUpperCase()} schemas`);\n\n for (const schema of schemas) {\n const rootTypes = extractRootTypes(schema);\n\n if (rootTypes.length === 0) {\n // No root elements - skip or export raw\n lines.push(\n `// ${schema.name}: No root elements found, skipping typed export`,\n );\n continue;\n }\n\n schemaExports.push({\n name: schema.name,\n sourceName,\n rootTypes,\n });\n\n const exportName = toValidIdentifier(schema.name);\n const schemaImport = `${schemasPath}/${sourceName}/${schema.name}`;\n const typesImport = `${typesPath}/${sourceName}/${schema.name}.types`;\n\n // Import raw schema\n lines.push(`import _${exportName} from '${schemaImport}';`);\n\n // Import type(s)\n if (rootTypes.length === 1) {\n lines.push(\n `import type { ${rootTypes[0]} } from '${typesImport}';`,\n );\n } else {\n // Multiple root types - import all\n lines.push(\n `import type { ${rootTypes.join(', ')} } from '${typesImport}';`,\n );\n }\n }\n\n lines.push('');\n }\n\n // Generate typed exports\n lines.push(\n '// ============================================================================',\n );\n lines.push('// TYPED SCHEMA EXPORTS');\n lines.push(\n '// ============================================================================',\n );\n lines.push('');\n\n for (const { name, rootTypes } of schemaExports) {\n const exportName = toValidIdentifier(name);\n\n if (rootTypes.length === 1) {\n // Single root type - explicit type annotation for isolatedDeclarations\n lines.push(\n `export const ${exportName}: TypedSchema<${rootTypes[0]}> = typedSchema<${rootTypes[0]}>(_${exportName});`,\n );\n } else {\n // Multiple root types - use union with explicit type annotation\n const unionType = rootTypes.join(' | ');\n lines.push(\n `export const ${exportName}: TypedSchema<${unionType}> = typedSchema<${unionType}>(_${exportName});`,\n );\n }\n }\n\n lines.push('');\n\n // NOTE: Types are NOT re-exported here to avoid duplicate export conflicts.\n // Types are internal to each schema file and used for typed wrappers.\n // If you need a specific type, import it directly from the types file:\n // import type { AbapClass } from './types/sap/classes.types';\n lines.push(\n '// Types are internal - import directly from types/{source}/{schema}.types if needed',\n );\n lines.push('');\n\n return [\n {\n path: outputPath,\n content: lines.join('\\n'),\n },\n ];\n },\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Extract root element type names from a schema\n */\nfunction extractRootTypes(schema: SchemaInfo): string[] {\n const types: string[] = [];\n const elements = schema.schema.element;\n\n if (!elements || elements.length === 0) {\n return types;\n }\n\n for (const element of elements) {\n if (element.type) {\n // Type reference like \"ns:TypeName\" or \"TypeName\"\n const typeName = stripNamespacePrefix(element.type);\n types.push(toPascalCase(typeName));\n } else if (element.name) {\n // Anonymous type - use element name as type\n types.push(toPascalCase(element.name));\n }\n }\n\n return types;\n}\n\n/**\n * Strip namespace prefix from QName (e.g., \"ns:TypeName\" -> \"TypeName\")\n */\nfunction stripNamespacePrefix(qname: string): string {\n const colonIndex = qname.indexOf(':');\n return colonIndex >= 0 ? qname.slice(colonIndex + 1) : qname;\n}\n\n/**\n * Convert to PascalCase\n */\nfunction toPascalCase(str: string): string {\n return str\n .replaceAll(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^./, (s) => s.toUpperCase());\n}\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\nfunction toValidIdentifier(name: string): string {\n // Convert hyphens to camelCase\n let result = name.replaceAll(/-([a-zA-Z])/g, (_, c) => c.toUpperCase());\n // Escape reserved words\n if (RESERVED_WORDS.has(result)) {\n result = `${result}_`;\n }\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["RESERVED_WORDS","pascalCase","generateInterfacesFromSchema","toValidIdentifier","RESERVED_WORDS"],"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"],"sourcesContent":["/**\n * Raw Schema Generator\n *\n * Generates raw schema literals with `as const` for type inference.\n *\n * Output: `export default { ... } as const;`\n */\n\nimport type {\n GeneratorPlugin,\n TransformContext,\n GeneratedFile,\n} from '../codegen/types';\nimport { resolveSchema, type ResolveOptions } from '../xsd/resolve';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface RawSchemaOptions {\n /** Use default export (default: true) */\n defaultExport?: boolean;\n /** Use named export with this name (alternative to default export) */\n namedExport?: string;\n /** Include $xmlns in output (default: true) */\n $xmlns?: boolean;\n /** Include $imports in output for xs:import (default: true) */\n $imports?: boolean;\n /** Include $includes in output for xs:include (default: true) */\n $includes?: boolean;\n /** Include $filename in output (default: false) */\n $filename?: boolean;\n /** Properties to exclude from output */\n exclude?: string[];\n /** Add file header comment */\n header?: boolean;\n /**\n * Resolve schema - merge imports, expand extensions and substitution groups.\n * When enabled, produces a self-contained schema with no $imports dependencies.\n * Can be boolean (true = all options) or ResolveOptions for fine control.\n */\n resolve?: boolean | ResolveOptions;\n /**\n * Resolve includes - merge included schema content directly into the main schema.\n * When enabled, xs:include content is merged recursively and no $includes or include\n * properties appear in the output. The schema becomes self-contained.\n */\n resolveIncludes?: boolean;\n /**\n * Resolve ALL dependencies - merge both $includes AND $imports into a single schema.\n * Creates a fully self-contained schema with all elements and types from the entire\n * dependency tree. Useful for generating a schema that can parse the complete XML\n * document structure (e.g., abapGit root element + asx:abap + values).\n *\n * When enabled, no $includes, $imports, include, or import properties appear in output.\n */\n resolveAll?: boolean;\n /**\n * Generate isolatedDeclarations-compatible output.\n * Uses `satisfies Schema as const` instead of just `as const`.\n * Also adds `import type { Schema } from '@abapify/ts-xsd';`\n */\n isolatedDeclarations?: boolean;\n /** Use single quotes for string literals and property names */\n singleQuote?: boolean;\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create a raw schema generator plugin\n *\n * @example\n * ```ts\n * import { rawSchema } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * rawSchema(), // default export\n * rawSchema({ namedExport: 'mySchema' }), // named export\n * ],\n * });\n * ```\n */\nexport function rawSchema(options: RawSchemaOptions = {}): GeneratorPlugin {\n const {\n defaultExport = true,\n namedExport,\n $xmlns = true,\n $imports = true,\n $includes = true,\n $filename = false,\n exclude = ['annotation'],\n header = true,\n resolveIncludes = false,\n resolveAll = false,\n isolatedDeclarations = false,\n singleQuote = false,\n } = options;\n\n return {\n name: 'raw-schema',\n\n transform(ctx: TransformContext): GeneratedFile[] {\n const { schema, source } = ctx;\n\n // Schema is already linked by runner.ts\n // Apply schema resolution if enabled\n const schemaToProcess = resolveSchemaToProcess(\n schema.schema,\n options.resolve,\n resolveIncludes,\n resolveAll,\n );\n\n // When resolving all, disable both $includes and $imports in output\n const disableRefs = resolveAll || resolveIncludes;\n const outputSchema = buildOutputSchema(schemaToProcess, {\n $xmlns,\n $imports: resolveAll ? false : $imports,\n $includes: disableRefs ? false : $includes,\n $filename,\n exclude,\n schemaName: schema.name,\n resolveImport: ctx.resolveImport,\n });\n\n const lines: string[] = [];\n\n // Header\n if (header) {\n lines.push(\n '/**',\n ' * Auto-generated schema from XSD',\n ' * ',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ` * Source: ${source.name}/${schema.name}.xsd`,\n ' */',\n '',\n );\n }\n\n // Add Schema type import for isolatedDeclarations mode\n if (isolatedDeclarations) {\n lines.push(\"import type { Schema } from '@abapify/ts-xsd';\");\n }\n\n // Imports for $imports/$includes (skip if resolve/resolveIncludes/resolveAll is enabled - schema is self-contained)\n // Also skip if both $imports and $includes are disabled\n const shouldGenerateImports =\n !options.resolve &&\n !resolveIncludes &&\n !resolveAll &&\n ($imports || $includes);\n if (shouldGenerateImports) {\n const imports = getSchemaImports(schema.schema, ctx.resolveImport, {\n $imports,\n $includes,\n });\n appendImportLines(lines, imports, isolatedDeclarations);\n }\n\n // Add blank line after imports if any were added\n if (\n isolatedDeclarations ||\n (shouldGenerateImports &&\n getSchemaImports(schema.schema, ctx.resolveImport, {\n $imports,\n $includes,\n }).length > 0)\n ) {\n lines.push('');\n }\n\n // Schema literal\n const literal = objectToLiteral(outputSchema, true, ' ', 0, singleQuote);\n\n appendExportLines(\n lines,\n literal,\n isolatedDeclarations,\n namedExport,\n defaultExport,\n );\n\n lines.push('');\n\n return [\n {\n path: `${schema.name}.ts`,\n content: lines.join('\\n'),\n },\n ];\n },\n };\n}\n\n/**\n * Apply schema resolution according to the resolve/resolveAll/resolveIncludes options.\n */\nfunction resolveSchemaToProcess(\n schema: Parameters<typeof resolveSchema>[0],\n resolveOption: boolean | ResolveOptions | undefined,\n resolveIncludes: boolean,\n resolveAll: boolean,\n): Record<string, unknown> {\n let schemaToProcess = schema as Record<string, unknown>;\n\n if (resolveOption) {\n const resolveOpts: ResolveOptions =\n resolveOption === true ? {} : resolveOption;\n schemaToProcess = resolveSchema(schema, resolveOpts) as Record<\n string,\n unknown\n >;\n }\n\n // Resolve ALL - merge both $includes AND $imports into a single schema\n // This creates a fully self-contained schema with all elements and types\n if (resolveAll) {\n schemaToProcess = resolveSchema(schema, {\n filterToRootElements: true,\n }) as Record<string, unknown>;\n }\n // Resolve includes only - merge included schema content recursively\n else if (resolveIncludes) {\n schemaToProcess = resolveSchema(schema, {\n resolveImports: false,\n keepImportsRef: true,\n }) as Record<string, unknown>;\n }\n\n return schemaToProcess;\n}\n\n/** Append one import statement per schema import. */\nfunction appendImportLines(\n lines: string[],\n imports: Array<{ name: string; path: string }>,\n isolatedDeclarations: boolean,\n): void {\n for (const imp of imports) {\n // For isolatedDeclarations, import the named 'schema' export and alias it\n // This is required because default exports can't be inferred with --isolatedDeclarations\n if (isolatedDeclarations) {\n lines.push(`import { schema as ${imp.name} } from '${imp.path}';`);\n } else {\n lines.push(`import ${imp.name} from '${imp.path}';`);\n }\n }\n}\n\n/** Append the export statement(s) for the schema literal. */\nfunction appendExportLines(\n lines: string[],\n literal: string,\n isolatedDeclarations: boolean,\n namedExport: string | undefined,\n defaultExport: boolean,\n): void {\n // For isolatedDeclarations, use named export with `as const satisfies Schema`\n // This is required because default exports can't be inferred with --isolatedDeclarations\n if (isolatedDeclarations) {\n const exportName = namedExport ?? 'schema';\n lines.push(\n `export const ${exportName} = ${literal} as const satisfies Schema;`,\n );\n // Also add default export pointing to the named export\n if (defaultExport && !namedExport) {\n lines.push(`export default ${exportName};`);\n }\n return;\n }\n\n if (namedExport) {\n lines.push(`export const ${namedExport} = ${literal} as const;`);\n return;\n }\n\n if (defaultExport) {\n lines.push(`export default ${literal} as const;`);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\ninterface BuildOptions {\n $xmlns: boolean;\n $imports: boolean;\n $includes: boolean;\n $filename: boolean;\n exclude: string[];\n schemaName: string;\n resolveImport: (schemaLocation: string) => string | null;\n}\n\nfunction buildOutputSchema(\n schema: Record<string, unknown>,\n options: BuildOptions,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const excludeSet = new Set(options.exclude);\n\n // Add $xmlns first if enabled\n if (options.$xmlns && schema.$xmlns) {\n result.$xmlns = schema.$xmlns;\n }\n\n // Add $imports if enabled (from xs:import - different namespace)\n if (options.$imports && schema.import) {\n const importRefs = buildSchemaRefs(\n schema.import as Array<{ schemaLocation?: string }>,\n 'xs:import',\n options,\n );\n if (importRefs.length > 0) {\n result.$imports = importRefs;\n }\n }\n\n // Add $includes if enabled (from xs:include - same namespace)\n if (options.$includes && schema.include) {\n const includeRefs = buildSchemaRefs(\n schema.include as Array<{ schemaLocation?: string }>,\n 'xs:include',\n options,\n );\n if (includeRefs.length > 0) {\n result.$includes = includeRefs;\n }\n }\n\n // Add $filename if enabled\n if (options.$filename) {\n result.$filename = `${options.schemaName}.xsd`;\n }\n\n // Copy remaining properties (excluding handled ones)\n copyRemainingProperties(schema, result, options, excludeSet);\n\n return result;\n}\n\n/**\n * Build $imports/$includes refs from xs:import/xs:include schemaLocation\n * entries. Unresolvable locations throw.\n */\nfunction buildSchemaRefs(\n refs: ReadonlyArray<{ schemaLocation?: string }>,\n kind: 'xs:import' | 'xs:include',\n options: BuildOptions,\n): SchemaRef[] {\n const schemaRefs: SchemaRef[] = [];\n for (const ref of refs) {\n if (ref.schemaLocation) {\n const resolved = options.resolveImport(ref.schemaLocation);\n if (!resolved) {\n throw new Error(\n `Cannot resolve ${kind} schemaLocation: ${ref.schemaLocation} (in ${options.schemaName}.xsd)`,\n );\n }\n // Use base name for valid JS identifier\n const name = ref.schemaLocation\n .replace(/\\.xsd$/, '')\n .replace(/^.*\\//, '');\n schemaRefs.push(new SchemaRef(name));\n }\n }\n return schemaRefs;\n}\n\n/**\n * Copy schema properties that are not handled elsewhere,\n * deep-filtering excluded keys.\n */\nfunction copyRemainingProperties(\n schema: Record<string, unknown>,\n result: Record<string, unknown>,\n options: BuildOptions,\n excludeSet: Set<string>,\n): void {\n for (const [key, value] of Object.entries(schema)) {\n if (shouldSkipProperty(key, options)) continue;\n if (!excludeSet.has(key)) {\n result[key] = filterDeep(value, excludeSet);\n }\n }\n}\n\n/** Whether a schema property is handled elsewhere and must not be copied. */\nfunction shouldSkipProperty(key: string, options: BuildOptions): boolean {\n // Skip extension properties\n if (\n key === '$xmlns' ||\n key === '$imports' ||\n key === '$includes' ||\n key === '$filename'\n ) {\n return true;\n }\n // Skip 'import' if $imports is enabled (we output $imports instead)\n if (key === 'import' && options.$imports) {\n return true;\n }\n // Skip 'include' if $includes is enabled (we output $includes instead)\n return key === 'include' && options.$includes;\n}\n\nconst DEFAULT_SCHEMA_IMPORT_OPTIONS: {\n $imports?: boolean;\n $includes?: boolean;\n} = {\n $imports: true,\n $includes: true,\n};\n\nfunction getSchemaImports(\n schema: Record<string, unknown>,\n resolveImport: (schemaLocation: string) => string | null,\n options: {\n $imports?: boolean;\n $includes?: boolean;\n } = DEFAULT_SCHEMA_IMPORT_OPTIONS,\n): Array<{ name: string; path: string }> {\n const imports: Array<{ name: string; path: string }> = [];\n\n // Handle xs:import (only if $imports is enabled)\n if (options.$imports) {\n imports.push(\n ...collectSchemaImports(\n schema.import as Array<{ schemaLocation?: string }> | undefined,\n resolveImport,\n ),\n );\n }\n\n // Handle xs:include (only if $includes is enabled)\n if (options.$includes) {\n imports.push(\n ...collectSchemaImports(\n schema.include as Array<{ schemaLocation?: string }> | undefined,\n resolveImport,\n ),\n );\n }\n\n return imports;\n}\n\n/**\n * Resolve module imports from schemaLocation entries;\n * unresolvable entries are skipped.\n */\nfunction collectSchemaImports(\n refs: ReadonlyArray<{ schemaLocation?: string }> | undefined,\n resolveImport: (schemaLocation: string) => string | null,\n): Array<{ name: string; path: string }> {\n const imports: Array<{ name: string; path: string }> = [];\n for (const ref of refs ?? []) {\n if (ref.schemaLocation) {\n const modulePath = resolveImport(ref.schemaLocation);\n if (modulePath) {\n // Use base name for valid JS identifier\n const name = ref.schemaLocation\n .replace(/\\.xsd$/, '')\n .replace(/^.*\\//, '');\n imports.push({ name, path: modulePath });\n }\n }\n }\n return imports;\n}\n\n/** Marker class for schema references in $imports */\nclass SchemaRef {\n constructor(public readonly name: string) {}\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(String.raw`\\\"`, '\"')\n .replaceAll(\"'\", String.raw`\\'`);\n return `'${inner}'`;\n}\n\nfunction filterDeep(value: unknown, exclude: Set<string>): unknown {\n if (value instanceof SchemaRef) {\n return value;\n }\n\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\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 if (value instanceof SchemaRef) {\n return value.name;\n }\n\n if (typeof value === 'string') {\n const json = JSON.stringify(value);\n return singleQuote ? toSingleQuoteLiteral(json) : json;\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n return arrayToLiteral(value, pretty, indent, depth, singleQuote);\n }\n\n if (typeof value === 'object') {\n return recordToLiteral(\n value as Record<string, unknown>,\n pretty,\n indent,\n depth,\n singleQuote,\n );\n }\n\n return 'undefined';\n}\n\n/** Render an array literal. */\nfunction arrayToLiteral(\n value: unknown[],\n pretty: boolean,\n indent: string,\n depth: number,\n singleQuote: boolean,\n): string {\n if (value.length === 0) return '[]';\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/** Render an object literal from record entries. */\nfunction recordToLiteral(\n obj: Record<string, unknown>,\n pretty: boolean,\n indent: string,\n depth: number,\n singleQuote: boolean,\n): string {\n const entries = Object.entries(obj).filter(([, v]) => v !== undefined);\n\n if (entries.length === 0) return '{}';\n\n const props = entries.map(([key, val]) =>\n propertyToLiteral(key, val, pretty, indent, depth, singleQuote),\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/** Render one `key: value` object property. */\nfunction propertyToLiteral(\n key: string,\n val: unknown,\n pretty: boolean,\n indent: string,\n depth: number,\n singleQuote: boolean,\n): string {\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(val, pretty, indent, depth + 1, singleQuote);\n return `${keyStr}: ${valStr}`;\n}\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\nfunction isValidIdentifier(str: string): boolean {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str) && !RESERVED_WORDS.has(str);\n}\n","/**\n * Inferred Types Generator\n *\n * Generates TypeScript types using InferSchema<typeof schema>.\n * Appends type export to the schema file generated by rawSchema().\n *\n * Output: `export type Intf = InferSchema<typeof schema>;`\n */\n\nimport type {\n GeneratorPlugin,\n TransformContext,\n GeneratedFile,\n} from '../codegen/types';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface InferredTypesOptions {\n /** Import path for InferSchema (default: 'ts-xsd') */\n inferSchemaImport?: string;\n /** Type name pattern. Use {Name} for PascalCase schema name (default: '{Name}') */\n typeNamePattern?: string;\n /** Schema variable name to infer from (default: 'schema' for default export) */\n schemaVariable?: string;\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create an inferred types generator plugin\n *\n * This generator should be used AFTER rawSchema() in the pipeline.\n * It modifies the generated schema file to add type exports.\n *\n * @example\n * ```ts\n * import { rawSchema, inferredTypes } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * rawSchema(),\n * inferredTypes(), // Adds: export type Intf = InferSchema<typeof schema>;\n * ],\n * });\n * ```\n */\nexport function inferredTypes(\n options: InferredTypesOptions = {},\n): GeneratorPlugin {\n const { inferSchemaImport = 'ts-xsd', typeNamePattern = '{Name}' } = options;\n\n return {\n name: 'inferred-types',\n\n transform(ctx: TransformContext): GeneratedFile[] {\n const { schema } = ctx;\n const typeName = typeNamePattern.replace(\n '{Name}',\n pascalCase(schema.name),\n );\n\n // Store for later - we'll modify the file in finalize\n // For now, generate a separate types file that re-exports\n const lines: string[] = [\n '/**',\n ' * Auto-generated type from schema',\n ' * ',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ' */',\n '',\n `import type { InferSchema } from '${inferSchemaImport}';`,\n `import schema from './${schema.name}';`,\n '',\n `/** Inferred type for ${schema.name} schema */`,\n `export type ${typeName} = InferSchema<typeof schema>;`,\n '',\n `export default schema;`,\n '',\n ];\n\n // Generate a typed wrapper file instead of modifying the raw schema\n return [\n {\n path: `${schema.name}.typed.ts`,\n content: lines.join('\\n'),\n },\n ];\n },\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction pascalCase(str: string): string {\n return str\n .replaceAll(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^./, (s) => s.toUpperCase());\n}\n","/**\n * Interfaces Generator\n *\n * Generates TypeScript interfaces from XSD schemas.\n * Uses ts-morph for TypeScript code generation.\n *\n * Two modes:\n * 1. flatten: false (default) - Generates interfaces with imports and extends\n * 2. flatten: true - Generates a single flattened type with all nested types inlined\n */\n\nimport type {\n GeneratorPlugin,\n TransformContext,\n GeneratedFile,\n} from '../codegen/types';\nimport { generateInterfaces as generateInterfacesFromSchema } from '../codegen/interface-generator';\nimport { resolveSchema } from '../xsd/resolve';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface InterfacesOptions {\n /** Output file name pattern. Use {name} for schema name, {source} for source name */\n filePattern?: string;\n /** Add file header comment */\n header?: boolean;\n /**\n * If true, generates a single flattened type with all nested types inlined.\n * If false (default), generates interfaces with imports and extends.\n */\n flatten?: boolean;\n /** Custom root type name pattern. Use {name} for schema name (default: '{Name}Schema') */\n rootTypePattern?: string;\n /** Add JSDoc comments to generated types */\n addJsDoc?: boolean;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Extract base name from schema name (handles paths like 'sap/atom' -> 'atom')\n */\nfunction getBaseName(schemaName: string): string {\n const parts = schemaName.split('/');\n return parts.at(-1) ?? schemaName;\n}\n\nfunction deriveRootTypeName(schemaName: string, pattern: string): string {\n const baseName = getBaseName(schemaName);\n const capitalized = baseName.charAt(0).toUpperCase() + baseName.slice(1);\n return pattern.replace('{name}', baseName).replace('{Name}', capitalized);\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create an interfaces generator plugin\n *\n * @example\n * ```ts\n * import { interfaces } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * interfaces(), // interfaces with imports\n * interfaces({ flatten: true }), // fully flattened types\n * ],\n * });\n * ```\n */\nexport function interfaces(options: InterfacesOptions = {}): GeneratorPlugin {\n const {\n filePattern = options.flatten ? '{name}.flattened.ts' : '{name}.types.ts',\n header = true,\n flatten = false,\n rootTypePattern = '{Name}Schema',\n addJsDoc = true,\n } = options;\n\n return {\n name: 'interfaces',\n\n transform(ctx: TransformContext): GeneratedFile[] {\n const { schema, source } = ctx;\n\n const rootTypeName = deriveRootTypeName(schema.name, rootTypePattern);\n\n // Always resolve the schema to merge all imports into one flat schema\n // This ensures all types are available in a single source file\n // keepImportsRef preserves $imports so element refs from imported schemas can be resolved\n const targetSchema = resolveSchema(schema.schema, {\n keepImportsRef: true,\n });\n\n // Check if resolved schema has root elements (check AFTER resolution for imported elements)\n const hasRootElements =\n targetSchema.element && targetSchema.element.length > 0;\n\n // When flatten=true, skip dependency schemas (no root elements)\n // Their types are already inlined into the schemas that use them\n if (flatten && !hasRootElements) {\n return []; // Skip - no file generated\n }\n\n // Generate interfaces\n // When flatten=false, disable root type generation (just interfaces)\n // When flatten=true, generate root type for the primary element\n const { code } = generateInterfacesFromSchema(targetSchema, {\n rootTypeName: flatten && hasRootElements ? rootTypeName : null,\n addJsDoc,\n flatten,\n });\n\n // Build output\n const lines: string[] = [];\n\n if (header) {\n lines.push(\n '/**',\n ' * Auto-generated TypeScript interfaces from XSD',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ` * Source: ${source.name}/${schema.name}.xsd`,\n flatten ? ' * Mode: Flattened' : ' * Mode: Interfaces',\n ' */',\n '',\n );\n }\n\n lines.push(code);\n\n const fileName = filePattern\n .replace('{name}', schema.name)\n .replace('{source}', source.name);\n\n return [\n {\n path: fileName,\n content: lines.join('\\n'),\n },\n ];\n },\n };\n}\n","/**\n * Index Barrel Generator\n *\n * Generates index.ts files that re-export all schemas in a source.\n *\n * Output: `export * from './schema1'; export * from './schema2'; ...`\n */\n\nimport type {\n GeneratorPlugin,\n FinalizeContext,\n GeneratedFile,\n} from '../codegen/types';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface IndexBarrelOptions {\n /** File name for the barrel (default: 'index.ts') */\n filename?: string;\n /** Use named re-exports instead of star exports */\n namedExports?: boolean;\n /** Export types from .typed.ts files if they exist */\n includeTypedExports?: boolean;\n /** Add file header comment */\n header?: boolean;\n /** Import extension to use: '.ts' for Node.js native, '' for bundlers (default: '' for bundler compatibility) */\n importExtension?: '.ts' | '';\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create an index barrel generator plugin\n *\n * This generator runs in finalize() after all schemas are processed.\n * It generates an index.ts that re-exports all schemas.\n *\n * @example\n * ```ts\n * import { rawSchema, indexBarrel } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * rawSchema(),\n * indexBarrel(), // Generates index.ts with all exports\n * ],\n * });\n * ```\n */\nexport function indexBarrel(options: IndexBarrelOptions = {}): GeneratorPlugin {\n const {\n filename = 'index.ts',\n importExtension = '', // Default to extensionless for bundler compatibility\n namedExports = false,\n includeTypedExports = false,\n header = true,\n } = options;\n\n return {\n name: 'index-barrel',\n\n finalize(ctx: FinalizeContext): GeneratedFile[] {\n const files: GeneratedFile[] = [];\n\n // Generate one index per source\n for (const [sourceName, schemas] of ctx.processedSchemas) {\n const source = ctx.sources[sourceName];\n if (!source) continue;\n\n const lines: string[] = [];\n\n // Header\n if (header) {\n lines.push(\n '/**',\n ` * Auto-generated index for ${sourceName} schemas`,\n ' * ',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ' */',\n '',\n );\n }\n\n // Sort schemas alphabetically for consistent output\n const sortedSchemas = [...schemas].sort((a, b) =>\n a.name.localeCompare(b.name),\n );\n\n // Generate exports\n for (const schema of sortedSchemas) {\n if (namedExports) {\n const exportName = toValidIdentifier(schema.name);\n lines.push(\n `export { default as ${exportName} } from './${schema.name}${importExtension}';`,\n );\n } else {\n lines.push(`export * from './${schema.name}${importExtension}';`);\n }\n\n // Also export from typed files if requested\n if (includeTypedExports) {\n const typeName = pascalCase(schema.name);\n lines.push(\n `export type { ${typeName} } from './${schema.name}.typed${importExtension}';`,\n );\n }\n }\n\n lines.push('');\n\n files.push({\n path: filename,\n content: lines.join('\\n'),\n });\n }\n\n return files;\n },\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\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\nfunction toValidIdentifier(name: string): string {\n // Convert hyphens to camelCase\n let result = name.replaceAll(/-([a-zA-Z])/g, (_, c) => c.toUpperCase());\n // Escape reserved words\n if (RESERVED_WORDS.has(result)) {\n result = `${result}_`;\n }\n return result;\n}\n\nfunction pascalCase(str: string): string {\n return str\n .replaceAll(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^./, (s) => s.toUpperCase());\n}\n","/**\n * Typed Schemas Generator\n *\n * Generates typed schema wrappers that combine raw schemas with pre-computed types.\n * This enables full type inference without runtime overhead.\n *\n * Output: A single index file that exports typed schemas ready for use.\n *\n * @example\n * ```ts\n * // Generated output\n * import { typed } from '../../speci';\n * import _atom from './schemas/sap/atom';\n * import type { LinkType } from './types/sap/atom.types';\n *\n * export const atom = typed<LinkType>(_atom);\n * ```\n */\n\nimport type {\n GeneratorPlugin,\n FinalizeContext,\n GeneratedFile,\n SchemaInfo,\n} from '../codegen/types';\n\n// ============================================================================\n// Options\n// ============================================================================\n\nexport interface TypedSchemasOptions {\n /** Output file path relative to package root (default: 'src/schemas/generated/index.ts') */\n outputPath?: string;\n /** Path to ts-xsd module from output file (default: 'ts-xsd') */\n tsXsdPath?: string;\n /** Path prefix to schemas from output file (default: './schemas') */\n schemasPath?: string;\n /** Path prefix to types from output file (default: './types') */\n typesPath?: string;\n /** Add file header comment */\n header?: boolean;\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\n/**\n * Create a typed schemas generator plugin\n *\n * This generator runs in finalize() after all schemas are processed.\n * It generates a single index file that exports typed schema wrappers.\n *\n * @example\n * ```ts\n * import { rawSchema, interfaces, typedSchemas } from '@abapify/ts-xsd/generators';\n *\n * export default defineConfig({\n * generators: [\n * rawSchema(),\n * interfaces(),\n * typedSchemas(), // Generates typed wrappers\n * ],\n * });\n * ```\n */\nexport function typedSchemas(\n options: TypedSchemasOptions = {},\n): GeneratorPlugin {\n const {\n outputPath = 'src/schemas/generated/index.ts',\n tsXsdPath = 'ts-xsd',\n schemasPath = './schemas',\n typesPath = './types',\n header = true,\n } = options;\n\n return {\n name: 'typed-schemas',\n\n finalize(ctx: FinalizeContext): GeneratedFile[] {\n const lines: string[] = [];\n\n // Header\n if (header) {\n lines.push(\n '/**',\n ' * Auto-generated typed schema exports',\n ' * ',\n ' * DO NOT EDIT - Generated by ts-xsd codegen',\n ' * ',\n ' * These schemas have pre-computed types for full type inference.',\n ' * Use these instead of raw schemas for type-safe parsing/building.',\n ' * ',\n ' * @example',\n \" * import { classes } from '@abapify/adt-schemas';\",\n ' * const data = classes.parse(xml); // data is fully typed!',\n ' */',\n '',\n );\n }\n\n // Import typedSchema helper and TypedSchema type\n lines.push(\n `import { typedSchema, type TypedSchema } from '${tsXsdPath}';`,\n '',\n );\n\n // Collect all schemas with their root types\n const schemaExports: Array<{\n name: string;\n sourceName: string;\n rootTypes: string[];\n }> = [];\n\n // Process each source\n for (const [sourceName, schemas] of ctx.processedSchemas) {\n lines.push(`// ${sourceName.toUpperCase()} schemas`);\n\n for (const schema of schemas) {\n const rootTypes = extractRootTypes(schema);\n\n if (rootTypes.length === 0) {\n // No root elements - skip or export raw\n lines.push(\n `// ${schema.name}: No root elements found, skipping typed export`,\n );\n continue;\n }\n\n schemaExports.push({\n name: schema.name,\n sourceName,\n rootTypes,\n });\n\n const exportName = toValidIdentifier(schema.name);\n const schemaImport = `${schemasPath}/${sourceName}/${schema.name}`;\n const typesImport = `${typesPath}/${sourceName}/${schema.name}.types`;\n\n // Import raw schema\n lines.push(`import _${exportName} from '${schemaImport}';`);\n\n // Import type(s)\n if (rootTypes.length === 1) {\n lines.push(\n `import type { ${rootTypes[0]} } from '${typesImport}';`,\n );\n } else {\n // Multiple root types - import all\n lines.push(\n `import type { ${rootTypes.join(', ')} } from '${typesImport}';`,\n );\n }\n }\n\n lines.push('');\n }\n\n // Generate typed exports\n lines.push(\n '// ============================================================================',\n '// TYPED SCHEMA EXPORTS',\n '// ============================================================================',\n '',\n );\n\n for (const { name, rootTypes } of schemaExports) {\n const exportName = toValidIdentifier(name);\n\n if (rootTypes.length === 1) {\n // Single root type - explicit type annotation for isolatedDeclarations\n lines.push(\n `export const ${exportName}: TypedSchema<${rootTypes[0]}> = typedSchema<${rootTypes[0]}>(_${exportName});`,\n );\n } else {\n // Multiple root types - use union with explicit type annotation\n const unionType = rootTypes.join(' | ');\n lines.push(\n `export const ${exportName}: TypedSchema<${unionType}> = typedSchema<${unionType}>(_${exportName});`,\n );\n }\n }\n\n // NOTE: Types are NOT re-exported here to avoid duplicate export conflicts.\n // Types are internal to each schema file and used for typed wrappers.\n // If you need a specific type, import it directly from the types file:\n // import type { AbapClass } from './types/sap/classes.types';\n lines.push(\n '',\n '// Types are internal - import directly from types/{source}/{schema}.types if needed',\n '',\n );\n\n return [\n {\n path: outputPath,\n content: lines.join('\\n'),\n },\n ];\n },\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Extract root element type names from a schema\n */\nfunction extractRootTypes(schema: SchemaInfo): string[] {\n const types: string[] = [];\n const elements = schema.schema.element;\n\n if (!elements || elements.length === 0) {\n return types;\n }\n\n for (const element of elements) {\n if (element.type) {\n // Type reference like \"ns:TypeName\" or \"TypeName\"\n const typeName = stripNamespacePrefix(element.type);\n types.push(toPascalCase(typeName));\n } else if (element.name) {\n // Anonymous type - use element name as type\n types.push(toPascalCase(element.name));\n }\n }\n\n return types;\n}\n\n/**\n * Strip namespace prefix from QName (e.g., \"ns:TypeName\" -> \"TypeName\")\n */\nfunction stripNamespacePrefix(qname: string): string {\n const colonIndex = qname.indexOf(':');\n return colonIndex >= 0 ? qname.slice(colonIndex + 1) : qname;\n}\n\n/**\n * Convert to PascalCase\n */\nfunction toPascalCase(str: string): string {\n return str\n .replaceAll(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^./, (s) => s.toUpperCase());\n}\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\nfunction toValidIdentifier(name: string): string {\n // Convert hyphens to camelCase\n let result = name.replaceAll(/-([a-zA-Z])/g, (_, c) => c.toUpperCase());\n // Escape reserved words\n if (RESERVED_WORDS.has(result)) {\n result = `${result}_`;\n }\n return result;\n}\n"],"mappings":"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"}
|