@omnifyjp/ts 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/cli.d.ts +13 -0
  2. package/dist/cli.js +180 -0
  3. package/dist/enum-generator.d.ts +28 -0
  4. package/dist/enum-generator.js +253 -0
  5. package/dist/generator.d.ts +19 -0
  6. package/dist/generator.js +330 -0
  7. package/dist/i18n-generator.d.ts +10 -0
  8. package/dist/i18n-generator.js +143 -0
  9. package/dist/index.d.ts +10 -0
  10. package/dist/index.js +9 -0
  11. package/dist/interface-generator.d.ts +31 -0
  12. package/dist/interface-generator.js +341 -0
  13. package/dist/php/base-model-generator.d.ts +7 -0
  14. package/dist/php/base-model-generator.js +70 -0
  15. package/dist/php/factory-generator.d.ts +7 -0
  16. package/dist/php/factory-generator.js +95 -0
  17. package/dist/php/faker-mapper.d.ts +12 -0
  18. package/dist/php/faker-mapper.js +206 -0
  19. package/dist/php/index.d.ts +18 -0
  20. package/dist/php/index.js +40 -0
  21. package/dist/php/locales-generator.d.ts +7 -0
  22. package/dist/php/locales-generator.js +135 -0
  23. package/dist/php/model-generator.d.ts +7 -0
  24. package/dist/php/model-generator.js +396 -0
  25. package/dist/php/naming-helper.d.ts +22 -0
  26. package/dist/php/naming-helper.js +61 -0
  27. package/dist/php/relation-builder.d.ts +12 -0
  28. package/dist/php/relation-builder.js +147 -0
  29. package/dist/php/request-generator.d.ts +7 -0
  30. package/dist/php/request-generator.js +221 -0
  31. package/dist/php/resource-generator.d.ts +7 -0
  32. package/dist/php/resource-generator.js +178 -0
  33. package/dist/php/schema-reader.d.ts +28 -0
  34. package/dist/php/schema-reader.js +79 -0
  35. package/dist/php/service-provider-generator.d.ts +7 -0
  36. package/dist/php/service-provider-generator.js +64 -0
  37. package/dist/php/trait-generator.d.ts +6 -0
  38. package/dist/php/trait-generator.js +104 -0
  39. package/dist/php/type-mapper.d.ts +25 -0
  40. package/dist/php/type-mapper.js +217 -0
  41. package/dist/php/types.d.ts +61 -0
  42. package/dist/php/types.js +68 -0
  43. package/dist/types.d.ts +196 -0
  44. package/dist/types.js +6 -0
  45. package/dist/zod-generator.d.ts +32 -0
  46. package/dist/zod-generator.js +428 -0
  47. package/package.json +31 -0
