@famgia/omnify-typescript 0.0.1 → 0.0.2
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/dist/chunk-J46F3EBS.js +638 -0
- package/dist/chunk-J46F3EBS.js.map +1 -0
- package/dist/index.cjs +315 -155
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -36
- package/dist/index.d.ts +43 -36
- package/dist/index.js +2 -7
- package/dist/plugin.cjs +324 -186
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +10 -20
- package/dist/plugin.d.ts +10 -20
- package/dist/plugin.js +11 -40
- package/dist/plugin.js.map +1 -1
- package/package.json +6 -4
- package/scripts/postinstall.js +274 -0
- package/dist/chunk-2BXDNKIN.js +0 -477
- package/dist/chunk-2BXDNKIN.js.map +0 -1
|
@@ -0,0 +1,638 @@
|
|
|
1
|
+
// src/interface-generator.ts
|
|
2
|
+
import { resolveLocalizedString } from "@famgia/omnify-types";
|
|
3
|
+
var TYPE_MAP = {
|
|
4
|
+
String: "string",
|
|
5
|
+
Int: "number",
|
|
6
|
+
BigInt: "number",
|
|
7
|
+
Float: "number",
|
|
8
|
+
Boolean: "boolean",
|
|
9
|
+
Text: "string",
|
|
10
|
+
LongText: "string",
|
|
11
|
+
Date: "string",
|
|
12
|
+
Time: "string",
|
|
13
|
+
Timestamp: "string",
|
|
14
|
+
Json: "unknown",
|
|
15
|
+
Email: "string",
|
|
16
|
+
Password: "string",
|
|
17
|
+
Enum: "string",
|
|
18
|
+
Select: "string",
|
|
19
|
+
Lookup: "number"
|
|
20
|
+
};
|
|
21
|
+
var FILE_INTERFACE_NAME = "File";
|
|
22
|
+
var PK_TYPE_MAP = {
|
|
23
|
+
Int: "number",
|
|
24
|
+
BigInt: "number",
|
|
25
|
+
Uuid: "string",
|
|
26
|
+
String: "string"
|
|
27
|
+
};
|
|
28
|
+
function resolveDisplayName(value, options = {}) {
|
|
29
|
+
if (value === void 0) {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
return resolveLocalizedString(value, {
|
|
33
|
+
locale: options.locale,
|
|
34
|
+
config: options.localeConfig
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function toPropertyName(name) {
|
|
38
|
+
return name;
|
|
39
|
+
}
|
|
40
|
+
function toInterfaceName(schemaName) {
|
|
41
|
+
return schemaName;
|
|
42
|
+
}
|
|
43
|
+
function getPropertyType(property, _allSchemas) {
|
|
44
|
+
if (property.type === "File") {
|
|
45
|
+
const fileProp = property;
|
|
46
|
+
if (fileProp.multiple) {
|
|
47
|
+
return `${FILE_INTERFACE_NAME}[]`;
|
|
48
|
+
}
|
|
49
|
+
return `${FILE_INTERFACE_NAME} | null`;
|
|
50
|
+
}
|
|
51
|
+
if (property.type === "Association") {
|
|
52
|
+
const assocProp = property;
|
|
53
|
+
const targetName = assocProp.target ?? "unknown";
|
|
54
|
+
switch (assocProp.relation) {
|
|
55
|
+
// Standard relations
|
|
56
|
+
case "OneToOne":
|
|
57
|
+
case "ManyToOne":
|
|
58
|
+
return targetName;
|
|
59
|
+
case "OneToMany":
|
|
60
|
+
case "ManyToMany":
|
|
61
|
+
return `${targetName}[]`;
|
|
62
|
+
// Polymorphic relations
|
|
63
|
+
case "MorphTo":
|
|
64
|
+
if (assocProp.targets && assocProp.targets.length > 0) {
|
|
65
|
+
return assocProp.targets.join(" | ");
|
|
66
|
+
}
|
|
67
|
+
return "unknown";
|
|
68
|
+
case "MorphOne":
|
|
69
|
+
return targetName;
|
|
70
|
+
case "MorphMany":
|
|
71
|
+
case "MorphToMany":
|
|
72
|
+
case "MorphedByMany":
|
|
73
|
+
return `${targetName}[]`;
|
|
74
|
+
default:
|
|
75
|
+
return "unknown";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (property.type === "Enum") {
|
|
79
|
+
const enumProp = property;
|
|
80
|
+
if (typeof enumProp.enum === "string") {
|
|
81
|
+
return enumProp.enum;
|
|
82
|
+
}
|
|
83
|
+
if (Array.isArray(enumProp.enum)) {
|
|
84
|
+
return enumProp.enum.map((v) => `'${v}'`).join(" | ");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (property.type === "Select") {
|
|
88
|
+
const selectProp = property;
|
|
89
|
+
if (selectProp.options && selectProp.options.length > 0) {
|
|
90
|
+
return selectProp.options.map((v) => `'${v}'`).join(" | ");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return TYPE_MAP[property.type] ?? "unknown";
|
|
94
|
+
}
|
|
95
|
+
function propertyToTSProperties(propertyName, property, allSchemas, options = {}) {
|
|
96
|
+
const baseProp = property;
|
|
97
|
+
const isReadonly = options.readonly ?? true;
|
|
98
|
+
const displayName = resolveDisplayName(baseProp.displayName, options);
|
|
99
|
+
if (property.type === "Association") {
|
|
100
|
+
const assocProp = property;
|
|
101
|
+
if (assocProp.relation === "MorphTo" && assocProp.targets && assocProp.targets.length > 0) {
|
|
102
|
+
const propBaseName = toPropertyName(propertyName);
|
|
103
|
+
const targetUnion = assocProp.targets.map((t) => `'${t}'`).join(" | ");
|
|
104
|
+
const relationUnion = assocProp.targets.join(" | ");
|
|
105
|
+
return [
|
|
106
|
+
{
|
|
107
|
+
name: `${propBaseName}Type`,
|
|
108
|
+
type: targetUnion,
|
|
109
|
+
optional: true,
|
|
110
|
+
// Polymorphic columns are nullable
|
|
111
|
+
readonly: isReadonly,
|
|
112
|
+
comment: `Polymorphic type for ${propertyName}`
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: `${propBaseName}Id`,
|
|
116
|
+
type: "number",
|
|
117
|
+
optional: true,
|
|
118
|
+
readonly: isReadonly,
|
|
119
|
+
comment: `Polymorphic ID for ${propertyName}`
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: propBaseName,
|
|
123
|
+
type: `${relationUnion} | null`,
|
|
124
|
+
optional: true,
|
|
125
|
+
readonly: isReadonly,
|
|
126
|
+
comment: displayName ?? `Polymorphic relation to ${assocProp.targets.join(", ")}`
|
|
127
|
+
}
|
|
128
|
+
];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const type = getPropertyType(property, allSchemas);
|
|
132
|
+
return [{
|
|
133
|
+
name: toPropertyName(propertyName),
|
|
134
|
+
type,
|
|
135
|
+
optional: baseProp.nullable ?? false,
|
|
136
|
+
readonly: isReadonly,
|
|
137
|
+
comment: displayName
|
|
138
|
+
}];
|
|
139
|
+
}
|
|
140
|
+
function propertyToTSProperty(propertyName, property, allSchemas, options = {}) {
|
|
141
|
+
return propertyToTSProperties(propertyName, property, allSchemas, options)[0];
|
|
142
|
+
}
|
|
143
|
+
function schemaToInterface(schema, allSchemas, options = {}) {
|
|
144
|
+
const properties = [];
|
|
145
|
+
if (schema.options?.id !== false) {
|
|
146
|
+
const pkType = schema.options?.idType ?? "BigInt";
|
|
147
|
+
properties.push({
|
|
148
|
+
name: "id",
|
|
149
|
+
type: PK_TYPE_MAP[pkType] ?? "number",
|
|
150
|
+
optional: false,
|
|
151
|
+
readonly: options.readonly ?? true,
|
|
152
|
+
comment: "Primary key"
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
if (schema.properties) {
|
|
156
|
+
for (const [propName, property] of Object.entries(schema.properties)) {
|
|
157
|
+
properties.push(...propertyToTSProperties(propName, property, allSchemas, options));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (schema.options?.timestamps !== false) {
|
|
161
|
+
properties.push(
|
|
162
|
+
{
|
|
163
|
+
name: "createdAt",
|
|
164
|
+
type: "string",
|
|
165
|
+
optional: true,
|
|
166
|
+
readonly: options.readonly ?? true,
|
|
167
|
+
comment: "Creation timestamp"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: "updatedAt",
|
|
171
|
+
type: "string",
|
|
172
|
+
optional: true,
|
|
173
|
+
readonly: options.readonly ?? true,
|
|
174
|
+
comment: "Last update timestamp"
|
|
175
|
+
}
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
if (schema.options?.softDelete) {
|
|
179
|
+
properties.push({
|
|
180
|
+
name: "deletedAt",
|
|
181
|
+
type: "string",
|
|
182
|
+
optional: true,
|
|
183
|
+
readonly: options.readonly ?? true,
|
|
184
|
+
comment: "Soft delete timestamp"
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const schemaDisplayName = resolveDisplayName(schema.displayName, options);
|
|
188
|
+
return {
|
|
189
|
+
name: toInterfaceName(schema.name),
|
|
190
|
+
properties,
|
|
191
|
+
comment: schemaDisplayName ?? schema.name
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function formatProperty(property) {
|
|
195
|
+
const readonly = property.readonly ? "readonly " : "";
|
|
196
|
+
const optional = property.optional ? "?" : "";
|
|
197
|
+
const comment = property.comment ? ` /** ${property.comment} */
|
|
198
|
+
` : "";
|
|
199
|
+
return `${comment} ${readonly}${property.name}${optional}: ${property.type};`;
|
|
200
|
+
}
|
|
201
|
+
function formatInterface(iface) {
|
|
202
|
+
const comment = iface.comment ? `/**
|
|
203
|
+
* ${iface.comment}
|
|
204
|
+
*/
|
|
205
|
+
` : "";
|
|
206
|
+
const extendsClause = iface.extends && iface.extends.length > 0 ? ` extends ${iface.extends.join(", ")}` : "";
|
|
207
|
+
const properties = iface.properties.map(formatProperty).join("\n");
|
|
208
|
+
return `${comment}export interface ${iface.name}${extendsClause} {
|
|
209
|
+
${properties}
|
|
210
|
+
}`;
|
|
211
|
+
}
|
|
212
|
+
function generateInterfaces(schemas, options = {}) {
|
|
213
|
+
const interfaces = [];
|
|
214
|
+
for (const schema of Object.values(schemas)) {
|
|
215
|
+
if (schema.kind === "enum") {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
interfaces.push(schemaToInterface(schema, schemas, options));
|
|
219
|
+
}
|
|
220
|
+
return interfaces;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// src/enum-generator.ts
|
|
224
|
+
import { resolveLocalizedString as resolveLocalizedString2 } from "@famgia/omnify-types";
|
|
225
|
+
function resolveDisplayName2(value, options = {}) {
|
|
226
|
+
if (value === void 0) {
|
|
227
|
+
return void 0;
|
|
228
|
+
}
|
|
229
|
+
return resolveLocalizedString2(value, {
|
|
230
|
+
locale: options.locale,
|
|
231
|
+
config: options.localeConfig
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
function toEnumMemberName(value) {
|
|
235
|
+
return value.split(/[-_\s]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
236
|
+
}
|
|
237
|
+
function toEnumName(schemaName) {
|
|
238
|
+
return schemaName;
|
|
239
|
+
}
|
|
240
|
+
function parseEnumValue(value) {
|
|
241
|
+
if (typeof value === "string") {
|
|
242
|
+
return {
|
|
243
|
+
name: toEnumMemberName(value),
|
|
244
|
+
value
|
|
245
|
+
// No label or extra - will fallback to value
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
name: toEnumMemberName(value.value),
|
|
250
|
+
value: value.value,
|
|
251
|
+
label: value.label,
|
|
252
|
+
extra: value.extra
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function schemaToEnum(schema, options = {}) {
|
|
256
|
+
if (schema.kind !== "enum" || !schema.values) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
const values = schema.values.map((value) => parseEnumValue(value));
|
|
260
|
+
const displayName = resolveDisplayName2(schema.displayName, options);
|
|
261
|
+
return {
|
|
262
|
+
name: toEnumName(schema.name),
|
|
263
|
+
values,
|
|
264
|
+
comment: displayName ?? schema.name
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function generateEnums(schemas, options = {}) {
|
|
268
|
+
const enums = [];
|
|
269
|
+
for (const schema of Object.values(schemas)) {
|
|
270
|
+
if (schema.kind === "enum") {
|
|
271
|
+
const enumDef = schemaToEnum(schema, options);
|
|
272
|
+
if (enumDef) {
|
|
273
|
+
enums.push(enumDef);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return enums;
|
|
278
|
+
}
|
|
279
|
+
function formatEnum(enumDef) {
|
|
280
|
+
const { name, values, comment } = enumDef;
|
|
281
|
+
const parts = [];
|
|
282
|
+
if (comment) {
|
|
283
|
+
parts.push(`/**
|
|
284
|
+
* ${comment}
|
|
285
|
+
*/
|
|
286
|
+
`);
|
|
287
|
+
}
|
|
288
|
+
const enumValues = values.map((v) => ` ${v.name} = '${v.value}',`).join("\n");
|
|
289
|
+
parts.push(`export enum ${name} {
|
|
290
|
+
${enumValues}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
`);
|
|
294
|
+
parts.push(`/** All ${name} values */
|
|
295
|
+
`);
|
|
296
|
+
parts.push(`export const ${name}Values = Object.values(${name});
|
|
297
|
+
|
|
298
|
+
`);
|
|
299
|
+
parts.push(`/** Type guard for ${name} */
|
|
300
|
+
`);
|
|
301
|
+
parts.push(`export function is${name}(value: unknown): value is ${name} {
|
|
302
|
+
`);
|
|
303
|
+
parts.push(` return ${name}Values.includes(value as ${name});
|
|
304
|
+
`);
|
|
305
|
+
parts.push(`}
|
|
306
|
+
|
|
307
|
+
`);
|
|
308
|
+
const hasLabels = values.some((v) => v.label !== void 0);
|
|
309
|
+
if (hasLabels) {
|
|
310
|
+
const labelEntries = values.filter((v) => v.label !== void 0).map((v) => ` [${name}.${v.name}]: '${v.label}',`).join("\n");
|
|
311
|
+
parts.push(`const ${lowerFirst(name)}Labels: Partial<Record<${name}, string>> = {
|
|
312
|
+
${labelEntries}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
`);
|
|
316
|
+
}
|
|
317
|
+
parts.push(`/** Get label for ${name} value (fallback to value if no label) */
|
|
318
|
+
`);
|
|
319
|
+
parts.push(`export function get${name}Label(value: ${name}): string {
|
|
320
|
+
`);
|
|
321
|
+
if (hasLabels) {
|
|
322
|
+
parts.push(` return ${lowerFirst(name)}Labels[value] ?? value;
|
|
323
|
+
`);
|
|
324
|
+
} else {
|
|
325
|
+
parts.push(` return value;
|
|
326
|
+
`);
|
|
327
|
+
}
|
|
328
|
+
parts.push(`}
|
|
329
|
+
|
|
330
|
+
`);
|
|
331
|
+
const hasExtra = values.some((v) => v.extra !== void 0);
|
|
332
|
+
if (hasExtra) {
|
|
333
|
+
const extraEntries = values.filter((v) => v.extra !== void 0).map((v) => ` [${name}.${v.name}]: ${JSON.stringify(v.extra)},`).join("\n");
|
|
334
|
+
parts.push(`const ${lowerFirst(name)}Extra: Partial<Record<${name}, Record<string, unknown>>> = {
|
|
335
|
+
${extraEntries}
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
`);
|
|
339
|
+
parts.push(`/** Get extra metadata for ${name} value (undefined if not defined) */
|
|
340
|
+
`);
|
|
341
|
+
parts.push(`export function get${name}Extra(value: ${name}): Record<string, unknown> | undefined {
|
|
342
|
+
`);
|
|
343
|
+
parts.push(` return ${lowerFirst(name)}Extra[value];
|
|
344
|
+
`);
|
|
345
|
+
parts.push(`}`);
|
|
346
|
+
} else {
|
|
347
|
+
parts.push(`/** Get extra metadata for ${name} value (undefined if not defined) */
|
|
348
|
+
`);
|
|
349
|
+
parts.push(`export function get${name}Extra(_value: ${name}): Record<string, unknown> | undefined {
|
|
350
|
+
`);
|
|
351
|
+
parts.push(` return undefined;
|
|
352
|
+
`);
|
|
353
|
+
parts.push(`}`);
|
|
354
|
+
}
|
|
355
|
+
return parts.join("");
|
|
356
|
+
}
|
|
357
|
+
function lowerFirst(str) {
|
|
358
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
359
|
+
}
|
|
360
|
+
function enumToUnionType(enumDef) {
|
|
361
|
+
const type = enumDef.values.map((v) => `'${v.value}'`).join(" | ");
|
|
362
|
+
return {
|
|
363
|
+
name: enumDef.name,
|
|
364
|
+
type,
|
|
365
|
+
comment: enumDef.comment
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
function formatTypeAlias(alias) {
|
|
369
|
+
const { name, type, comment } = alias;
|
|
370
|
+
const parts = [];
|
|
371
|
+
if (comment) {
|
|
372
|
+
parts.push(`/**
|
|
373
|
+
* ${comment}
|
|
374
|
+
*/
|
|
375
|
+
`);
|
|
376
|
+
}
|
|
377
|
+
parts.push(`export type ${name} = ${type};
|
|
378
|
+
|
|
379
|
+
`);
|
|
380
|
+
const values = type.split(" | ").map((v) => v.trim());
|
|
381
|
+
parts.push(`/** All ${name} values */
|
|
382
|
+
`);
|
|
383
|
+
parts.push(`export const ${name}Values: ${name}[] = [${values.join(", ")}];
|
|
384
|
+
|
|
385
|
+
`);
|
|
386
|
+
parts.push(`/** Type guard for ${name} */
|
|
387
|
+
`);
|
|
388
|
+
parts.push(`export function is${name}(value: unknown): value is ${name} {
|
|
389
|
+
`);
|
|
390
|
+
parts.push(` return ${name}Values.includes(value as ${name});
|
|
391
|
+
`);
|
|
392
|
+
parts.push(`}
|
|
393
|
+
|
|
394
|
+
`);
|
|
395
|
+
parts.push(`/** Get label for ${name} value (returns value as-is) */
|
|
396
|
+
`);
|
|
397
|
+
parts.push(`export function get${name}Label(value: ${name}): string {
|
|
398
|
+
`);
|
|
399
|
+
parts.push(` return value;
|
|
400
|
+
`);
|
|
401
|
+
parts.push(`}
|
|
402
|
+
|
|
403
|
+
`);
|
|
404
|
+
parts.push(`/** Get extra metadata for ${name} value (always undefined for type aliases) */
|
|
405
|
+
`);
|
|
406
|
+
parts.push(`export function get${name}Extra(_value: ${name}): Record<string, unknown> | undefined {
|
|
407
|
+
`);
|
|
408
|
+
parts.push(` return undefined;
|
|
409
|
+
`);
|
|
410
|
+
parts.push(`}`);
|
|
411
|
+
return parts.join("");
|
|
412
|
+
}
|
|
413
|
+
function extractInlineEnums(schemas, options = {}) {
|
|
414
|
+
const typeAliases = [];
|
|
415
|
+
for (const schema of Object.values(schemas)) {
|
|
416
|
+
if (schema.kind === "enum" || !schema.properties) {
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
for (const [propName, property] of Object.entries(schema.properties)) {
|
|
420
|
+
if (property.type === "Enum") {
|
|
421
|
+
const enumProp = property;
|
|
422
|
+
if (Array.isArray(enumProp.enum) && enumProp.enum.length > 0) {
|
|
423
|
+
const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;
|
|
424
|
+
const values = enumProp.enum.map(
|
|
425
|
+
(v) => typeof v === "string" ? v : v.value
|
|
426
|
+
);
|
|
427
|
+
const displayName = resolveDisplayName2(enumProp.displayName, options);
|
|
428
|
+
typeAliases.push({
|
|
429
|
+
name: typeName,
|
|
430
|
+
type: values.map((v) => `'${v}'`).join(" | "),
|
|
431
|
+
comment: displayName ?? `${schema.name} ${propName} enum`
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if (property.type === "Select") {
|
|
436
|
+
const selectProp = property;
|
|
437
|
+
if (selectProp.options && selectProp.options.length > 0) {
|
|
438
|
+
const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;
|
|
439
|
+
const displayName = resolveDisplayName2(selectProp.displayName, options);
|
|
440
|
+
typeAliases.push({
|
|
441
|
+
name: typeName,
|
|
442
|
+
type: selectProp.options.map((v) => `'${v}'`).join(" | "),
|
|
443
|
+
comment: displayName ?? `${schema.name} ${propName} options`
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return typeAliases;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// src/generator.ts
|
|
453
|
+
var DEFAULT_OPTIONS = {
|
|
454
|
+
readonly: true,
|
|
455
|
+
strictNullChecks: true
|
|
456
|
+
};
|
|
457
|
+
function generateBaseHeader() {
|
|
458
|
+
return `/**
|
|
459
|
+
* Auto-generated TypeScript types from Omnify schemas.
|
|
460
|
+
* DO NOT EDIT - This file is automatically generated and will be overwritten.
|
|
461
|
+
*/
|
|
462
|
+
|
|
463
|
+
`;
|
|
464
|
+
}
|
|
465
|
+
function generateModelHeader(schemaName) {
|
|
466
|
+
return `/**
|
|
467
|
+
* ${schemaName} Model
|
|
468
|
+
*
|
|
469
|
+
* This file extends the auto-generated base interface.
|
|
470
|
+
* You can add custom methods, computed properties, or override types here.
|
|
471
|
+
* This file will NOT be overwritten by the generator.
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
`;
|
|
475
|
+
}
|
|
476
|
+
function generateBaseInterfaceFile(schemaName, schemas, options) {
|
|
477
|
+
const interfaces = generateInterfaces(schemas, options);
|
|
478
|
+
const iface = interfaces.find((i) => i.name === schemaName);
|
|
479
|
+
if (!iface) {
|
|
480
|
+
throw new Error(`Interface not found for schema: ${schemaName}`);
|
|
481
|
+
}
|
|
482
|
+
const parts = [generateBaseHeader()];
|
|
483
|
+
parts.push(formatInterface(iface));
|
|
484
|
+
parts.push("\n");
|
|
485
|
+
return {
|
|
486
|
+
filePath: `base/${schemaName}.ts`,
|
|
487
|
+
content: parts.join(""),
|
|
488
|
+
types: [schemaName],
|
|
489
|
+
overwrite: true
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
function generateEnumFile(enumDef) {
|
|
493
|
+
const parts = [generateBaseHeader()];
|
|
494
|
+
parts.push(formatEnum(enumDef));
|
|
495
|
+
parts.push("\n");
|
|
496
|
+
return {
|
|
497
|
+
filePath: `enum/${enumDef.name}.ts`,
|
|
498
|
+
content: parts.join(""),
|
|
499
|
+
types: [enumDef.name],
|
|
500
|
+
overwrite: true
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
function generateTypeAliasFile(alias) {
|
|
504
|
+
const parts = [generateBaseHeader()];
|
|
505
|
+
parts.push(formatTypeAlias(alias));
|
|
506
|
+
parts.push("\n");
|
|
507
|
+
return {
|
|
508
|
+
filePath: `enum/${alias.name}.ts`,
|
|
509
|
+
content: parts.join(""),
|
|
510
|
+
types: [alias.name],
|
|
511
|
+
overwrite: true
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
function generateModelFile(schemaName) {
|
|
515
|
+
const parts = [generateModelHeader(schemaName)];
|
|
516
|
+
parts.push(`import type { ${schemaName} as ${schemaName}Base } from './base/${schemaName}.js';
|
|
517
|
+
|
|
518
|
+
`);
|
|
519
|
+
parts.push(`/**
|
|
520
|
+
* ${schemaName} model interface.
|
|
521
|
+
* Add custom properties or methods here.
|
|
522
|
+
*/
|
|
523
|
+
`);
|
|
524
|
+
parts.push(`export interface ${schemaName} extends ${schemaName}Base {
|
|
525
|
+
`);
|
|
526
|
+
parts.push(` // Add custom properties here
|
|
527
|
+
`);
|
|
528
|
+
parts.push(`}
|
|
529
|
+
|
|
530
|
+
`);
|
|
531
|
+
parts.push(`// Re-export base type for internal use
|
|
532
|
+
`);
|
|
533
|
+
parts.push(`export type { ${schemaName}Base };
|
|
534
|
+
`);
|
|
535
|
+
return {
|
|
536
|
+
filePath: `${schemaName}.ts`,
|
|
537
|
+
content: parts.join(""),
|
|
538
|
+
types: [schemaName],
|
|
539
|
+
overwrite: false
|
|
540
|
+
// Never overwrite user models
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
function generateIndexFile(schemas, enums, typeAliases) {
|
|
544
|
+
const parts = [generateBaseHeader()];
|
|
545
|
+
if (enums.length > 0 || typeAliases.length > 0) {
|
|
546
|
+
parts.push(`// Enums
|
|
547
|
+
`);
|
|
548
|
+
for (const enumDef of enums) {
|
|
549
|
+
parts.push(`export {
|
|
550
|
+
`);
|
|
551
|
+
parts.push(` ${enumDef.name},
|
|
552
|
+
`);
|
|
553
|
+
parts.push(` ${enumDef.name}Values,
|
|
554
|
+
`);
|
|
555
|
+
parts.push(` is${enumDef.name},
|
|
556
|
+
`);
|
|
557
|
+
parts.push(` get${enumDef.name}Label,
|
|
558
|
+
`);
|
|
559
|
+
parts.push(` get${enumDef.name}Extra,
|
|
560
|
+
`);
|
|
561
|
+
parts.push(`} from './enum/${enumDef.name}.js';
|
|
562
|
+
`);
|
|
563
|
+
}
|
|
564
|
+
for (const alias of typeAliases) {
|
|
565
|
+
parts.push(`export {
|
|
566
|
+
`);
|
|
567
|
+
parts.push(` type ${alias.name},
|
|
568
|
+
`);
|
|
569
|
+
parts.push(` ${alias.name}Values,
|
|
570
|
+
`);
|
|
571
|
+
parts.push(` is${alias.name},
|
|
572
|
+
`);
|
|
573
|
+
parts.push(` get${alias.name}Label,
|
|
574
|
+
`);
|
|
575
|
+
parts.push(` get${alias.name}Extra,
|
|
576
|
+
`);
|
|
577
|
+
parts.push(`} from './enum/${alias.name}.js';
|
|
578
|
+
`);
|
|
579
|
+
}
|
|
580
|
+
parts.push("\n");
|
|
581
|
+
}
|
|
582
|
+
parts.push(`// Models
|
|
583
|
+
`);
|
|
584
|
+
for (const schema of Object.values(schemas)) {
|
|
585
|
+
if (schema.kind === "enum") continue;
|
|
586
|
+
parts.push(`export type { ${schema.name} } from './${schema.name}.js';
|
|
587
|
+
`);
|
|
588
|
+
}
|
|
589
|
+
return {
|
|
590
|
+
filePath: "index.ts",
|
|
591
|
+
content: parts.join(""),
|
|
592
|
+
types: [],
|
|
593
|
+
overwrite: true
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
function generateTypeScript(schemas, options = {}) {
|
|
597
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
598
|
+
const files = [];
|
|
599
|
+
const enums = generateEnums(schemas);
|
|
600
|
+
for (const enumDef of enums) {
|
|
601
|
+
files.push(generateEnumFile(enumDef));
|
|
602
|
+
}
|
|
603
|
+
const typeAliases = extractInlineEnums(schemas);
|
|
604
|
+
for (const alias of typeAliases) {
|
|
605
|
+
files.push(generateTypeAliasFile(alias));
|
|
606
|
+
}
|
|
607
|
+
for (const schema of Object.values(schemas)) {
|
|
608
|
+
if (schema.kind === "enum") continue;
|
|
609
|
+
files.push(generateBaseInterfaceFile(schema.name, schemas, opts));
|
|
610
|
+
}
|
|
611
|
+
for (const schema of Object.values(schemas)) {
|
|
612
|
+
if (schema.kind === "enum") continue;
|
|
613
|
+
files.push(generateModelFile(schema.name));
|
|
614
|
+
}
|
|
615
|
+
files.push(generateIndexFile(schemas, enums, typeAliases));
|
|
616
|
+
return files;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
export {
|
|
620
|
+
toPropertyName,
|
|
621
|
+
toInterfaceName,
|
|
622
|
+
getPropertyType,
|
|
623
|
+
propertyToTSProperty,
|
|
624
|
+
schemaToInterface,
|
|
625
|
+
formatProperty,
|
|
626
|
+
formatInterface,
|
|
627
|
+
generateInterfaces,
|
|
628
|
+
toEnumMemberName,
|
|
629
|
+
toEnumName,
|
|
630
|
+
schemaToEnum,
|
|
631
|
+
generateEnums,
|
|
632
|
+
formatEnum,
|
|
633
|
+
enumToUnionType,
|
|
634
|
+
formatTypeAlias,
|
|
635
|
+
extractInlineEnums,
|
|
636
|
+
generateTypeScript
|
|
637
|
+
};
|
|
638
|
+
//# sourceMappingURL=chunk-J46F3EBS.js.map
|