package/dist/cli.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @omnify/ts CLI
4
+ *
5
+ * Reads omnify.yaml to resolve schemas.json input and TypeScript output paths.
6
+ * Falls back to explicit --input / --output flags.
7
+ *
8
+ * Usage:
9
+ * omnify-ts # reads omnify.yaml in cwd
10
+ * omnify-ts --config path/to/omnify.yaml
11
+ * omnify-ts --input schemas.json --output ./types # explicit override
12
+ */
13
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @omnify/ts CLI
4
+ *
5
+ * Reads omnify.yaml to resolve schemas.json input and TypeScript output paths.
6
+ * Falls back to explicit --input / --output flags.
7
+ *
8
+ * Usage:
9
+ * omnify-ts # reads omnify.yaml in cwd
10
+ * omnify-ts --config path/to/omnify.yaml
11
+ * omnify-ts --input schemas.json --output ./types # explicit override
12
+ */
13
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
14
+ import { resolve, dirname, join } from 'node:path';
15
+ import { Command } from 'commander';
16
+ import { parse as parseYaml } from 'yaml';
17
+ import { generateTypeScript } from './generator.js';
18
+ import { generatePhp } from './php/index.js';
19
+ function resolveFromConfig(configPath) {
20
+ const raw = readFileSync(configPath, 'utf-8');
21
+ const config = parseYaml(raw);
22
+ const configDir = dirname(configPath);
23
+ // Find default connection
24
+ const defaultName = config.default ?? 'default';
25
+ const connections = config.connections ?? {};
26
+ const conn = connections[defaultName];
27
+ if (!conn) {
28
+ throw new Error(`Connection "${defaultName}" not found in ${configPath}`);
29
+ }
30
+ // Resolve schemas.json input path from migrations[type=laravel].schemasPath
31
+ let schemasPath;
32
+ for (const m of conn.migrations ?? []) {
33
+ if (m.type === 'laravel' && m.schemasPath) {
34
+ schemasPath = m.schemasPath;
35
+ break;
36
+ }
37
+ }
38
+ if (!schemasPath) {
39
+ throw new Error(`No schemasPath found in laravel migration for connection "${defaultName}" in ${configPath}.\n` +
40
+ `Either add schemasPath to your laravel migration config, or use --input explicitly.`);
41
+ }
42
+ // TypeScript config (enable defaults to false)
43
+ const tsConfig = config.codegen?.typescript;
44
+ const tsEnabled = tsConfig?.enable === true && !!tsConfig?.modelsPath;
45
+ const tsOutput = tsEnabled ? resolve(configDir, tsConfig.modelsPath) : undefined;
46
+ // Laravel config (enable defaults to false)
47
+ const laravelConfig = config.codegen?.laravel;
48
+ const laravelEnabled = laravelConfig?.enable === true;
49
+ const laravelOverrides = laravelEnabled ? {
50
+ model: laravelConfig?.model,
51
+ request: laravelConfig?.request,
52
+ resource: laravelConfig?.resource,
53
+ factory: laravelConfig?.factory,
54
+ provider: laravelConfig?.provider,
55
+ } : undefined;
56
+ return {
57
+ input: resolve(configDir, schemasPath),
58
+ tsEnabled,
59
+ tsOutput,
60
+ laravelEnabled,
61
+ laravelOverrides,
62
+ };
63
+ }
64
+ // ============================================================================
65
+ // CLI
66
+ // ============================================================================
67
+ const program = new Command();
68
+ program
69
+ .name('omnify-ts')
70
+ .description('Generate TypeScript types and Laravel PHP code from Omnify schemas.json')
71
+ .option('-c, --config <path>', 'Path to omnify.yaml (default: ./omnify.yaml)')
72
+ .option('-i, --input <path>', 'Path to schemas.json (overrides config)')
73
+ .option('-o, --output <path>', 'Output directory for TypeScript (overrides config)')
74
+ .option('--force', 'Overwrite user-editable model files', false)
75
+ .action((opts) => {
76
+ let inputPath;
77
+ let tsEnabled = true;
78
+ let tsOutput;
79
+ let laravelEnabled = false;
80
+ let laravelOverrides;
81
+ let configDir = process.cwd();
82
+ if (opts.input && opts.output) {
83
+ // Explicit flags — skip config, only TS generation
84
+ inputPath = resolve(opts.input);
85
+ tsOutput = resolve(opts.output);
86
+ }
87
+ else {
88
+ // Read from omnify.yaml
89
+ const configPath = resolve(opts.config ?? 'omnify.yaml');
90
+ configDir = dirname(configPath);
91
+ if (!existsSync(configPath)) {
92
+ console.error(`Error: Config not found: ${configPath}\n` +
93
+ `Run from a directory with omnify.yaml, or use --config / --input + --output.`);
94
+ process.exit(1);
95
+ }
96
+ const resolved = resolveFromConfig(configPath);
97
+ inputPath = opts.input ? resolve(opts.input) : resolved.input;
98
+ tsEnabled = resolved.tsEnabled;
99
+ tsOutput = opts.output ? resolve(opts.output) : resolved.tsOutput;
100
+ laravelEnabled = resolved.laravelEnabled;
101
+ laravelOverrides = resolved.laravelOverrides;
102
+ }
103
+ // Read schemas.json
104
+ if (!existsSync(inputPath)) {
105
+ console.error(`Error: schemas.json not found: ${inputPath}\nRun "omnify generate" first.`);
106
+ process.exit(1);
107
+ }
108
+ const raw = readFileSync(inputPath, 'utf-8');
109
+ const input = JSON.parse(raw);
110
+ console.log(`Reading schemas from ${inputPath}`);
111
+ // ---- TypeScript generation ----
112
+ if (tsEnabled && tsOutput) {
113
+ console.log(`\n[TypeScript] Output: ${tsOutput}`);
114
+ const files = generateTypeScript(input);
115
+ mkdirSync(join(tsOutput, 'base'), { recursive: true });
116
+ mkdirSync(join(tsOutput, 'enum'), { recursive: true });
117
+ let tsCreated = 0;
118
+ let tsOverwritten = 0;
119
+ let tsSkipped = 0;
120
+ for (const file of files) {
121
+ let filePath;
122
+ if (file.category === 'enum' || file.category === 'plugin-enum') {
123
+ filePath = join(tsOutput, 'enum', file.filePath);
124
+ }
125
+ else {
126
+ filePath = join(tsOutput, file.filePath);
127
+ }
128
+ mkdirSync(dirname(filePath), { recursive: true });
129
+ if (!file.overwrite && existsSync(filePath) && !opts.force) {
130
+ tsSkipped++;
131
+ continue;
132
+ }
133
+ writeFileSync(filePath, file.content, 'utf-8');
134
+ if (file.overwrite || !existsSync(filePath)) {
135
+ tsOverwritten++;
136
+ }
137
+ else {
138
+ tsCreated++;
139
+ }
140
+ }
141
+ console.log(` ${tsOverwritten} files written (auto-generated)`);
142
+ if (tsCreated > 0)
143
+ console.log(` ${tsCreated} files created (user-editable)`);
144
+ if (tsSkipped > 0)
145
+ console.log(` ${tsSkipped} files skipped (already exist)`);
146
+ }
147
+ else {
148
+ console.log(`\n[TypeScript] Skipped (disabled)`);
149
+ }
150
+ // ---- PHP/Laravel generation ----
151
+ if (laravelEnabled) {
152
+ console.log(`\n[Laravel] Generating PHP files`);
153
+ const phpFiles = generatePhp(input, laravelOverrides);
154
+ let phpCreated = 0;
155
+ let phpOverwritten = 0;
156
+ let phpSkipped = 0;
157
+ for (const file of phpFiles) {
158
+ const filePath = resolve(configDir, file.path);
159
+ mkdirSync(dirname(filePath), { recursive: true });
160
+ if (!file.overwrite && existsSync(filePath) && !opts.force) {
161
+ phpSkipped++;
162
+ continue;
163
+ }
164
+ writeFileSync(filePath, file.content, 'utf-8');
165
+ if (file.overwrite || !existsSync(filePath)) {
166
+ phpOverwritten++;
167
+ }
168
+ else {
169
+ phpCreated++;
170
+ }
171
+ }
172
+ console.log(` ${phpOverwritten} files written (auto-generated)`);
173
+ if (phpCreated > 0)
174
+ console.log(` ${phpCreated} files created (user-editable)`);
175
+ if (phpSkipped > 0)
176
+ console.log(` ${phpSkipped} files skipped (already exist)`);
177
+ }
178
+ console.log(`\nGeneration complete.`);
179
+ });
180
+ program.parse();
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @omnify/ts — TypeScript Enum Generator
3
+ *
4
+ * Generates TypeScript enums with helper methods from schema enum definitions,
5
+ * plugin enums (customTypes.enums), and inline property enums.
6
+ */
7
+ import type { SchemaDefinition, TSEnum, TSTypeAlias, GeneratorOptions } from './types.js';
8
+ /** Convert a string to PascalCase. */
9
+ export declare function toPascalCase(value: string): string;
10
+ /** Convert enum value to valid TypeScript enum member name. */
11
+ export declare function toEnumMemberName(value: string): string;
12
+ /** Generate TSEnum from a schema enum definition. */
13
+ export declare function schemaToEnum(schema: SchemaDefinition, options: GeneratorOptions): TSEnum | null;
14
+ /** Generate enums from all schema enums. */
15
+ export declare function generateEnums(schemas: Record<string, SchemaDefinition>, options: GeneratorOptions): TSEnum[];
16
+ /** Generate enums from plugin enums (customTypes.enums in schemas.json). */
17
+ export declare function generatePluginEnums(pluginEnums: Record<string, string[]>, _options: GeneratorOptions): TSEnum[];
18
+ /** Format a TypeScript enum with helpers (Values array, type guard, label getter). */
19
+ export declare function formatEnum(enumDef: TSEnum): string;
20
+ /** Format a TypeScript type alias with helpers. */
21
+ export declare function formatTypeAlias(alias: TSTypeAlias): string;
22
+ /** Result of extracting inline enums. */
23
+ export interface ExtractedInlineEnum {
24
+ typeAlias?: TSTypeAlias;
25
+ enum?: TSEnum;
26
+ }
27
+ /** Extract inline enums from Enum/Select properties. */
28
+ export declare function extractInlineEnums(schemas: Record<string, SchemaDefinition>, options: GeneratorOptions): ExtractedInlineEnum[];
@@ -0,0 +1,253 @@
1
+ /**
2
+ * @omnify/ts — TypeScript Enum Generator
3
+ *
4
+ * Generates TypeScript enums with helper methods from schema enum definitions,
5
+ * plugin enums (customTypes.enums), and inline property enums.
6
+ */
7
+ /** Convert a string to PascalCase. */
8
+ export function toPascalCase(value) {
9
+ const normalized = value.replace(/([a-z])([A-Z])/g, '$1_$2');
10
+ return normalized
11
+ .split(/[-_\s]+/)
12
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
13
+ .join('');
14
+ }
15
+ /** Convert enum value to valid TypeScript enum member name. */
16
+ export function toEnumMemberName(value) {
17
+ let result = value
18
+ .split(/[-_\s]+/)
19
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
20
+ .join('')
21
+ .replace(/[^a-zA-Z0-9]/g, '');
22
+ if (/^\d/.test(result)) {
23
+ result = '_' + result;
24
+ }
25
+ return result;
26
+ }
27
+ /** Parse an enum value from schema (string or object with value/label). */
28
+ function parseEnumValue(value, options) {
29
+ if (typeof value === 'string') {
30
+ return { name: toEnumMemberName(value), value };
31
+ }
32
+ let label;
33
+ if (value.label !== undefined) {
34
+ if (typeof value.label === 'object') {
35
+ // Multi-locale: keep all locales
36
+ label = value.label;
37
+ }
38
+ else {
39
+ label = value.label;
40
+ }
41
+ }
42
+ return {
43
+ name: toEnumMemberName(value.value),
44
+ value: value.value,
45
+ label,
46
+ extra: value.extra,
47
+ };
48
+ }
49
+ /** Generate TSEnum from a schema enum definition. */
50
+ export function schemaToEnum(schema, options) {
51
+ if (schema.kind !== 'enum' || !schema.values)
52
+ return null;
53
+ const values = schema.values.map(v => parseEnumValue(v, options));
54
+ const displayName = resolveString(schema.displayName, options);
55
+ return {
56
+ name: schema.name,
57
+ values,
58
+ comment: displayName ?? schema.name,
59
+ };
60
+ }
61
+ /** Generate enums from all schema enums. */
62
+ export function generateEnums(schemas, options) {
63
+ const enums = [];
64
+ for (const schema of Object.values(schemas)) {
65
+ if (schema.kind === 'enum') {
66
+ const enumDef = schemaToEnum(schema, options);
67
+ if (enumDef)
68
+ enums.push(enumDef);
69
+ }
70
+ }
71
+ return enums;
72
+ }
73
+ /** Generate enums from plugin enums (customTypes.enums in schemas.json). */
74
+ export function generatePluginEnums(pluginEnums, _options) {
75
+ const enums = [];
76
+ for (const [name, values] of Object.entries(pluginEnums)) {
77
+ enums.push({
78
+ name,
79
+ values: values.map(v => ({
80
+ name: toEnumMemberName(v),
81
+ value: v,
82
+ })),
83
+ comment: name,
84
+ });
85
+ }
86
+ return enums;
87
+ }
88
+ /** Check if label is multi-locale. */
89
+ function isMultiLocaleLabel(label) {
90
+ return label !== undefined && typeof label === 'object';
91
+ }
92
+ /** Lowercase first character. */
93
+ function lowerFirst(str) {
94
+ return str.charAt(0).toLowerCase() + str.slice(1);
95
+ }
96
+ /** Escape single quotes in strings. */
97
+ function escapeString(str) {
98
+ return str.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
99
+ }
100
+ /** Format a TypeScript enum with helpers (Values array, type guard, label getter). */
101
+ export function formatEnum(enumDef) {
102
+ const { name, values, comment } = enumDef;
103
+ const parts = [];
104
+ if (comment) {
105
+ parts.push(`/**\n * ${comment}\n */\n`);
106
+ }
107
+ // Enum definition
108
+ const enumValues = values.map(v => ` ${v.name} = '${v.value}',`).join('\n');
109
+ parts.push(`export enum ${name} {\n${enumValues}\n}\n\n`);
110
+ // Values array
111
+ parts.push(`/** All ${name} values */\n`);
112
+ parts.push(`export const ${name}Values = Object.values(${name}) as ${name}[];\n\n`);
113
+ // Type guard
114
+ parts.push(`/** Type guard for ${name} */\n`);
115
+ parts.push(`export function is${name}(value: unknown): value is ${name} {\n`);
116
+ parts.push(` return ${name}Values.includes(value as ${name});\n`);
117
+ parts.push(`}\n\n`);
118
+ // Labels
119
+ const hasLabels = values.some(v => v.label !== undefined);
120
+ const hasMultiLocale = values.some(v => isMultiLocaleLabel(v.label));
121
+ if (hasLabels) {
122
+ if (hasMultiLocale) {
123
+ const labelEntries = values
124
+ .filter(v => v.label !== undefined)
125
+ .map(v => {
126
+ if (isMultiLocaleLabel(v.label)) {
127
+ const locales = Object.entries(v.label)
128
+ .map(([locale, text]) => `'${locale}': '${escapeString(text)}'`)
129
+ .join(', ');
130
+ return ` [${name}.${v.name}]: { ${locales} },`;
131
+ }
132
+ return ` [${name}.${v.name}]: { default: '${escapeString(String(v.label))}' },`;
133
+ })
134
+ .join('\n');
135
+ parts.push(`const ${lowerFirst(name)}Labels: Partial<Record<${name}, Record<string, string>>> = {\n${labelEntries}\n};\n\n`);
136
+ parts.push(`/** Get label for ${name} value with locale support */\n`);
137
+ parts.push(`export function get${name}Label(value: ${name}, locale?: string): string {\n`);
138
+ parts.push(` const labels = ${lowerFirst(name)}Labels[value];\n`);
139
+ parts.push(` if (!labels) return value;\n`);
140
+ parts.push(` if (locale && labels[locale]) return labels[locale];\n`);
141
+ parts.push(` return labels['ja'] ?? labels['en'] ?? Object.values(labels)[0] ?? value;\n`);
142
+ parts.push(`}\n\n`);
143
+ }
144
+ else {
145
+ const labelEntries = values
146
+ .filter(v => v.label !== undefined)
147
+ .map(v => ` [${name}.${v.name}]: '${escapeString(String(v.label))}',`)
148
+ .join('\n');
149
+ parts.push(`const ${lowerFirst(name)}Labels: Partial<Record<${name}, string>> = {\n${labelEntries}\n};\n\n`);
150
+ parts.push(`/** Get label for ${name} value */\n`);
151
+ parts.push(`export function get${name}Label(value: ${name}): string {\n`);
152
+ parts.push(` return ${lowerFirst(name)}Labels[value] ?? value;\n`);
153
+ parts.push(`}\n\n`);
154
+ }
155
+ }
156
+ else {
157
+ parts.push(`/** Get label for ${name} value */\n`);
158
+ parts.push(`export function get${name}Label(value: ${name}): string {\n`);
159
+ parts.push(` return value;\n`);
160
+ parts.push(`}\n\n`);
161
+ }
162
+ // Extra
163
+ const hasExtra = values.some(v => v.extra !== undefined);
164
+ if (hasExtra) {
165
+ const extraEntries = values
166
+ .filter(v => v.extra !== undefined)
167
+ .map(v => ` [${name}.${v.name}]: ${JSON.stringify(v.extra)},`)
168
+ .join('\n');
169
+ parts.push(`const ${lowerFirst(name)}Extra: Partial<Record<${name}, Record<string, unknown>>> = {\n${extraEntries}\n};\n\n`);
170
+ parts.push(`/** Get extra metadata for ${name} value */\n`);
171
+ parts.push(`export function get${name}Extra(value: ${name}): Record<string, unknown> | undefined {\n`);
172
+ parts.push(` return ${lowerFirst(name)}Extra[value];\n`);
173
+ parts.push(`}`);
174
+ }
175
+ else {
176
+ parts.push(`/** Get extra metadata for ${name} value */\n`);
177
+ parts.push(`export function get${name}Extra(_value: ${name}): Record<string, unknown> | undefined {\n`);
178
+ parts.push(` return undefined;\n`);
179
+ parts.push(`}`);
180
+ }
181
+ return parts.join('');
182
+ }
183
+ /** Format a TypeScript type alias with helpers. */
184
+ export function formatTypeAlias(alias) {
185
+ const { name, type, comment } = alias;
186
+ const parts = [];
187
+ if (comment) {
188
+ parts.push(`/**\n * ${comment}\n */\n`);
189
+ }
190
+ parts.push(`export type ${name} = ${type};\n\n`);
191
+ const values = type.split(' | ').map(v => v.trim());
192
+ parts.push(`/** All ${name} values */\n`);
193
+ parts.push(`export const ${name}Values: ${name}[] = [${values.join(', ')}];\n\n`);
194
+ parts.push(`/** Type guard for ${name} */\n`);
195
+ parts.push(`export function is${name}(value: unknown): value is ${name} {\n`);
196
+ parts.push(` return ${name}Values.includes(value as ${name});\n`);
197
+ parts.push(`}\n\n`);
198
+ parts.push(`/** Get label for ${name} value */\n`);
199
+ parts.push(`export function get${name}Label(value: ${name}): string {\n`);
200
+ parts.push(` return value;\n`);
201
+ parts.push(`}\n\n`);
202
+ parts.push(`/** Get extra metadata for ${name} value */\n`);
203
+ parts.push(`export function get${name}Extra(_value: ${name}): Record<string, unknown> | undefined {\n`);
204
+ parts.push(` return undefined;\n`);
205
+ parts.push(`}`);
206
+ return parts.join('');
207
+ }
208
+ /** Extract inline enums from Enum/Select properties. */
209
+ export function extractInlineEnums(schemas, options) {
210
+ const results = [];
211
+ for (const schema of Object.values(schemas)) {
212
+ if (schema.kind === 'enum' || !schema.properties)
213
+ continue;
214
+ for (const [propName, property] of Object.entries(schema.properties)) {
215
+ if (property.type === 'Enum' && Array.isArray(property.enum) && property.enum.length > 0) {
216
+ const typeName = `${schema.name}${toPascalCase(propName)}`;
217
+ const displayName = resolveString(schema.displayName, options);
218
+ // Check if values have labels (i.e., are objects not strings)
219
+ const enumValues = property.enum;
220
+ const hasLabels = enumValues.some(v => typeof v !== 'string' && v.label !== undefined);
221
+ if (hasLabels) {
222
+ const values = enumValues.map(v => parseEnumValue(v, options));
223
+ results.push({
224
+ enum: {
225
+ name: typeName,
226
+ values,
227
+ comment: displayName ?? `${schema.name} ${propName} enum`,
228
+ },
229
+ });
230
+ }
231
+ else {
232
+ const values = enumValues.map(v => typeof v === 'string' ? v : v.value);
233
+ results.push({
234
+ typeAlias: {
235
+ name: typeName,
236
+ type: values.map(v => `'${v}'`).join(' | '),
237
+ comment: displayName ?? `${schema.name} ${propName} enum`,
238
+ },
239
+ });
240
+ }
241
+ }
242
+ }
243
+ }
244
+ return results;
245
+ }
246
+ /** Resolve a LocalizedString to a single string. */
247
+ function resolveString(value, options) {
248
+ if (value === undefined)
249
+ return undefined;
250
+ if (typeof value === 'string')
251
+ return value;
252
+ return value[options.defaultLocale] ?? value[options.fallbackLocale] ?? value['en'] ?? Object.values(value)[0];
253
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @omnify/ts — Main Generator
3
+ *
4
+ * Orchestrates TypeScript code generation from schemas.json.
5
+ * Reads the JSON, builds options, calls sub-generators, and assembles output files.
6
+ *
7
+ * Output structure:
8
+ * base/{SchemaName}.ts — Auto-generated interfaces + Zod + i18n (always overwritten)
9
+ * enum/{EnumName}.ts — Auto-generated enums (always overwritten)
10
+ * common.ts — Shared types (DateTimeString, etc.)
11
+ * i18n.ts — Validation messages + locale helpers
12
+ * {SchemaName}.ts — User-editable models extending base (created once, never overwritten)
13
+ * index.ts — Re-exports (always overwritten)
14
+ */
15
+ import type { SchemasJson, TypeScriptFile } from './types.js';
16
+ /**
17
+ * Generate all TypeScript files from schemas.json input.
18
+ */
19
+ export declare function generateTypeScript(input: SchemasJson): TypeScriptFile[];