@famgia/omnify-typescript 0.0.127 → 0.0.128
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/index.cjs +17 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +21 -76
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/stubs/ai-guides/DEPRECATED.md +19 -0
package/dist/index.cjs
CHANGED
|
@@ -2519,21 +2519,7 @@ function getStubPaths() {
|
|
|
2519
2519
|
// src/ai-guides/generator.ts
|
|
2520
2520
|
var import_node_fs = require("fs");
|
|
2521
2521
|
var import_node_path = require("path");
|
|
2522
|
-
var
|
|
2523
|
-
var import_meta2 = {};
|
|
2524
|
-
var __filename2 = (0, import_node_url.fileURLToPath)(import_meta2.url);
|
|
2525
|
-
var __dirname2 = (0, import_node_path.dirname)(__filename2);
|
|
2526
|
-
function getStubsDir() {
|
|
2527
|
-
const devPath = (0, import_node_path.resolve)(__dirname2, "../../stubs/ai-guides");
|
|
2528
|
-
if ((0, import_node_fs.existsSync)(devPath)) {
|
|
2529
|
-
return devPath;
|
|
2530
|
-
}
|
|
2531
|
-
const distPath = (0, import_node_path.resolve)(__dirname2, "../stubs/ai-guides");
|
|
2532
|
-
if ((0, import_node_fs.existsSync)(distPath)) {
|
|
2533
|
-
return distPath;
|
|
2534
|
-
}
|
|
2535
|
-
throw new Error("AI guides stubs not found");
|
|
2536
|
-
}
|
|
2522
|
+
var import_omnify_core = require("@famgia/omnify-core");
|
|
2537
2523
|
function extractTypescriptBasePath(typescriptPath) {
|
|
2538
2524
|
if (!typescriptPath) return "src";
|
|
2539
2525
|
const normalized = typescriptPath.replace(/\\/g, "/");
|
|
@@ -2543,71 +2529,28 @@ function extractTypescriptBasePath(typescriptPath) {
|
|
|
2543
2529
|
}
|
|
2544
2530
|
return "src";
|
|
2545
2531
|
}
|
|
2546
|
-
function replacePlaceholders(content, basePath) {
|
|
2547
|
-
return content.replace(/\{\{TYPESCRIPT_BASE\}\}/g, basePath);
|
|
2548
|
-
}
|
|
2549
|
-
function copyStubs2(srcDir, destDir, transform) {
|
|
2550
|
-
const writtenFiles = [];
|
|
2551
|
-
if (!(0, import_node_fs.existsSync)(srcDir)) {
|
|
2552
|
-
return writtenFiles;
|
|
2553
|
-
}
|
|
2554
|
-
if (!(0, import_node_fs.existsSync)(destDir)) {
|
|
2555
|
-
(0, import_node_fs.mkdirSync)(destDir, { recursive: true });
|
|
2556
|
-
}
|
|
2557
|
-
const entries = (0, import_node_fs.readdirSync)(srcDir, { withFileTypes: true });
|
|
2558
|
-
for (const entry of entries) {
|
|
2559
|
-
const srcPath = (0, import_node_path.join)(srcDir, entry.name);
|
|
2560
|
-
if (entry.isDirectory()) {
|
|
2561
|
-
const subDestDir = (0, import_node_path.join)(destDir, entry.name);
|
|
2562
|
-
const subFiles = copyStubs2(srcPath, subDestDir, transform);
|
|
2563
|
-
writtenFiles.push(...subFiles);
|
|
2564
|
-
} else if (entry.isFile() && entry.name.endsWith(".stub")) {
|
|
2565
|
-
const destName = entry.name.slice(0, -5);
|
|
2566
|
-
const destPath = (0, import_node_path.join)(destDir, destName);
|
|
2567
|
-
let content = (0, import_node_fs.readFileSync)(srcPath, "utf-8");
|
|
2568
|
-
if (transform) {
|
|
2569
|
-
content = transform(content);
|
|
2570
|
-
}
|
|
2571
|
-
(0, import_node_fs.writeFileSync)(destPath, content);
|
|
2572
|
-
writtenFiles.push(destPath);
|
|
2573
|
-
}
|
|
2574
|
-
}
|
|
2575
|
-
return writtenFiles;
|
|
2576
|
-
}
|
|
2577
2532
|
function generateAIGuides(rootDir, options = {}) {
|
|
2578
|
-
const stubsDir = getStubsDir();
|
|
2579
2533
|
const basePath = options.typescriptBasePath || extractTypescriptBasePath(options.typescriptPath);
|
|
2534
|
+
const coreResult = (0, import_omnify_core.generateAIGuides)(rootDir, {
|
|
2535
|
+
placeholders: {
|
|
2536
|
+
TYPESCRIPT_BASE: basePath,
|
|
2537
|
+
LARAVEL_BASE: "app",
|
|
2538
|
+
LARAVEL_ROOT: ""
|
|
2539
|
+
},
|
|
2540
|
+
// TypeScriptプロジェクトではReact関連のみ
|
|
2541
|
+
adapters: ["cursor", "claude"]
|
|
2542
|
+
});
|
|
2580
2543
|
const result = {
|
|
2581
2544
|
claudeGuides: 0,
|
|
2582
2545
|
claudeChecklists: 0,
|
|
2583
2546
|
cursorRules: 0,
|
|
2584
|
-
files:
|
|
2547
|
+
files: coreResult.files
|
|
2585
2548
|
};
|
|
2586
|
-
const
|
|
2587
|
-
const
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
result.files.push(...files);
|
|
2592
|
-
}
|
|
2593
|
-
const claudeChecklistsSrcDir = (0, import_node_path.join)(stubsDir, "checklists");
|
|
2594
|
-
const claudeChecklistsDestDir = (0, import_node_path.resolve)(rootDir, ".claude/omnify/checklists");
|
|
2595
|
-
if ((0, import_node_fs.existsSync)(claudeChecklistsSrcDir)) {
|
|
2596
|
-
const files = copyStubs2(claudeChecklistsSrcDir, claudeChecklistsDestDir);
|
|
2597
|
-
result.claudeChecklists = files.length;
|
|
2598
|
-
result.files.push(...files);
|
|
2599
|
-
}
|
|
2600
|
-
const cursorSrcDir = (0, import_node_path.join)(stubsDir, "cursor");
|
|
2601
|
-
const cursorDestDir = (0, import_node_path.resolve)(rootDir, ".cursor/rules/omnify");
|
|
2602
|
-
if ((0, import_node_fs.existsSync)(cursorSrcDir)) {
|
|
2603
|
-
const files = copyStubs2(
|
|
2604
|
-
cursorSrcDir,
|
|
2605
|
-
cursorDestDir,
|
|
2606
|
-
(content) => replacePlaceholders(content, basePath)
|
|
2607
|
-
);
|
|
2608
|
-
result.cursorRules = files.length;
|
|
2609
|
-
result.files.push(...files);
|
|
2610
|
-
}
|
|
2549
|
+
const claudeCount = coreResult.counts["claude"] || 0;
|
|
2550
|
+
const cursorCount = coreResult.counts["cursor"] || 0;
|
|
2551
|
+
result.claudeGuides = Math.floor(claudeCount * 0.8);
|
|
2552
|
+
result.claudeChecklists = claudeCount - result.claudeGuides;
|
|
2553
|
+
result.cursorRules = cursorCount;
|
|
2611
2554
|
return result;
|
|
2612
2555
|
}
|
|
2613
2556
|
function shouldGenerateAIGuides(rootDir) {
|
|
@@ -2619,8 +2562,7 @@ function shouldGenerateAIGuides(rootDir) {
|
|
|
2619
2562
|
try {
|
|
2620
2563
|
const claudeFiles = (0, import_node_fs.readdirSync)(claudeDir);
|
|
2621
2564
|
const cursorFiles = (0, import_node_fs.readdirSync)(cursorDir);
|
|
2622
|
-
|
|
2623
|
-
return claudeFiles.length === 0 || !hasReactRules;
|
|
2565
|
+
return claudeFiles.length === 0 || cursorFiles.length === 0;
|
|
2624
2566
|
} catch {
|
|
2625
2567
|
return true;
|
|
2626
2568
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/interface-generator.ts","../src/enum-generator.ts","../src/validation-templates.ts","../src/rules-generator.ts","../src/zod-generator.ts","../src/generator.ts","../src/stubs.ts","../src/ai-guides/generator.ts"],"sourcesContent":["/**\n * @famgia/omnify-typescript\n *\n * TypeScript type definitions generator for Omnify schemas.\n */\n\nexport type {\n TypeScriptFile,\n TypeScriptOptions,\n TSProperty,\n TSInterface,\n TSEnum,\n TSEnumValue,\n TSTypeAlias,\n} from './types.js';\n\nexport {\n toPropertyName,\n toInterfaceName,\n getPropertyType,\n propertyToTSProperty,\n schemaToInterface,\n formatProperty,\n formatInterface,\n generateInterfaces,\n} from './interface-generator.js';\n\nexport {\n toEnumMemberName,\n toEnumName,\n schemaToEnum,\n generateEnums,\n generatePluginEnums,\n pluginEnumToTSEnum,\n formatEnum,\n enumToUnionType,\n formatTypeAlias,\n extractInlineEnums,\n type ExtractedInlineEnum,\n} from './enum-generator.js';\n\nexport {\n generateTypeScript,\n generateTypeScriptFiles,\n} from './generator.js';\n\nexport {\n DEFAULT_VALIDATION_TEMPLATES,\n mergeValidationTemplates,\n formatValidationMessage,\n getValidationMessages,\n type ValidationTemplates,\n} from './validation-templates.js';\n\nexport {\n generateModelRules,\n generateRulesFiles,\n} from './rules-generator.js';\n\nexport {\n copyStubs,\n getStubPaths,\n STUB_FILES,\n type CopyStubsOptions,\n type CopyStubsResult,\n} from './stubs.js';\n\nexport type { LocaleMap } from './types.js';\n\n// AI Guides generation\nexport {\n generateAIGuides,\n shouldGenerateAIGuides,\n type AIGuidesOptions,\n type AIGuidesResult,\n} from './ai-guides/index.js';\n","/**\n * @famgia/omnify-laravel - TypeScript Interface Generator\n *\n * Generates TypeScript interfaces from schemas.\n */\n\nimport type { LoadedSchema, PropertyDefinition, SchemaCollection, LocalizedString } from '@famgia/omnify-types';\nimport { resolveLocalizedString } from '@famgia/omnify-types';\nimport type { TSInterface, TSProperty, TypeScriptOptions } from './types.js';\n\n/**\n * Convert a string to snake_case.\n */\nexport function toSnakeCase(str: string): string {\n return str\n .replace(/([A-Z])/g, '_$1')\n .replace(/^_/, '')\n .toLowerCase();\n}\n\n/**\n * Maps Omnify property types to TypeScript types.\n */\nconst TYPE_MAP: Record<string, string> = {\n String: 'string',\n TinyInt: 'number',\n Int: 'number',\n BigInt: 'number',\n Float: 'number',\n Boolean: 'boolean',\n Text: 'string',\n MediumText: 'string',\n LongText: 'string',\n Date: 'DateString',\n Time: 'string',\n DateTime: 'DateTimeString',\n Timestamp: 'DateTimeString',\n Json: 'unknown',\n Email: 'string',\n Password: 'string',\n Enum: 'string',\n Select: 'string',\n Lookup: 'number',\n};\n\n/**\n * File interface name (references the File.yaml schema).\n * The File schema is auto-generated by ensureFileSchema() when File type is used.\n */\nexport const FILE_INTERFACE_NAME = 'File';\n\n/**\n * Maps primary key types to TypeScript types.\n */\nconst PK_TYPE_MAP: Record<string, string> = {\n Int: 'number',\n BigInt: 'number',\n Uuid: 'string',\n String: 'string',\n};\n\n/**\n * Resolves a localized string using the given options.\n * Returns undefined if the value is undefined or cannot be resolved.\n */\nfunction resolveDisplayName(\n value: LocalizedString | undefined,\n options: TypeScriptOptions = {}\n): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n return resolveLocalizedString(value, {\n locale: options.locale,\n config: options.localeConfig,\n });\n}\n\n/**\n * Converts property name to TypeScript property name.\n * Preserves camelCase.\n */\nexport function toPropertyName(name: string): string {\n return name;\n}\n\n/**\n * Converts schema name to TypeScript interface name.\n * Preserves PascalCase.\n */\nexport function toInterfaceName(schemaName: string): string {\n return schemaName;\n}\n\n/**\n * Gets TypeScript type for a property.\n */\nexport function getPropertyType(\n property: PropertyDefinition,\n _allSchemas: SchemaCollection\n): string {\n // Handle File type specially (polymorphic relation to files table)\n // References the File interface generated from File.yaml schema\n if (property.type === 'File') {\n const fileProp = property as { multiple?: boolean };\n if (fileProp.multiple) {\n return `${FILE_INTERFACE_NAME}[]`;\n }\n return `${FILE_INTERFACE_NAME} | null`;\n }\n\n // Handle associations\n if (property.type === 'Association') {\n const assocProp = property as {\n relation?: string;\n target?: string;\n targets?: readonly string[];\n };\n\n const targetName = assocProp.target ?? 'unknown';\n\n switch (assocProp.relation) {\n // Standard relations\n case 'OneToOne':\n case 'ManyToOne':\n return targetName;\n case 'OneToMany':\n case 'ManyToMany':\n return `${targetName}[]`;\n\n // Polymorphic relations\n case 'MorphTo':\n // Union type of all possible targets\n if (assocProp.targets && assocProp.targets.length > 0) {\n return assocProp.targets.join(' | ');\n }\n return 'unknown';\n case 'MorphOne':\n return targetName;\n case 'MorphMany':\n case 'MorphToMany':\n case 'MorphedByMany':\n return `${targetName}[]`;\n\n default:\n return 'unknown';\n }\n }\n\n // Handle EnumRef types (reference to shared enum schema)\n if (property.type === 'EnumRef') {\n const enumRefProp = property as { enum: string };\n return enumRefProp.enum;\n }\n\n // Handle enum types\n if (property.type === 'Enum') {\n const enumProp = property as { enum?: string | readonly string[] };\n if (typeof enumProp.enum === 'string') {\n // Reference to a named enum\n return enumProp.enum;\n }\n if (Array.isArray(enumProp.enum)) {\n // Inline enum - create union type\n return enumProp.enum.map(v => `'${v}'`).join(' | ');\n }\n }\n\n // Handle Select with options\n if (property.type === 'Select') {\n const selectProp = property as { options?: readonly string[] };\n if (selectProp.options && selectProp.options.length > 0) {\n return selectProp.options.map(v => `'${v}'`).join(' | ');\n }\n }\n\n // Standard type mapping\n return TYPE_MAP[property.type] ?? 'unknown';\n}\n\n/**\n * Converts a property to TypeScript property definition.\n * For MorphTo, returns multiple properties (_type, _id, and relation).\n * For compound custom types, expands to multiple properties.\n */\nexport function propertyToTSProperties(\n propertyName: string,\n property: PropertyDefinition,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSProperty[] {\n const baseProp = property as { nullable?: boolean; displayName?: LocalizedString; fields?: Record<string, { nullable?: boolean }> };\n const isReadonly = options.readonly ?? true;\n // Resolve displayName using locale config\n const displayName = resolveDisplayName(baseProp.displayName, options);\n\n // Handle custom compound types from plugins (e.g., JapaneseName, JapaneseAddress)\n if (options.customTypes) {\n const customType = options.customTypes.get(property.type);\n if (customType?.compound && customType.expand) {\n const expandedProps: TSProperty[] = [];\n for (const field of customType.expand) {\n const fieldName = `${propertyName}_${toSnakeCase(field.suffix)}`;\n const fieldOverride = baseProp.fields?.[field.suffix];\n // Nullable priority: schema field override > plugin field default > parent property > false\n const isNullable = fieldOverride?.nullable ?? field.sql?.nullable ?? baseProp.nullable ?? false;\n const tsType = field.typescript?.type ?? 'string';\n\n expandedProps.push({\n name: fieldName,\n type: tsType,\n optional: isNullable,\n readonly: isReadonly,\n comment: `${displayName ?? propertyName} (${field.suffix})`,\n });\n }\n\n // Add accessor properties (computed properties like full_name)\n if (customType.accessors) {\n for (const accessor of customType.accessors) {\n const accessorName = `${propertyName}_${toSnakeCase(accessor.name)}`;\n expandedProps.push({\n name: accessorName,\n type: 'string | null',\n optional: true,\n readonly: isReadonly,\n comment: `${displayName ?? propertyName} (computed)`,\n });\n }\n }\n\n return expandedProps;\n }\n // Handle simple custom types (non-compound)\n if (customType && !customType.compound) {\n const tsType = customType.typescript?.type ?? 'string';\n return [{\n name: toPropertyName(propertyName),\n type: tsType,\n optional: baseProp.nullable ?? false,\n readonly: isReadonly,\n comment: displayName,\n }];\n }\n }\n\n // Handle MorphTo specially - it creates _type and _id columns\n if (property.type === 'Association') {\n const assocProp = property as {\n relation?: string;\n targets?: readonly string[];\n };\n\n if (assocProp.relation === 'MorphTo' && assocProp.targets && assocProp.targets.length > 0) {\n const propBaseName = toPropertyName(propertyName);\n const targetUnion = assocProp.targets.map(t => `'${t}'`).join(' | ');\n const relationUnion = assocProp.targets.join(' | ');\n\n return [\n {\n name: `${propBaseName}Type`,\n type: targetUnion,\n optional: true, // Polymorphic columns are nullable\n readonly: isReadonly,\n comment: `Polymorphic type for ${propertyName}`,\n },\n {\n name: `${propBaseName}Id`,\n type: 'number',\n optional: true,\n readonly: isReadonly,\n comment: `Polymorphic ID for ${propertyName}`,\n },\n {\n name: propBaseName,\n type: `${relationUnion} | null`,\n optional: true,\n readonly: isReadonly,\n comment: displayName ?? `Polymorphic relation to ${assocProp.targets.join(', ')}`,\n },\n ];\n }\n }\n\n // Default: single property\n const type = getPropertyType(property, allSchemas);\n\n return [{\n name: toPropertyName(propertyName),\n type,\n optional: baseProp.nullable ?? false,\n readonly: isReadonly,\n comment: displayName,\n }];\n}\n\n/**\n * Converts a property to TypeScript property definition (legacy - returns single property).\n */\nexport function propertyToTSProperty(\n propertyName: string,\n property: PropertyDefinition,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSProperty {\n return propertyToTSProperties(propertyName, property, allSchemas, options)[0]!;\n}\n\n/**\n * Extracts referenced interface names from a TypeScript type string.\n * Returns only interface names (not primitives like string, number, boolean, unknown).\n */\nfunction extractTypeReferences(type: string, allSchemaNames: Set<string>): string[] {\n const primitives = new Set(['string', 'number', 'boolean', 'unknown', 'null', 'undefined', 'void', 'never', 'any']);\n const refs: string[] = [];\n\n // Remove array notation and split by | for union types\n const cleanType = type.replace(/\\[\\]/g, '').replace(/\\s*\\|\\s*null/g, '');\n const parts = cleanType.split(/\\s*\\|\\s*/);\n\n for (const part of parts) {\n // Remove quotes (for string literal types like 'Post')\n const trimmed = part.trim().replace(/^['\"]|['\"]$/g, '');\n if (!primitives.has(trimmed) && allSchemaNames.has(trimmed)) {\n refs.push(trimmed);\n }\n }\n\n return refs;\n}\n\n/**\n * Generates TypeScript interface from schema.\n */\nexport function schemaToInterface(\n schema: LoadedSchema,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSInterface {\n const properties: TSProperty[] = [];\n const allSchemaNames = new Set(Object.keys(allSchemas).filter(name => allSchemas[name]!.kind !== 'enum'));\n\n // ID property (only if id is not disabled)\n if (schema.options?.id !== false) {\n const pkType = (schema.options?.idType ?? 'BigInt') as keyof typeof PK_TYPE_MAP;\n properties.push({\n name: 'id',\n type: PK_TYPE_MAP[pkType] ?? 'number',\n optional: false,\n readonly: options.readonly ?? true,\n comment: 'Primary key',\n });\n }\n\n // Schema properties\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n // Use propertyToTSProperties which handles MorphTo returning multiple properties\n properties.push(...propertyToTSProperties(propName, property, allSchemas, options));\n }\n }\n\n // Timestamps (snake_case to match database columns)\n if (schema.options?.timestamps !== false) {\n properties.push(\n {\n name: 'created_at',\n type: 'DateTimeString',\n optional: true,\n readonly: options.readonly ?? true,\n comment: 'Creation timestamp',\n },\n {\n name: 'updated_at',\n type: 'DateTimeString',\n optional: true,\n readonly: options.readonly ?? true,\n comment: 'Last update timestamp',\n }\n );\n }\n\n // Soft delete (snake_case to match database columns)\n if (schema.options?.softDelete) {\n properties.push({\n name: 'deleted_at',\n type: 'DateTimeString',\n optional: true,\n readonly: options.readonly ?? true,\n comment: 'Soft delete timestamp',\n });\n }\n\n // Collect dependencies from property types\n const dependencySet = new Set<string>();\n for (const prop of properties) {\n for (const ref of extractTypeReferences(prop.type, allSchemaNames)) {\n if (ref !== schema.name) { // Don't include self-references\n dependencySet.add(ref);\n }\n }\n }\n\n // Collect enum dependencies from EnumRef properties\n const enumDependencySet = new Set<string>();\n if (schema.properties) {\n for (const property of Object.values(schema.properties)) {\n if (property.type === 'EnumRef') {\n const enumRefProp = property as { enum: string };\n if (enumRefProp.enum) {\n enumDependencySet.add(enumRefProp.enum);\n }\n }\n }\n }\n\n // Resolve schema displayName using locale config\n const schemaDisplayName = resolveDisplayName(schema.displayName, options);\n\n return {\n name: toInterfaceName(schema.name),\n properties,\n comment: schemaDisplayName ?? schema.name,\n dependencies: dependencySet.size > 0 ? Array.from(dependencySet).sort() : undefined,\n enumDependencies: enumDependencySet.size > 0 ? Array.from(enumDependencySet).sort() : undefined,\n };\n}\n\n/**\n * Formats a TypeScript property.\n */\nexport function formatProperty(property: TSProperty): string {\n const readonly = property.readonly ? 'readonly ' : '';\n const optional = property.optional ? '?' : '';\n const comment = property.comment ? ` /** ${property.comment} */\\n` : '';\n return `${comment} ${readonly}${property.name}${optional}: ${property.type};`;\n}\n\n/**\n * Formats a TypeScript interface.\n */\nexport function formatInterface(iface: TSInterface): string {\n const comment = iface.comment ? `/**\\n * ${iface.comment}\\n */\\n` : '';\n const extendsClause = iface.extends && iface.extends.length > 0\n ? ` extends ${iface.extends.join(', ')}`\n : '';\n const properties = iface.properties.map(formatProperty).join('\\n');\n\n return `${comment}export interface ${iface.name}${extendsClause} {\\n${properties}\\n}`;\n}\n\n/**\n * Generates interfaces for all schemas.\n * Note: File interface is now generated from File.yaml schema (use ensureFileSchema() to auto-create it).\n */\nexport function generateInterfaces(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSInterface[] {\n const interfaces: TSInterface[] = [];\n\n for (const schema of Object.values(schemas)) {\n // Skip enum schemas\n if (schema.kind === 'enum') {\n continue;\n }\n\n // Skip hidden schemas (e.g., cache, jobs, sessions)\n if (schema.options?.hidden === true) {\n continue;\n }\n\n interfaces.push(schemaToInterface(schema, schemas, options));\n }\n\n return interfaces;\n}\n","/**\n * @famgia/omnify-typescript - TypeScript Enum Generator\n *\n * Generates TypeScript enums with helper methods from schema enum definitions.\n */\n\nimport type { LoadedSchema, SchemaCollection, LocalizedString, PluginEnumDefinition } from '@famgia/omnify-types';\nimport { resolveLocalizedString } from '@famgia/omnify-types';\nimport type { TSEnum, TSEnumValue, TSTypeAlias, TypeScriptOptions } from './types.js';\n\n/**\n * Resolves a localized string using the given options.\n */\nfunction resolveDisplayName(\n value: LocalizedString | undefined,\n options: TypeScriptOptions = {}\n): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n return resolveLocalizedString(value, {\n locale: options.locale,\n config: options.localeConfig,\n });\n}\n\n/**\n * Inline enum value from schema (can be string or object with value/label/extra).\n */\ninterface InlineEnumValue {\n readonly value: string;\n /** Display label - supports multi-language (string or locale map) */\n readonly label?: LocalizedString;\n readonly extra?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Converts enum value to valid TypeScript enum member name.\n */\nexport function toEnumMemberName(value: string): string {\n // Convert to PascalCase and remove invalid characters\n let result = value\n .split(/[-_\\s]+/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '');\n\n // TypeScript enum member names cannot start with a number\n if (/^\\d/.test(result)) {\n result = '_' + result;\n }\n\n return result;\n}\n\n/**\n * Converts schema name to TypeScript enum name.\n */\nexport function toEnumName(schemaName: string): string {\n return schemaName;\n}\n\n/**\n * Parses enum value from schema (can be string or object).\n * If multiLocale is true, keeps all locales. Otherwise resolves to single locale.\n */\nfunction parseEnumValue(\n value: string | InlineEnumValue,\n options: TypeScriptOptions = {}\n): TSEnumValue {\n if (typeof value === 'string') {\n return {\n name: toEnumMemberName(value),\n value,\n // No label or extra - will fallback to value\n };\n }\n\n // Handle label - either multi-locale or resolved single locale\n let label: string | Record<string, string> | undefined;\n if (value.label !== undefined) {\n if (options.multiLocale && typeof value.label === 'object') {\n // Keep all locales as object\n label = value.label as Record<string, string>;\n } else {\n // Resolve to single locale\n label = resolveDisplayName(value.label, options);\n }\n }\n\n return {\n name: toEnumMemberName(value.value),\n value: value.value,\n label,\n extra: value.extra,\n };\n}\n\n/**\n * Generates TypeScript enum from schema enum.\n */\nexport function schemaToEnum(schema: LoadedSchema, options: TypeScriptOptions = {}): TSEnum | null {\n if (schema.kind !== 'enum' || !schema.values) {\n return null;\n }\n\n const values: TSEnumValue[] = schema.values.map(value =>\n parseEnumValue(value as string | InlineEnumValue, options)\n );\n const displayName = resolveDisplayName(schema.displayName, options);\n\n return {\n name: toEnumName(schema.name),\n values,\n comment: displayName ?? schema.name,\n };\n}\n\n/**\n * Generates enums for all enum schemas.\n */\nexport function generateEnums(schemas: SchemaCollection, options: TypeScriptOptions = {}): TSEnum[] {\n const enums: TSEnum[] = [];\n\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') {\n const enumDef = schemaToEnum(schema, options);\n if (enumDef) {\n enums.push(enumDef);\n }\n }\n }\n\n return enums;\n}\n\n/**\n * Converts a plugin enum definition to TSEnum.\n * Plugin enums come from plugins like @famgia/omnify-japan (e.g., Prefecture, BankAccountType).\n */\nexport function pluginEnumToTSEnum(enumDef: PluginEnumDefinition, options: TypeScriptOptions = {}): TSEnum {\n const values: TSEnumValue[] = enumDef.values.map(v => {\n // Handle label - can be string or locale map\n let label: string | Record<string, string> | undefined;\n if (v.label !== undefined) {\n if (typeof v.label === 'string') {\n label = v.label;\n } else if (options.multiLocale) {\n // Keep all locales\n label = v.label as Record<string, string>;\n } else {\n // Resolve to single locale\n label = resolveDisplayName(v.label, options);\n }\n }\n\n return {\n name: toEnumMemberName(v.value),\n value: v.value,\n label,\n extra: v.extra,\n };\n });\n\n // Resolve displayName\n let comment: string | undefined;\n if (enumDef.displayName !== undefined) {\n if (typeof enumDef.displayName === 'string') {\n comment = enumDef.displayName;\n } else {\n comment = resolveDisplayName(enumDef.displayName, options);\n }\n }\n\n return {\n name: enumDef.name,\n values,\n comment: comment ?? enumDef.name,\n };\n}\n\n/**\n * Generates enums from plugin enum definitions.\n */\nexport function generatePluginEnums(\n pluginEnums: ReadonlyMap<string, PluginEnumDefinition>,\n options: TypeScriptOptions = {}\n): TSEnum[] {\n const enums: TSEnum[] = [];\n\n for (const enumDef of pluginEnums.values()) {\n enums.push(pluginEnumToTSEnum(enumDef, options));\n }\n\n return enums;\n}\n\n/**\n * Check if label is multi-locale (object) or single string.\n */\nfunction isMultiLocaleLabel(label: string | Record<string, string> | undefined): label is Record<string, string> {\n return label !== undefined && typeof label === 'object';\n}\n\n/**\n * Formats a TypeScript enum with helper methods.\n */\nexport function formatEnum(enumDef: TSEnum): string {\n const { name, values, comment } = enumDef;\n const parts: string[] = [];\n\n // JSDoc comment\n if (comment) {\n parts.push(`/**\\n * ${comment}\\n */\\n`);\n }\n\n // Enum definition\n const enumValues = values\n .map(v => ` ${v.name} = '${v.value}',`)\n .join('\\n');\n parts.push(`export enum ${name} {\\n${enumValues}\\n}\\n\\n`);\n\n // Values array\n parts.push(`/** All ${name} values */\\n`);\n parts.push(`export const ${name}Values = Object.values(${name}) as ${name}[];\\n\\n`);\n\n // Type guard\n parts.push(`/** Type guard for ${name} */\\n`);\n parts.push(`export function is${name}(value: unknown): value is ${name} {\\n`);\n parts.push(` return ${name}Values.includes(value as ${name});\\n`);\n parts.push(`}\\n\\n`);\n\n // Check if we have multi-locale labels or single-locale labels\n const hasLabels = values.some(v => v.label !== undefined);\n const hasMultiLocale = values.some(v => isMultiLocaleLabel(v.label));\n\n if (hasLabels) {\n if (hasMultiLocale) {\n // Multi-locale labels: Record<Enum, Record<string, string>>\n const labelEntries = values\n .filter(v => v.label !== undefined)\n .map(v => {\n if (isMultiLocaleLabel(v.label)) {\n const locales = Object.entries(v.label)\n .map(([locale, text]) => `'${locale}': '${escapeString(text)}'`)\n .join(', ');\n return ` [${name}.${v.name}]: { ${locales} },`;\n }\n return ` [${name}.${v.name}]: { default: '${escapeString(String(v.label))}' },`;\n })\n .join('\\n');\n parts.push(`const ${lowerFirst(name)}Labels: Partial<Record<${name}, Record<string, string>>> = {\\n${labelEntries}\\n};\\n\\n`);\n\n parts.push(`/** Get label for ${name} value with locale support */\\n`);\n parts.push(`export function get${name}Label(value: ${name}, locale?: string): string {\\n`);\n parts.push(` const labels = ${lowerFirst(name)}Labels[value];\\n`);\n parts.push(` if (!labels) return value;\\n`);\n parts.push(` if (locale && labels[locale]) return labels[locale];\\n`);\n parts.push(` // Fallback: ja → en → first available\\n`);\n parts.push(` return labels['ja'] ?? labels['en'] ?? Object.values(labels)[0] ?? value;\\n`);\n parts.push(`}\\n\\n`);\n } else {\n // Single-locale labels: Record<Enum, string>\n const labelEntries = values\n .filter(v => v.label !== undefined)\n .map(v => ` [${name}.${v.name}]: '${escapeString(String(v.label))}',`)\n .join('\\n');\n parts.push(`const ${lowerFirst(name)}Labels: Partial<Record<${name}, string>> = {\\n${labelEntries}\\n};\\n\\n`);\n\n parts.push(`/** Get label for ${name} value (fallback to value if no label) */\\n`);\n parts.push(`export function get${name}Label(value: ${name}): string {\\n`);\n parts.push(` return ${lowerFirst(name)}Labels[value] ?? value;\\n`);\n parts.push(`}\\n\\n`);\n }\n } else {\n parts.push(`/** Get label for ${name} value (returns value as-is) */\\n`);\n parts.push(`export function get${name}Label(value: ${name}): string {\\n`);\n parts.push(` return value;\\n`);\n parts.push(`}\\n\\n`);\n }\n\n // Extra - only generate if at least one value has extra\n const hasExtra = values.some(v => v.extra !== undefined);\n if (hasExtra) {\n const extraEntries = values\n .filter(v => v.extra !== undefined)\n .map(v => ` [${name}.${v.name}]: ${JSON.stringify(v.extra)},`)\n .join('\\n');\n parts.push(`const ${lowerFirst(name)}Extra: Partial<Record<${name}, Record<string, unknown>>> = {\\n${extraEntries}\\n};\\n\\n`);\n\n parts.push(`/** Get extra metadata for ${name} value (undefined if not defined) */\\n`);\n parts.push(`export function get${name}Extra(value: ${name}): Record<string, unknown> | undefined {\\n`);\n parts.push(` return ${lowerFirst(name)}Extra[value];\\n`);\n parts.push(`}`);\n } else {\n parts.push(`/** Get extra metadata for ${name} value (undefined if not defined) */\\n`);\n parts.push(`export function get${name}Extra(_value: ${name}): Record<string, unknown> | undefined {\\n`);\n parts.push(` return undefined;\\n`);\n parts.push(`}`);\n }\n\n return parts.join('');\n}\n\n/**\n * Convert first character to lowercase.\n */\nfunction lowerFirst(str: string): string {\n return str.charAt(0).toLowerCase() + str.slice(1);\n}\n\n/**\n * Escape special characters in strings for JavaScript output.\n */\nfunction escapeString(str: string): string {\n return str.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\n/**\n * Generates a union type alias as an alternative to enum.\n */\nexport function enumToUnionType(enumDef: TSEnum): TSTypeAlias {\n const type = enumDef.values\n .map(v => `'${v.value}'`)\n .join(' | ');\n\n return {\n name: enumDef.name,\n type,\n comment: enumDef.comment,\n };\n}\n\n/**\n * Formats a TypeScript type alias with helper methods.\n */\nexport function formatTypeAlias(alias: TSTypeAlias): string {\n const { name, type, comment } = alias;\n const parts: string[] = [];\n\n // JSDoc comment\n if (comment) {\n parts.push(`/**\\n * ${comment}\\n */\\n`);\n }\n\n // Type alias\n parts.push(`export type ${name} = ${type};\\n\\n`);\n\n // Values array\n const values = type.split(' | ').map(v => v.trim());\n parts.push(`/** All ${name} values */\\n`);\n parts.push(`export const ${name}Values: ${name}[] = [${values.join(', ')}];\\n\\n`);\n\n // Type guard\n parts.push(`/** Type guard for ${name} */\\n`);\n parts.push(`export function is${name}(value: unknown): value is ${name} {\\n`);\n parts.push(` return ${name}Values.includes(value as ${name});\\n`);\n parts.push(`}\\n\\n`);\n\n // Label getter (fallback to value for type aliases - no labels)\n parts.push(`/** Get label for ${name} value (returns value as-is) */\\n`);\n parts.push(`export function get${name}Label(value: ${name}): string {\\n`);\n parts.push(` return value;\\n`);\n parts.push(`}\\n\\n`);\n\n // Extra getter (always undefined for type aliases)\n parts.push(`/** Get extra metadata for ${name} value (always undefined for type aliases) */\\n`);\n parts.push(`export function get${name}Extra(_value: ${name}): Record<string, unknown> | undefined {\\n`);\n parts.push(` return undefined;\\n`);\n parts.push(`}`);\n\n return parts.join('');\n}\n\n/**\n * Result of extracting inline enums - can be type alias or full enum with labels.\n */\nexport interface ExtractedInlineEnum {\n /** Type alias for simple enums */\n typeAlias?: TSTypeAlias;\n /** Full enum with i18n labels */\n enum?: TSEnum;\n}\n\n/**\n * Extracts inline enums from properties for type generation.\n * Returns both type aliases (simple enums) and full enums (with i18n labels).\n */\nexport function extractInlineEnums(schemas: SchemaCollection, options: TypeScriptOptions = {}): ExtractedInlineEnum[] {\n const results: ExtractedInlineEnum[] = [];\n\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum' || !schema.properties) {\n continue;\n }\n\n for (const [propName, property] of Object.entries(schema.properties)) {\n if (property.type === 'Enum') {\n const enumProp = property as { enum?: readonly (string | InlineEnumValue)[]; displayName?: LocalizedString };\n\n // Only handle inline array enums (not references to named enums)\n if (Array.isArray(enumProp.enum) && enumProp.enum.length > 0) {\n const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;\n const displayName = resolveDisplayName(enumProp.displayName, options);\n\n // Check if any value has labels (i18n support needed)\n const hasLabels = enumProp.enum.some(v => typeof v !== 'string' && v.label !== undefined);\n\n if (hasLabels) {\n // Generate full enum with i18n labels\n const values: TSEnumValue[] = enumProp.enum.map(v => parseEnumValue(v, options));\n results.push({\n enum: {\n name: typeName,\n values,\n comment: displayName ?? `${schema.name} ${propName} enum`,\n },\n });\n } else {\n // Generate simple type alias (no labels)\n const values = enumProp.enum.map(v =>\n typeof v === 'string' ? v : v.value\n );\n results.push({\n typeAlias: {\n name: typeName,\n type: values.map(v => `'${v}'`).join(' | '),\n comment: displayName ?? `${schema.name} ${propName} enum`,\n },\n });\n }\n }\n }\n\n if (property.type === 'Select') {\n const selectProp = property as { options?: readonly (string | InlineEnumValue)[]; displayName?: LocalizedString };\n\n if (selectProp.options && selectProp.options.length > 0) {\n const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;\n const displayName = resolveDisplayName(selectProp.displayName, options);\n\n // Check if any option has labels\n const hasLabels = selectProp.options.some(v => typeof v !== 'string' && (v as InlineEnumValue).label !== undefined);\n\n if (hasLabels) {\n // Generate full enum with i18n labels\n const values: TSEnumValue[] = selectProp.options.map(v => parseEnumValue(v as string | InlineEnumValue, options));\n results.push({\n enum: {\n name: typeName,\n values,\n comment: displayName ?? `${schema.name} ${propName} options`,\n },\n });\n } else {\n // Generate simple type alias\n const values = selectProp.options.map(v =>\n typeof v === 'string' ? v : (v as InlineEnumValue).value\n );\n results.push({\n typeAlias: {\n name: typeName,\n type: values.map(v => `'${v}'`).join(' | '),\n comment: displayName ?? `${schema.name} ${propName} options`,\n },\n });\n }\n }\n }\n }\n }\n\n return results;\n}\n","/**\n * Built-in validation message templates for common languages.\n * Templates use ${displayName}, ${min}, ${max}, ${pattern} placeholders.\n */\n\nexport interface ValidationTemplates {\n readonly required: Record<string, string>;\n readonly minLength: Record<string, string>;\n readonly maxLength: Record<string, string>;\n readonly min: Record<string, string>;\n readonly max: Record<string, string>;\n readonly email: Record<string, string>;\n readonly url: Record<string, string>;\n readonly pattern: Record<string, string>;\n readonly enum: Record<string, string>;\n}\n\n/**\n * Default validation message templates.\n * Supports: ja (Japanese), en (English), vi (Vietnamese), ko (Korean), zh (Chinese)\n */\nexport const DEFAULT_VALIDATION_TEMPLATES: ValidationTemplates = {\n required: {\n ja: '${displayName}は必須です',\n en: '${displayName} is required',\n vi: '${displayName} là bắt buộc',\n ko: '${displayName}은(는) 필수입니다',\n zh: '${displayName}为必填项',\n },\n minLength: {\n ja: '${displayName}は${min}文字以上で入力してください',\n en: '${displayName} must be at least ${min} characters',\n vi: '${displayName} phải có ít nhất ${min} ký tự',\n ko: '${displayName}은(는) ${min}자 이상이어야 합니다',\n zh: '${displayName}至少需要${min}个字符',\n },\n maxLength: {\n ja: '${displayName}は${max}文字以内で入力してください',\n en: '${displayName} must be at most ${max} characters',\n vi: '${displayName} tối đa ${max} ký tự',\n ko: '${displayName}은(는) ${max}자 이하여야 합니다',\n zh: '${displayName}不能超过${max}个字符',\n },\n min: {\n ja: '${displayName}は${min}以上の値を入力してください',\n en: '${displayName} must be at least ${min}',\n vi: '${displayName} phải lớn hơn hoặc bằng ${min}',\n ko: '${displayName}은(는) ${min} 이상이어야 합니다',\n zh: '${displayName}不能小于${min}',\n },\n max: {\n ja: '${displayName}は${max}以下の値を入力してください',\n en: '${displayName} must be at most ${max}',\n vi: '${displayName} phải nhỏ hơn hoặc bằng ${max}',\n ko: '${displayName}은(는) ${max} 이하여야 합니다',\n zh: '${displayName}不能大于${max}',\n },\n email: {\n ja: '${displayName}の形式が正しくありません',\n en: '${displayName} is not a valid email address',\n vi: '${displayName} không phải là địa chỉ email hợp lệ',\n ko: '${displayName} 형식이 올바르지 않습니다',\n zh: '${displayName}不是有效的邮箱地址',\n },\n url: {\n ja: '${displayName}は有効なURLではありません',\n en: '${displayName} is not a valid URL',\n vi: '${displayName} không phải là URL hợp lệ',\n ko: '${displayName}은(는) 유효한 URL이 아닙니다',\n zh: '${displayName}不是有效的URL',\n },\n pattern: {\n ja: '${displayName}の形式が正しくありません',\n en: '${displayName} format is invalid',\n vi: '${displayName} không đúng định dạng',\n ko: '${displayName} 형식이 올바르지 않습니다',\n zh: '${displayName}格式不正确',\n },\n enum: {\n ja: '${displayName}の値が無効です',\n en: '${displayName} has an invalid value',\n vi: '${displayName} có giá trị không hợp lệ',\n ko: '${displayName} 값이 유효하지 않습니다',\n zh: '${displayName}的值无效',\n },\n};\n\n/**\n * Merge user templates with default templates.\n */\nexport function mergeValidationTemplates(\n userTemplates?: Partial<ValidationTemplates>\n): ValidationTemplates {\n if (!userTemplates) {\n return DEFAULT_VALIDATION_TEMPLATES;\n }\n\n // Create mutable copies of each template category\n const merged: Record<keyof ValidationTemplates, Record<string, string>> = {\n required: { ...DEFAULT_VALIDATION_TEMPLATES.required },\n minLength: { ...DEFAULT_VALIDATION_TEMPLATES.minLength },\n maxLength: { ...DEFAULT_VALIDATION_TEMPLATES.maxLength },\n min: { ...DEFAULT_VALIDATION_TEMPLATES.min },\n max: { ...DEFAULT_VALIDATION_TEMPLATES.max },\n email: { ...DEFAULT_VALIDATION_TEMPLATES.email },\n url: { ...DEFAULT_VALIDATION_TEMPLATES.url },\n pattern: { ...DEFAULT_VALIDATION_TEMPLATES.pattern },\n enum: { ...DEFAULT_VALIDATION_TEMPLATES.enum },\n };\n\n // Merge user templates\n for (const [key, value] of Object.entries(userTemplates)) {\n if (value && key in merged) {\n merged[key as keyof ValidationTemplates] = {\n ...merged[key as keyof ValidationTemplates],\n ...value,\n };\n }\n }\n\n return merged as ValidationTemplates;\n}\n\n/**\n * Format a validation message with placeholders.\n */\nexport function formatValidationMessage(\n template: string,\n vars: Record<string, string | number>\n): string {\n let result = template;\n for (const [key, value] of Object.entries(vars)) {\n result = result.replace(new RegExp(`\\\\$\\\\{${key}\\\\}`, 'g'), String(value));\n }\n return result;\n}\n\n/**\n * Get validation messages for all configured locales.\n * Fallback order: locale -> fallbackLocale -> 'en'\n */\nexport function getValidationMessages(\n templates: ValidationTemplates,\n ruleType: keyof ValidationTemplates,\n locales: string[],\n vars: Record<string, string | number>,\n fallbackLocale?: string\n): Record<string, string> {\n const ruleTemplates = templates[ruleType];\n const messages: Record<string, string> = {};\n\n for (const locale of locales) {\n // Try: locale -> fallbackLocale -> 'en'\n const template = ruleTemplates[locale]\n ?? (fallbackLocale ? ruleTemplates[fallbackLocale] : undefined)\n ?? ruleTemplates['en']\n ?? '';\n messages[locale] = formatValidationMessage(template, vars);\n }\n\n return messages;\n}\n","/**\n * Generates Ant Design compatible validation rules from schemas.\n */\n\nimport type { LoadedSchema, SchemaCollection, PropertyDefinition, LocalizedString, LocaleConfig } from '@famgia/omnify-types';\nimport type { TypeScriptFile, TypeScriptOptions, LocaleMap } from './types.js';\nimport {\n DEFAULT_VALIDATION_TEMPLATES,\n mergeValidationTemplates,\n getValidationMessages,\n type ValidationTemplates,\n} from './validation-templates.js';\n\n/**\n * Ant Design rule structure with multi-locale message.\n */\ninterface AntdRule {\n required?: boolean;\n type?: 'string' | 'number' | 'email' | 'url' | 'integer';\n min?: number;\n max?: number;\n len?: number;\n pattern?: string;\n message: LocaleMap;\n}\n\n/**\n * Property rules for a model.\n */\ninterface PropertyRules {\n displayName: LocaleMap;\n rules: AntdRule[];\n}\n\n/**\n * Model rules structure.\n */\ninterface ModelRules {\n displayName: LocaleMap;\n properties: Record<string, PropertyRules>;\n}\n\n/**\n * Get localized display name as object with all locales.\n */\nfunction getMultiLocaleDisplayName(\n value: LocalizedString | undefined,\n locales: string[],\n fallbackLocale: string,\n defaultValue: string\n): LocaleMap {\n if (!value) {\n // Return default value for all locales\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = defaultValue;\n }\n return result;\n }\n\n if (typeof value === 'string') {\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = value;\n }\n return result;\n }\n\n // It's a locale map\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = value[locale] ?? value[fallbackLocale] ?? value['en'] ?? defaultValue;\n }\n return result;\n}\n\n/**\n * Generate validation rules for a property.\n */\nfunction generatePropertyRules(\n propName: string,\n property: PropertyDefinition,\n displayName: LocaleMap,\n locales: string[],\n fallbackLocale: string,\n templates: ValidationTemplates\n): AntdRule[] {\n const rules: AntdRule[] = [];\n const propDef = property as {\n nullable?: boolean;\n length?: number;\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n pattern?: string;\n };\n\n // Required rule (if not nullable)\n if (!propDef.nullable) {\n rules.push({\n required: true,\n message: getValidationMessages(templates, 'required', locales, { displayName: '${displayName}' }, fallbackLocale),\n });\n }\n\n // Type-specific rules\n if (property.type === 'Email') {\n rules.push({\n type: 'email',\n message: getValidationMessages(templates, 'email', locales, { displayName: '${displayName}' }, fallbackLocale),\n });\n }\n\n // Length rules for strings\n if (property.type === 'String' || property.type === 'Text' || property.type === 'LongText') {\n if (propDef.minLength) {\n rules.push({\n min: propDef.minLength,\n message: getValidationMessages(templates, 'minLength', locales, { displayName: '${displayName}', min: propDef.minLength }, fallbackLocale),\n });\n }\n if (propDef.maxLength || propDef.length) {\n const max = propDef.maxLength ?? propDef.length!;\n rules.push({\n max,\n message: getValidationMessages(templates, 'maxLength', locales, { displayName: '${displayName}', max }, fallbackLocale),\n });\n }\n }\n\n // Numeric range rules\n if (property.type === 'Int' || property.type === 'BigInt' || property.type === 'Float') {\n if (propDef.min !== undefined) {\n rules.push({\n type: property.type === 'Float' ? 'number' : 'integer',\n min: propDef.min,\n message: getValidationMessages(templates, 'min', locales, { displayName: '${displayName}', min: propDef.min }, fallbackLocale),\n });\n }\n if (propDef.max !== undefined) {\n rules.push({\n type: property.type === 'Float' ? 'number' : 'integer',\n max: propDef.max,\n message: getValidationMessages(templates, 'max', locales, { displayName: '${displayName}', max: propDef.max }, fallbackLocale),\n });\n }\n }\n\n // Pattern rule\n if (propDef.pattern) {\n rules.push({\n pattern: propDef.pattern,\n message: getValidationMessages(templates, 'pattern', locales, { displayName: '${displayName}' }, fallbackLocale),\n });\n }\n\n // Replace ${displayName} placeholder with actual display name per locale\n for (const rule of rules) {\n const newMessage: Record<string, string> = {};\n for (const locale of locales) {\n const msg = rule.message[locale];\n if (msg) {\n newMessage[locale] = msg.replace(/\\$\\{displayName\\}/g, displayName[locale] ?? propName);\n }\n }\n (rule as { message: Record<string, string> }).message = newMessage;\n }\n\n return rules;\n}\n\n/**\n * Generate rules for a schema.\n */\nexport function generateModelRules(\n schema: LoadedSchema,\n locales: string[],\n fallbackLocale: string,\n templates: ValidationTemplates\n): ModelRules {\n const modelDisplayName = getMultiLocaleDisplayName(\n schema.displayName,\n locales,\n fallbackLocale,\n schema.name\n );\n\n const properties: Record<string, PropertyRules> = {};\n\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n const propDef = property as { displayName?: LocalizedString };\n const displayName = getMultiLocaleDisplayName(\n propDef.displayName,\n locales,\n fallbackLocale,\n propName\n );\n\n properties[propName] = {\n displayName,\n rules: generatePropertyRules(propName, property, displayName, locales, fallbackLocale, templates),\n };\n }\n }\n\n return {\n displayName: modelDisplayName,\n properties,\n };\n}\n\n/**\n * Gets file extension for imports based on options.\n */\nfunction getImportExt(options: TypeScriptOptions): string {\n return options.useJsExtension ? '.js' : '';\n}\n\n/**\n * Format rules as TypeScript code.\n */\nfunction formatRulesFile(\n schemaName: string,\n rules: ModelRules,\n options: TypeScriptOptions\n): string {\n const parts: string[] = [];\n const ext = getImportExt(options);\n\n parts.push(`/**\n * ⚠️ DO NOT EDIT THIS FILE! ⚠️\n * このファイルを編集しないでください!\n * KHÔNG ĐƯỢC SỬA FILE NÀY!\n *\n * Auto-generated validation rules and metadata for ${schemaName}.\n * Any manual changes will be OVERWRITTEN on next generation.\n *\n * To modify: Edit the schema YAML file and run: npx omnify generate\n */\n\nimport type { LocaleMap, ValidationRule } from '../common${ext}';\n\n`);\n\n // Model display name\n parts.push(`/** Display name for ${schemaName} */\\n`);\n parts.push(`export const ${schemaName}DisplayName: LocaleMap = ${JSON.stringify(rules.displayName, null, 2)};\\n\\n`);\n\n // Property metadata and rules\n parts.push(`/** Property display names for ${schemaName} */\\n`);\n parts.push(`export const ${schemaName}PropertyDisplayNames: Record<string, LocaleMap> = {\\n`);\n for (const [propName, propRules] of Object.entries(rules.properties)) {\n parts.push(` ${propName}: ${JSON.stringify(propRules.displayName)},\\n`);\n }\n parts.push(`};\\n\\n`);\n\n // Validation rules\n parts.push(`/** Validation rules for ${schemaName} (Ant Design compatible) */\\n`);\n parts.push(`export const ${schemaName}Rules: Record<string, ValidationRule[]> = {\\n`);\n for (const [propName, propRules] of Object.entries(rules.properties)) {\n if (propRules.rules.length > 0) {\n parts.push(` ${propName}: [\\n`);\n for (const rule of propRules.rules) {\n const ruleObj: Record<string, unknown> = {};\n if (rule.required) ruleObj.required = true;\n if (rule.type) ruleObj.type = `'${rule.type}'`;\n if (rule.min !== undefined) ruleObj.min = rule.min;\n if (rule.max !== undefined) ruleObj.max = rule.max;\n if (rule.pattern) ruleObj.pattern = `/${rule.pattern}/`;\n ruleObj.message = rule.message;\n\n // Format as JS object\n const ruleStr = Object.entries(ruleObj)\n .map(([k, v]) => {\n if (k === 'type') return `${k}: ${v}`;\n if (k === 'pattern') return `${k}: ${v}`;\n return `${k}: ${JSON.stringify(v)}`;\n })\n .join(', ');\n parts.push(` { ${ruleStr} },\\n`);\n }\n parts.push(` ],\\n`);\n }\n }\n parts.push(`};\\n\\n`);\n\n // Helper function to get rules with locale-specific messages\n parts.push(`/** Get validation rules with messages for a specific locale */\\n`);\n parts.push(`export function get${schemaName}Rules(locale: string): Record<string, Array<{ required?: boolean; type?: string; min?: number; max?: number; pattern?: RegExp; message: string }>> {\n const result: Record<string, Array<{ required?: boolean; type?: string; min?: number; max?: number; pattern?: RegExp; message: string }>> = {};\n for (const [prop, rules] of Object.entries(${schemaName}Rules)) {\n result[prop] = rules.map(rule => ({\n ...rule,\n message: rule.message[locale] ?? rule.message['en'] ?? '',\n }));\n }\n return result;\n}\\n\\n`);\n\n // Helper function to get display name\n parts.push(`/** Get display name for a specific locale */\\n`);\n parts.push(`export function get${schemaName}DisplayName(locale: string): string {\n return ${schemaName}DisplayName[locale] ?? ${schemaName}DisplayName['en'] ?? '${schemaName}';\n}\\n\\n`);\n\n parts.push(`/** Get property display name for a specific locale */\\n`);\n parts.push(`export function get${schemaName}PropertyDisplayName(property: string, locale: string): string {\n const names = ${schemaName}PropertyDisplayNames[property];\n return names?.[locale] ?? names?.['en'] ?? property;\n}\\n`);\n\n return parts.join('');\n}\n\n/**\n * Generate rules files for all schemas.\n */\nexport function generateRulesFiles(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TypeScriptFile[] {\n const files: TypeScriptFile[] = [];\n const localeConfig = options.localeConfig;\n const locales = [...(localeConfig?.locales ?? ['en'])]; // Convert readonly to mutable\n const fallbackLocale = localeConfig?.fallbackLocale ?? 'en';\n\n // Merge user templates with defaults\n const templates = mergeValidationTemplates(options.validationTemplates as Partial<ValidationTemplates> | undefined);\n\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n\n const rules = generateModelRules(schema, locales, fallbackLocale, templates);\n const content = formatRulesFile(schema.name, rules, options);\n\n files.push({\n filePath: `rules/${schema.name}.rules.ts`,\n content,\n types: [`${schema.name}Rules`, `${schema.name}DisplayName`],\n overwrite: true,\n });\n }\n\n return files;\n}\n","/**\n * @famgia/omnify-typescript - Zod Schema Generator\n *\n * Generates Zod schemas alongside TypeScript interfaces.\n */\n\nimport type { LoadedSchema, PropertyDefinition, LocalizedString, CustomTypeDefinition } from '@famgia/omnify-types';\nimport type { TypeScriptOptions, LocaleMap } from './types.js';\nimport { toSnakeCase } from './interface-generator.js';\n\n/**\n * Zod schema information for a property.\n */\nexport interface ZodPropertySchema {\n /** Field name in snake_case */\n readonly fieldName: string;\n /** Zod schema string (e.g., \"z.string().min(1).max(255)\") */\n readonly schema: string;\n /** Whether this field should be in create schema */\n readonly inCreate: boolean;\n /** Whether this field should be in update schema */\n readonly inUpdate: boolean;\n /** Comment for the schema */\n readonly comment?: string;\n}\n\n/**\n * Display names for a schema.\n */\nexport interface SchemaDisplayNames {\n /** Model display name per locale */\n readonly displayName: LocaleMap;\n /** Property display names per locale */\n readonly propertyDisplayNames: Record<string, LocaleMap>;\n /** Property placeholders per locale */\n readonly propertyPlaceholders: Record<string, LocaleMap>;\n}\n\n/**\n * Get localized display name as object with all locales.\n */\nfunction getMultiLocaleDisplayName(\n value: LocalizedString | undefined,\n locales: readonly string[],\n fallbackLocale: string,\n defaultValue: string\n): LocaleMap {\n if (!value) {\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = defaultValue;\n }\n return result;\n }\n\n if (typeof value === 'string') {\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = value;\n }\n return result;\n }\n\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = value[locale] ?? value[fallbackLocale] ?? value['en'] ?? defaultValue;\n }\n return result;\n}\n\n/**\n * Validation rules type for internal use.\n */\ninterface InternalValidationRules {\n readonly required?: boolean;\n readonly minLength?: number;\n readonly maxLength?: number;\n readonly url?: boolean;\n readonly uuid?: boolean;\n readonly ip?: boolean;\n readonly ipv4?: boolean;\n readonly ipv6?: boolean;\n readonly alpha?: boolean;\n readonly alphaNum?: boolean;\n readonly alphaDash?: boolean;\n readonly numeric?: boolean;\n readonly digits?: number;\n readonly digitsBetween?: readonly [number, number];\n readonly startsWith?: string | readonly string[];\n readonly endsWith?: string | readonly string[];\n readonly lowercase?: boolean;\n readonly uppercase?: boolean;\n readonly min?: number;\n readonly max?: number;\n readonly between?: readonly [number, number];\n readonly gt?: number;\n readonly lt?: number;\n readonly multipleOf?: number;\n readonly arrayMin?: number;\n readonly arrayMax?: number;\n}\n\n/**\n * Apply validation rules to a Zod schema string.\n */\nfunction applyValidationRules(\n schema: string,\n rules: InternalValidationRules | undefined,\n propType: string\n): string {\n if (!rules) return schema;\n\n let result = schema;\n\n // === Format Rules (override base type) ===\n if (rules.url) {\n // z.url() is a top-level type in Zod v4\n result = 'z.url()';\n } else if (rules.uuid) {\n result = 'z.uuid()';\n } else if (rules.ip) {\n result = 'z.ip()';\n } else if (rules.ipv4) {\n result = 'z.ipv4()';\n } else if (rules.ipv6) {\n result = 'z.ipv6()';\n }\n\n // === Check if this is a string type ===\n const isStringType = ['String', 'Text', 'MediumText', 'LongText', 'Password', 'Email'].includes(propType);\n\n // === String Length Rules (only for string types) ===\n if (isStringType) {\n if (rules.minLength !== undefined) {\n result += `.min(${rules.minLength})`;\n }\n if (rules.maxLength !== undefined) {\n result += `.max(${rules.maxLength})`;\n }\n }\n\n // === Character Pattern Rules (only for string types) ===\n if (isStringType) {\n if (rules.alpha) {\n result += `.regex(/^[a-zA-Z]*$/, { message: 'Must contain only letters' })`;\n }\n if (rules.alphaNum) {\n result += `.regex(/^[a-zA-Z0-9]*$/, { message: 'Must contain only letters and numbers' })`;\n }\n if (rules.alphaDash) {\n result += `.regex(/^[a-zA-Z0-9_-]*$/, { message: 'Must contain only letters, numbers, dashes, and underscores' })`;\n }\n if (rules.numeric) {\n result += `.regex(/^\\\\d*$/, { message: 'Must contain only numbers' })`;\n }\n if (rules.digits !== undefined) {\n result += `.length(${rules.digits}).regex(/^\\\\d+$/, { message: 'Must be exactly ${rules.digits} digits' })`;\n }\n if (rules.digitsBetween) {\n const [min, max] = rules.digitsBetween;\n result += `.min(${min}).max(${max}).regex(/^\\\\d+$/, { message: 'Must be ${min}-${max} digits' })`;\n }\n\n // === String Matching Rules ===\n if (rules.startsWith) {\n const prefixes = Array.isArray(rules.startsWith) ? rules.startsWith : [rules.startsWith];\n // 空文字列は無視\n const validPrefixes = prefixes.filter(p => p.length > 0);\n if (validPrefixes.length === 1) {\n result += `.startsWith('${validPrefixes[0]}')`;\n } else if (validPrefixes.length > 1) {\n const regex = validPrefixes.map(p => p.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|');\n result += `.regex(/^(${regex})/, { message: 'Must start with: ${validPrefixes.join(', ')}' })`;\n }\n }\n if (rules.endsWith) {\n const suffixes = Array.isArray(rules.endsWith) ? rules.endsWith : [rules.endsWith];\n // 空文字列は無視\n const validSuffixes = suffixes.filter(s => s.length > 0);\n if (validSuffixes.length === 1) {\n result += `.endsWith('${validSuffixes[0]}')`;\n } else if (validSuffixes.length > 1) {\n const regex = validSuffixes.map(s => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|');\n result += `.regex(/(${regex})$/, { message: 'Must end with: ${validSuffixes.join(', ')}' })`;\n }\n }\n if (rules.lowercase) {\n result += `.refine(v => v === v.toLowerCase(), { message: 'Must be lowercase' })`;\n }\n if (rules.uppercase) {\n result += `.refine(v => v === v.toUpperCase(), { message: 'Must be uppercase' })`;\n }\n }\n\n // === Numeric Rules ===\n if (propType === 'Int' || propType === 'TinyInt' || propType === 'BigInt' || propType === 'Float') {\n if (rules.min !== undefined) {\n result += `.gte(${rules.min})`;\n }\n if (rules.max !== undefined) {\n result += `.lte(${rules.max})`;\n }\n if (rules.between) {\n const [min, max] = rules.between;\n result += `.gte(${min}).lte(${max})`;\n }\n if (rules.gt !== undefined) {\n result += `.gt(${rules.gt})`;\n }\n if (rules.lt !== undefined) {\n result += `.lt(${rules.lt})`;\n }\n if (rules.multipleOf !== undefined) {\n result += `.multipleOf(${rules.multipleOf})`;\n }\n }\n\n return result;\n}\n\n/**\n * Generate Zod schema string for a property type.\n */\nfunction getZodSchemaForType(\n propDef: PropertyDefinition,\n fieldName: string,\n customTypes?: ReadonlyMap<string, CustomTypeDefinition>\n): string {\n const def = propDef as {\n nullable?: boolean;\n length?: number;\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n pattern?: string;\n enum?: string | readonly string[];\n options?: readonly string[];\n rules?: InternalValidationRules;\n };\n\n const isNullable = def.nullable ?? false;\n let schema = '';\n\n // Check for custom simple types first\n if (customTypes) {\n const customType = customTypes.get(propDef.type);\n if (customType && !customType.compound) {\n // Simple custom type - use string based on SQL type\n const sqlType = customType.sql?.sqlType || 'VARCHAR';\n schema = 'z.string()';\n\n // Add length constraint if available\n if (customType.sql?.length) {\n schema += `.max(${customType.sql.length})`;\n }\n\n if (isNullable) {\n schema += '.optional().nullable()';\n }\n return schema;\n }\n }\n\n switch (propDef.type) {\n case 'String':\n case 'Text':\n case 'MediumText':\n case 'LongText':\n case 'Password':\n schema = 'z.string()';\n if (!isNullable) {\n schema += '.min(1)';\n }\n if (def.maxLength || def.length) {\n schema += `.max(${def.maxLength ?? def.length})`;\n }\n if (def.minLength && def.minLength > 1) {\n // Replace .min(1) with actual minLength\n schema = schema.replace('.min(1)', `.min(${def.minLength})`);\n }\n break;\n\n case 'Email':\n // Zod v4: Use z.email() top-level for better tree-shaking\n schema = 'z.email()';\n if (def.maxLength || def.length) {\n schema += `.max(${def.maxLength ?? def.length ?? 255})`;\n }\n break;\n\n case 'TinyInt':\n case 'Int':\n case 'BigInt':\n schema = 'z.number().int()';\n if (def.min !== undefined) {\n schema += `.gte(${def.min})`;\n }\n if (def.max !== undefined) {\n schema += `.lte(${def.max})`;\n }\n break;\n\n case 'Float':\n schema = 'z.number()';\n if (def.min !== undefined) {\n schema += `.gte(${def.min})`;\n }\n if (def.max !== undefined) {\n schema += `.lte(${def.max})`;\n }\n break;\n\n case 'Boolean':\n schema = 'z.boolean()';\n break;\n\n case 'Date':\n schema = 'z.string().date()';\n break;\n\n case 'DateTime':\n case 'Timestamp':\n schema = 'z.string().datetime({ offset: true })';\n break;\n\n case 'Time':\n schema = 'z.string().time()';\n break;\n\n case 'Json':\n schema = 'z.unknown()';\n break;\n\n case 'EnumRef':\n // Reference to shared enum schema\n if (typeof def.enum === 'string') {\n schema = `z.nativeEnum(${def.enum})`;\n } else {\n schema = 'z.string()';\n }\n break;\n\n case 'Enum':\n if (typeof def.enum === 'string') {\n // Reference to named enum - will need to be imported\n schema = `${def.enum}Schema`;\n } else if (Array.isArray(def.enum)) {\n // Inline enum values\n const values = def.enum.map(v => `'${v}'`).join(', ');\n schema = `z.enum([${values}])`;\n } else {\n schema = 'z.string()';\n }\n break;\n\n case 'Select':\n if (def.options && def.options.length > 0) {\n const values = def.options.map(v => `'${v}'`).join(', ');\n schema = `z.enum([${values}])`;\n } else {\n schema = 'z.string()';\n }\n break;\n\n case 'Lookup':\n schema = 'z.number().int().positive()';\n break;\n\n case 'Association':\n // Associations are not validated in forms, skip\n return '';\n\n case 'File':\n // File uploads handled separately\n return '';\n\n default:\n schema = 'z.string()';\n }\n\n // Apply validation rules from schema definition\n if (def.rules && schema) {\n schema = applyValidationRules(schema, def.rules, propDef.type);\n }\n\n // Apply nullable/optional\n if (isNullable && schema) {\n schema += '.optional().nullable()';\n }\n\n // Apply pattern (legacy support, prefer rules.pattern in future)\n if (def.pattern && schema) {\n schema += `.regex(/${def.pattern}/)`;\n }\n\n return schema;\n}\n\n/**\n * Generate Zod schemas for compound type fields.\n */\nfunction generateCompoundTypeSchemas(\n propName: string,\n propDef: PropertyDefinition,\n customType: CustomTypeDefinition,\n options: TypeScriptOptions\n): ZodPropertySchema[] {\n const schemas: ZodPropertySchema[] = [];\n const propFields = (propDef as { fields?: Record<string, { nullable?: boolean; length?: number; hidden?: boolean }> }).fields;\n const locales = options.localeConfig?.locales ?? ['en'];\n const fallbackLocale = options.localeConfig?.fallbackLocale ?? 'en';\n\n if (!customType.expand) return schemas;\n\n for (const field of customType.expand) {\n const fieldName = `${toSnakeCase(propName)}_${toSnakeCase(field.suffix)}`;\n const fieldOverride = propFields?.[field.suffix] as {\n nullable?: boolean;\n length?: number;\n rules?: {\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n pattern?: string;\n format?: string;\n };\n } | undefined;\n\n // Nullable priority: schema field override > plugin field default > parent property > false\n const isNullable = fieldOverride?.nullable ?? field.sql?.nullable ?? (propDef as { nullable?: boolean }).nullable ?? false;\n\n // Rules priority: schema field override > plugin field rules > defaults from sql\n const pluginRules = field.rules;\n const overrideRules = fieldOverride?.rules;\n const length = fieldOverride?.length ?? overrideRules?.maxLength ?? pluginRules?.maxLength ?? field.sql?.length;\n const minLength = overrideRules?.minLength ?? pluginRules?.minLength;\n const pattern = overrideRules?.pattern ?? pluginRules?.pattern;\n const format = overrideRules?.format ?? pluginRules?.format;\n\n // Build Zod schema based on format or type\n let schema = 'z.string()';\n\n // Apply format-specific validation\n // Zod v4: Use top-level validators for better tree-shaking\n if (format === 'email') {\n schema = 'z.email()';\n } else if (format === 'url') {\n schema = 'z.url()';\n } else if (format === 'phone') {\n // Japanese phone pattern: 0X0-XXXX-XXXX or 0X-XXXX-XXXX\n schema = 'z.string()';\n } else if (format === 'postal_code') {\n // Japanese postal code: XXX-XXXX\n schema = `z.string().regex(/^\\\\d{3}-?\\\\d{4}$/)`;\n }\n\n // Apply length constraints\n if (!isNullable) {\n const min = minLength ?? 1;\n schema += `.min(${min})`;\n } else if (minLength) {\n schema += `.min(${minLength})`;\n }\n\n if (length) {\n schema += `.max(${length})`;\n }\n\n // Apply pattern (if not already applied via format)\n if (pattern && !format) {\n schema += `.regex(/${pattern}/)`;\n }\n\n // Apply nullable\n if (isNullable) {\n schema += '.optional().nullable()';\n }\n\n // Get display name\n const propDisplayName = getMultiLocaleDisplayName(\n (propDef as { displayName?: LocalizedString }).displayName,\n locales,\n fallbackLocale,\n propName\n );\n\n schemas.push({\n fieldName,\n schema,\n inCreate: true,\n inUpdate: true,\n comment: `${propDisplayName['en'] ?? propName} (${field.suffix})`,\n });\n }\n\n return schemas;\n}\n\n/**\n * Generate Zod schemas for all properties in a schema.\n */\nexport function generateZodSchemas(\n schema: LoadedSchema,\n options: TypeScriptOptions\n): ZodPropertySchema[] {\n const schemas: ZodPropertySchema[] = [];\n const customTypes = options.customTypes;\n\n if (!schema.properties) return schemas;\n\n for (const [propName, propDef] of Object.entries(schema.properties)) {\n // Check for compound custom types\n if (customTypes) {\n const customType = customTypes.get(propDef.type);\n if (customType?.compound) {\n schemas.push(...generateCompoundTypeSchemas(propName, propDef, customType, options));\n continue;\n }\n }\n\n const zodSchema = getZodSchemaForType(propDef, propName, customTypes);\n if (!zodSchema) continue;\n\n const fieldName = toSnakeCase(propName);\n\n schemas.push({\n fieldName,\n schema: zodSchema,\n inCreate: true,\n inUpdate: true,\n comment: undefined,\n });\n }\n\n return schemas;\n}\n\n/**\n * Generate display names and placeholders for a schema.\n */\nexport function generateDisplayNames(\n schema: LoadedSchema,\n options: TypeScriptOptions\n): SchemaDisplayNames {\n const locales = options.localeConfig?.locales ?? ['en'];\n const fallbackLocale = options.localeConfig?.fallbackLocale ?? 'en';\n const customTypes = options.customTypes;\n\n const displayName = getMultiLocaleDisplayName(\n schema.displayName,\n locales,\n fallbackLocale,\n schema.name\n );\n\n const propertyDisplayNames: Record<string, LocaleMap> = {};\n const propertyPlaceholders: Record<string, LocaleMap> = {};\n\n if (schema.properties) {\n for (const [propName, propDef] of Object.entries(schema.properties)) {\n const prop = propDef as {\n displayName?: LocalizedString;\n placeholder?: LocalizedString;\n fields?: Record<string, { displayName?: LocalizedString; placeholder?: LocalizedString }>;\n };\n const fieldName = toSnakeCase(propName);\n\n // Check for compound types - expand to individual fields\n if (customTypes) {\n const customType = customTypes.get(propDef.type);\n if (customType?.compound && customType.expand) {\n // Add compound-level displayName (e.g., `name` -> `氏名`)\n // This is used by components that need the combined field's label\n if (prop.displayName) {\n propertyDisplayNames[fieldName] = getMultiLocaleDisplayName(\n prop.displayName,\n locales,\n fallbackLocale,\n propName\n );\n }\n\n for (const field of customType.expand) {\n const expandedFieldName = `${fieldName}_${toSnakeCase(field.suffix)}`;\n const fieldOverride = prop.fields?.[field.suffix];\n\n // Display name for compound field (priority: schema override > plugin label > fallback)\n const labelSource = fieldOverride?.displayName ?? field.label;\n if (labelSource) {\n // Use explicit label from schema override or plugin\n propertyDisplayNames[expandedFieldName] = getMultiLocaleDisplayName(\n labelSource,\n locales,\n fallbackLocale,\n field.suffix\n );\n } else {\n // Fallback: parent displayName + field suffix\n propertyDisplayNames[expandedFieldName] = getMultiLocaleDisplayName(\n prop.displayName,\n locales,\n fallbackLocale,\n propName\n );\n // Append field suffix to display name\n for (const locale of locales) {\n propertyDisplayNames[expandedFieldName] = {\n ...propertyDisplayNames[expandedFieldName],\n [locale]: `${propertyDisplayNames[expandedFieldName][locale]} (${field.suffix})`,\n };\n }\n }\n\n // Placeholder for compound field (priority: schema override > plugin default > empty)\n const placeholderSource = fieldOverride?.placeholder ?? field.placeholder;\n if (placeholderSource) {\n propertyPlaceholders[expandedFieldName] = getMultiLocaleDisplayName(\n placeholderSource,\n locales,\n fallbackLocale,\n ''\n );\n }\n }\n continue;\n }\n }\n\n // Display name for regular field\n propertyDisplayNames[fieldName] = getMultiLocaleDisplayName(\n prop.displayName,\n locales,\n fallbackLocale,\n propName\n );\n\n // Placeholder for regular field\n if (prop.placeholder) {\n propertyPlaceholders[fieldName] = getMultiLocaleDisplayName(\n prop.placeholder,\n locales,\n fallbackLocale,\n ''\n );\n }\n }\n }\n\n return { displayName, propertyDisplayNames, propertyPlaceholders };\n}\n\n/**\n * Get fields to exclude from create/update schemas.\n */\nexport function getExcludedFields(\n schema: LoadedSchema,\n customTypes?: ReadonlyMap<string, CustomTypeDefinition>\n): { create: Set<string>; update: Set<string> } {\n const createExclude = new Set<string>();\n const updateExclude = new Set<string>();\n\n // Always exclude id\n if (schema.options?.id !== false) {\n createExclude.add('id');\n updateExclude.add('id');\n }\n\n // Exclude timestamps\n if (schema.options?.timestamps !== false) {\n createExclude.add('created_at');\n createExclude.add('updated_at');\n updateExclude.add('created_at');\n updateExclude.add('updated_at');\n }\n\n // Exclude soft delete\n if (schema.options?.softDelete) {\n createExclude.add('deleted_at');\n updateExclude.add('deleted_at');\n }\n\n // Exclude email_verified_at\n if (schema.properties) {\n if (schema.properties['emailVerifiedAt'] || schema.properties['email_verified_at']) {\n createExclude.add('email_verified_at');\n updateExclude.add('email_verified_at');\n }\n }\n\n // Exclude computed fields from compound types\n if (schema.properties && customTypes) {\n for (const [propName, propDef] of Object.entries(schema.properties)) {\n const customType = customTypes.get(propDef.type);\n if (customType?.accessors) {\n for (const accessor of customType.accessors) {\n const fieldName = `${toSnakeCase(propName)}_${toSnakeCase(accessor.name)}`;\n createExclude.add(fieldName);\n updateExclude.add(fieldName);\n }\n }\n }\n }\n\n return { create: createExclude, update: updateExclude };\n}\n\n/**\n * Format Zod schemas section for base file.\n */\nexport function formatZodSchemasSection(\n schemaName: string,\n zodSchemas: ZodPropertySchema[],\n displayNames: SchemaDisplayNames,\n excludedFields: { create: Set<string>; update: Set<string> }\n): string {\n const parts: string[] = [];\n const lowerName = schemaName.charAt(0).toLowerCase() + schemaName.slice(1);\n\n // I18n - Unified locale object\n parts.push(`// ============================================================================\\n`);\n parts.push(`// I18n (Internationalization)\\n`);\n parts.push(`// ============================================================================\\n\\n`);\n\n parts.push(`/**\\n`);\n parts.push(` * Unified i18n object for ${schemaName}\\n`);\n parts.push(` * Contains model label and all field labels/placeholders\\n`);\n parts.push(` */\\n`);\n parts.push(`export const ${lowerName}I18n = {\\n`);\n parts.push(` /** Model display name */\\n`);\n parts.push(` label: ${JSON.stringify(displayNames.displayName)},\\n`);\n parts.push(` /** Field labels and placeholders */\\n`);\n parts.push(` fields: {\\n`);\n for (const [propName, labelMap] of Object.entries(displayNames.propertyDisplayNames)) {\n const placeholderMap = displayNames.propertyPlaceholders[propName];\n parts.push(` ${propName}: {\\n`);\n parts.push(` label: ${JSON.stringify(labelMap)},\\n`);\n if (placeholderMap) {\n parts.push(` placeholder: ${JSON.stringify(placeholderMap)},\\n`);\n }\n parts.push(` },\\n`);\n }\n parts.push(` },\\n`);\n parts.push(`} as const;\\n\\n`);\n\n // Field Schemas\n parts.push(`// ============================================================================\\n`);\n parts.push(`// Zod Schemas\\n`);\n parts.push(`// ============================================================================\\n\\n`);\n\n parts.push(`/** Field schemas for ${schemaName} */\\n`);\n parts.push(`export const base${schemaName}Schemas = {\\n`);\n for (const prop of zodSchemas) {\n if (prop.comment) {\n parts.push(` /** ${prop.comment} */\\n`);\n }\n parts.push(` ${prop.fieldName}: ${prop.schema},\\n`);\n }\n parts.push(`} as const;\\n\\n`);\n\n // Create Schema\n const createFields = zodSchemas.filter(p => p.inCreate && !excludedFields.create.has(p.fieldName));\n parts.push(`/** Create schema for ${schemaName} (POST requests) */\\n`);\n parts.push(`export const base${schemaName}CreateSchema = z.object({\\n`);\n for (const prop of createFields) {\n parts.push(` ${prop.fieldName}: base${schemaName}Schemas.${prop.fieldName},\\n`);\n }\n parts.push(`});\\n\\n`);\n\n // Update Schema\n parts.push(`/** Update schema for ${schemaName} (PUT/PATCH requests) */\\n`);\n parts.push(`export const base${schemaName}UpdateSchema = base${schemaName}CreateSchema.partial();\\n\\n`);\n\n // Inferred Types\n parts.push(`// ============================================================================\\n`);\n parts.push(`// Inferred Types\\n`);\n parts.push(`// ============================================================================\\n\\n`);\n\n parts.push(`export type Base${schemaName}Create = z.infer<typeof base${schemaName}CreateSchema>;\\n`);\n parts.push(`export type Base${schemaName}Update = z.infer<typeof base${schemaName}UpdateSchema>;\\n\\n`);\n\n // Helper Functions\n parts.push(`// ============================================================================\\n`);\n parts.push(`// I18n Helper Functions\\n`);\n parts.push(`// ============================================================================\\n\\n`);\n\n parts.push(`/** Get model label for a specific locale */\\n`);\n parts.push(`export function get${schemaName}Label(locale: string): string {\\n`);\n parts.push(` return ${lowerName}I18n.label[locale as keyof typeof ${lowerName}I18n.label] ?? ${lowerName}I18n.label['en'] ?? '${schemaName}';\\n`);\n parts.push(`}\\n\\n`);\n\n parts.push(`/** Get field label for a specific locale */\\n`);\n parts.push(`export function get${schemaName}FieldLabel(field: string, locale: string): string {\\n`);\n parts.push(` const fieldI18n = ${lowerName}I18n.fields[field as keyof typeof ${lowerName}I18n.fields];\\n`);\n parts.push(` if (!fieldI18n) return field;\\n`);\n parts.push(` return fieldI18n.label[locale as keyof typeof fieldI18n.label] ?? fieldI18n.label['en'] ?? field;\\n`);\n parts.push(`}\\n\\n`);\n\n parts.push(`/** Get field placeholder for a specific locale */\\n`);\n parts.push(`export function get${schemaName}FieldPlaceholder(field: string, locale: string): string {\\n`);\n parts.push(` const fieldI18n = ${lowerName}I18n.fields[field as keyof typeof ${lowerName}I18n.fields];\\n`);\n parts.push(` if (!fieldI18n || !('placeholder' in fieldI18n)) return '';\\n`);\n parts.push(` const placeholder = fieldI18n.placeholder as Record<string, string>;\\n`);\n parts.push(` return placeholder[locale] ?? placeholder['en'] ?? '';\\n`);\n parts.push(`}\\n`);\n\n return parts.join('');\n}\n\n/**\n * Format user model file with Zod re-exports.\n * @param schemaName - The schema name\n * @param ext - Import extension ('.js' for ESM, '' for bundlers)\n */\nexport function formatZodModelFile(schemaName: string, ext: string = ''): string {\n const lowerName = schemaName.charAt(0).toLowerCase() + schemaName.slice(1);\n\n return `/**\n * ${schemaName} Model\n *\n * This file extends the auto-generated base interface.\n * You can add custom methods, computed properties, or override types/schemas here.\n * This file will NOT be overwritten by the generator.\n */\n\nimport { z } from 'zod';\nimport type { ${schemaName} as ${schemaName}Base } from './base/${schemaName}${ext}';\nimport {\n base${schemaName}Schemas,\n base${schemaName}CreateSchema,\n base${schemaName}UpdateSchema,\n ${lowerName}I18n,\n get${schemaName}Label,\n get${schemaName}FieldLabel,\n get${schemaName}FieldPlaceholder,\n} from './base/${schemaName}${ext}';\n\n// ============================================================================\n// Types (extend or re-export)\n// ============================================================================\n\nexport interface ${schemaName} extends ${schemaName}Base {\n // Add custom properties here\n}\n\n// ============================================================================\n// Schemas (extend or re-export)\n// ============================================================================\n\nexport const ${lowerName}Schemas = { ...base${schemaName}Schemas };\nexport const ${lowerName}CreateSchema = base${schemaName}CreateSchema;\nexport const ${lowerName}UpdateSchema = base${schemaName}UpdateSchema;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ${schemaName}Create = z.infer<typeof ${lowerName}CreateSchema>;\nexport type ${schemaName}Update = z.infer<typeof ${lowerName}UpdateSchema>;\n\n// Re-export i18n and helpers\nexport {\n ${lowerName}I18n,\n get${schemaName}Label,\n get${schemaName}FieldLabel,\n get${schemaName}FieldPlaceholder,\n};\n\n// Re-export base type for internal use\nexport type { ${schemaName}Base };\n`;\n}\n","/**\n * @famgia/omnify-typescript - TypeScript Generator\n *\n * Generates TypeScript models with base/model pattern:\n * - models/base/[SchemaName].ts - Auto-generated base interfaces, DO NOT EDIT\n * - models/enum/[EnumName].ts - Auto-generated enums/type aliases, DO NOT EDIT\n * - models/[SchemaName].ts - Extends base, user can customize\n * - models/index.ts - Re-exports all\n */\n\nimport type { SchemaCollection } from '@famgia/omnify-types';\nimport type { TypeScriptFile, TypeScriptOptions, TSEnum, TSTypeAlias } from './types.js';\nimport { generateInterfaces, formatInterface, toSnakeCase } from './interface-generator.js';\nimport { generateEnums, generatePluginEnums, formatEnum, formatTypeAlias, extractInlineEnums } from './enum-generator.js';\nimport { generateRulesFiles } from './rules-generator.js';\nimport {\n generateZodSchemas,\n generateDisplayNames,\n getExcludedFields,\n formatZodSchemasSection,\n formatZodModelFile,\n} from './zod-generator.js';\n\n/**\n * Default options for TypeScript generation.\n */\nconst DEFAULT_OPTIONS: TypeScriptOptions = {\n readonly: false, // Changed: interfaces should be mutable for forms/mutations\n strictNullChecks: true,\n generateZodSchemas: true, // Generate Zod schemas by default\n generateRules: false, // Legacy Ant Design rules (deprecated, ignored when generateZodSchemas=true)\n useJsExtension: false, // Bundlers (Vite, webpack) don't need .js extension\n};\n\n/**\n * Gets file extension for imports based on options.\n * Returns '.js' for native ESM, empty string for bundlers.\n */\nfunction getImportExt(options: TypeScriptOptions): string {\n return options.useJsExtension ? '.js' : '';\n}\n\n/**\n * Generates the base file header comment (DO NOT EDIT).\n */\nfunction generateBaseHeader(): string {\n return `/**\n * ⚠️ DO NOT EDIT THIS FILE! ⚠️\n * このファイルを編集しないでください!\n * KHÔNG ĐƯỢC SỬA FILE NÀY!\n *\n * Auto-generated TypeScript types from Omnify schemas.\n * Any manual changes will be OVERWRITTEN on next generation.\n *\n * To modify: Edit the schema YAML file and run: npx omnify generate\n */\n\n`;\n}\n\n/**\n * Generates the model file header comment (user can edit).\n */\nfunction generateModelHeader(schemaName: string): string {\n return `/**\n * ${schemaName} Model\n *\n * This file extends the auto-generated base interface.\n * You can add custom methods, computed properties, or override types here.\n * This file will NOT be overwritten by the generator.\n */\n\n`;\n}\n\n/**\n * Collects all computed field names from a schema.\n * Includes accessor fields from compound types.\n */\nfunction getComputedFields(\n schema: { properties?: Record<string, { type: string }> },\n customTypes: ReadonlyMap<string, { accessors?: readonly { name: string }[] }> | undefined\n): string[] {\n const computedFields: string[] = [];\n if (!schema.properties) return computedFields;\n\n for (const [propName, propDef] of Object.entries(schema.properties)) {\n const snakeName = toSnakeCase(propName);\n const customType = customTypes?.get(propDef.type);\n\n // Add accessor fields from compound types\n if (customType?.accessors) {\n for (const accessor of customType.accessors) {\n computedFields.push(`${snakeName}_${toSnakeCase(accessor.name)}`);\n }\n }\n }\n\n return computedFields;\n}\n\n/**\n * Generates utility types for a schema.\n * - Create: For POST requests (excludes id, timestamps, computed fields, server-managed fields)\n * - Update: For PUT/PATCH requests (all fields optional)\n */\nfunction generateUtilityTypes(\n schemaName: string,\n schema: { options?: { id?: boolean; timestamps?: boolean; softDelete?: boolean }; properties?: Record<string, { type: string }> },\n customTypes?: ReadonlyMap<string, { accessors?: readonly { name: string }[] }>\n): string {\n const parts: string[] = [];\n const excludeFields: string[] = [];\n\n // Exclude id if auto-generated\n if (schema.options?.id !== false) {\n excludeFields.push(\"'id'\");\n }\n\n // Exclude timestamps if enabled\n if (schema.options?.timestamps !== false) {\n excludeFields.push(\"'created_at'\", \"'updated_at'\");\n }\n\n // Exclude soft delete if enabled\n if (schema.options?.softDelete) {\n excludeFields.push(\"'deleted_at'\");\n }\n\n // Exclude email_verified_at (server-managed field)\n if (schema.properties?.['emailVerifiedAt'] || schema.properties?.['email_verified_at']) {\n excludeFields.push(\"'email_verified_at'\");\n }\n\n // Exclude computed fields from compound types\n const computedFields = getComputedFields(schema, customTypes);\n for (const field of computedFields) {\n excludeFields.push(`'${field}'`);\n }\n\n const omitType = excludeFields.length > 0\n ? `Omit<${schemaName}, ${excludeFields.join(' | ')}>`\n : schemaName;\n\n // Create type - for POST requests\n parts.push(`\\n/** For creating new ${schemaName} (POST requests) */`);\n parts.push(`\\nexport type ${schemaName}Create = ${omitType};\\n`);\n\n // Update type - for PUT/PATCH requests (all optional)\n parts.push(`\\n/** For updating ${schemaName} (PUT/PATCH requests) */`);\n parts.push(`\\nexport type ${schemaName}Update = Partial<${schemaName}Create>;\\n`);\n\n return parts.join('');\n}\n\n/**\n * Checks if interface uses DateTimeString or DateString types.\n */\nfunction needsDateTimeImports(iface: { properties: readonly { type: string }[] }): { dateTime: boolean; date: boolean } {\n let dateTime = false;\n let date = false;\n for (const prop of iface.properties) {\n if (prop.type === 'DateTimeString' || prop.type.includes('DateTimeString')) {\n dateTime = true;\n }\n if (prop.type === 'DateString' || prop.type.includes('DateString')) {\n date = true;\n }\n }\n return { dateTime, date };\n}\n\n/**\n * Generates a single base interface file.\n */\nfunction generateBaseInterfaceFile(\n schemaName: string,\n schemas: SchemaCollection,\n options: TypeScriptOptions\n): TypeScriptFile {\n const interfaces = generateInterfaces(schemas, options);\n const iface = interfaces.find(i => i.name === schemaName);\n const schema = schemas[schemaName];\n\n if (!iface || !schema) {\n throw new Error(`Interface not found for schema: ${schemaName}`);\n }\n\n const parts: string[] = [generateBaseHeader()];\n\n // Add Zod import if generating Zod schemas\n if (options.generateZodSchemas) {\n parts.push(`import { z } from 'zod';\\n`);\n }\n\n // Check if we need to import DateTimeString or DateString\n const dateImports = needsDateTimeImports(iface);\n const commonImports: string[] = [];\n if (dateImports.dateTime) commonImports.push('DateTimeString');\n if (dateImports.date) commonImports.push('DateString');\n const ext = getImportExt(options);\n if (commonImports.length > 0) {\n parts.push(`import type { ${commonImports.join(', ')} } from '../common${ext}';\\n`);\n }\n\n // Add imports for enum dependencies\n if (iface.enumDependencies && iface.enumDependencies.length > 0) {\n // When enums are in separate folder, use ../../enum/ (from base/ folder)\n const enumPrefix = options.enumImportPrefix ? `../${options.enumImportPrefix}` : '../enum';\n // Build set of plugin enum names for path resolution\n const pluginEnumNames = new Set(\n options.pluginEnums ? Array.from(options.pluginEnums.keys()) : []\n );\n for (const enumName of iface.enumDependencies) {\n // Plugin enums are in plugin/ subfolder to avoid conflicts\n const enumPath = pluginEnumNames.has(enumName)\n ? `${enumPrefix}/plugin/${enumName}${ext}`\n : `${enumPrefix}/${enumName}${ext}`;\n parts.push(`import { ${enumName} } from '${enumPath}';\\n`);\n }\n }\n\n // Add imports for dependencies\n if (iface.dependencies && iface.dependencies.length > 0) {\n for (const dep of iface.dependencies) {\n parts.push(`import type { ${dep} } from './${dep}${ext}';\\n`);\n }\n parts.push('\\n');\n } else if (commonImports.length > 0 || options.generateZodSchemas || (iface.enumDependencies && iface.enumDependencies.length > 0)) {\n parts.push('\\n');\n }\n\n // Main interface\n parts.push(formatInterface(iface));\n parts.push('\\n');\n\n // Generate Zod schemas if enabled\n if (options.generateZodSchemas) {\n const zodSchemas = generateZodSchemas(schema, options);\n const displayNames = generateDisplayNames(schema, options);\n const excludedFields = getExcludedFields(schema, options.customTypes);\n parts.push('\\n');\n parts.push(formatZodSchemasSection(schemaName, zodSchemas, displayNames, excludedFields));\n } else {\n // Legacy: Utility types (Create, Update) without Zod\n parts.push(generateUtilityTypes(schemaName, schema, options.customTypes));\n }\n\n return {\n filePath: `base/${schemaName}.ts`,\n content: parts.join(''),\n types: [schemaName, `${schemaName}Create`, `${schemaName}Update`],\n overwrite: true,\n };\n}\n\n/**\n * Generates a single enum file.\n * @param enumDef - The enum definition\n * @param isPluginEnum - If true, places in plugin/ subfolder to avoid conflicts\n */\nfunction generateEnumFile(enumDef: TSEnum, isPluginEnum = false): TypeScriptFile {\n const parts: string[] = [generateBaseHeader()];\n parts.push(formatEnum(enumDef));\n parts.push('\\n');\n\n // Plugin enums go to plugin/ subfolder to avoid conflicts with schema enums\n const filePath = isPluginEnum\n ? `plugin/${enumDef.name}.ts`\n : `${enumDef.name}.ts`;\n\n return {\n filePath,\n content: parts.join(''),\n types: [enumDef.name],\n overwrite: true,\n category: 'enum',\n };\n}\n\n/**\n * Generates a single type alias file.\n */\nfunction generateTypeAliasFile(alias: TSTypeAlias): TypeScriptFile {\n const parts: string[] = [generateBaseHeader()];\n parts.push(formatTypeAlias(alias));\n parts.push('\\n');\n\n return {\n filePath: `${alias.name}.ts`,\n content: parts.join(''),\n types: [alias.name],\n overwrite: true,\n category: 'enum',\n };\n}\n\n/**\n * Generates model file content that extends base.\n */\nfunction generateModelFile(schemaName: string, options: TypeScriptOptions): TypeScriptFile {\n // Use Zod format if enabled\n if (options.generateZodSchemas) {\n return {\n filePath: `${schemaName}.ts`,\n content: formatZodModelFile(schemaName, getImportExt(options)),\n types: [schemaName],\n overwrite: false, // Never overwrite user models\n };\n }\n\n // Legacy format without Zod\n const parts: string[] = [generateModelHeader(schemaName)];\n const ext = getImportExt(options);\n\n // Import base interface\n parts.push(`import type { ${schemaName} as ${schemaName}Base } from './base/${schemaName}${ext}';\\n\\n`);\n\n // Export interface that extends base\n parts.push(`/**\\n * ${schemaName} model interface.\\n * Add custom properties or methods here.\\n */\\n`);\n parts.push(`export interface ${schemaName} extends ${schemaName}Base {\\n`);\n parts.push(` // Add custom properties here\\n`);\n parts.push(`}\\n\\n`);\n\n // Re-export base for convenience\n parts.push(`// Re-export base type for internal use\\n`);\n parts.push(`export type { ${schemaName}Base };\\n`);\n\n return {\n filePath: `${schemaName}.ts`,\n content: parts.join(''),\n types: [schemaName],\n overwrite: false, // Never overwrite user models\n };\n}\n\n/**\n * Default validation messages for all supported locales.\n * Supported: en, ja, vi, ko, zh-CN (Simplified), zh-TW (Traditional), th, es\n */\nconst DEFAULT_VALIDATION_MESSAGES: Record<string, Record<string, string>> = {\n required: {\n en: '${displayName} is required',\n ja: '${displayName}は必須です',\n vi: '${displayName} là bắt buộc',\n ko: '${displayName}은(는) 필수입니다',\n 'zh-CN': '${displayName}是必填项',\n 'zh-TW': '${displayName}為必填欄位',\n th: '${displayName} จำเป็นต้องกรอก',\n es: '${displayName} es obligatorio',\n },\n minLength: {\n en: '${displayName} must be at least ${min} characters',\n ja: '${displayName}は${min}文字以上で入力してください',\n vi: '${displayName} phải có ít nhất ${min} ký tự',\n ko: '${displayName}은(는) ${min}자 이상이어야 합니다',\n 'zh-CN': '${displayName}至少需要${min}个字符',\n 'zh-TW': '${displayName}至少需要${min}個字元',\n th: '${displayName} ต้องมีอย่างน้อย ${min} ตัวอักษร',\n es: '${displayName} debe tener al menos ${min} caracteres',\n },\n maxLength: {\n en: '${displayName} must be at most ${max} characters',\n ja: '${displayName}は${max}文字以内で入力してください',\n vi: '${displayName} không được quá ${max} ký tự',\n ko: '${displayName}은(는) ${max}자 이하여야 합니다',\n 'zh-CN': '${displayName}最多${max}个字符',\n 'zh-TW': '${displayName}最多${max}個字元',\n th: '${displayName} ต้องไม่เกิน ${max} ตัวอักษร',\n es: '${displayName} debe tener como máximo ${max} caracteres',\n },\n min: {\n en: '${displayName} must be at least ${min}',\n ja: '${displayName}は${min}以上で入力してください',\n vi: '${displayName} phải lớn hơn hoặc bằng ${min}',\n ko: '${displayName}은(는) ${min} 이상이어야 합니다',\n 'zh-CN': '${displayName}必须大于等于${min}',\n 'zh-TW': '${displayName}必須大於等於${min}',\n th: '${displayName} ต้องมากกว่าหรือเท่ากับ ${min}',\n es: '${displayName} debe ser al menos ${min}',\n },\n max: {\n en: '${displayName} must be at most ${max}',\n ja: '${displayName}は${max}以下で入力してください',\n vi: '${displayName} phải nhỏ hơn hoặc bằng ${max}',\n ko: '${displayName}은(는) ${max} 이하여야 합니다',\n 'zh-CN': '${displayName}必须小于等于${max}',\n 'zh-TW': '${displayName}必須小於等於${max}',\n th: '${displayName} ต้องน้อยกว่าหรือเท่ากับ ${max}',\n es: '${displayName} debe ser como máximo ${max}',\n },\n email: {\n en: 'Please enter a valid email address',\n ja: '有効なメールアドレスを入力してください',\n vi: 'Vui lòng nhập địa chỉ email hợp lệ',\n ko: '유효한 이메일 주소를 입력하세요',\n 'zh-CN': '请输入有效的电子邮件地址',\n 'zh-TW': '請輸入有效的電子郵件地址',\n th: 'กรุณากรอกอีเมลที่ถูกต้อง',\n es: 'Por favor, introduce una dirección de correo electrónico válida',\n },\n url: {\n en: 'Please enter a valid URL',\n ja: '有効なURLを入力してください',\n vi: 'Vui lòng nhập URL hợp lệ',\n ko: '유효한 URL을 입력하세요',\n 'zh-CN': '请输入有效的URL',\n 'zh-TW': '請輸入有效的網址',\n th: 'กรุณากรอก URL ที่ถูกต้อง',\n es: 'Por favor, introduce una URL válida',\n },\n pattern: {\n en: '${displayName} format is invalid',\n ja: '${displayName}の形式が正しくありません',\n vi: '${displayName} không đúng định dạng',\n ko: '${displayName} 형식이 올바르지 않습니다',\n 'zh-CN': '${displayName}格式不正确',\n 'zh-TW': '${displayName}格式不正確',\n th: 'รูปแบบ${displayName}ไม่ถูกต้อง',\n es: 'El formato de ${displayName} no es válido',\n },\n};\n\n/**\n * Generates common.ts with shared types.\n */\nfunction generateCommonFile(options: TypeScriptOptions): TypeScriptFile {\n const locales = options.localeConfig?.locales ?? ['ja', 'en'];\n const localeUnion = locales.map(l => `'${l}'`).join(' | ');\n\n const content = `${generateBaseHeader()}\n/**\n * Locale map for multi-language support.\n */\nexport interface LocaleMap {\n [locale: string]: string;\n}\n\n/**\n * Supported locales in this project.\n */\nexport type Locale = ${localeUnion};\n\n/**\n * Validation rule with multi-locale messages.\n * Use get{Model}Rules(locale) to get Ant Design compatible rules with string messages.\n */\nexport interface ValidationRule {\n required?: boolean;\n type?: 'string' | 'number' | 'email' | 'url' | 'integer' | 'array' | 'object';\n min?: number;\n max?: number;\n len?: number;\n pattern?: RegExp;\n message: LocaleMap;\n}\n\n/**\n * ISO 8601 date-time string.\n */\nexport type DateTimeString = string;\n\n/**\n * ISO 8601 date string (YYYY-MM-DD).\n */\nexport type DateString = string;\n`;\n\n return {\n filePath: 'common.ts',\n content,\n types: ['LocaleMap', 'Locale', 'ValidationRule', 'DateTimeString', 'DateString'],\n overwrite: true,\n };\n}\n\n/**\n * Generates i18n.ts with validation messages and locale helpers.\n */\nfunction generateI18nFile(options: TypeScriptOptions): TypeScriptFile {\n const locales = options.localeConfig?.locales ?? ['ja', 'en'];\n const defaultLocale = options.localeConfig?.defaultLocale ?? 'ja';\n const fallbackLocale = options.localeConfig?.fallbackLocale ?? 'en';\n const userMessages = options.localeConfig?.messages ?? {};\n\n // Merge user messages with defaults (user takes priority)\n const mergedMessages: Record<string, Record<string, string>> = {};\n\n // Start with defaults for supported locales only\n for (const [key, defaultMsgs] of Object.entries(DEFAULT_VALIDATION_MESSAGES)) {\n mergedMessages[key] = {};\n for (const locale of locales) {\n if (defaultMsgs[locale]) {\n mergedMessages[key][locale] = defaultMsgs[locale];\n }\n }\n }\n\n // Override with user messages\n for (const [key, userMsgs] of Object.entries(userMessages)) {\n if (userMsgs) {\n if (!mergedMessages[key]) {\n mergedMessages[key] = {};\n }\n for (const [locale, msg] of Object.entries(userMsgs)) {\n mergedMessages[key][locale] = msg;\n }\n }\n }\n\n const messagesJson = JSON.stringify(mergedMessages, null, 2);\n const ext = getImportExt(options);\n\n const content = `${generateBaseHeader()}\nimport type { LocaleMap } from './common${ext}';\n\n/**\n * Default locale for this project.\n */\nexport const defaultLocale = '${defaultLocale}' as const;\n\n/**\n * Fallback locale when requested locale is not found.\n */\nexport const fallbackLocale = '${fallbackLocale}' as const;\n\n/**\n * Supported locales in this project.\n */\nexport const supportedLocales = ${JSON.stringify(locales)} as const;\n\n/**\n * Validation messages for all supported locales.\n * Use getMessage(key, locale, params) to get formatted message.\n */\nexport const validationMessages = ${messagesJson} as const;\n\n/**\n * Get validation message for a specific key and locale.\n * Supports template placeholders: \\${displayName}, \\${min}, \\${max}, etc.\n *\n * @param key - Message key (e.g., 'required', 'minLength')\n * @param locale - Locale code (e.g., 'ja', 'en')\n * @param params - Template parameters to replace\n * @returns Formatted message string\n *\n * @example\n * getMessage('required', 'ja', { displayName: '氏名' })\n * // => '氏名は必須です'\n */\nexport function getMessage(\n key: string,\n locale: string,\n params: Record<string, string | number> = {}\n): string {\n const messages = validationMessages[key as keyof typeof validationMessages];\n if (!messages) return key;\n\n let message = (messages as LocaleMap)[locale]\n ?? (messages as LocaleMap)[fallbackLocale]\n ?? (messages as LocaleMap)[defaultLocale]\n ?? key;\n\n // Replace template placeholders\n for (const [param, value] of Object.entries(params)) {\n message = message.replace(new RegExp(\\`\\\\\\\\$\\\\{$\\{param}\\\\}\\`, 'g'), String(value));\n }\n\n return message;\n}\n\n/**\n * Get all validation messages for a specific locale.\n *\n * @param locale - Locale code\n * @returns Object with all messages for the locale\n */\nexport function getMessages(locale: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, messages] of Object.entries(validationMessages)) {\n result[key] = (messages as LocaleMap)[locale]\n ?? (messages as LocaleMap)[fallbackLocale]\n ?? (messages as LocaleMap)[defaultLocale]\n ?? key;\n }\n return result;\n}\n`;\n\n return {\n filePath: 'i18n.ts',\n content,\n types: ['validationMessages', 'getMessage', 'getMessages'],\n overwrite: true,\n };\n}\n\n/**\n * Generates index file for re-exports.\n */\nfunction generateIndexFile(\n schemas: SchemaCollection,\n enums: TSEnum[],\n pluginEnums: TSEnum[],\n typeAliases: TSTypeAlias[],\n options: TypeScriptOptions\n): TypeScriptFile {\n const parts: string[] = [generateBaseHeader()];\n const ext = getImportExt(options);\n\n // Export common types\n parts.push(`// Common Types\\n`);\n parts.push(`export type { LocaleMap, Locale, ValidationRule, DateTimeString, DateString } from './common${ext}';\\n\\n`);\n\n // Export i18n utilities\n parts.push(`// i18n (Internationalization)\\n`);\n parts.push(`export {\\n`);\n parts.push(` defaultLocale,\\n`);\n parts.push(` fallbackLocale,\\n`);\n parts.push(` supportedLocales,\\n`);\n parts.push(` validationMessages,\\n`);\n parts.push(` getMessage,\\n`);\n parts.push(` getMessages,\\n`);\n parts.push(`} from './i18n${ext}';\\n\\n`);\n\n const enumPrefix = options.enumImportPrefix ?? './enum';\n\n // Export schema enums (enum + Values + isX + getXLabel + getXExtra)\n if (enums.length > 0) {\n parts.push(`// Schema Enums\\n`);\n for (const enumDef of enums) {\n parts.push(`export {\\n`);\n parts.push(` ${enumDef.name},\\n`);\n parts.push(` ${enumDef.name}Values,\\n`);\n parts.push(` is${enumDef.name},\\n`);\n parts.push(` get${enumDef.name}Label,\\n`);\n parts.push(` get${enumDef.name}Extra,\\n`);\n parts.push(`} from '${enumPrefix}/${enumDef.name}${ext}';\\n`);\n }\n parts.push('\\n');\n }\n\n // Export plugin enums (from plugin/ subfolder)\n if (pluginEnums.length > 0) {\n parts.push(`// Plugin Enums\\n`);\n for (const enumDef of pluginEnums) {\n parts.push(`export {\\n`);\n parts.push(` ${enumDef.name},\\n`);\n parts.push(` ${enumDef.name}Values,\\n`);\n parts.push(` is${enumDef.name},\\n`);\n parts.push(` get${enumDef.name}Label,\\n`);\n parts.push(` get${enumDef.name}Extra,\\n`);\n parts.push(`} from '${enumPrefix}/plugin/${enumDef.name}${ext}';\\n`);\n }\n parts.push('\\n');\n }\n\n // Export inline enums (type aliases)\n if (typeAliases.length > 0) {\n parts.push(`// Inline Enums (Type Aliases)\\n`);\n for (const alias of typeAliases) {\n parts.push(`export {\\n`);\n parts.push(` type ${alias.name},\\n`);\n parts.push(` ${alias.name}Values,\\n`);\n parts.push(` is${alias.name},\\n`);\n parts.push(` get${alias.name}Label,\\n`);\n parts.push(` get${alias.name}Extra,\\n`);\n parts.push(`} from '${enumPrefix}/${alias.name}${ext}';\\n`);\n }\n parts.push('\\n');\n }\n\n // Export all models with utility types\n if (options.generateZodSchemas) {\n // Zod format: export from user model files\n parts.push(`// Models (with Zod schemas, i18n, and Create/Update types)\\n`);\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n const lowerName = schema.name.charAt(0).toLowerCase() + schema.name.slice(1);\n parts.push(`export type { ${schema.name}, ${schema.name}Create, ${schema.name}Update } from './${schema.name}${ext}';\\n`);\n parts.push(`export {\\n`);\n parts.push(` ${lowerName}Schemas,\\n`);\n parts.push(` ${lowerName}CreateSchema,\\n`);\n parts.push(` ${lowerName}UpdateSchema,\\n`);\n parts.push(` ${lowerName}I18n,\\n`);\n parts.push(` get${schema.name}Label,\\n`);\n parts.push(` get${schema.name}FieldLabel,\\n`);\n parts.push(` get${schema.name}FieldPlaceholder,\\n`);\n parts.push(`} from './${schema.name}${ext}';\\n`);\n }\n } else {\n // Legacy format\n parts.push(`// Models (with Create/Update utility types)\\n`);\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n parts.push(`export type { ${schema.name} } from './${schema.name}${ext}';\\n`);\n parts.push(`export type { ${schema.name}Create, ${schema.name}Update } from './base/${schema.name}${ext}';\\n`);\n }\n\n // Export rules functions if enabled (legacy)\n if (options.generateRules) {\n parts.push(`\\n// Validation Rules\\n`);\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n parts.push(`export {\\n`);\n parts.push(` get${schema.name}Rules,\\n`);\n parts.push(` get${schema.name}DisplayName,\\n`);\n parts.push(` get${schema.name}PropertyDisplayName,\\n`);\n parts.push(`} from './rules/${schema.name}.rules${ext}';\\n`);\n }\n }\n }\n\n return {\n filePath: 'index.ts',\n content: parts.join(''),\n types: [],\n overwrite: true,\n };\n}\n\n/**\n * Generates TypeScript files with base/model pattern.\n *\n * Output structure:\n * - models/base/[SchemaName].ts - Auto-generated base interfaces (always overwritten)\n * - models/enum/[EnumName].ts - Auto-generated enums/type aliases (always overwritten)\n * - models/[SchemaName].ts - User-editable models that extend base (created once, never overwritten)\n * - models/index.ts - Re-exports (always overwritten)\n */\nexport function generateTypeScript(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TypeScriptFile[] {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const files: TypeScriptFile[] = [];\n\n // ========================================\n // Detect name conflicts\n // ========================================\n\n // Check for duplicate schema/enum names\n const schemasByName = new Map<string, string[]>(); // name -> [filePaths]\n for (const schema of Object.values(schemas)) {\n const paths = schemasByName.get(schema.name) ?? [];\n paths.push(schema.relativePath ?? schema.filePath);\n schemasByName.set(schema.name, paths);\n }\n\n const duplicateSchemas = Array.from(schemasByName.entries())\n .filter(([, paths]) => paths.length > 1);\n\n if (duplicateSchemas.length > 0) {\n const errors = duplicateSchemas.map(([name, paths]) =>\n ` - \"${name}\" defined in: ${paths.join(', ')}`\n ).join('\\n');\n throw new Error(\n `Duplicate schema/enum names detected. Names must be globally unique:\\n${errors}\\n` +\n `Hint: Rename to unique names like \"Blog${duplicateSchemas[0][0]}\" or \"Shop${duplicateSchemas[0][0]}\"`\n );\n }\n\n // Check for conflicts between schema enums and plugin enums\n if (opts.pluginEnums && opts.pluginEnums.size > 0) {\n const conflicts: string[] = [];\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum' && opts.pluginEnums.has(schema.name)) {\n conflicts.push(`\"${schema.name}\" (schema: ${schema.relativePath ?? schema.filePath}, plugin enum)`);\n }\n }\n if (conflicts.length > 0) {\n throw new Error(\n `Schema enum conflicts with plugin enum:\\n - ${conflicts.join('\\n - ')}\\n` +\n `Hint: Rename your schema enum to avoid conflict with plugin-provided enums`\n );\n }\n }\n\n // ========================================\n // Generate files\n // ========================================\n\n // Generate enum files from schema enums\n const enums = generateEnums(schemas, opts);\n for (const enumDef of enums) {\n files.push(generateEnumFile(enumDef, false)); // Schema enums in enum/\n }\n\n // Generate enum files from plugin enums (e.g., Prefecture, BankAccountType)\n // These go to enum/plugin/ to avoid conflicts with schema enums\n if (opts.pluginEnums && opts.pluginEnums.size > 0) {\n const pluginEnums = generatePluginEnums(opts.pluginEnums, opts);\n for (const enumDef of pluginEnums) {\n files.push(generateEnumFile(enumDef, true)); // Plugin enums in enum/plugin/\n }\n }\n\n // Generate inline enum files (type aliases or full enums with i18n)\n const inlineEnums = extractInlineEnums(schemas, opts);\n const inlineTypeAliases: TSTypeAlias[] = [];\n for (const item of inlineEnums) {\n if (item.enum) {\n // Full enum with i18n labels - add to enums list for index file\n enums.push(item.enum);\n files.push(generateEnumFile(item.enum, false));\n } else if (item.typeAlias) {\n // Simple type alias (no labels)\n inlineTypeAliases.push(item.typeAlias);\n files.push(generateTypeAliasFile(item.typeAlias));\n }\n }\n\n // Generate base interface files\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n files.push(generateBaseInterfaceFile(schema.name, schemas, opts));\n }\n\n // Generate model files (only created if not exists)\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n files.push(generateModelFile(schema.name, opts));\n }\n\n // Generate validation rules files (legacy, only if Zod is disabled)\n if (!opts.generateZodSchemas && opts.generateRules) {\n const rulesFiles = generateRulesFiles(schemas, opts);\n files.push(...rulesFiles);\n }\n\n // Generate common.ts\n files.push(generateCommonFile(opts));\n\n // Generate i18n.ts with validation messages\n files.push(generateI18nFile(opts));\n\n // Get plugin enums for index file generation\n const pluginEnumsList = opts.pluginEnums\n ? generatePluginEnums(opts.pluginEnums, opts)\n : [];\n\n // Generate index file\n files.push(generateIndexFile(schemas, enums, pluginEnumsList, inlineTypeAliases, opts));\n\n return files;\n}\n\n// Legacy exports for compatibility\nexport { generateTypeScript as generateTypeScriptFiles };\n","/**\n * Stub file utilities for React/Ant Design/TanStack Query utilities.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Stub file definitions\n */\nexport const STUB_FILES = [\n // Components\n {\n stub: 'JapaneseNameField.tsx.stub',\n output: 'components/JapaneseNameField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'JapaneseAddressField.tsx.stub',\n output: 'components/JapaneseAddressField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'JapaneseBankField.tsx.stub',\n output: 'components/JapaneseBankField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'components-index.ts.stub',\n output: 'components/index.ts',\n indexExport: '', // This IS the index\n },\n // Hooks\n {\n stub: 'use-form-mutation.ts.stub',\n output: 'hooks/use-form-mutation.ts',\n indexExport: `export { useFormMutation } from './use-form-mutation';\\n`,\n },\n // Lib\n {\n stub: 'zod-i18n.ts.stub',\n output: 'lib/zod-i18n.ts',\n indexExport: `export { setZodLocale, getZodLocale, getZodMessage } from './zod-i18n';\\n`,\n },\n {\n stub: 'form-validation.ts.stub',\n output: 'lib/form-validation.ts',\n indexExport: `export { zodRule, requiredRule } from './form-validation';\\nexport * from './rules';\\n`,\n },\n // Rules\n {\n stub: 'rules/kana.ts.stub',\n output: 'lib/rules/kana.ts',\n indexExport: '', // Will be handled by rules/index.ts\n },\n {\n stub: 'rules/index.ts.stub',\n output: 'lib/rules/index.ts',\n indexExport: '', // Already exported via form-validation\n },\n] as const;\n\nexport interface CopyStubsOptions {\n /** Target directory (e.g., 'resources/ts/omnify') */\n targetDir: string;\n /** Skip if file exists (default: false - always overwrite library files) */\n skipIfExists?: boolean;\n}\n\nexport interface CopyStubsResult {\n copied: string[];\n skipped: string[];\n}\n\n/**\n * Copy React utility stubs to the target directory.\n *\n * @example\n * copyStubs({\n * targetDir: 'resources/ts/omnify',\n * skipIfExists: true,\n * });\n */\nexport function copyStubs(options: CopyStubsOptions): CopyStubsResult {\n const { targetDir, skipIfExists = false } = options;\n const stubsDir = path.join(__dirname, '..', 'stubs');\n const result: CopyStubsResult = { copied: [], skipped: [] };\n\n // Group stubs by directory for index file generation\n const directories = new Map<string, string>();\n\n for (const { stub, output, indexExport } of STUB_FILES) {\n const stubPath = path.join(stubsDir, stub);\n const outputPath = path.join(targetDir, output);\n const outputDir = path.dirname(outputPath);\n const dirName = path.dirname(output).split('/')[0]; // e.g., 'components', 'hooks', 'lib'\n\n // Track index exports per directory\n if (!directories.has(dirName)) {\n directories.set(dirName, '');\n }\n directories.set(dirName, directories.get(dirName)! + indexExport);\n\n // Create directory if not exists\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // Skip if file exists and skipIfExists is true\n if (skipIfExists && fs.existsSync(outputPath)) {\n result.skipped.push(output);\n continue;\n }\n\n // Copy stub file\n if (fs.existsSync(stubPath)) {\n const content = fs.readFileSync(stubPath, 'utf-8');\n fs.writeFileSync(outputPath, content);\n result.copied.push(output);\n }\n }\n\n // Generate index files for each directory\n for (const [dirName, exports] of directories) {\n const indexPath = path.join(targetDir, dirName, 'index.ts');\n if (skipIfExists && fs.existsSync(indexPath)) {\n continue;\n }\n fs.writeFileSync(indexPath, exports);\n result.copied.push(`${dirName}/index.ts`);\n }\n\n return result;\n}\n\n/**\n * Get list of stub files that would be generated.\n */\nexport function getStubPaths(): string[] {\n return STUB_FILES.map(s => s.output);\n}\n","/**\n * AI Guides Generator for TypeScript/Frontend\n *\n * Generates AI assistant guides (Claude, Cursor) for TypeScript/React projects.\n * Simply copies .stub files, removes .stub extension, and replaces placeholders.\n */\n\nimport { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Options for AI guides generation\n */\nexport interface AIGuidesOptions {\n /**\n * TypeScript output path from config (e.g., 'resources/ts/omnify')\n * Used to extract the base path for glob replacement\n */\n typescriptPath?: string;\n\n /**\n * Base path for TypeScript files (default: extracted from typescriptPath or 'src')\n * Used for placeholder replacement in Cursor rules\n */\n typescriptBasePath?: string;\n}\n\n/**\n * Result of AI guides generation\n */\nexport interface AIGuidesResult {\n claudeGuides: number;\n claudeChecklists: number;\n cursorRules: number;\n files: string[];\n}\n\n/**\n * Get the stubs directory path\n */\nfunction getStubsDir(): string {\n // Try dev path first: packages/typescript-generator/stubs/ai-guides\n const devPath = resolve(__dirname, '../../stubs/ai-guides');\n if (existsSync(devPath)) {\n return devPath;\n }\n\n // Try dist path (when installed as package)\n const distPath = resolve(__dirname, '../stubs/ai-guides');\n if (existsSync(distPath)) {\n return distPath;\n }\n\n throw new Error('AI guides stubs not found');\n}\n\n/**\n * Extract TypeScript base path from typescriptPath\n * e.g., 'resources/ts/omnify' -> 'resources/ts'\n * e.g., 'src/generated' -> 'src'\n */\nfunction extractTypescriptBasePath(typescriptPath?: string): string {\n if (!typescriptPath) return 'src';\n\n const normalized = typescriptPath.replace(/\\\\/g, '/');\n\n // Remove last segment (omnify, generated, etc.)\n const parts = normalized.split('/').filter(Boolean);\n if (parts.length > 1) {\n return parts.slice(0, -1).join('/');\n }\n\n return 'src';\n}\n\n/**\n * Replace placeholders in stub content\n * - {{TYPESCRIPT_BASE}} -> actual base path (e.g., 'resources/ts')\n */\nfunction replacePlaceholders(content: string, basePath: string): string {\n return content.replace(/\\{\\{TYPESCRIPT_BASE\\}\\}/g, basePath);\n}\n\n/**\n * Copy .stub files to destination, removing .stub extension and replacing placeholders\n */\nfunction copyStubs(\n srcDir: string,\n destDir: string,\n transform?: (content: string) => string\n): string[] {\n const writtenFiles: string[] = [];\n\n if (!existsSync(srcDir)) {\n return writtenFiles;\n }\n\n if (!existsSync(destDir)) {\n mkdirSync(destDir, { recursive: true });\n }\n\n const entries = readdirSync(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name);\n\n if (entry.isDirectory()) {\n // Recursively copy subdirectories\n const subDestDir = join(destDir, entry.name);\n const subFiles = copyStubs(srcPath, subDestDir, transform);\n writtenFiles.push(...subFiles);\n } else if (entry.isFile() && entry.name.endsWith('.stub')) {\n // Remove .stub extension\n const destName = entry.name.slice(0, -5);\n const destPath = join(destDir, destName);\n\n let content = readFileSync(srcPath, 'utf-8');\n\n if (transform) {\n content = transform(content);\n }\n\n writeFileSync(destPath, content);\n writtenFiles.push(destPath);\n }\n }\n\n return writtenFiles;\n}\n\n/**\n * Generate AI guides for Claude and Cursor\n */\nexport function generateAIGuides(\n rootDir: string,\n options: AIGuidesOptions = {}\n): AIGuidesResult {\n const stubsDir = getStubsDir();\n const basePath = options.typescriptBasePath || extractTypescriptBasePath(options.typescriptPath);\n\n const result: AIGuidesResult = {\n claudeGuides: 0,\n claudeChecklists: 0,\n cursorRules: 0,\n files: [],\n };\n\n // All Claude files go under .claude/omnify/\n\n // 1. Copy React guides to .claude/omnify/guides/react/\n const claudeSrcDir = join(stubsDir, 'react');\n const claudeDestDir = resolve(rootDir, '.claude/omnify/guides/react');\n\n if (existsSync(claudeSrcDir)) {\n const files = copyStubs(claudeSrcDir, claudeDestDir);\n result.claudeGuides = files.length;\n result.files.push(...files);\n }\n\n // 2. Copy checklists to .claude/omnify/checklists/\n const claudeChecklistsSrcDir = join(stubsDir, 'checklists');\n const claudeChecklistsDestDir = resolve(rootDir, '.claude/omnify/checklists');\n\n if (existsSync(claudeChecklistsSrcDir)) {\n const files = copyStubs(claudeChecklistsSrcDir, claudeChecklistsDestDir);\n result.claudeChecklists = files.length;\n result.files.push(...files);\n }\n\n // 3. Copy Cursor rules to .cursor/rules/omnify/\n const cursorSrcDir = join(stubsDir, 'cursor');\n const cursorDestDir = resolve(rootDir, '.cursor/rules/omnify');\n\n if (existsSync(cursorSrcDir)) {\n const files = copyStubs(cursorSrcDir, cursorDestDir, (content) =>\n replacePlaceholders(content, basePath)\n );\n result.cursorRules = files.length;\n result.files.push(...files);\n }\n\n return result;\n}\n\n/**\n * Check if AI guides need to be generated\n */\nexport function shouldGenerateAIGuides(rootDir: string): boolean {\n const claudeDir = resolve(rootDir, '.claude/omnify/guides/react');\n const cursorDir = resolve(rootDir, '.cursor/rules/omnify');\n\n if (!existsSync(claudeDir) || !existsSync(cursorDir)) {\n return true;\n }\n\n try {\n const claudeFiles = readdirSync(claudeDir);\n const cursorFiles = readdirSync(cursorDir);\n const hasReactRules = cursorFiles.some((f) => f.startsWith('react'));\n\n return claudeFiles.length === 0 || !hasReactRules;\n } catch {\n return true;\n }\n}\n"],"mappings":"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","names":["import_omnify_types","resolveDisplayName","result","getMultiLocaleDisplayName","result","getImportExt","path","fs","exports","import_meta","__filename","__dirname","copyStubs"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/interface-generator.ts","../src/enum-generator.ts","../src/validation-templates.ts","../src/rules-generator.ts","../src/zod-generator.ts","../src/generator.ts","../src/stubs.ts","../src/ai-guides/generator.ts"],"sourcesContent":["/**\n * @famgia/omnify-typescript\n *\n * TypeScript type definitions generator for Omnify schemas.\n */\n\nexport type {\n TypeScriptFile,\n TypeScriptOptions,\n TSProperty,\n TSInterface,\n TSEnum,\n TSEnumValue,\n TSTypeAlias,\n} from './types.js';\n\nexport {\n toPropertyName,\n toInterfaceName,\n getPropertyType,\n propertyToTSProperty,\n schemaToInterface,\n formatProperty,\n formatInterface,\n generateInterfaces,\n} from './interface-generator.js';\n\nexport {\n toEnumMemberName,\n toEnumName,\n schemaToEnum,\n generateEnums,\n generatePluginEnums,\n pluginEnumToTSEnum,\n formatEnum,\n enumToUnionType,\n formatTypeAlias,\n extractInlineEnums,\n type ExtractedInlineEnum,\n} from './enum-generator.js';\n\nexport {\n generateTypeScript,\n generateTypeScriptFiles,\n} from './generator.js';\n\nexport {\n DEFAULT_VALIDATION_TEMPLATES,\n mergeValidationTemplates,\n formatValidationMessage,\n getValidationMessages,\n type ValidationTemplates,\n} from './validation-templates.js';\n\nexport {\n generateModelRules,\n generateRulesFiles,\n} from './rules-generator.js';\n\nexport {\n copyStubs,\n getStubPaths,\n STUB_FILES,\n type CopyStubsOptions,\n type CopyStubsResult,\n} from './stubs.js';\n\nexport type { LocaleMap } from './types.js';\n\n// AI Guides generation\nexport {\n generateAIGuides,\n shouldGenerateAIGuides,\n type AIGuidesOptions,\n type AIGuidesResult,\n} from './ai-guides/index.js';\n","/**\n * @famgia/omnify-laravel - TypeScript Interface Generator\n *\n * Generates TypeScript interfaces from schemas.\n */\n\nimport type { LoadedSchema, PropertyDefinition, SchemaCollection, LocalizedString } from '@famgia/omnify-types';\nimport { resolveLocalizedString } from '@famgia/omnify-types';\nimport type { TSInterface, TSProperty, TypeScriptOptions } from './types.js';\n\n/**\n * Convert a string to snake_case.\n */\nexport function toSnakeCase(str: string): string {\n return str\n .replace(/([A-Z])/g, '_$1')\n .replace(/^_/, '')\n .toLowerCase();\n}\n\n/**\n * Maps Omnify property types to TypeScript types.\n */\nconst TYPE_MAP: Record<string, string> = {\n String: 'string',\n TinyInt: 'number',\n Int: 'number',\n BigInt: 'number',\n Float: 'number',\n Boolean: 'boolean',\n Text: 'string',\n MediumText: 'string',\n LongText: 'string',\n Date: 'DateString',\n Time: 'string',\n DateTime: 'DateTimeString',\n Timestamp: 'DateTimeString',\n Json: 'unknown',\n Email: 'string',\n Password: 'string',\n Enum: 'string',\n Select: 'string',\n Lookup: 'number',\n};\n\n/**\n * File interface name (references the File.yaml schema).\n * The File schema is auto-generated by ensureFileSchema() when File type is used.\n */\nexport const FILE_INTERFACE_NAME = 'File';\n\n/**\n * Maps primary key types to TypeScript types.\n */\nconst PK_TYPE_MAP: Record<string, string> = {\n Int: 'number',\n BigInt: 'number',\n Uuid: 'string',\n String: 'string',\n};\n\n/**\n * Resolves a localized string using the given options.\n * Returns undefined if the value is undefined or cannot be resolved.\n */\nfunction resolveDisplayName(\n value: LocalizedString | undefined,\n options: TypeScriptOptions = {}\n): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n return resolveLocalizedString(value, {\n locale: options.locale,\n config: options.localeConfig,\n });\n}\n\n/**\n * Converts property name to TypeScript property name.\n * Preserves camelCase.\n */\nexport function toPropertyName(name: string): string {\n return name;\n}\n\n/**\n * Converts schema name to TypeScript interface name.\n * Preserves PascalCase.\n */\nexport function toInterfaceName(schemaName: string): string {\n return schemaName;\n}\n\n/**\n * Gets TypeScript type for a property.\n */\nexport function getPropertyType(\n property: PropertyDefinition,\n _allSchemas: SchemaCollection\n): string {\n // Handle File type specially (polymorphic relation to files table)\n // References the File interface generated from File.yaml schema\n if (property.type === 'File') {\n const fileProp = property as { multiple?: boolean };\n if (fileProp.multiple) {\n return `${FILE_INTERFACE_NAME}[]`;\n }\n return `${FILE_INTERFACE_NAME} | null`;\n }\n\n // Handle associations\n if (property.type === 'Association') {\n const assocProp = property as {\n relation?: string;\n target?: string;\n targets?: readonly string[];\n };\n\n const targetName = assocProp.target ?? 'unknown';\n\n switch (assocProp.relation) {\n // Standard relations\n case 'OneToOne':\n case 'ManyToOne':\n return targetName;\n case 'OneToMany':\n case 'ManyToMany':\n return `${targetName}[]`;\n\n // Polymorphic relations\n case 'MorphTo':\n // Union type of all possible targets\n if (assocProp.targets && assocProp.targets.length > 0) {\n return assocProp.targets.join(' | ');\n }\n return 'unknown';\n case 'MorphOne':\n return targetName;\n case 'MorphMany':\n case 'MorphToMany':\n case 'MorphedByMany':\n return `${targetName}[]`;\n\n default:\n return 'unknown';\n }\n }\n\n // Handle EnumRef types (reference to shared enum schema)\n if (property.type === 'EnumRef') {\n const enumRefProp = property as { enum: string };\n return enumRefProp.enum;\n }\n\n // Handle enum types\n if (property.type === 'Enum') {\n const enumProp = property as { enum?: string | readonly string[] };\n if (typeof enumProp.enum === 'string') {\n // Reference to a named enum\n return enumProp.enum;\n }\n if (Array.isArray(enumProp.enum)) {\n // Inline enum - create union type\n return enumProp.enum.map(v => `'${v}'`).join(' | ');\n }\n }\n\n // Handle Select with options\n if (property.type === 'Select') {\n const selectProp = property as { options?: readonly string[] };\n if (selectProp.options && selectProp.options.length > 0) {\n return selectProp.options.map(v => `'${v}'`).join(' | ');\n }\n }\n\n // Standard type mapping\n return TYPE_MAP[property.type] ?? 'unknown';\n}\n\n/**\n * Converts a property to TypeScript property definition.\n * For MorphTo, returns multiple properties (_type, _id, and relation).\n * For compound custom types, expands to multiple properties.\n */\nexport function propertyToTSProperties(\n propertyName: string,\n property: PropertyDefinition,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSProperty[] {\n const baseProp = property as { nullable?: boolean; displayName?: LocalizedString; fields?: Record<string, { nullable?: boolean }> };\n const isReadonly = options.readonly ?? true;\n // Resolve displayName using locale config\n const displayName = resolveDisplayName(baseProp.displayName, options);\n\n // Handle custom compound types from plugins (e.g., JapaneseName, JapaneseAddress)\n if (options.customTypes) {\n const customType = options.customTypes.get(property.type);\n if (customType?.compound && customType.expand) {\n const expandedProps: TSProperty[] = [];\n for (const field of customType.expand) {\n const fieldName = `${propertyName}_${toSnakeCase(field.suffix)}`;\n const fieldOverride = baseProp.fields?.[field.suffix];\n // Nullable priority: schema field override > plugin field default > parent property > false\n const isNullable = fieldOverride?.nullable ?? field.sql?.nullable ?? baseProp.nullable ?? false;\n const tsType = field.typescript?.type ?? 'string';\n\n expandedProps.push({\n name: fieldName,\n type: tsType,\n optional: isNullable,\n readonly: isReadonly,\n comment: `${displayName ?? propertyName} (${field.suffix})`,\n });\n }\n\n // Add accessor properties (computed properties like full_name)\n if (customType.accessors) {\n for (const accessor of customType.accessors) {\n const accessorName = `${propertyName}_${toSnakeCase(accessor.name)}`;\n expandedProps.push({\n name: accessorName,\n type: 'string | null',\n optional: true,\n readonly: isReadonly,\n comment: `${displayName ?? propertyName} (computed)`,\n });\n }\n }\n\n return expandedProps;\n }\n // Handle simple custom types (non-compound)\n if (customType && !customType.compound) {\n const tsType = customType.typescript?.type ?? 'string';\n return [{\n name: toPropertyName(propertyName),\n type: tsType,\n optional: baseProp.nullable ?? false,\n readonly: isReadonly,\n comment: displayName,\n }];\n }\n }\n\n // Handle MorphTo specially - it creates _type and _id columns\n if (property.type === 'Association') {\n const assocProp = property as {\n relation?: string;\n targets?: readonly string[];\n };\n\n if (assocProp.relation === 'MorphTo' && assocProp.targets && assocProp.targets.length > 0) {\n const propBaseName = toPropertyName(propertyName);\n const targetUnion = assocProp.targets.map(t => `'${t}'`).join(' | ');\n const relationUnion = assocProp.targets.join(' | ');\n\n return [\n {\n name: `${propBaseName}Type`,\n type: targetUnion,\n optional: true, // Polymorphic columns are nullable\n readonly: isReadonly,\n comment: `Polymorphic type for ${propertyName}`,\n },\n {\n name: `${propBaseName}Id`,\n type: 'number',\n optional: true,\n readonly: isReadonly,\n comment: `Polymorphic ID for ${propertyName}`,\n },\n {\n name: propBaseName,\n type: `${relationUnion} | null`,\n optional: true,\n readonly: isReadonly,\n comment: displayName ?? `Polymorphic relation to ${assocProp.targets.join(', ')}`,\n },\n ];\n }\n }\n\n // Default: single property\n const type = getPropertyType(property, allSchemas);\n\n return [{\n name: toPropertyName(propertyName),\n type,\n optional: baseProp.nullable ?? false,\n readonly: isReadonly,\n comment: displayName,\n }];\n}\n\n/**\n * Converts a property to TypeScript property definition (legacy - returns single property).\n */\nexport function propertyToTSProperty(\n propertyName: string,\n property: PropertyDefinition,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSProperty {\n return propertyToTSProperties(propertyName, property, allSchemas, options)[0]!;\n}\n\n/**\n * Extracts referenced interface names from a TypeScript type string.\n * Returns only interface names (not primitives like string, number, boolean, unknown).\n */\nfunction extractTypeReferences(type: string, allSchemaNames: Set<string>): string[] {\n const primitives = new Set(['string', 'number', 'boolean', 'unknown', 'null', 'undefined', 'void', 'never', 'any']);\n const refs: string[] = [];\n\n // Remove array notation and split by | for union types\n const cleanType = type.replace(/\\[\\]/g, '').replace(/\\s*\\|\\s*null/g, '');\n const parts = cleanType.split(/\\s*\\|\\s*/);\n\n for (const part of parts) {\n // Remove quotes (for string literal types like 'Post')\n const trimmed = part.trim().replace(/^['\"]|['\"]$/g, '');\n if (!primitives.has(trimmed) && allSchemaNames.has(trimmed)) {\n refs.push(trimmed);\n }\n }\n\n return refs;\n}\n\n/**\n * Generates TypeScript interface from schema.\n */\nexport function schemaToInterface(\n schema: LoadedSchema,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSInterface {\n const properties: TSProperty[] = [];\n const allSchemaNames = new Set(Object.keys(allSchemas).filter(name => allSchemas[name]!.kind !== 'enum'));\n\n // ID property (only if id is not disabled)\n if (schema.options?.id !== false) {\n const pkType = (schema.options?.idType ?? 'BigInt') as keyof typeof PK_TYPE_MAP;\n properties.push({\n name: 'id',\n type: PK_TYPE_MAP[pkType] ?? 'number',\n optional: false,\n readonly: options.readonly ?? true,\n comment: 'Primary key',\n });\n }\n\n // Schema properties\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n // Use propertyToTSProperties which handles MorphTo returning multiple properties\n properties.push(...propertyToTSProperties(propName, property, allSchemas, options));\n }\n }\n\n // Timestamps (snake_case to match database columns)\n if (schema.options?.timestamps !== false) {\n properties.push(\n {\n name: 'created_at',\n type: 'DateTimeString',\n optional: true,\n readonly: options.readonly ?? true,\n comment: 'Creation timestamp',\n },\n {\n name: 'updated_at',\n type: 'DateTimeString',\n optional: true,\n readonly: options.readonly ?? true,\n comment: 'Last update timestamp',\n }\n );\n }\n\n // Soft delete (snake_case to match database columns)\n if (schema.options?.softDelete) {\n properties.push({\n name: 'deleted_at',\n type: 'DateTimeString',\n optional: true,\n readonly: options.readonly ?? true,\n comment: 'Soft delete timestamp',\n });\n }\n\n // Collect dependencies from property types\n const dependencySet = new Set<string>();\n for (const prop of properties) {\n for (const ref of extractTypeReferences(prop.type, allSchemaNames)) {\n if (ref !== schema.name) { // Don't include self-references\n dependencySet.add(ref);\n }\n }\n }\n\n // Collect enum dependencies from EnumRef properties\n const enumDependencySet = new Set<string>();\n if (schema.properties) {\n for (const property of Object.values(schema.properties)) {\n if (property.type === 'EnumRef') {\n const enumRefProp = property as { enum: string };\n if (enumRefProp.enum) {\n enumDependencySet.add(enumRefProp.enum);\n }\n }\n }\n }\n\n // Resolve schema displayName using locale config\n const schemaDisplayName = resolveDisplayName(schema.displayName, options);\n\n return {\n name: toInterfaceName(schema.name),\n properties,\n comment: schemaDisplayName ?? schema.name,\n dependencies: dependencySet.size > 0 ? Array.from(dependencySet).sort() : undefined,\n enumDependencies: enumDependencySet.size > 0 ? Array.from(enumDependencySet).sort() : undefined,\n };\n}\n\n/**\n * Formats a TypeScript property.\n */\nexport function formatProperty(property: TSProperty): string {\n const readonly = property.readonly ? 'readonly ' : '';\n const optional = property.optional ? '?' : '';\n const comment = property.comment ? ` /** ${property.comment} */\\n` : '';\n return `${comment} ${readonly}${property.name}${optional}: ${property.type};`;\n}\n\n/**\n * Formats a TypeScript interface.\n */\nexport function formatInterface(iface: TSInterface): string {\n const comment = iface.comment ? `/**\\n * ${iface.comment}\\n */\\n` : '';\n const extendsClause = iface.extends && iface.extends.length > 0\n ? ` extends ${iface.extends.join(', ')}`\n : '';\n const properties = iface.properties.map(formatProperty).join('\\n');\n\n return `${comment}export interface ${iface.name}${extendsClause} {\\n${properties}\\n}`;\n}\n\n/**\n * Generates interfaces for all schemas.\n * Note: File interface is now generated from File.yaml schema (use ensureFileSchema() to auto-create it).\n */\nexport function generateInterfaces(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSInterface[] {\n const interfaces: TSInterface[] = [];\n\n for (const schema of Object.values(schemas)) {\n // Skip enum schemas\n if (schema.kind === 'enum') {\n continue;\n }\n\n // Skip hidden schemas (e.g., cache, jobs, sessions)\n if (schema.options?.hidden === true) {\n continue;\n }\n\n interfaces.push(schemaToInterface(schema, schemas, options));\n }\n\n return interfaces;\n}\n","/**\n * @famgia/omnify-typescript - TypeScript Enum Generator\n *\n * Generates TypeScript enums with helper methods from schema enum definitions.\n */\n\nimport type { LoadedSchema, SchemaCollection, LocalizedString, PluginEnumDefinition } from '@famgia/omnify-types';\nimport { resolveLocalizedString } from '@famgia/omnify-types';\nimport type { TSEnum, TSEnumValue, TSTypeAlias, TypeScriptOptions } from './types.js';\n\n/**\n * Resolves a localized string using the given options.\n */\nfunction resolveDisplayName(\n value: LocalizedString | undefined,\n options: TypeScriptOptions = {}\n): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n return resolveLocalizedString(value, {\n locale: options.locale,\n config: options.localeConfig,\n });\n}\n\n/**\n * Inline enum value from schema (can be string or object with value/label/extra).\n */\ninterface InlineEnumValue {\n readonly value: string;\n /** Display label - supports multi-language (string or locale map) */\n readonly label?: LocalizedString;\n readonly extra?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Converts enum value to valid TypeScript enum member name.\n */\nexport function toEnumMemberName(value: string): string {\n // Convert to PascalCase and remove invalid characters\n let result = value\n .split(/[-_\\s]+/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '');\n\n // TypeScript enum member names cannot start with a number\n if (/^\\d/.test(result)) {\n result = '_' + result;\n }\n\n return result;\n}\n\n/**\n * Converts schema name to TypeScript enum name.\n */\nexport function toEnumName(schemaName: string): string {\n return schemaName;\n}\n\n/**\n * Parses enum value from schema (can be string or object).\n * If multiLocale is true, keeps all locales. Otherwise resolves to single locale.\n */\nfunction parseEnumValue(\n value: string | InlineEnumValue,\n options: TypeScriptOptions = {}\n): TSEnumValue {\n if (typeof value === 'string') {\n return {\n name: toEnumMemberName(value),\n value,\n // No label or extra - will fallback to value\n };\n }\n\n // Handle label - either multi-locale or resolved single locale\n let label: string | Record<string, string> | undefined;\n if (value.label !== undefined) {\n if (options.multiLocale && typeof value.label === 'object') {\n // Keep all locales as object\n label = value.label as Record<string, string>;\n } else {\n // Resolve to single locale\n label = resolveDisplayName(value.label, options);\n }\n }\n\n return {\n name: toEnumMemberName(value.value),\n value: value.value,\n label,\n extra: value.extra,\n };\n}\n\n/**\n * Generates TypeScript enum from schema enum.\n */\nexport function schemaToEnum(schema: LoadedSchema, options: TypeScriptOptions = {}): TSEnum | null {\n if (schema.kind !== 'enum' || !schema.values) {\n return null;\n }\n\n const values: TSEnumValue[] = schema.values.map(value =>\n parseEnumValue(value as string | InlineEnumValue, options)\n );\n const displayName = resolveDisplayName(schema.displayName, options);\n\n return {\n name: toEnumName(schema.name),\n values,\n comment: displayName ?? schema.name,\n };\n}\n\n/**\n * Generates enums for all enum schemas.\n */\nexport function generateEnums(schemas: SchemaCollection, options: TypeScriptOptions = {}): TSEnum[] {\n const enums: TSEnum[] = [];\n\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') {\n const enumDef = schemaToEnum(schema, options);\n if (enumDef) {\n enums.push(enumDef);\n }\n }\n }\n\n return enums;\n}\n\n/**\n * Converts a plugin enum definition to TSEnum.\n * Plugin enums come from plugins like @famgia/omnify-japan (e.g., Prefecture, BankAccountType).\n */\nexport function pluginEnumToTSEnum(enumDef: PluginEnumDefinition, options: TypeScriptOptions = {}): TSEnum {\n const values: TSEnumValue[] = enumDef.values.map(v => {\n // Handle label - can be string or locale map\n let label: string | Record<string, string> | undefined;\n if (v.label !== undefined) {\n if (typeof v.label === 'string') {\n label = v.label;\n } else if (options.multiLocale) {\n // Keep all locales\n label = v.label as Record<string, string>;\n } else {\n // Resolve to single locale\n label = resolveDisplayName(v.label, options);\n }\n }\n\n return {\n name: toEnumMemberName(v.value),\n value: v.value,\n label,\n extra: v.extra,\n };\n });\n\n // Resolve displayName\n let comment: string | undefined;\n if (enumDef.displayName !== undefined) {\n if (typeof enumDef.displayName === 'string') {\n comment = enumDef.displayName;\n } else {\n comment = resolveDisplayName(enumDef.displayName, options);\n }\n }\n\n return {\n name: enumDef.name,\n values,\n comment: comment ?? enumDef.name,\n };\n}\n\n/**\n * Generates enums from plugin enum definitions.\n */\nexport function generatePluginEnums(\n pluginEnums: ReadonlyMap<string, PluginEnumDefinition>,\n options: TypeScriptOptions = {}\n): TSEnum[] {\n const enums: TSEnum[] = [];\n\n for (const enumDef of pluginEnums.values()) {\n enums.push(pluginEnumToTSEnum(enumDef, options));\n }\n\n return enums;\n}\n\n/**\n * Check if label is multi-locale (object) or single string.\n */\nfunction isMultiLocaleLabel(label: string | Record<string, string> | undefined): label is Record<string, string> {\n return label !== undefined && typeof label === 'object';\n}\n\n/**\n * Formats a TypeScript enum with helper methods.\n */\nexport function formatEnum(enumDef: TSEnum): string {\n const { name, values, comment } = enumDef;\n const parts: string[] = [];\n\n // JSDoc comment\n if (comment) {\n parts.push(`/**\\n * ${comment}\\n */\\n`);\n }\n\n // Enum definition\n const enumValues = values\n .map(v => ` ${v.name} = '${v.value}',`)\n .join('\\n');\n parts.push(`export enum ${name} {\\n${enumValues}\\n}\\n\\n`);\n\n // Values array\n parts.push(`/** All ${name} values */\\n`);\n parts.push(`export const ${name}Values = Object.values(${name}) as ${name}[];\\n\\n`);\n\n // Type guard\n parts.push(`/** Type guard for ${name} */\\n`);\n parts.push(`export function is${name}(value: unknown): value is ${name} {\\n`);\n parts.push(` return ${name}Values.includes(value as ${name});\\n`);\n parts.push(`}\\n\\n`);\n\n // Check if we have multi-locale labels or single-locale labels\n const hasLabels = values.some(v => v.label !== undefined);\n const hasMultiLocale = values.some(v => isMultiLocaleLabel(v.label));\n\n if (hasLabels) {\n if (hasMultiLocale) {\n // Multi-locale labels: Record<Enum, Record<string, string>>\n const labelEntries = values\n .filter(v => v.label !== undefined)\n .map(v => {\n if (isMultiLocaleLabel(v.label)) {\n const locales = Object.entries(v.label)\n .map(([locale, text]) => `'${locale}': '${escapeString(text)}'`)\n .join(', ');\n return ` [${name}.${v.name}]: { ${locales} },`;\n }\n return ` [${name}.${v.name}]: { default: '${escapeString(String(v.label))}' },`;\n })\n .join('\\n');\n parts.push(`const ${lowerFirst(name)}Labels: Partial<Record<${name}, Record<string, string>>> = {\\n${labelEntries}\\n};\\n\\n`);\n\n parts.push(`/** Get label for ${name} value with locale support */\\n`);\n parts.push(`export function get${name}Label(value: ${name}, locale?: string): string {\\n`);\n parts.push(` const labels = ${lowerFirst(name)}Labels[value];\\n`);\n parts.push(` if (!labels) return value;\\n`);\n parts.push(` if (locale && labels[locale]) return labels[locale];\\n`);\n parts.push(` // Fallback: ja → en → first available\\n`);\n parts.push(` return labels['ja'] ?? labels['en'] ?? Object.values(labels)[0] ?? value;\\n`);\n parts.push(`}\\n\\n`);\n } else {\n // Single-locale labels: Record<Enum, string>\n const labelEntries = values\n .filter(v => v.label !== undefined)\n .map(v => ` [${name}.${v.name}]: '${escapeString(String(v.label))}',`)\n .join('\\n');\n parts.push(`const ${lowerFirst(name)}Labels: Partial<Record<${name}, string>> = {\\n${labelEntries}\\n};\\n\\n`);\n\n parts.push(`/** Get label for ${name} value (fallback to value if no label) */\\n`);\n parts.push(`export function get${name}Label(value: ${name}): string {\\n`);\n parts.push(` return ${lowerFirst(name)}Labels[value] ?? value;\\n`);\n parts.push(`}\\n\\n`);\n }\n } else {\n parts.push(`/** Get label for ${name} value (returns value as-is) */\\n`);\n parts.push(`export function get${name}Label(value: ${name}): string {\\n`);\n parts.push(` return value;\\n`);\n parts.push(`}\\n\\n`);\n }\n\n // Extra - only generate if at least one value has extra\n const hasExtra = values.some(v => v.extra !== undefined);\n if (hasExtra) {\n const extraEntries = values\n .filter(v => v.extra !== undefined)\n .map(v => ` [${name}.${v.name}]: ${JSON.stringify(v.extra)},`)\n .join('\\n');\n parts.push(`const ${lowerFirst(name)}Extra: Partial<Record<${name}, Record<string, unknown>>> = {\\n${extraEntries}\\n};\\n\\n`);\n\n parts.push(`/** Get extra metadata for ${name} value (undefined if not defined) */\\n`);\n parts.push(`export function get${name}Extra(value: ${name}): Record<string, unknown> | undefined {\\n`);\n parts.push(` return ${lowerFirst(name)}Extra[value];\\n`);\n parts.push(`}`);\n } else {\n parts.push(`/** Get extra metadata for ${name} value (undefined if not defined) */\\n`);\n parts.push(`export function get${name}Extra(_value: ${name}): Record<string, unknown> | undefined {\\n`);\n parts.push(` return undefined;\\n`);\n parts.push(`}`);\n }\n\n return parts.join('');\n}\n\n/**\n * Convert first character to lowercase.\n */\nfunction lowerFirst(str: string): string {\n return str.charAt(0).toLowerCase() + str.slice(1);\n}\n\n/**\n * Escape special characters in strings for JavaScript output.\n */\nfunction escapeString(str: string): string {\n return str.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\n/**\n * Generates a union type alias as an alternative to enum.\n */\nexport function enumToUnionType(enumDef: TSEnum): TSTypeAlias {\n const type = enumDef.values\n .map(v => `'${v.value}'`)\n .join(' | ');\n\n return {\n name: enumDef.name,\n type,\n comment: enumDef.comment,\n };\n}\n\n/**\n * Formats a TypeScript type alias with helper methods.\n */\nexport function formatTypeAlias(alias: TSTypeAlias): string {\n const { name, type, comment } = alias;\n const parts: string[] = [];\n\n // JSDoc comment\n if (comment) {\n parts.push(`/**\\n * ${comment}\\n */\\n`);\n }\n\n // Type alias\n parts.push(`export type ${name} = ${type};\\n\\n`);\n\n // Values array\n const values = type.split(' | ').map(v => v.trim());\n parts.push(`/** All ${name} values */\\n`);\n parts.push(`export const ${name}Values: ${name}[] = [${values.join(', ')}];\\n\\n`);\n\n // Type guard\n parts.push(`/** Type guard for ${name} */\\n`);\n parts.push(`export function is${name}(value: unknown): value is ${name} {\\n`);\n parts.push(` return ${name}Values.includes(value as ${name});\\n`);\n parts.push(`}\\n\\n`);\n\n // Label getter (fallback to value for type aliases - no labels)\n parts.push(`/** Get label for ${name} value (returns value as-is) */\\n`);\n parts.push(`export function get${name}Label(value: ${name}): string {\\n`);\n parts.push(` return value;\\n`);\n parts.push(`}\\n\\n`);\n\n // Extra getter (always undefined for type aliases)\n parts.push(`/** Get extra metadata for ${name} value (always undefined for type aliases) */\\n`);\n parts.push(`export function get${name}Extra(_value: ${name}): Record<string, unknown> | undefined {\\n`);\n parts.push(` return undefined;\\n`);\n parts.push(`}`);\n\n return parts.join('');\n}\n\n/**\n * Result of extracting inline enums - can be type alias or full enum with labels.\n */\nexport interface ExtractedInlineEnum {\n /** Type alias for simple enums */\n typeAlias?: TSTypeAlias;\n /** Full enum with i18n labels */\n enum?: TSEnum;\n}\n\n/**\n * Extracts inline enums from properties for type generation.\n * Returns both type aliases (simple enums) and full enums (with i18n labels).\n */\nexport function extractInlineEnums(schemas: SchemaCollection, options: TypeScriptOptions = {}): ExtractedInlineEnum[] {\n const results: ExtractedInlineEnum[] = [];\n\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum' || !schema.properties) {\n continue;\n }\n\n for (const [propName, property] of Object.entries(schema.properties)) {\n if (property.type === 'Enum') {\n const enumProp = property as { enum?: readonly (string | InlineEnumValue)[]; displayName?: LocalizedString };\n\n // Only handle inline array enums (not references to named enums)\n if (Array.isArray(enumProp.enum) && enumProp.enum.length > 0) {\n const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;\n const displayName = resolveDisplayName(enumProp.displayName, options);\n\n // Check if any value has labels (i18n support needed)\n const hasLabels = enumProp.enum.some(v => typeof v !== 'string' && v.label !== undefined);\n\n if (hasLabels) {\n // Generate full enum with i18n labels\n const values: TSEnumValue[] = enumProp.enum.map(v => parseEnumValue(v, options));\n results.push({\n enum: {\n name: typeName,\n values,\n comment: displayName ?? `${schema.name} ${propName} enum`,\n },\n });\n } else {\n // Generate simple type alias (no labels)\n const values = enumProp.enum.map(v =>\n typeof v === 'string' ? v : v.value\n );\n results.push({\n typeAlias: {\n name: typeName,\n type: values.map(v => `'${v}'`).join(' | '),\n comment: displayName ?? `${schema.name} ${propName} enum`,\n },\n });\n }\n }\n }\n\n if (property.type === 'Select') {\n const selectProp = property as { options?: readonly (string | InlineEnumValue)[]; displayName?: LocalizedString };\n\n if (selectProp.options && selectProp.options.length > 0) {\n const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;\n const displayName = resolveDisplayName(selectProp.displayName, options);\n\n // Check if any option has labels\n const hasLabels = selectProp.options.some(v => typeof v !== 'string' && (v as InlineEnumValue).label !== undefined);\n\n if (hasLabels) {\n // Generate full enum with i18n labels\n const values: TSEnumValue[] = selectProp.options.map(v => parseEnumValue(v as string | InlineEnumValue, options));\n results.push({\n enum: {\n name: typeName,\n values,\n comment: displayName ?? `${schema.name} ${propName} options`,\n },\n });\n } else {\n // Generate simple type alias\n const values = selectProp.options.map(v =>\n typeof v === 'string' ? v : (v as InlineEnumValue).value\n );\n results.push({\n typeAlias: {\n name: typeName,\n type: values.map(v => `'${v}'`).join(' | '),\n comment: displayName ?? `${schema.name} ${propName} options`,\n },\n });\n }\n }\n }\n }\n }\n\n return results;\n}\n","/**\n * Built-in validation message templates for common languages.\n * Templates use ${displayName}, ${min}, ${max}, ${pattern} placeholders.\n */\n\nexport interface ValidationTemplates {\n readonly required: Record<string, string>;\n readonly minLength: Record<string, string>;\n readonly maxLength: Record<string, string>;\n readonly min: Record<string, string>;\n readonly max: Record<string, string>;\n readonly email: Record<string, string>;\n readonly url: Record<string, string>;\n readonly pattern: Record<string, string>;\n readonly enum: Record<string, string>;\n}\n\n/**\n * Default validation message templates.\n * Supports: ja (Japanese), en (English), vi (Vietnamese), ko (Korean), zh (Chinese)\n */\nexport const DEFAULT_VALIDATION_TEMPLATES: ValidationTemplates = {\n required: {\n ja: '${displayName}は必須です',\n en: '${displayName} is required',\n vi: '${displayName} là bắt buộc',\n ko: '${displayName}은(는) 필수입니다',\n zh: '${displayName}为必填项',\n },\n minLength: {\n ja: '${displayName}は${min}文字以上で入力してください',\n en: '${displayName} must be at least ${min} characters',\n vi: '${displayName} phải có ít nhất ${min} ký tự',\n ko: '${displayName}은(는) ${min}자 이상이어야 합니다',\n zh: '${displayName}至少需要${min}个字符',\n },\n maxLength: {\n ja: '${displayName}は${max}文字以内で入力してください',\n en: '${displayName} must be at most ${max} characters',\n vi: '${displayName} tối đa ${max} ký tự',\n ko: '${displayName}은(는) ${max}자 이하여야 합니다',\n zh: '${displayName}不能超过${max}个字符',\n },\n min: {\n ja: '${displayName}は${min}以上の値を入力してください',\n en: '${displayName} must be at least ${min}',\n vi: '${displayName} phải lớn hơn hoặc bằng ${min}',\n ko: '${displayName}은(는) ${min} 이상이어야 합니다',\n zh: '${displayName}不能小于${min}',\n },\n max: {\n ja: '${displayName}は${max}以下の値を入力してください',\n en: '${displayName} must be at most ${max}',\n vi: '${displayName} phải nhỏ hơn hoặc bằng ${max}',\n ko: '${displayName}은(는) ${max} 이하여야 합니다',\n zh: '${displayName}不能大于${max}',\n },\n email: {\n ja: '${displayName}の形式が正しくありません',\n en: '${displayName} is not a valid email address',\n vi: '${displayName} không phải là địa chỉ email hợp lệ',\n ko: '${displayName} 형식이 올바르지 않습니다',\n zh: '${displayName}不是有效的邮箱地址',\n },\n url: {\n ja: '${displayName}は有効なURLではありません',\n en: '${displayName} is not a valid URL',\n vi: '${displayName} không phải là URL hợp lệ',\n ko: '${displayName}은(는) 유효한 URL이 아닙니다',\n zh: '${displayName}不是有效的URL',\n },\n pattern: {\n ja: '${displayName}の形式が正しくありません',\n en: '${displayName} format is invalid',\n vi: '${displayName} không đúng định dạng',\n ko: '${displayName} 형식이 올바르지 않습니다',\n zh: '${displayName}格式不正确',\n },\n enum: {\n ja: '${displayName}の値が無効です',\n en: '${displayName} has an invalid value',\n vi: '${displayName} có giá trị không hợp lệ',\n ko: '${displayName} 값이 유효하지 않습니다',\n zh: '${displayName}的值无效',\n },\n};\n\n/**\n * Merge user templates with default templates.\n */\nexport function mergeValidationTemplates(\n userTemplates?: Partial<ValidationTemplates>\n): ValidationTemplates {\n if (!userTemplates) {\n return DEFAULT_VALIDATION_TEMPLATES;\n }\n\n // Create mutable copies of each template category\n const merged: Record<keyof ValidationTemplates, Record<string, string>> = {\n required: { ...DEFAULT_VALIDATION_TEMPLATES.required },\n minLength: { ...DEFAULT_VALIDATION_TEMPLATES.minLength },\n maxLength: { ...DEFAULT_VALIDATION_TEMPLATES.maxLength },\n min: { ...DEFAULT_VALIDATION_TEMPLATES.min },\n max: { ...DEFAULT_VALIDATION_TEMPLATES.max },\n email: { ...DEFAULT_VALIDATION_TEMPLATES.email },\n url: { ...DEFAULT_VALIDATION_TEMPLATES.url },\n pattern: { ...DEFAULT_VALIDATION_TEMPLATES.pattern },\n enum: { ...DEFAULT_VALIDATION_TEMPLATES.enum },\n };\n\n // Merge user templates\n for (const [key, value] of Object.entries(userTemplates)) {\n if (value && key in merged) {\n merged[key as keyof ValidationTemplates] = {\n ...merged[key as keyof ValidationTemplates],\n ...value,\n };\n }\n }\n\n return merged as ValidationTemplates;\n}\n\n/**\n * Format a validation message with placeholders.\n */\nexport function formatValidationMessage(\n template: string,\n vars: Record<string, string | number>\n): string {\n let result = template;\n for (const [key, value] of Object.entries(vars)) {\n result = result.replace(new RegExp(`\\\\$\\\\{${key}\\\\}`, 'g'), String(value));\n }\n return result;\n}\n\n/**\n * Get validation messages for all configured locales.\n * Fallback order: locale -> fallbackLocale -> 'en'\n */\nexport function getValidationMessages(\n templates: ValidationTemplates,\n ruleType: keyof ValidationTemplates,\n locales: string[],\n vars: Record<string, string | number>,\n fallbackLocale?: string\n): Record<string, string> {\n const ruleTemplates = templates[ruleType];\n const messages: Record<string, string> = {};\n\n for (const locale of locales) {\n // Try: locale -> fallbackLocale -> 'en'\n const template = ruleTemplates[locale]\n ?? (fallbackLocale ? ruleTemplates[fallbackLocale] : undefined)\n ?? ruleTemplates['en']\n ?? '';\n messages[locale] = formatValidationMessage(template, vars);\n }\n\n return messages;\n}\n","/**\n * Generates Ant Design compatible validation rules from schemas.\n */\n\nimport type { LoadedSchema, SchemaCollection, PropertyDefinition, LocalizedString, LocaleConfig } from '@famgia/omnify-types';\nimport type { TypeScriptFile, TypeScriptOptions, LocaleMap } from './types.js';\nimport {\n DEFAULT_VALIDATION_TEMPLATES,\n mergeValidationTemplates,\n getValidationMessages,\n type ValidationTemplates,\n} from './validation-templates.js';\n\n/**\n * Ant Design rule structure with multi-locale message.\n */\ninterface AntdRule {\n required?: boolean;\n type?: 'string' | 'number' | 'email' | 'url' | 'integer';\n min?: number;\n max?: number;\n len?: number;\n pattern?: string;\n message: LocaleMap;\n}\n\n/**\n * Property rules for a model.\n */\ninterface PropertyRules {\n displayName: LocaleMap;\n rules: AntdRule[];\n}\n\n/**\n * Model rules structure.\n */\ninterface ModelRules {\n displayName: LocaleMap;\n properties: Record<string, PropertyRules>;\n}\n\n/**\n * Get localized display name as object with all locales.\n */\nfunction getMultiLocaleDisplayName(\n value: LocalizedString | undefined,\n locales: string[],\n fallbackLocale: string,\n defaultValue: string\n): LocaleMap {\n if (!value) {\n // Return default value for all locales\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = defaultValue;\n }\n return result;\n }\n\n if (typeof value === 'string') {\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = value;\n }\n return result;\n }\n\n // It's a locale map\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = value[locale] ?? value[fallbackLocale] ?? value['en'] ?? defaultValue;\n }\n return result;\n}\n\n/**\n * Generate validation rules for a property.\n */\nfunction generatePropertyRules(\n propName: string,\n property: PropertyDefinition,\n displayName: LocaleMap,\n locales: string[],\n fallbackLocale: string,\n templates: ValidationTemplates\n): AntdRule[] {\n const rules: AntdRule[] = [];\n const propDef = property as {\n nullable?: boolean;\n length?: number;\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n pattern?: string;\n };\n\n // Required rule (if not nullable)\n if (!propDef.nullable) {\n rules.push({\n required: true,\n message: getValidationMessages(templates, 'required', locales, { displayName: '${displayName}' }, fallbackLocale),\n });\n }\n\n // Type-specific rules\n if (property.type === 'Email') {\n rules.push({\n type: 'email',\n message: getValidationMessages(templates, 'email', locales, { displayName: '${displayName}' }, fallbackLocale),\n });\n }\n\n // Length rules for strings\n if (property.type === 'String' || property.type === 'Text' || property.type === 'LongText') {\n if (propDef.minLength) {\n rules.push({\n min: propDef.minLength,\n message: getValidationMessages(templates, 'minLength', locales, { displayName: '${displayName}', min: propDef.minLength }, fallbackLocale),\n });\n }\n if (propDef.maxLength || propDef.length) {\n const max = propDef.maxLength ?? propDef.length!;\n rules.push({\n max,\n message: getValidationMessages(templates, 'maxLength', locales, { displayName: '${displayName}', max }, fallbackLocale),\n });\n }\n }\n\n // Numeric range rules\n if (property.type === 'Int' || property.type === 'BigInt' || property.type === 'Float') {\n if (propDef.min !== undefined) {\n rules.push({\n type: property.type === 'Float' ? 'number' : 'integer',\n min: propDef.min,\n message: getValidationMessages(templates, 'min', locales, { displayName: '${displayName}', min: propDef.min }, fallbackLocale),\n });\n }\n if (propDef.max !== undefined) {\n rules.push({\n type: property.type === 'Float' ? 'number' : 'integer',\n max: propDef.max,\n message: getValidationMessages(templates, 'max', locales, { displayName: '${displayName}', max: propDef.max }, fallbackLocale),\n });\n }\n }\n\n // Pattern rule\n if (propDef.pattern) {\n rules.push({\n pattern: propDef.pattern,\n message: getValidationMessages(templates, 'pattern', locales, { displayName: '${displayName}' }, fallbackLocale),\n });\n }\n\n // Replace ${displayName} placeholder with actual display name per locale\n for (const rule of rules) {\n const newMessage: Record<string, string> = {};\n for (const locale of locales) {\n const msg = rule.message[locale];\n if (msg) {\n newMessage[locale] = msg.replace(/\\$\\{displayName\\}/g, displayName[locale] ?? propName);\n }\n }\n (rule as { message: Record<string, string> }).message = newMessage;\n }\n\n return rules;\n}\n\n/**\n * Generate rules for a schema.\n */\nexport function generateModelRules(\n schema: LoadedSchema,\n locales: string[],\n fallbackLocale: string,\n templates: ValidationTemplates\n): ModelRules {\n const modelDisplayName = getMultiLocaleDisplayName(\n schema.displayName,\n locales,\n fallbackLocale,\n schema.name\n );\n\n const properties: Record<string, PropertyRules> = {};\n\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n const propDef = property as { displayName?: LocalizedString };\n const displayName = getMultiLocaleDisplayName(\n propDef.displayName,\n locales,\n fallbackLocale,\n propName\n );\n\n properties[propName] = {\n displayName,\n rules: generatePropertyRules(propName, property, displayName, locales, fallbackLocale, templates),\n };\n }\n }\n\n return {\n displayName: modelDisplayName,\n properties,\n };\n}\n\n/**\n * Gets file extension for imports based on options.\n */\nfunction getImportExt(options: TypeScriptOptions): string {\n return options.useJsExtension ? '.js' : '';\n}\n\n/**\n * Format rules as TypeScript code.\n */\nfunction formatRulesFile(\n schemaName: string,\n rules: ModelRules,\n options: TypeScriptOptions\n): string {\n const parts: string[] = [];\n const ext = getImportExt(options);\n\n parts.push(`/**\n * ⚠️ DO NOT EDIT THIS FILE! ⚠️\n * このファイルを編集しないでください!\n * KHÔNG ĐƯỢC SỬA FILE NÀY!\n *\n * Auto-generated validation rules and metadata for ${schemaName}.\n * Any manual changes will be OVERWRITTEN on next generation.\n *\n * To modify: Edit the schema YAML file and run: npx omnify generate\n */\n\nimport type { LocaleMap, ValidationRule } from '../common${ext}';\n\n`);\n\n // Model display name\n parts.push(`/** Display name for ${schemaName} */\\n`);\n parts.push(`export const ${schemaName}DisplayName: LocaleMap = ${JSON.stringify(rules.displayName, null, 2)};\\n\\n`);\n\n // Property metadata and rules\n parts.push(`/** Property display names for ${schemaName} */\\n`);\n parts.push(`export const ${schemaName}PropertyDisplayNames: Record<string, LocaleMap> = {\\n`);\n for (const [propName, propRules] of Object.entries(rules.properties)) {\n parts.push(` ${propName}: ${JSON.stringify(propRules.displayName)},\\n`);\n }\n parts.push(`};\\n\\n`);\n\n // Validation rules\n parts.push(`/** Validation rules for ${schemaName} (Ant Design compatible) */\\n`);\n parts.push(`export const ${schemaName}Rules: Record<string, ValidationRule[]> = {\\n`);\n for (const [propName, propRules] of Object.entries(rules.properties)) {\n if (propRules.rules.length > 0) {\n parts.push(` ${propName}: [\\n`);\n for (const rule of propRules.rules) {\n const ruleObj: Record<string, unknown> = {};\n if (rule.required) ruleObj.required = true;\n if (rule.type) ruleObj.type = `'${rule.type}'`;\n if (rule.min !== undefined) ruleObj.min = rule.min;\n if (rule.max !== undefined) ruleObj.max = rule.max;\n if (rule.pattern) ruleObj.pattern = `/${rule.pattern}/`;\n ruleObj.message = rule.message;\n\n // Format as JS object\n const ruleStr = Object.entries(ruleObj)\n .map(([k, v]) => {\n if (k === 'type') return `${k}: ${v}`;\n if (k === 'pattern') return `${k}: ${v}`;\n return `${k}: ${JSON.stringify(v)}`;\n })\n .join(', ');\n parts.push(` { ${ruleStr} },\\n`);\n }\n parts.push(` ],\\n`);\n }\n }\n parts.push(`};\\n\\n`);\n\n // Helper function to get rules with locale-specific messages\n parts.push(`/** Get validation rules with messages for a specific locale */\\n`);\n parts.push(`export function get${schemaName}Rules(locale: string): Record<string, Array<{ required?: boolean; type?: string; min?: number; max?: number; pattern?: RegExp; message: string }>> {\n const result: Record<string, Array<{ required?: boolean; type?: string; min?: number; max?: number; pattern?: RegExp; message: string }>> = {};\n for (const [prop, rules] of Object.entries(${schemaName}Rules)) {\n result[prop] = rules.map(rule => ({\n ...rule,\n message: rule.message[locale] ?? rule.message['en'] ?? '',\n }));\n }\n return result;\n}\\n\\n`);\n\n // Helper function to get display name\n parts.push(`/** Get display name for a specific locale */\\n`);\n parts.push(`export function get${schemaName}DisplayName(locale: string): string {\n return ${schemaName}DisplayName[locale] ?? ${schemaName}DisplayName['en'] ?? '${schemaName}';\n}\\n\\n`);\n\n parts.push(`/** Get property display name for a specific locale */\\n`);\n parts.push(`export function get${schemaName}PropertyDisplayName(property: string, locale: string): string {\n const names = ${schemaName}PropertyDisplayNames[property];\n return names?.[locale] ?? names?.['en'] ?? property;\n}\\n`);\n\n return parts.join('');\n}\n\n/**\n * Generate rules files for all schemas.\n */\nexport function generateRulesFiles(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TypeScriptFile[] {\n const files: TypeScriptFile[] = [];\n const localeConfig = options.localeConfig;\n const locales = [...(localeConfig?.locales ?? ['en'])]; // Convert readonly to mutable\n const fallbackLocale = localeConfig?.fallbackLocale ?? 'en';\n\n // Merge user templates with defaults\n const templates = mergeValidationTemplates(options.validationTemplates as Partial<ValidationTemplates> | undefined);\n\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n\n const rules = generateModelRules(schema, locales, fallbackLocale, templates);\n const content = formatRulesFile(schema.name, rules, options);\n\n files.push({\n filePath: `rules/${schema.name}.rules.ts`,\n content,\n types: [`${schema.name}Rules`, `${schema.name}DisplayName`],\n overwrite: true,\n });\n }\n\n return files;\n}\n","/**\n * @famgia/omnify-typescript - Zod Schema Generator\n *\n * Generates Zod schemas alongside TypeScript interfaces.\n */\n\nimport type { LoadedSchema, PropertyDefinition, LocalizedString, CustomTypeDefinition } from '@famgia/omnify-types';\nimport type { TypeScriptOptions, LocaleMap } from './types.js';\nimport { toSnakeCase } from './interface-generator.js';\n\n/**\n * Zod schema information for a property.\n */\nexport interface ZodPropertySchema {\n /** Field name in snake_case */\n readonly fieldName: string;\n /** Zod schema string (e.g., \"z.string().min(1).max(255)\") */\n readonly schema: string;\n /** Whether this field should be in create schema */\n readonly inCreate: boolean;\n /** Whether this field should be in update schema */\n readonly inUpdate: boolean;\n /** Comment for the schema */\n readonly comment?: string;\n}\n\n/**\n * Display names for a schema.\n */\nexport interface SchemaDisplayNames {\n /** Model display name per locale */\n readonly displayName: LocaleMap;\n /** Property display names per locale */\n readonly propertyDisplayNames: Record<string, LocaleMap>;\n /** Property placeholders per locale */\n readonly propertyPlaceholders: Record<string, LocaleMap>;\n}\n\n/**\n * Get localized display name as object with all locales.\n */\nfunction getMultiLocaleDisplayName(\n value: LocalizedString | undefined,\n locales: readonly string[],\n fallbackLocale: string,\n defaultValue: string\n): LocaleMap {\n if (!value) {\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = defaultValue;\n }\n return result;\n }\n\n if (typeof value === 'string') {\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = value;\n }\n return result;\n }\n\n const result: Record<string, string> = {};\n for (const locale of locales) {\n result[locale] = value[locale] ?? value[fallbackLocale] ?? value['en'] ?? defaultValue;\n }\n return result;\n}\n\n/**\n * Validation rules type for internal use.\n */\ninterface InternalValidationRules {\n readonly required?: boolean;\n readonly minLength?: number;\n readonly maxLength?: number;\n readonly url?: boolean;\n readonly uuid?: boolean;\n readonly ip?: boolean;\n readonly ipv4?: boolean;\n readonly ipv6?: boolean;\n readonly alpha?: boolean;\n readonly alphaNum?: boolean;\n readonly alphaDash?: boolean;\n readonly numeric?: boolean;\n readonly digits?: number;\n readonly digitsBetween?: readonly [number, number];\n readonly startsWith?: string | readonly string[];\n readonly endsWith?: string | readonly string[];\n readonly lowercase?: boolean;\n readonly uppercase?: boolean;\n readonly min?: number;\n readonly max?: number;\n readonly between?: readonly [number, number];\n readonly gt?: number;\n readonly lt?: number;\n readonly multipleOf?: number;\n readonly arrayMin?: number;\n readonly arrayMax?: number;\n}\n\n/**\n * Apply validation rules to a Zod schema string.\n */\nfunction applyValidationRules(\n schema: string,\n rules: InternalValidationRules | undefined,\n propType: string\n): string {\n if (!rules) return schema;\n\n let result = schema;\n\n // === Format Rules (override base type) ===\n if (rules.url) {\n // z.url() is a top-level type in Zod v4\n result = 'z.url()';\n } else if (rules.uuid) {\n result = 'z.uuid()';\n } else if (rules.ip) {\n result = 'z.ip()';\n } else if (rules.ipv4) {\n result = 'z.ipv4()';\n } else if (rules.ipv6) {\n result = 'z.ipv6()';\n }\n\n // === Check if this is a string type ===\n const isStringType = ['String', 'Text', 'MediumText', 'LongText', 'Password', 'Email'].includes(propType);\n\n // === String Length Rules (only for string types) ===\n if (isStringType) {\n if (rules.minLength !== undefined) {\n result += `.min(${rules.minLength})`;\n }\n if (rules.maxLength !== undefined) {\n result += `.max(${rules.maxLength})`;\n }\n }\n\n // === Character Pattern Rules (only for string types) ===\n if (isStringType) {\n if (rules.alpha) {\n result += `.regex(/^[a-zA-Z]*$/, { message: 'Must contain only letters' })`;\n }\n if (rules.alphaNum) {\n result += `.regex(/^[a-zA-Z0-9]*$/, { message: 'Must contain only letters and numbers' })`;\n }\n if (rules.alphaDash) {\n result += `.regex(/^[a-zA-Z0-9_-]*$/, { message: 'Must contain only letters, numbers, dashes, and underscores' })`;\n }\n if (rules.numeric) {\n result += `.regex(/^\\\\d*$/, { message: 'Must contain only numbers' })`;\n }\n if (rules.digits !== undefined) {\n result += `.length(${rules.digits}).regex(/^\\\\d+$/, { message: 'Must be exactly ${rules.digits} digits' })`;\n }\n if (rules.digitsBetween) {\n const [min, max] = rules.digitsBetween;\n result += `.min(${min}).max(${max}).regex(/^\\\\d+$/, { message: 'Must be ${min}-${max} digits' })`;\n }\n\n // === String Matching Rules ===\n if (rules.startsWith) {\n const prefixes = Array.isArray(rules.startsWith) ? rules.startsWith : [rules.startsWith];\n // 空文字列は無視\n const validPrefixes = prefixes.filter(p => p.length > 0);\n if (validPrefixes.length === 1) {\n result += `.startsWith('${validPrefixes[0]}')`;\n } else if (validPrefixes.length > 1) {\n const regex = validPrefixes.map(p => p.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|');\n result += `.regex(/^(${regex})/, { message: 'Must start with: ${validPrefixes.join(', ')}' })`;\n }\n }\n if (rules.endsWith) {\n const suffixes = Array.isArray(rules.endsWith) ? rules.endsWith : [rules.endsWith];\n // 空文字列は無視\n const validSuffixes = suffixes.filter(s => s.length > 0);\n if (validSuffixes.length === 1) {\n result += `.endsWith('${validSuffixes[0]}')`;\n } else if (validSuffixes.length > 1) {\n const regex = validSuffixes.map(s => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|');\n result += `.regex(/(${regex})$/, { message: 'Must end with: ${validSuffixes.join(', ')}' })`;\n }\n }\n if (rules.lowercase) {\n result += `.refine(v => v === v.toLowerCase(), { message: 'Must be lowercase' })`;\n }\n if (rules.uppercase) {\n result += `.refine(v => v === v.toUpperCase(), { message: 'Must be uppercase' })`;\n }\n }\n\n // === Numeric Rules ===\n if (propType === 'Int' || propType === 'TinyInt' || propType === 'BigInt' || propType === 'Float') {\n if (rules.min !== undefined) {\n result += `.gte(${rules.min})`;\n }\n if (rules.max !== undefined) {\n result += `.lte(${rules.max})`;\n }\n if (rules.between) {\n const [min, max] = rules.between;\n result += `.gte(${min}).lte(${max})`;\n }\n if (rules.gt !== undefined) {\n result += `.gt(${rules.gt})`;\n }\n if (rules.lt !== undefined) {\n result += `.lt(${rules.lt})`;\n }\n if (rules.multipleOf !== undefined) {\n result += `.multipleOf(${rules.multipleOf})`;\n }\n }\n\n return result;\n}\n\n/**\n * Generate Zod schema string for a property type.\n */\nfunction getZodSchemaForType(\n propDef: PropertyDefinition,\n fieldName: string,\n customTypes?: ReadonlyMap<string, CustomTypeDefinition>\n): string {\n const def = propDef as {\n nullable?: boolean;\n length?: number;\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n pattern?: string;\n enum?: string | readonly string[];\n options?: readonly string[];\n rules?: InternalValidationRules;\n };\n\n const isNullable = def.nullable ?? false;\n let schema = '';\n\n // Check for custom simple types first\n if (customTypes) {\n const customType = customTypes.get(propDef.type);\n if (customType && !customType.compound) {\n // Simple custom type - use string based on SQL type\n const sqlType = customType.sql?.sqlType || 'VARCHAR';\n schema = 'z.string()';\n\n // Add length constraint if available\n if (customType.sql?.length) {\n schema += `.max(${customType.sql.length})`;\n }\n\n if (isNullable) {\n schema += '.optional().nullable()';\n }\n return schema;\n }\n }\n\n switch (propDef.type) {\n case 'String':\n case 'Text':\n case 'MediumText':\n case 'LongText':\n case 'Password':\n schema = 'z.string()';\n if (!isNullable) {\n schema += '.min(1)';\n }\n if (def.maxLength || def.length) {\n schema += `.max(${def.maxLength ?? def.length})`;\n }\n if (def.minLength && def.minLength > 1) {\n // Replace .min(1) with actual minLength\n schema = schema.replace('.min(1)', `.min(${def.minLength})`);\n }\n break;\n\n case 'Email':\n // Zod v4: Use z.email() top-level for better tree-shaking\n schema = 'z.email()';\n if (def.maxLength || def.length) {\n schema += `.max(${def.maxLength ?? def.length ?? 255})`;\n }\n break;\n\n case 'TinyInt':\n case 'Int':\n case 'BigInt':\n schema = 'z.number().int()';\n if (def.min !== undefined) {\n schema += `.gte(${def.min})`;\n }\n if (def.max !== undefined) {\n schema += `.lte(${def.max})`;\n }\n break;\n\n case 'Float':\n schema = 'z.number()';\n if (def.min !== undefined) {\n schema += `.gte(${def.min})`;\n }\n if (def.max !== undefined) {\n schema += `.lte(${def.max})`;\n }\n break;\n\n case 'Boolean':\n schema = 'z.boolean()';\n break;\n\n case 'Date':\n schema = 'z.string().date()';\n break;\n\n case 'DateTime':\n case 'Timestamp':\n schema = 'z.string().datetime({ offset: true })';\n break;\n\n case 'Time':\n schema = 'z.string().time()';\n break;\n\n case 'Json':\n schema = 'z.unknown()';\n break;\n\n case 'EnumRef':\n // Reference to shared enum schema\n if (typeof def.enum === 'string') {\n schema = `z.nativeEnum(${def.enum})`;\n } else {\n schema = 'z.string()';\n }\n break;\n\n case 'Enum':\n if (typeof def.enum === 'string') {\n // Reference to named enum - will need to be imported\n schema = `${def.enum}Schema`;\n } else if (Array.isArray(def.enum)) {\n // Inline enum values\n const values = def.enum.map(v => `'${v}'`).join(', ');\n schema = `z.enum([${values}])`;\n } else {\n schema = 'z.string()';\n }\n break;\n\n case 'Select':\n if (def.options && def.options.length > 0) {\n const values = def.options.map(v => `'${v}'`).join(', ');\n schema = `z.enum([${values}])`;\n } else {\n schema = 'z.string()';\n }\n break;\n\n case 'Lookup':\n schema = 'z.number().int().positive()';\n break;\n\n case 'Association':\n // Associations are not validated in forms, skip\n return '';\n\n case 'File':\n // File uploads handled separately\n return '';\n\n default:\n schema = 'z.string()';\n }\n\n // Apply validation rules from schema definition\n if (def.rules && schema) {\n schema = applyValidationRules(schema, def.rules, propDef.type);\n }\n\n // Apply nullable/optional\n if (isNullable && schema) {\n schema += '.optional().nullable()';\n }\n\n // Apply pattern (legacy support, prefer rules.pattern in future)\n if (def.pattern && schema) {\n schema += `.regex(/${def.pattern}/)`;\n }\n\n return schema;\n}\n\n/**\n * Generate Zod schemas for compound type fields.\n */\nfunction generateCompoundTypeSchemas(\n propName: string,\n propDef: PropertyDefinition,\n customType: CustomTypeDefinition,\n options: TypeScriptOptions\n): ZodPropertySchema[] {\n const schemas: ZodPropertySchema[] = [];\n const propFields = (propDef as { fields?: Record<string, { nullable?: boolean; length?: number; hidden?: boolean }> }).fields;\n const locales = options.localeConfig?.locales ?? ['en'];\n const fallbackLocale = options.localeConfig?.fallbackLocale ?? 'en';\n\n if (!customType.expand) return schemas;\n\n for (const field of customType.expand) {\n const fieldName = `${toSnakeCase(propName)}_${toSnakeCase(field.suffix)}`;\n const fieldOverride = propFields?.[field.suffix] as {\n nullable?: boolean;\n length?: number;\n rules?: {\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n pattern?: string;\n format?: string;\n };\n } | undefined;\n\n // Nullable priority: schema field override > plugin field default > parent property > false\n const isNullable = fieldOverride?.nullable ?? field.sql?.nullable ?? (propDef as { nullable?: boolean }).nullable ?? false;\n\n // Rules priority: schema field override > plugin field rules > defaults from sql\n const pluginRules = field.rules;\n const overrideRules = fieldOverride?.rules;\n const length = fieldOverride?.length ?? overrideRules?.maxLength ?? pluginRules?.maxLength ?? field.sql?.length;\n const minLength = overrideRules?.minLength ?? pluginRules?.minLength;\n const pattern = overrideRules?.pattern ?? pluginRules?.pattern;\n const format = overrideRules?.format ?? pluginRules?.format;\n\n // Build Zod schema based on format or type\n let schema = 'z.string()';\n\n // Apply format-specific validation\n // Zod v4: Use top-level validators for better tree-shaking\n if (format === 'email') {\n schema = 'z.email()';\n } else if (format === 'url') {\n schema = 'z.url()';\n } else if (format === 'phone') {\n // Japanese phone pattern: 0X0-XXXX-XXXX or 0X-XXXX-XXXX\n schema = 'z.string()';\n } else if (format === 'postal_code') {\n // Japanese postal code: XXX-XXXX\n schema = `z.string().regex(/^\\\\d{3}-?\\\\d{4}$/)`;\n }\n\n // Apply length constraints\n if (!isNullable) {\n const min = minLength ?? 1;\n schema += `.min(${min})`;\n } else if (minLength) {\n schema += `.min(${minLength})`;\n }\n\n if (length) {\n schema += `.max(${length})`;\n }\n\n // Apply pattern (if not already applied via format)\n if (pattern && !format) {\n schema += `.regex(/${pattern}/)`;\n }\n\n // Apply nullable\n if (isNullable) {\n schema += '.optional().nullable()';\n }\n\n // Get display name\n const propDisplayName = getMultiLocaleDisplayName(\n (propDef as { displayName?: LocalizedString }).displayName,\n locales,\n fallbackLocale,\n propName\n );\n\n schemas.push({\n fieldName,\n schema,\n inCreate: true,\n inUpdate: true,\n comment: `${propDisplayName['en'] ?? propName} (${field.suffix})`,\n });\n }\n\n return schemas;\n}\n\n/**\n * Generate Zod schemas for all properties in a schema.\n */\nexport function generateZodSchemas(\n schema: LoadedSchema,\n options: TypeScriptOptions\n): ZodPropertySchema[] {\n const schemas: ZodPropertySchema[] = [];\n const customTypes = options.customTypes;\n\n if (!schema.properties) return schemas;\n\n for (const [propName, propDef] of Object.entries(schema.properties)) {\n // Check for compound custom types\n if (customTypes) {\n const customType = customTypes.get(propDef.type);\n if (customType?.compound) {\n schemas.push(...generateCompoundTypeSchemas(propName, propDef, customType, options));\n continue;\n }\n }\n\n const zodSchema = getZodSchemaForType(propDef, propName, customTypes);\n if (!zodSchema) continue;\n\n const fieldName = toSnakeCase(propName);\n\n schemas.push({\n fieldName,\n schema: zodSchema,\n inCreate: true,\n inUpdate: true,\n comment: undefined,\n });\n }\n\n return schemas;\n}\n\n/**\n * Generate display names and placeholders for a schema.\n */\nexport function generateDisplayNames(\n schema: LoadedSchema,\n options: TypeScriptOptions\n): SchemaDisplayNames {\n const locales = options.localeConfig?.locales ?? ['en'];\n const fallbackLocale = options.localeConfig?.fallbackLocale ?? 'en';\n const customTypes = options.customTypes;\n\n const displayName = getMultiLocaleDisplayName(\n schema.displayName,\n locales,\n fallbackLocale,\n schema.name\n );\n\n const propertyDisplayNames: Record<string, LocaleMap> = {};\n const propertyPlaceholders: Record<string, LocaleMap> = {};\n\n if (schema.properties) {\n for (const [propName, propDef] of Object.entries(schema.properties)) {\n const prop = propDef as {\n displayName?: LocalizedString;\n placeholder?: LocalizedString;\n fields?: Record<string, { displayName?: LocalizedString; placeholder?: LocalizedString }>;\n };\n const fieldName = toSnakeCase(propName);\n\n // Check for compound types - expand to individual fields\n if (customTypes) {\n const customType = customTypes.get(propDef.type);\n if (customType?.compound && customType.expand) {\n // Add compound-level displayName (e.g., `name` -> `氏名`)\n // This is used by components that need the combined field's label\n if (prop.displayName) {\n propertyDisplayNames[fieldName] = getMultiLocaleDisplayName(\n prop.displayName,\n locales,\n fallbackLocale,\n propName\n );\n }\n\n for (const field of customType.expand) {\n const expandedFieldName = `${fieldName}_${toSnakeCase(field.suffix)}`;\n const fieldOverride = prop.fields?.[field.suffix];\n\n // Display name for compound field (priority: schema override > plugin label > fallback)\n const labelSource = fieldOverride?.displayName ?? field.label;\n if (labelSource) {\n // Use explicit label from schema override or plugin\n propertyDisplayNames[expandedFieldName] = getMultiLocaleDisplayName(\n labelSource,\n locales,\n fallbackLocale,\n field.suffix\n );\n } else {\n // Fallback: parent displayName + field suffix\n propertyDisplayNames[expandedFieldName] = getMultiLocaleDisplayName(\n prop.displayName,\n locales,\n fallbackLocale,\n propName\n );\n // Append field suffix to display name\n for (const locale of locales) {\n propertyDisplayNames[expandedFieldName] = {\n ...propertyDisplayNames[expandedFieldName],\n [locale]: `${propertyDisplayNames[expandedFieldName][locale]} (${field.suffix})`,\n };\n }\n }\n\n // Placeholder for compound field (priority: schema override > plugin default > empty)\n const placeholderSource = fieldOverride?.placeholder ?? field.placeholder;\n if (placeholderSource) {\n propertyPlaceholders[expandedFieldName] = getMultiLocaleDisplayName(\n placeholderSource,\n locales,\n fallbackLocale,\n ''\n );\n }\n }\n continue;\n }\n }\n\n // Display name for regular field\n propertyDisplayNames[fieldName] = getMultiLocaleDisplayName(\n prop.displayName,\n locales,\n fallbackLocale,\n propName\n );\n\n // Placeholder for regular field\n if (prop.placeholder) {\n propertyPlaceholders[fieldName] = getMultiLocaleDisplayName(\n prop.placeholder,\n locales,\n fallbackLocale,\n ''\n );\n }\n }\n }\n\n return { displayName, propertyDisplayNames, propertyPlaceholders };\n}\n\n/**\n * Get fields to exclude from create/update schemas.\n */\nexport function getExcludedFields(\n schema: LoadedSchema,\n customTypes?: ReadonlyMap<string, CustomTypeDefinition>\n): { create: Set<string>; update: Set<string> } {\n const createExclude = new Set<string>();\n const updateExclude = new Set<string>();\n\n // Always exclude id\n if (schema.options?.id !== false) {\n createExclude.add('id');\n updateExclude.add('id');\n }\n\n // Exclude timestamps\n if (schema.options?.timestamps !== false) {\n createExclude.add('created_at');\n createExclude.add('updated_at');\n updateExclude.add('created_at');\n updateExclude.add('updated_at');\n }\n\n // Exclude soft delete\n if (schema.options?.softDelete) {\n createExclude.add('deleted_at');\n updateExclude.add('deleted_at');\n }\n\n // Exclude email_verified_at\n if (schema.properties) {\n if (schema.properties['emailVerifiedAt'] || schema.properties['email_verified_at']) {\n createExclude.add('email_verified_at');\n updateExclude.add('email_verified_at');\n }\n }\n\n // Exclude computed fields from compound types\n if (schema.properties && customTypes) {\n for (const [propName, propDef] of Object.entries(schema.properties)) {\n const customType = customTypes.get(propDef.type);\n if (customType?.accessors) {\n for (const accessor of customType.accessors) {\n const fieldName = `${toSnakeCase(propName)}_${toSnakeCase(accessor.name)}`;\n createExclude.add(fieldName);\n updateExclude.add(fieldName);\n }\n }\n }\n }\n\n return { create: createExclude, update: updateExclude };\n}\n\n/**\n * Format Zod schemas section for base file.\n */\nexport function formatZodSchemasSection(\n schemaName: string,\n zodSchemas: ZodPropertySchema[],\n displayNames: SchemaDisplayNames,\n excludedFields: { create: Set<string>; update: Set<string> }\n): string {\n const parts: string[] = [];\n const lowerName = schemaName.charAt(0).toLowerCase() + schemaName.slice(1);\n\n // I18n - Unified locale object\n parts.push(`// ============================================================================\\n`);\n parts.push(`// I18n (Internationalization)\\n`);\n parts.push(`// ============================================================================\\n\\n`);\n\n parts.push(`/**\\n`);\n parts.push(` * Unified i18n object for ${schemaName}\\n`);\n parts.push(` * Contains model label and all field labels/placeholders\\n`);\n parts.push(` */\\n`);\n parts.push(`export const ${lowerName}I18n = {\\n`);\n parts.push(` /** Model display name */\\n`);\n parts.push(` label: ${JSON.stringify(displayNames.displayName)},\\n`);\n parts.push(` /** Field labels and placeholders */\\n`);\n parts.push(` fields: {\\n`);\n for (const [propName, labelMap] of Object.entries(displayNames.propertyDisplayNames)) {\n const placeholderMap = displayNames.propertyPlaceholders[propName];\n parts.push(` ${propName}: {\\n`);\n parts.push(` label: ${JSON.stringify(labelMap)},\\n`);\n if (placeholderMap) {\n parts.push(` placeholder: ${JSON.stringify(placeholderMap)},\\n`);\n }\n parts.push(` },\\n`);\n }\n parts.push(` },\\n`);\n parts.push(`} as const;\\n\\n`);\n\n // Field Schemas\n parts.push(`// ============================================================================\\n`);\n parts.push(`// Zod Schemas\\n`);\n parts.push(`// ============================================================================\\n\\n`);\n\n parts.push(`/** Field schemas for ${schemaName} */\\n`);\n parts.push(`export const base${schemaName}Schemas = {\\n`);\n for (const prop of zodSchemas) {\n if (prop.comment) {\n parts.push(` /** ${prop.comment} */\\n`);\n }\n parts.push(` ${prop.fieldName}: ${prop.schema},\\n`);\n }\n parts.push(`} as const;\\n\\n`);\n\n // Create Schema\n const createFields = zodSchemas.filter(p => p.inCreate && !excludedFields.create.has(p.fieldName));\n parts.push(`/** Create schema for ${schemaName} (POST requests) */\\n`);\n parts.push(`export const base${schemaName}CreateSchema = z.object({\\n`);\n for (const prop of createFields) {\n parts.push(` ${prop.fieldName}: base${schemaName}Schemas.${prop.fieldName},\\n`);\n }\n parts.push(`});\\n\\n`);\n\n // Update Schema\n parts.push(`/** Update schema for ${schemaName} (PUT/PATCH requests) */\\n`);\n parts.push(`export const base${schemaName}UpdateSchema = base${schemaName}CreateSchema.partial();\\n\\n`);\n\n // Inferred Types\n parts.push(`// ============================================================================\\n`);\n parts.push(`// Inferred Types\\n`);\n parts.push(`// ============================================================================\\n\\n`);\n\n parts.push(`export type Base${schemaName}Create = z.infer<typeof base${schemaName}CreateSchema>;\\n`);\n parts.push(`export type Base${schemaName}Update = z.infer<typeof base${schemaName}UpdateSchema>;\\n\\n`);\n\n // Helper Functions\n parts.push(`// ============================================================================\\n`);\n parts.push(`// I18n Helper Functions\\n`);\n parts.push(`// ============================================================================\\n\\n`);\n\n parts.push(`/** Get model label for a specific locale */\\n`);\n parts.push(`export function get${schemaName}Label(locale: string): string {\\n`);\n parts.push(` return ${lowerName}I18n.label[locale as keyof typeof ${lowerName}I18n.label] ?? ${lowerName}I18n.label['en'] ?? '${schemaName}';\\n`);\n parts.push(`}\\n\\n`);\n\n parts.push(`/** Get field label for a specific locale */\\n`);\n parts.push(`export function get${schemaName}FieldLabel(field: string, locale: string): string {\\n`);\n parts.push(` const fieldI18n = ${lowerName}I18n.fields[field as keyof typeof ${lowerName}I18n.fields];\\n`);\n parts.push(` if (!fieldI18n) return field;\\n`);\n parts.push(` return fieldI18n.label[locale as keyof typeof fieldI18n.label] ?? fieldI18n.label['en'] ?? field;\\n`);\n parts.push(`}\\n\\n`);\n\n parts.push(`/** Get field placeholder for a specific locale */\\n`);\n parts.push(`export function get${schemaName}FieldPlaceholder(field: string, locale: string): string {\\n`);\n parts.push(` const fieldI18n = ${lowerName}I18n.fields[field as keyof typeof ${lowerName}I18n.fields];\\n`);\n parts.push(` if (!fieldI18n || !('placeholder' in fieldI18n)) return '';\\n`);\n parts.push(` const placeholder = fieldI18n.placeholder as Record<string, string>;\\n`);\n parts.push(` return placeholder[locale] ?? placeholder['en'] ?? '';\\n`);\n parts.push(`}\\n`);\n\n return parts.join('');\n}\n\n/**\n * Format user model file with Zod re-exports.\n * @param schemaName - The schema name\n * @param ext - Import extension ('.js' for ESM, '' for bundlers)\n */\nexport function formatZodModelFile(schemaName: string, ext: string = ''): string {\n const lowerName = schemaName.charAt(0).toLowerCase() + schemaName.slice(1);\n\n return `/**\n * ${schemaName} Model\n *\n * This file extends the auto-generated base interface.\n * You can add custom methods, computed properties, or override types/schemas here.\n * This file will NOT be overwritten by the generator.\n */\n\nimport { z } from 'zod';\nimport type { ${schemaName} as ${schemaName}Base } from './base/${schemaName}${ext}';\nimport {\n base${schemaName}Schemas,\n base${schemaName}CreateSchema,\n base${schemaName}UpdateSchema,\n ${lowerName}I18n,\n get${schemaName}Label,\n get${schemaName}FieldLabel,\n get${schemaName}FieldPlaceholder,\n} from './base/${schemaName}${ext}';\n\n// ============================================================================\n// Types (extend or re-export)\n// ============================================================================\n\nexport interface ${schemaName} extends ${schemaName}Base {\n // Add custom properties here\n}\n\n// ============================================================================\n// Schemas (extend or re-export)\n// ============================================================================\n\nexport const ${lowerName}Schemas = { ...base${schemaName}Schemas };\nexport const ${lowerName}CreateSchema = base${schemaName}CreateSchema;\nexport const ${lowerName}UpdateSchema = base${schemaName}UpdateSchema;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ${schemaName}Create = z.infer<typeof ${lowerName}CreateSchema>;\nexport type ${schemaName}Update = z.infer<typeof ${lowerName}UpdateSchema>;\n\n// Re-export i18n and helpers\nexport {\n ${lowerName}I18n,\n get${schemaName}Label,\n get${schemaName}FieldLabel,\n get${schemaName}FieldPlaceholder,\n};\n\n// Re-export base type for internal use\nexport type { ${schemaName}Base };\n`;\n}\n","/**\n * @famgia/omnify-typescript - TypeScript Generator\n *\n * Generates TypeScript models with base/model pattern:\n * - models/base/[SchemaName].ts - Auto-generated base interfaces, DO NOT EDIT\n * - models/enum/[EnumName].ts - Auto-generated enums/type aliases, DO NOT EDIT\n * - models/[SchemaName].ts - Extends base, user can customize\n * - models/index.ts - Re-exports all\n */\n\nimport type { SchemaCollection } from '@famgia/omnify-types';\nimport type { TypeScriptFile, TypeScriptOptions, TSEnum, TSTypeAlias } from './types.js';\nimport { generateInterfaces, formatInterface, toSnakeCase } from './interface-generator.js';\nimport { generateEnums, generatePluginEnums, formatEnum, formatTypeAlias, extractInlineEnums } from './enum-generator.js';\nimport { generateRulesFiles } from './rules-generator.js';\nimport {\n generateZodSchemas,\n generateDisplayNames,\n getExcludedFields,\n formatZodSchemasSection,\n formatZodModelFile,\n} from './zod-generator.js';\n\n/**\n * Default options for TypeScript generation.\n */\nconst DEFAULT_OPTIONS: TypeScriptOptions = {\n readonly: false, // Changed: interfaces should be mutable for forms/mutations\n strictNullChecks: true,\n generateZodSchemas: true, // Generate Zod schemas by default\n generateRules: false, // Legacy Ant Design rules (deprecated, ignored when generateZodSchemas=true)\n useJsExtension: false, // Bundlers (Vite, webpack) don't need .js extension\n};\n\n/**\n * Gets file extension for imports based on options.\n * Returns '.js' for native ESM, empty string for bundlers.\n */\nfunction getImportExt(options: TypeScriptOptions): string {\n return options.useJsExtension ? '.js' : '';\n}\n\n/**\n * Generates the base file header comment (DO NOT EDIT).\n */\nfunction generateBaseHeader(): string {\n return `/**\n * ⚠️ DO NOT EDIT THIS FILE! ⚠️\n * このファイルを編集しないでください!\n * KHÔNG ĐƯỢC SỬA FILE NÀY!\n *\n * Auto-generated TypeScript types from Omnify schemas.\n * Any manual changes will be OVERWRITTEN on next generation.\n *\n * To modify: Edit the schema YAML file and run: npx omnify generate\n */\n\n`;\n}\n\n/**\n * Generates the model file header comment (user can edit).\n */\nfunction generateModelHeader(schemaName: string): string {\n return `/**\n * ${schemaName} Model\n *\n * This file extends the auto-generated base interface.\n * You can add custom methods, computed properties, or override types here.\n * This file will NOT be overwritten by the generator.\n */\n\n`;\n}\n\n/**\n * Collects all computed field names from a schema.\n * Includes accessor fields from compound types.\n */\nfunction getComputedFields(\n schema: { properties?: Record<string, { type: string }> },\n customTypes: ReadonlyMap<string, { accessors?: readonly { name: string }[] }> | undefined\n): string[] {\n const computedFields: string[] = [];\n if (!schema.properties) return computedFields;\n\n for (const [propName, propDef] of Object.entries(schema.properties)) {\n const snakeName = toSnakeCase(propName);\n const customType = customTypes?.get(propDef.type);\n\n // Add accessor fields from compound types\n if (customType?.accessors) {\n for (const accessor of customType.accessors) {\n computedFields.push(`${snakeName}_${toSnakeCase(accessor.name)}`);\n }\n }\n }\n\n return computedFields;\n}\n\n/**\n * Generates utility types for a schema.\n * - Create: For POST requests (excludes id, timestamps, computed fields, server-managed fields)\n * - Update: For PUT/PATCH requests (all fields optional)\n */\nfunction generateUtilityTypes(\n schemaName: string,\n schema: { options?: { id?: boolean; timestamps?: boolean; softDelete?: boolean }; properties?: Record<string, { type: string }> },\n customTypes?: ReadonlyMap<string, { accessors?: readonly { name: string }[] }>\n): string {\n const parts: string[] = [];\n const excludeFields: string[] = [];\n\n // Exclude id if auto-generated\n if (schema.options?.id !== false) {\n excludeFields.push(\"'id'\");\n }\n\n // Exclude timestamps if enabled\n if (schema.options?.timestamps !== false) {\n excludeFields.push(\"'created_at'\", \"'updated_at'\");\n }\n\n // Exclude soft delete if enabled\n if (schema.options?.softDelete) {\n excludeFields.push(\"'deleted_at'\");\n }\n\n // Exclude email_verified_at (server-managed field)\n if (schema.properties?.['emailVerifiedAt'] || schema.properties?.['email_verified_at']) {\n excludeFields.push(\"'email_verified_at'\");\n }\n\n // Exclude computed fields from compound types\n const computedFields = getComputedFields(schema, customTypes);\n for (const field of computedFields) {\n excludeFields.push(`'${field}'`);\n }\n\n const omitType = excludeFields.length > 0\n ? `Omit<${schemaName}, ${excludeFields.join(' | ')}>`\n : schemaName;\n\n // Create type - for POST requests\n parts.push(`\\n/** For creating new ${schemaName} (POST requests) */`);\n parts.push(`\\nexport type ${schemaName}Create = ${omitType};\\n`);\n\n // Update type - for PUT/PATCH requests (all optional)\n parts.push(`\\n/** For updating ${schemaName} (PUT/PATCH requests) */`);\n parts.push(`\\nexport type ${schemaName}Update = Partial<${schemaName}Create>;\\n`);\n\n return parts.join('');\n}\n\n/**\n * Checks if interface uses DateTimeString or DateString types.\n */\nfunction needsDateTimeImports(iface: { properties: readonly { type: string }[] }): { dateTime: boolean; date: boolean } {\n let dateTime = false;\n let date = false;\n for (const prop of iface.properties) {\n if (prop.type === 'DateTimeString' || prop.type.includes('DateTimeString')) {\n dateTime = true;\n }\n if (prop.type === 'DateString' || prop.type.includes('DateString')) {\n date = true;\n }\n }\n return { dateTime, date };\n}\n\n/**\n * Generates a single base interface file.\n */\nfunction generateBaseInterfaceFile(\n schemaName: string,\n schemas: SchemaCollection,\n options: TypeScriptOptions\n): TypeScriptFile {\n const interfaces = generateInterfaces(schemas, options);\n const iface = interfaces.find(i => i.name === schemaName);\n const schema = schemas[schemaName];\n\n if (!iface || !schema) {\n throw new Error(`Interface not found for schema: ${schemaName}`);\n }\n\n const parts: string[] = [generateBaseHeader()];\n\n // Add Zod import if generating Zod schemas\n if (options.generateZodSchemas) {\n parts.push(`import { z } from 'zod';\\n`);\n }\n\n // Check if we need to import DateTimeString or DateString\n const dateImports = needsDateTimeImports(iface);\n const commonImports: string[] = [];\n if (dateImports.dateTime) commonImports.push('DateTimeString');\n if (dateImports.date) commonImports.push('DateString');\n const ext = getImportExt(options);\n if (commonImports.length > 0) {\n parts.push(`import type { ${commonImports.join(', ')} } from '../common${ext}';\\n`);\n }\n\n // Add imports for enum dependencies\n if (iface.enumDependencies && iface.enumDependencies.length > 0) {\n // When enums are in separate folder, use ../../enum/ (from base/ folder)\n const enumPrefix = options.enumImportPrefix ? `../${options.enumImportPrefix}` : '../enum';\n // Build set of plugin enum names for path resolution\n const pluginEnumNames = new Set(\n options.pluginEnums ? Array.from(options.pluginEnums.keys()) : []\n );\n for (const enumName of iface.enumDependencies) {\n // Plugin enums are in plugin/ subfolder to avoid conflicts\n const enumPath = pluginEnumNames.has(enumName)\n ? `${enumPrefix}/plugin/${enumName}${ext}`\n : `${enumPrefix}/${enumName}${ext}`;\n parts.push(`import { ${enumName} } from '${enumPath}';\\n`);\n }\n }\n\n // Add imports for dependencies\n if (iface.dependencies && iface.dependencies.length > 0) {\n for (const dep of iface.dependencies) {\n parts.push(`import type { ${dep} } from './${dep}${ext}';\\n`);\n }\n parts.push('\\n');\n } else if (commonImports.length > 0 || options.generateZodSchemas || (iface.enumDependencies && iface.enumDependencies.length > 0)) {\n parts.push('\\n');\n }\n\n // Main interface\n parts.push(formatInterface(iface));\n parts.push('\\n');\n\n // Generate Zod schemas if enabled\n if (options.generateZodSchemas) {\n const zodSchemas = generateZodSchemas(schema, options);\n const displayNames = generateDisplayNames(schema, options);\n const excludedFields = getExcludedFields(schema, options.customTypes);\n parts.push('\\n');\n parts.push(formatZodSchemasSection(schemaName, zodSchemas, displayNames, excludedFields));\n } else {\n // Legacy: Utility types (Create, Update) without Zod\n parts.push(generateUtilityTypes(schemaName, schema, options.customTypes));\n }\n\n return {\n filePath: `base/${schemaName}.ts`,\n content: parts.join(''),\n types: [schemaName, `${schemaName}Create`, `${schemaName}Update`],\n overwrite: true,\n };\n}\n\n/**\n * Generates a single enum file.\n * @param enumDef - The enum definition\n * @param isPluginEnum - If true, places in plugin/ subfolder to avoid conflicts\n */\nfunction generateEnumFile(enumDef: TSEnum, isPluginEnum = false): TypeScriptFile {\n const parts: string[] = [generateBaseHeader()];\n parts.push(formatEnum(enumDef));\n parts.push('\\n');\n\n // Plugin enums go to plugin/ subfolder to avoid conflicts with schema enums\n const filePath = isPluginEnum\n ? `plugin/${enumDef.name}.ts`\n : `${enumDef.name}.ts`;\n\n return {\n filePath,\n content: parts.join(''),\n types: [enumDef.name],\n overwrite: true,\n category: 'enum',\n };\n}\n\n/**\n * Generates a single type alias file.\n */\nfunction generateTypeAliasFile(alias: TSTypeAlias): TypeScriptFile {\n const parts: string[] = [generateBaseHeader()];\n parts.push(formatTypeAlias(alias));\n parts.push('\\n');\n\n return {\n filePath: `${alias.name}.ts`,\n content: parts.join(''),\n types: [alias.name],\n overwrite: true,\n category: 'enum',\n };\n}\n\n/**\n * Generates model file content that extends base.\n */\nfunction generateModelFile(schemaName: string, options: TypeScriptOptions): TypeScriptFile {\n // Use Zod format if enabled\n if (options.generateZodSchemas) {\n return {\n filePath: `${schemaName}.ts`,\n content: formatZodModelFile(schemaName, getImportExt(options)),\n types: [schemaName],\n overwrite: false, // Never overwrite user models\n };\n }\n\n // Legacy format without Zod\n const parts: string[] = [generateModelHeader(schemaName)];\n const ext = getImportExt(options);\n\n // Import base interface\n parts.push(`import type { ${schemaName} as ${schemaName}Base } from './base/${schemaName}${ext}';\\n\\n`);\n\n // Export interface that extends base\n parts.push(`/**\\n * ${schemaName} model interface.\\n * Add custom properties or methods here.\\n */\\n`);\n parts.push(`export interface ${schemaName} extends ${schemaName}Base {\\n`);\n parts.push(` // Add custom properties here\\n`);\n parts.push(`}\\n\\n`);\n\n // Re-export base for convenience\n parts.push(`// Re-export base type for internal use\\n`);\n parts.push(`export type { ${schemaName}Base };\\n`);\n\n return {\n filePath: `${schemaName}.ts`,\n content: parts.join(''),\n types: [schemaName],\n overwrite: false, // Never overwrite user models\n };\n}\n\n/**\n * Default validation messages for all supported locales.\n * Supported: en, ja, vi, ko, zh-CN (Simplified), zh-TW (Traditional), th, es\n */\nconst DEFAULT_VALIDATION_MESSAGES: Record<string, Record<string, string>> = {\n required: {\n en: '${displayName} is required',\n ja: '${displayName}は必須です',\n vi: '${displayName} là bắt buộc',\n ko: '${displayName}은(는) 필수입니다',\n 'zh-CN': '${displayName}是必填项',\n 'zh-TW': '${displayName}為必填欄位',\n th: '${displayName} จำเป็นต้องกรอก',\n es: '${displayName} es obligatorio',\n },\n minLength: {\n en: '${displayName} must be at least ${min} characters',\n ja: '${displayName}は${min}文字以上で入力してください',\n vi: '${displayName} phải có ít nhất ${min} ký tự',\n ko: '${displayName}은(는) ${min}자 이상이어야 합니다',\n 'zh-CN': '${displayName}至少需要${min}个字符',\n 'zh-TW': '${displayName}至少需要${min}個字元',\n th: '${displayName} ต้องมีอย่างน้อย ${min} ตัวอักษร',\n es: '${displayName} debe tener al menos ${min} caracteres',\n },\n maxLength: {\n en: '${displayName} must be at most ${max} characters',\n ja: '${displayName}は${max}文字以内で入力してください',\n vi: '${displayName} không được quá ${max} ký tự',\n ko: '${displayName}은(는) ${max}자 이하여야 합니다',\n 'zh-CN': '${displayName}最多${max}个字符',\n 'zh-TW': '${displayName}最多${max}個字元',\n th: '${displayName} ต้องไม่เกิน ${max} ตัวอักษร',\n es: '${displayName} debe tener como máximo ${max} caracteres',\n },\n min: {\n en: '${displayName} must be at least ${min}',\n ja: '${displayName}は${min}以上で入力してください',\n vi: '${displayName} phải lớn hơn hoặc bằng ${min}',\n ko: '${displayName}은(는) ${min} 이상이어야 합니다',\n 'zh-CN': '${displayName}必须大于等于${min}',\n 'zh-TW': '${displayName}必須大於等於${min}',\n th: '${displayName} ต้องมากกว่าหรือเท่ากับ ${min}',\n es: '${displayName} debe ser al menos ${min}',\n },\n max: {\n en: '${displayName} must be at most ${max}',\n ja: '${displayName}は${max}以下で入力してください',\n vi: '${displayName} phải nhỏ hơn hoặc bằng ${max}',\n ko: '${displayName}은(는) ${max} 이하여야 합니다',\n 'zh-CN': '${displayName}必须小于等于${max}',\n 'zh-TW': '${displayName}必須小於等於${max}',\n th: '${displayName} ต้องน้อยกว่าหรือเท่ากับ ${max}',\n es: '${displayName} debe ser como máximo ${max}',\n },\n email: {\n en: 'Please enter a valid email address',\n ja: '有効なメールアドレスを入力してください',\n vi: 'Vui lòng nhập địa chỉ email hợp lệ',\n ko: '유효한 이메일 주소를 입력하세요',\n 'zh-CN': '请输入有效的电子邮件地址',\n 'zh-TW': '請輸入有效的電子郵件地址',\n th: 'กรุณากรอกอีเมลที่ถูกต้อง',\n es: 'Por favor, introduce una dirección de correo electrónico válida',\n },\n url: {\n en: 'Please enter a valid URL',\n ja: '有効なURLを入力してください',\n vi: 'Vui lòng nhập URL hợp lệ',\n ko: '유효한 URL을 입력하세요',\n 'zh-CN': '请输入有效的URL',\n 'zh-TW': '請輸入有效的網址',\n th: 'กรุณากรอก URL ที่ถูกต้อง',\n es: 'Por favor, introduce una URL válida',\n },\n pattern: {\n en: '${displayName} format is invalid',\n ja: '${displayName}の形式が正しくありません',\n vi: '${displayName} không đúng định dạng',\n ko: '${displayName} 형식이 올바르지 않습니다',\n 'zh-CN': '${displayName}格式不正确',\n 'zh-TW': '${displayName}格式不正確',\n th: 'รูปแบบ${displayName}ไม่ถูกต้อง',\n es: 'El formato de ${displayName} no es válido',\n },\n};\n\n/**\n * Generates common.ts with shared types.\n */\nfunction generateCommonFile(options: TypeScriptOptions): TypeScriptFile {\n const locales = options.localeConfig?.locales ?? ['ja', 'en'];\n const localeUnion = locales.map(l => `'${l}'`).join(' | ');\n\n const content = `${generateBaseHeader()}\n/**\n * Locale map for multi-language support.\n */\nexport interface LocaleMap {\n [locale: string]: string;\n}\n\n/**\n * Supported locales in this project.\n */\nexport type Locale = ${localeUnion};\n\n/**\n * Validation rule with multi-locale messages.\n * Use get{Model}Rules(locale) to get Ant Design compatible rules with string messages.\n */\nexport interface ValidationRule {\n required?: boolean;\n type?: 'string' | 'number' | 'email' | 'url' | 'integer' | 'array' | 'object';\n min?: number;\n max?: number;\n len?: number;\n pattern?: RegExp;\n message: LocaleMap;\n}\n\n/**\n * ISO 8601 date-time string.\n */\nexport type DateTimeString = string;\n\n/**\n * ISO 8601 date string (YYYY-MM-DD).\n */\nexport type DateString = string;\n`;\n\n return {\n filePath: 'common.ts',\n content,\n types: ['LocaleMap', 'Locale', 'ValidationRule', 'DateTimeString', 'DateString'],\n overwrite: true,\n };\n}\n\n/**\n * Generates i18n.ts with validation messages and locale helpers.\n */\nfunction generateI18nFile(options: TypeScriptOptions): TypeScriptFile {\n const locales = options.localeConfig?.locales ?? ['ja', 'en'];\n const defaultLocale = options.localeConfig?.defaultLocale ?? 'ja';\n const fallbackLocale = options.localeConfig?.fallbackLocale ?? 'en';\n const userMessages = options.localeConfig?.messages ?? {};\n\n // Merge user messages with defaults (user takes priority)\n const mergedMessages: Record<string, Record<string, string>> = {};\n\n // Start with defaults for supported locales only\n for (const [key, defaultMsgs] of Object.entries(DEFAULT_VALIDATION_MESSAGES)) {\n mergedMessages[key] = {};\n for (const locale of locales) {\n if (defaultMsgs[locale]) {\n mergedMessages[key][locale] = defaultMsgs[locale];\n }\n }\n }\n\n // Override with user messages\n for (const [key, userMsgs] of Object.entries(userMessages)) {\n if (userMsgs) {\n if (!mergedMessages[key]) {\n mergedMessages[key] = {};\n }\n for (const [locale, msg] of Object.entries(userMsgs)) {\n mergedMessages[key][locale] = msg;\n }\n }\n }\n\n const messagesJson = JSON.stringify(mergedMessages, null, 2);\n const ext = getImportExt(options);\n\n const content = `${generateBaseHeader()}\nimport type { LocaleMap } from './common${ext}';\n\n/**\n * Default locale for this project.\n */\nexport const defaultLocale = '${defaultLocale}' as const;\n\n/**\n * Fallback locale when requested locale is not found.\n */\nexport const fallbackLocale = '${fallbackLocale}' as const;\n\n/**\n * Supported locales in this project.\n */\nexport const supportedLocales = ${JSON.stringify(locales)} as const;\n\n/**\n * Validation messages for all supported locales.\n * Use getMessage(key, locale, params) to get formatted message.\n */\nexport const validationMessages = ${messagesJson} as const;\n\n/**\n * Get validation message for a specific key and locale.\n * Supports template placeholders: \\${displayName}, \\${min}, \\${max}, etc.\n *\n * @param key - Message key (e.g., 'required', 'minLength')\n * @param locale - Locale code (e.g., 'ja', 'en')\n * @param params - Template parameters to replace\n * @returns Formatted message string\n *\n * @example\n * getMessage('required', 'ja', { displayName: '氏名' })\n * // => '氏名は必須です'\n */\nexport function getMessage(\n key: string,\n locale: string,\n params: Record<string, string | number> = {}\n): string {\n const messages = validationMessages[key as keyof typeof validationMessages];\n if (!messages) return key;\n\n let message = (messages as LocaleMap)[locale]\n ?? (messages as LocaleMap)[fallbackLocale]\n ?? (messages as LocaleMap)[defaultLocale]\n ?? key;\n\n // Replace template placeholders\n for (const [param, value] of Object.entries(params)) {\n message = message.replace(new RegExp(\\`\\\\\\\\$\\\\{$\\{param}\\\\}\\`, 'g'), String(value));\n }\n\n return message;\n}\n\n/**\n * Get all validation messages for a specific locale.\n *\n * @param locale - Locale code\n * @returns Object with all messages for the locale\n */\nexport function getMessages(locale: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, messages] of Object.entries(validationMessages)) {\n result[key] = (messages as LocaleMap)[locale]\n ?? (messages as LocaleMap)[fallbackLocale]\n ?? (messages as LocaleMap)[defaultLocale]\n ?? key;\n }\n return result;\n}\n`;\n\n return {\n filePath: 'i18n.ts',\n content,\n types: ['validationMessages', 'getMessage', 'getMessages'],\n overwrite: true,\n };\n}\n\n/**\n * Generates index file for re-exports.\n */\nfunction generateIndexFile(\n schemas: SchemaCollection,\n enums: TSEnum[],\n pluginEnums: TSEnum[],\n typeAliases: TSTypeAlias[],\n options: TypeScriptOptions\n): TypeScriptFile {\n const parts: string[] = [generateBaseHeader()];\n const ext = getImportExt(options);\n\n // Export common types\n parts.push(`// Common Types\\n`);\n parts.push(`export type { LocaleMap, Locale, ValidationRule, DateTimeString, DateString } from './common${ext}';\\n\\n`);\n\n // Export i18n utilities\n parts.push(`// i18n (Internationalization)\\n`);\n parts.push(`export {\\n`);\n parts.push(` defaultLocale,\\n`);\n parts.push(` fallbackLocale,\\n`);\n parts.push(` supportedLocales,\\n`);\n parts.push(` validationMessages,\\n`);\n parts.push(` getMessage,\\n`);\n parts.push(` getMessages,\\n`);\n parts.push(`} from './i18n${ext}';\\n\\n`);\n\n const enumPrefix = options.enumImportPrefix ?? './enum';\n\n // Export schema enums (enum + Values + isX + getXLabel + getXExtra)\n if (enums.length > 0) {\n parts.push(`// Schema Enums\\n`);\n for (const enumDef of enums) {\n parts.push(`export {\\n`);\n parts.push(` ${enumDef.name},\\n`);\n parts.push(` ${enumDef.name}Values,\\n`);\n parts.push(` is${enumDef.name},\\n`);\n parts.push(` get${enumDef.name}Label,\\n`);\n parts.push(` get${enumDef.name}Extra,\\n`);\n parts.push(`} from '${enumPrefix}/${enumDef.name}${ext}';\\n`);\n }\n parts.push('\\n');\n }\n\n // Export plugin enums (from plugin/ subfolder)\n if (pluginEnums.length > 0) {\n parts.push(`// Plugin Enums\\n`);\n for (const enumDef of pluginEnums) {\n parts.push(`export {\\n`);\n parts.push(` ${enumDef.name},\\n`);\n parts.push(` ${enumDef.name}Values,\\n`);\n parts.push(` is${enumDef.name},\\n`);\n parts.push(` get${enumDef.name}Label,\\n`);\n parts.push(` get${enumDef.name}Extra,\\n`);\n parts.push(`} from '${enumPrefix}/plugin/${enumDef.name}${ext}';\\n`);\n }\n parts.push('\\n');\n }\n\n // Export inline enums (type aliases)\n if (typeAliases.length > 0) {\n parts.push(`// Inline Enums (Type Aliases)\\n`);\n for (const alias of typeAliases) {\n parts.push(`export {\\n`);\n parts.push(` type ${alias.name},\\n`);\n parts.push(` ${alias.name}Values,\\n`);\n parts.push(` is${alias.name},\\n`);\n parts.push(` get${alias.name}Label,\\n`);\n parts.push(` get${alias.name}Extra,\\n`);\n parts.push(`} from '${enumPrefix}/${alias.name}${ext}';\\n`);\n }\n parts.push('\\n');\n }\n\n // Export all models with utility types\n if (options.generateZodSchemas) {\n // Zod format: export from user model files\n parts.push(`// Models (with Zod schemas, i18n, and Create/Update types)\\n`);\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n const lowerName = schema.name.charAt(0).toLowerCase() + schema.name.slice(1);\n parts.push(`export type { ${schema.name}, ${schema.name}Create, ${schema.name}Update } from './${schema.name}${ext}';\\n`);\n parts.push(`export {\\n`);\n parts.push(` ${lowerName}Schemas,\\n`);\n parts.push(` ${lowerName}CreateSchema,\\n`);\n parts.push(` ${lowerName}UpdateSchema,\\n`);\n parts.push(` ${lowerName}I18n,\\n`);\n parts.push(` get${schema.name}Label,\\n`);\n parts.push(` get${schema.name}FieldLabel,\\n`);\n parts.push(` get${schema.name}FieldPlaceholder,\\n`);\n parts.push(`} from './${schema.name}${ext}';\\n`);\n }\n } else {\n // Legacy format\n parts.push(`// Models (with Create/Update utility types)\\n`);\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n parts.push(`export type { ${schema.name} } from './${schema.name}${ext}';\\n`);\n parts.push(`export type { ${schema.name}Create, ${schema.name}Update } from './base/${schema.name}${ext}';\\n`);\n }\n\n // Export rules functions if enabled (legacy)\n if (options.generateRules) {\n parts.push(`\\n// Validation Rules\\n`);\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n parts.push(`export {\\n`);\n parts.push(` get${schema.name}Rules,\\n`);\n parts.push(` get${schema.name}DisplayName,\\n`);\n parts.push(` get${schema.name}PropertyDisplayName,\\n`);\n parts.push(`} from './rules/${schema.name}.rules${ext}';\\n`);\n }\n }\n }\n\n return {\n filePath: 'index.ts',\n content: parts.join(''),\n types: [],\n overwrite: true,\n };\n}\n\n/**\n * Generates TypeScript files with base/model pattern.\n *\n * Output structure:\n * - models/base/[SchemaName].ts - Auto-generated base interfaces (always overwritten)\n * - models/enum/[EnumName].ts - Auto-generated enums/type aliases (always overwritten)\n * - models/[SchemaName].ts - User-editable models that extend base (created once, never overwritten)\n * - models/index.ts - Re-exports (always overwritten)\n */\nexport function generateTypeScript(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TypeScriptFile[] {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const files: TypeScriptFile[] = [];\n\n // ========================================\n // Detect name conflicts\n // ========================================\n\n // Check for duplicate schema/enum names\n const schemasByName = new Map<string, string[]>(); // name -> [filePaths]\n for (const schema of Object.values(schemas)) {\n const paths = schemasByName.get(schema.name) ?? [];\n paths.push(schema.relativePath ?? schema.filePath);\n schemasByName.set(schema.name, paths);\n }\n\n const duplicateSchemas = Array.from(schemasByName.entries())\n .filter(([, paths]) => paths.length > 1);\n\n if (duplicateSchemas.length > 0) {\n const errors = duplicateSchemas.map(([name, paths]) =>\n ` - \"${name}\" defined in: ${paths.join(', ')}`\n ).join('\\n');\n throw new Error(\n `Duplicate schema/enum names detected. Names must be globally unique:\\n${errors}\\n` +\n `Hint: Rename to unique names like \"Blog${duplicateSchemas[0][0]}\" or \"Shop${duplicateSchemas[0][0]}\"`\n );\n }\n\n // Check for conflicts between schema enums and plugin enums\n if (opts.pluginEnums && opts.pluginEnums.size > 0) {\n const conflicts: string[] = [];\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum' && opts.pluginEnums.has(schema.name)) {\n conflicts.push(`\"${schema.name}\" (schema: ${schema.relativePath ?? schema.filePath}, plugin enum)`);\n }\n }\n if (conflicts.length > 0) {\n throw new Error(\n `Schema enum conflicts with plugin enum:\\n - ${conflicts.join('\\n - ')}\\n` +\n `Hint: Rename your schema enum to avoid conflict with plugin-provided enums`\n );\n }\n }\n\n // ========================================\n // Generate files\n // ========================================\n\n // Generate enum files from schema enums\n const enums = generateEnums(schemas, opts);\n for (const enumDef of enums) {\n files.push(generateEnumFile(enumDef, false)); // Schema enums in enum/\n }\n\n // Generate enum files from plugin enums (e.g., Prefecture, BankAccountType)\n // These go to enum/plugin/ to avoid conflicts with schema enums\n if (opts.pluginEnums && opts.pluginEnums.size > 0) {\n const pluginEnums = generatePluginEnums(opts.pluginEnums, opts);\n for (const enumDef of pluginEnums) {\n files.push(generateEnumFile(enumDef, true)); // Plugin enums in enum/plugin/\n }\n }\n\n // Generate inline enum files (type aliases or full enums with i18n)\n const inlineEnums = extractInlineEnums(schemas, opts);\n const inlineTypeAliases: TSTypeAlias[] = [];\n for (const item of inlineEnums) {\n if (item.enum) {\n // Full enum with i18n labels - add to enums list for index file\n enums.push(item.enum);\n files.push(generateEnumFile(item.enum, false));\n } else if (item.typeAlias) {\n // Simple type alias (no labels)\n inlineTypeAliases.push(item.typeAlias);\n files.push(generateTypeAliasFile(item.typeAlias));\n }\n }\n\n // Generate base interface files\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n files.push(generateBaseInterfaceFile(schema.name, schemas, opts));\n }\n\n // Generate model files (only created if not exists)\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') continue;\n if (schema.options?.hidden === true) continue;\n files.push(generateModelFile(schema.name, opts));\n }\n\n // Generate validation rules files (legacy, only if Zod is disabled)\n if (!opts.generateZodSchemas && opts.generateRules) {\n const rulesFiles = generateRulesFiles(schemas, opts);\n files.push(...rulesFiles);\n }\n\n // Generate common.ts\n files.push(generateCommonFile(opts));\n\n // Generate i18n.ts with validation messages\n files.push(generateI18nFile(opts));\n\n // Get plugin enums for index file generation\n const pluginEnumsList = opts.pluginEnums\n ? generatePluginEnums(opts.pluginEnums, opts)\n : [];\n\n // Generate index file\n files.push(generateIndexFile(schemas, enums, pluginEnumsList, inlineTypeAliases, opts));\n\n return files;\n}\n\n// Legacy exports for compatibility\nexport { generateTypeScript as generateTypeScriptFiles };\n","/**\n * Stub file utilities for React/Ant Design/TanStack Query utilities.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Stub file definitions\n */\nexport const STUB_FILES = [\n // Components\n {\n stub: 'JapaneseNameField.tsx.stub',\n output: 'components/JapaneseNameField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'JapaneseAddressField.tsx.stub',\n output: 'components/JapaneseAddressField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'JapaneseBankField.tsx.stub',\n output: 'components/JapaneseBankField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'components-index.ts.stub',\n output: 'components/index.ts',\n indexExport: '', // This IS the index\n },\n // Hooks\n {\n stub: 'use-form-mutation.ts.stub',\n output: 'hooks/use-form-mutation.ts',\n indexExport: `export { useFormMutation } from './use-form-mutation';\\n`,\n },\n // Lib\n {\n stub: 'zod-i18n.ts.stub',\n output: 'lib/zod-i18n.ts',\n indexExport: `export { setZodLocale, getZodLocale, getZodMessage } from './zod-i18n';\\n`,\n },\n {\n stub: 'form-validation.ts.stub',\n output: 'lib/form-validation.ts',\n indexExport: `export { zodRule, requiredRule } from './form-validation';\\nexport * from './rules';\\n`,\n },\n // Rules\n {\n stub: 'rules/kana.ts.stub',\n output: 'lib/rules/kana.ts',\n indexExport: '', // Will be handled by rules/index.ts\n },\n {\n stub: 'rules/index.ts.stub',\n output: 'lib/rules/index.ts',\n indexExport: '', // Already exported via form-validation\n },\n] as const;\n\nexport interface CopyStubsOptions {\n /** Target directory (e.g., 'resources/ts/omnify') */\n targetDir: string;\n /** Skip if file exists (default: false - always overwrite library files) */\n skipIfExists?: boolean;\n}\n\nexport interface CopyStubsResult {\n copied: string[];\n skipped: string[];\n}\n\n/**\n * Copy React utility stubs to the target directory.\n *\n * @example\n * copyStubs({\n * targetDir: 'resources/ts/omnify',\n * skipIfExists: true,\n * });\n */\nexport function copyStubs(options: CopyStubsOptions): CopyStubsResult {\n const { targetDir, skipIfExists = false } = options;\n const stubsDir = path.join(__dirname, '..', 'stubs');\n const result: CopyStubsResult = { copied: [], skipped: [] };\n\n // Group stubs by directory for index file generation\n const directories = new Map<string, string>();\n\n for (const { stub, output, indexExport } of STUB_FILES) {\n const stubPath = path.join(stubsDir, stub);\n const outputPath = path.join(targetDir, output);\n const outputDir = path.dirname(outputPath);\n const dirName = path.dirname(output).split('/')[0]; // e.g., 'components', 'hooks', 'lib'\n\n // Track index exports per directory\n if (!directories.has(dirName)) {\n directories.set(dirName, '');\n }\n directories.set(dirName, directories.get(dirName)! + indexExport);\n\n // Create directory if not exists\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // Skip if file exists and skipIfExists is true\n if (skipIfExists && fs.existsSync(outputPath)) {\n result.skipped.push(output);\n continue;\n }\n\n // Copy stub file\n if (fs.existsSync(stubPath)) {\n const content = fs.readFileSync(stubPath, 'utf-8');\n fs.writeFileSync(outputPath, content);\n result.copied.push(output);\n }\n }\n\n // Generate index files for each directory\n for (const [dirName, exports] of directories) {\n const indexPath = path.join(targetDir, dirName, 'index.ts');\n if (skipIfExists && fs.existsSync(indexPath)) {\n continue;\n }\n fs.writeFileSync(indexPath, exports);\n result.copied.push(`${dirName}/index.ts`);\n }\n\n return result;\n}\n\n/**\n * Get list of stub files that would be generated.\n */\nexport function getStubPaths(): string[] {\n return STUB_FILES.map(s => s.output);\n}\n","/**\n * AI Guides Generator for TypeScript/Frontend\n *\n * TypeScript/Reactプロジェクト用のAIガイド生成\n * @famgia/omnify-coreの統一ジェネレーターを使用\n */\n\nimport { existsSync, readdirSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport {\n generateAIGuides as coreGenerateAIGuides,\n} from '@famgia/omnify-core';\n\n/**\n * Options for AI guides generation\n */\nexport interface AIGuidesOptions {\n /**\n * TypeScript output path from config (e.g., 'resources/ts/omnify')\n * Used to extract the base path for glob replacement\n */\n typescriptPath?: string;\n\n /**\n * Base path for TypeScript files (default: extracted from typescriptPath or 'src')\n * Used for placeholder replacement in Cursor rules\n */\n typescriptBasePath?: string;\n}\n\n/**\n * Result of AI guides generation\n */\nexport interface AIGuidesResult {\n claudeGuides: number;\n claudeChecklists: number;\n cursorRules: number;\n files: string[];\n}\n\n/**\n * Extract TypeScript base path from typescriptPath\n * e.g., 'resources/ts/omnify' -> 'resources/ts'\n * e.g., 'src/generated' -> 'src'\n */\nfunction extractTypescriptBasePath(typescriptPath?: string): string {\n if (!typescriptPath) return 'src';\n\n const normalized = typescriptPath.replace(/\\\\/g, '/');\n\n // Remove last segment (omnify, generated, etc.)\n const parts = normalized.split('/').filter(Boolean);\n if (parts.length > 1) {\n return parts.slice(0, -1).join('/');\n }\n\n return 'src';\n}\n\n/**\n * Generate AI guides for Claude and Cursor\n */\nexport function generateAIGuides(\n rootDir: string,\n options: AIGuidesOptions = {}\n): AIGuidesResult {\n const basePath = options.typescriptBasePath || extractTypescriptBasePath(options.typescriptPath);\n\n // Coreジェネレーターを呼び出し\n const coreResult = coreGenerateAIGuides(rootDir, {\n placeholders: {\n TYPESCRIPT_BASE: basePath,\n LARAVEL_BASE: 'app',\n LARAVEL_ROOT: '',\n },\n // TypeScriptプロジェクトではReact関連のみ\n adapters: ['cursor', 'claude'],\n });\n\n // 結果を変換 (後方互換性のため)\n const result: AIGuidesResult = {\n claudeGuides: 0,\n claudeChecklists: 0,\n cursorRules: 0,\n files: coreResult.files,\n };\n\n // ファイル数をカウント\n const claudeCount = coreResult.counts['claude'] || 0;\n const cursorCount = coreResult.counts['cursor'] || 0;\n\n result.claudeGuides = Math.floor(claudeCount * 0.8);\n result.claudeChecklists = claudeCount - result.claudeGuides;\n result.cursorRules = cursorCount;\n\n return result;\n}\n\n/**\n * Check if AI guides need to be generated\n */\nexport function shouldGenerateAIGuides(rootDir: string): boolean {\n const claudeDir = resolve(rootDir, '.claude/omnify/guides/react');\n const cursorDir = resolve(rootDir, '.cursor/rules/omnify');\n\n if (!existsSync(claudeDir) || !existsSync(cursorDir)) {\n return true;\n }\n\n try {\n const claudeFiles = readdirSync(claudeDir);\n const cursorFiles = readdirSync(cursorDir);\n\n return claudeFiles.length === 0 || cursorFiles.length === 0;\n } catch {\n return true;\n }\n}\n"],"mappings":"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","names":["import_omnify_types","resolveDisplayName","result","getMultiLocaleDisplayName","result","getImportExt","path","fs","exports","coreGenerateAIGuides"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -427,8 +427,8 @@ declare function getStubPaths(): string[];
|
|
|
427
427
|
/**
|
|
428
428
|
* AI Guides Generator for TypeScript/Frontend
|
|
429
429
|
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
430
|
+
* TypeScript/Reactプロジェクト用のAIガイド生成
|
|
431
|
+
* @famgia/omnify-coreの統一ジェネレーターを使用
|
|
432
432
|
*/
|
|
433
433
|
/**
|
|
434
434
|
* Options for AI guides generation
|
package/dist/index.d.ts
CHANGED
|
@@ -427,8 +427,8 @@ declare function getStubPaths(): string[];
|
|
|
427
427
|
/**
|
|
428
428
|
* AI Guides Generator for TypeScript/Frontend
|
|
429
429
|
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
430
|
+
* TypeScript/Reactプロジェクト用のAIガイド生成
|
|
431
|
+
* @famgia/omnify-coreの統一ジェネレーターを使用
|
|
432
432
|
*/
|
|
433
433
|
/**
|
|
434
434
|
* Options for AI guides generation
|
package/dist/index.js
CHANGED
|
@@ -135,22 +135,11 @@ function getStubPaths() {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
// src/ai-guides/generator.ts
|
|
138
|
-
import { existsSync,
|
|
139
|
-
import { resolve
|
|
140
|
-
import {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
function getStubsDir() {
|
|
144
|
-
const devPath = resolve(__dirname2, "../../stubs/ai-guides");
|
|
145
|
-
if (existsSync(devPath)) {
|
|
146
|
-
return devPath;
|
|
147
|
-
}
|
|
148
|
-
const distPath = resolve(__dirname2, "../stubs/ai-guides");
|
|
149
|
-
if (existsSync(distPath)) {
|
|
150
|
-
return distPath;
|
|
151
|
-
}
|
|
152
|
-
throw new Error("AI guides stubs not found");
|
|
153
|
-
}
|
|
138
|
+
import { existsSync, readdirSync } from "fs";
|
|
139
|
+
import { resolve } from "path";
|
|
140
|
+
import {
|
|
141
|
+
generateAIGuides as coreGenerateAIGuides
|
|
142
|
+
} from "@famgia/omnify-core";
|
|
154
143
|
function extractTypescriptBasePath(typescriptPath) {
|
|
155
144
|
if (!typescriptPath) return "src";
|
|
156
145
|
const normalized = typescriptPath.replace(/\\/g, "/");
|
|
@@ -160,71 +149,28 @@ function extractTypescriptBasePath(typescriptPath) {
|
|
|
160
149
|
}
|
|
161
150
|
return "src";
|
|
162
151
|
}
|
|
163
|
-
function replacePlaceholders(content, basePath) {
|
|
164
|
-
return content.replace(/\{\{TYPESCRIPT_BASE\}\}/g, basePath);
|
|
165
|
-
}
|
|
166
|
-
function copyStubs2(srcDir, destDir, transform) {
|
|
167
|
-
const writtenFiles = [];
|
|
168
|
-
if (!existsSync(srcDir)) {
|
|
169
|
-
return writtenFiles;
|
|
170
|
-
}
|
|
171
|
-
if (!existsSync(destDir)) {
|
|
172
|
-
mkdirSync(destDir, { recursive: true });
|
|
173
|
-
}
|
|
174
|
-
const entries = readdirSync(srcDir, { withFileTypes: true });
|
|
175
|
-
for (const entry of entries) {
|
|
176
|
-
const srcPath = join(srcDir, entry.name);
|
|
177
|
-
if (entry.isDirectory()) {
|
|
178
|
-
const subDestDir = join(destDir, entry.name);
|
|
179
|
-
const subFiles = copyStubs2(srcPath, subDestDir, transform);
|
|
180
|
-
writtenFiles.push(...subFiles);
|
|
181
|
-
} else if (entry.isFile() && entry.name.endsWith(".stub")) {
|
|
182
|
-
const destName = entry.name.slice(0, -5);
|
|
183
|
-
const destPath = join(destDir, destName);
|
|
184
|
-
let content = readFileSync(srcPath, "utf-8");
|
|
185
|
-
if (transform) {
|
|
186
|
-
content = transform(content);
|
|
187
|
-
}
|
|
188
|
-
writeFileSync(destPath, content);
|
|
189
|
-
writtenFiles.push(destPath);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return writtenFiles;
|
|
193
|
-
}
|
|
194
152
|
function generateAIGuides(rootDir, options = {}) {
|
|
195
|
-
const stubsDir = getStubsDir();
|
|
196
153
|
const basePath = options.typescriptBasePath || extractTypescriptBasePath(options.typescriptPath);
|
|
154
|
+
const coreResult = coreGenerateAIGuides(rootDir, {
|
|
155
|
+
placeholders: {
|
|
156
|
+
TYPESCRIPT_BASE: basePath,
|
|
157
|
+
LARAVEL_BASE: "app",
|
|
158
|
+
LARAVEL_ROOT: ""
|
|
159
|
+
},
|
|
160
|
+
// TypeScriptプロジェクトではReact関連のみ
|
|
161
|
+
adapters: ["cursor", "claude"]
|
|
162
|
+
});
|
|
197
163
|
const result = {
|
|
198
164
|
claudeGuides: 0,
|
|
199
165
|
claudeChecklists: 0,
|
|
200
166
|
cursorRules: 0,
|
|
201
|
-
files:
|
|
167
|
+
files: coreResult.files
|
|
202
168
|
};
|
|
203
|
-
const
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
result.files.push(...files);
|
|
209
|
-
}
|
|
210
|
-
const claudeChecklistsSrcDir = join(stubsDir, "checklists");
|
|
211
|
-
const claudeChecklistsDestDir = resolve(rootDir, ".claude/omnify/checklists");
|
|
212
|
-
if (existsSync(claudeChecklistsSrcDir)) {
|
|
213
|
-
const files = copyStubs2(claudeChecklistsSrcDir, claudeChecklistsDestDir);
|
|
214
|
-
result.claudeChecklists = files.length;
|
|
215
|
-
result.files.push(...files);
|
|
216
|
-
}
|
|
217
|
-
const cursorSrcDir = join(stubsDir, "cursor");
|
|
218
|
-
const cursorDestDir = resolve(rootDir, ".cursor/rules/omnify");
|
|
219
|
-
if (existsSync(cursorSrcDir)) {
|
|
220
|
-
const files = copyStubs2(
|
|
221
|
-
cursorSrcDir,
|
|
222
|
-
cursorDestDir,
|
|
223
|
-
(content) => replacePlaceholders(content, basePath)
|
|
224
|
-
);
|
|
225
|
-
result.cursorRules = files.length;
|
|
226
|
-
result.files.push(...files);
|
|
227
|
-
}
|
|
169
|
+
const claudeCount = coreResult.counts["claude"] || 0;
|
|
170
|
+
const cursorCount = coreResult.counts["cursor"] || 0;
|
|
171
|
+
result.claudeGuides = Math.floor(claudeCount * 0.8);
|
|
172
|
+
result.claudeChecklists = claudeCount - result.claudeGuides;
|
|
173
|
+
result.cursorRules = cursorCount;
|
|
228
174
|
return result;
|
|
229
175
|
}
|
|
230
176
|
function shouldGenerateAIGuides(rootDir) {
|
|
@@ -236,8 +182,7 @@ function shouldGenerateAIGuides(rootDir) {
|
|
|
236
182
|
try {
|
|
237
183
|
const claudeFiles = readdirSync(claudeDir);
|
|
238
184
|
const cursorFiles = readdirSync(cursorDir);
|
|
239
|
-
|
|
240
|
-
return claudeFiles.length === 0 || !hasReactRules;
|
|
185
|
+
return claudeFiles.length === 0 || cursorFiles.length === 0;
|
|
241
186
|
} catch {
|
|
242
187
|
return true;
|
|
243
188
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/stubs.ts","../src/ai-guides/generator.ts"],"sourcesContent":["/**\n * Stub file utilities for React/Ant Design/TanStack Query utilities.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Stub file definitions\n */\nexport const STUB_FILES = [\n // Components\n {\n stub: 'JapaneseNameField.tsx.stub',\n output: 'components/JapaneseNameField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'JapaneseAddressField.tsx.stub',\n output: 'components/JapaneseAddressField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'JapaneseBankField.tsx.stub',\n output: 'components/JapaneseBankField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'components-index.ts.stub',\n output: 'components/index.ts',\n indexExport: '', // This IS the index\n },\n // Hooks\n {\n stub: 'use-form-mutation.ts.stub',\n output: 'hooks/use-form-mutation.ts',\n indexExport: `export { useFormMutation } from './use-form-mutation';\\n`,\n },\n // Lib\n {\n stub: 'zod-i18n.ts.stub',\n output: 'lib/zod-i18n.ts',\n indexExport: `export { setZodLocale, getZodLocale, getZodMessage } from './zod-i18n';\\n`,\n },\n {\n stub: 'form-validation.ts.stub',\n output: 'lib/form-validation.ts',\n indexExport: `export { zodRule, requiredRule } from './form-validation';\\nexport * from './rules';\\n`,\n },\n // Rules\n {\n stub: 'rules/kana.ts.stub',\n output: 'lib/rules/kana.ts',\n indexExport: '', // Will be handled by rules/index.ts\n },\n {\n stub: 'rules/index.ts.stub',\n output: 'lib/rules/index.ts',\n indexExport: '', // Already exported via form-validation\n },\n] as const;\n\nexport interface CopyStubsOptions {\n /** Target directory (e.g., 'resources/ts/omnify') */\n targetDir: string;\n /** Skip if file exists (default: false - always overwrite library files) */\n skipIfExists?: boolean;\n}\n\nexport interface CopyStubsResult {\n copied: string[];\n skipped: string[];\n}\n\n/**\n * Copy React utility stubs to the target directory.\n *\n * @example\n * copyStubs({\n * targetDir: 'resources/ts/omnify',\n * skipIfExists: true,\n * });\n */\nexport function copyStubs(options: CopyStubsOptions): CopyStubsResult {\n const { targetDir, skipIfExists = false } = options;\n const stubsDir = path.join(__dirname, '..', 'stubs');\n const result: CopyStubsResult = { copied: [], skipped: [] };\n\n // Group stubs by directory for index file generation\n const directories = new Map<string, string>();\n\n for (const { stub, output, indexExport } of STUB_FILES) {\n const stubPath = path.join(stubsDir, stub);\n const outputPath = path.join(targetDir, output);\n const outputDir = path.dirname(outputPath);\n const dirName = path.dirname(output).split('/')[0]; // e.g., 'components', 'hooks', 'lib'\n\n // Track index exports per directory\n if (!directories.has(dirName)) {\n directories.set(dirName, '');\n }\n directories.set(dirName, directories.get(dirName)! + indexExport);\n\n // Create directory if not exists\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // Skip if file exists and skipIfExists is true\n if (skipIfExists && fs.existsSync(outputPath)) {\n result.skipped.push(output);\n continue;\n }\n\n // Copy stub file\n if (fs.existsSync(stubPath)) {\n const content = fs.readFileSync(stubPath, 'utf-8');\n fs.writeFileSync(outputPath, content);\n result.copied.push(output);\n }\n }\n\n // Generate index files for each directory\n for (const [dirName, exports] of directories) {\n const indexPath = path.join(targetDir, dirName, 'index.ts');\n if (skipIfExists && fs.existsSync(indexPath)) {\n continue;\n }\n fs.writeFileSync(indexPath, exports);\n result.copied.push(`${dirName}/index.ts`);\n }\n\n return result;\n}\n\n/**\n * Get list of stub files that would be generated.\n */\nexport function getStubPaths(): string[] {\n return STUB_FILES.map(s => s.output);\n}\n","/**\n * AI Guides Generator for TypeScript/Frontend\n *\n * Generates AI assistant guides (Claude, Cursor) for TypeScript/React projects.\n * Simply copies .stub files, removes .stub extension, and replaces placeholders.\n */\n\nimport { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Options for AI guides generation\n */\nexport interface AIGuidesOptions {\n /**\n * TypeScript output path from config (e.g., 'resources/ts/omnify')\n * Used to extract the base path for glob replacement\n */\n typescriptPath?: string;\n\n /**\n * Base path for TypeScript files (default: extracted from typescriptPath or 'src')\n * Used for placeholder replacement in Cursor rules\n */\n typescriptBasePath?: string;\n}\n\n/**\n * Result of AI guides generation\n */\nexport interface AIGuidesResult {\n claudeGuides: number;\n claudeChecklists: number;\n cursorRules: number;\n files: string[];\n}\n\n/**\n * Get the stubs directory path\n */\nfunction getStubsDir(): string {\n // Try dev path first: packages/typescript-generator/stubs/ai-guides\n const devPath = resolve(__dirname, '../../stubs/ai-guides');\n if (existsSync(devPath)) {\n return devPath;\n }\n\n // Try dist path (when installed as package)\n const distPath = resolve(__dirname, '../stubs/ai-guides');\n if (existsSync(distPath)) {\n return distPath;\n }\n\n throw new Error('AI guides stubs not found');\n}\n\n/**\n * Extract TypeScript base path from typescriptPath\n * e.g., 'resources/ts/omnify' -> 'resources/ts'\n * e.g., 'src/generated' -> 'src'\n */\nfunction extractTypescriptBasePath(typescriptPath?: string): string {\n if (!typescriptPath) return 'src';\n\n const normalized = typescriptPath.replace(/\\\\/g, '/');\n\n // Remove last segment (omnify, generated, etc.)\n const parts = normalized.split('/').filter(Boolean);\n if (parts.length > 1) {\n return parts.slice(0, -1).join('/');\n }\n\n return 'src';\n}\n\n/**\n * Replace placeholders in stub content\n * - {{TYPESCRIPT_BASE}} -> actual base path (e.g., 'resources/ts')\n */\nfunction replacePlaceholders(content: string, basePath: string): string {\n return content.replace(/\\{\\{TYPESCRIPT_BASE\\}\\}/g, basePath);\n}\n\n/**\n * Copy .stub files to destination, removing .stub extension and replacing placeholders\n */\nfunction copyStubs(\n srcDir: string,\n destDir: string,\n transform?: (content: string) => string\n): string[] {\n const writtenFiles: string[] = [];\n\n if (!existsSync(srcDir)) {\n return writtenFiles;\n }\n\n if (!existsSync(destDir)) {\n mkdirSync(destDir, { recursive: true });\n }\n\n const entries = readdirSync(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name);\n\n if (entry.isDirectory()) {\n // Recursively copy subdirectories\n const subDestDir = join(destDir, entry.name);\n const subFiles = copyStubs(srcPath, subDestDir, transform);\n writtenFiles.push(...subFiles);\n } else if (entry.isFile() && entry.name.endsWith('.stub')) {\n // Remove .stub extension\n const destName = entry.name.slice(0, -5);\n const destPath = join(destDir, destName);\n\n let content = readFileSync(srcPath, 'utf-8');\n\n if (transform) {\n content = transform(content);\n }\n\n writeFileSync(destPath, content);\n writtenFiles.push(destPath);\n }\n }\n\n return writtenFiles;\n}\n\n/**\n * Generate AI guides for Claude and Cursor\n */\nexport function generateAIGuides(\n rootDir: string,\n options: AIGuidesOptions = {}\n): AIGuidesResult {\n const stubsDir = getStubsDir();\n const basePath = options.typescriptBasePath || extractTypescriptBasePath(options.typescriptPath);\n\n const result: AIGuidesResult = {\n claudeGuides: 0,\n claudeChecklists: 0,\n cursorRules: 0,\n files: [],\n };\n\n // All Claude files go under .claude/omnify/\n\n // 1. Copy React guides to .claude/omnify/guides/react/\n const claudeSrcDir = join(stubsDir, 'react');\n const claudeDestDir = resolve(rootDir, '.claude/omnify/guides/react');\n\n if (existsSync(claudeSrcDir)) {\n const files = copyStubs(claudeSrcDir, claudeDestDir);\n result.claudeGuides = files.length;\n result.files.push(...files);\n }\n\n // 2. Copy checklists to .claude/omnify/checklists/\n const claudeChecklistsSrcDir = join(stubsDir, 'checklists');\n const claudeChecklistsDestDir = resolve(rootDir, '.claude/omnify/checklists');\n\n if (existsSync(claudeChecklistsSrcDir)) {\n const files = copyStubs(claudeChecklistsSrcDir, claudeChecklistsDestDir);\n result.claudeChecklists = files.length;\n result.files.push(...files);\n }\n\n // 3. Copy Cursor rules to .cursor/rules/omnify/\n const cursorSrcDir = join(stubsDir, 'cursor');\n const cursorDestDir = resolve(rootDir, '.cursor/rules/omnify');\n\n if (existsSync(cursorSrcDir)) {\n const files = copyStubs(cursorSrcDir, cursorDestDir, (content) =>\n replacePlaceholders(content, basePath)\n );\n result.cursorRules = files.length;\n result.files.push(...files);\n }\n\n return result;\n}\n\n/**\n * Check if AI guides need to be generated\n */\nexport function shouldGenerateAIGuides(rootDir: string): boolean {\n const claudeDir = resolve(rootDir, '.claude/omnify/guides/react');\n const cursorDir = resolve(rootDir, '.cursor/rules/omnify');\n\n if (!existsSync(claudeDir) || !existsSync(cursorDir)) {\n return true;\n }\n\n try {\n const claudeFiles = readdirSync(claudeDir);\n const cursorFiles = readdirSync(cursorDir);\n const hasReactRules = cursorFiles.some((f) => f.startsWith('react'));\n\n return claudeFiles.length === 0 || !hasReactRules;\n } catch {\n return true;\n }\n}\n"],"mappings":"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","names":["fileURLToPath","__filename","__dirname","copyStubs"]}
|
|
1
|
+
{"version":3,"sources":["../src/stubs.ts","../src/ai-guides/generator.ts"],"sourcesContent":["/**\n * Stub file utilities for React/Ant Design/TanStack Query utilities.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Stub file definitions\n */\nexport const STUB_FILES = [\n // Components\n {\n stub: 'JapaneseNameField.tsx.stub',\n output: 'components/JapaneseNameField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'JapaneseAddressField.tsx.stub',\n output: 'components/JapaneseAddressField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'JapaneseBankField.tsx.stub',\n output: 'components/JapaneseBankField.tsx',\n indexExport: '', // Handled by components-index.ts.stub\n },\n {\n stub: 'components-index.ts.stub',\n output: 'components/index.ts',\n indexExport: '', // This IS the index\n },\n // Hooks\n {\n stub: 'use-form-mutation.ts.stub',\n output: 'hooks/use-form-mutation.ts',\n indexExport: `export { useFormMutation } from './use-form-mutation';\\n`,\n },\n // Lib\n {\n stub: 'zod-i18n.ts.stub',\n output: 'lib/zod-i18n.ts',\n indexExport: `export { setZodLocale, getZodLocale, getZodMessage } from './zod-i18n';\\n`,\n },\n {\n stub: 'form-validation.ts.stub',\n output: 'lib/form-validation.ts',\n indexExport: `export { zodRule, requiredRule } from './form-validation';\\nexport * from './rules';\\n`,\n },\n // Rules\n {\n stub: 'rules/kana.ts.stub',\n output: 'lib/rules/kana.ts',\n indexExport: '', // Will be handled by rules/index.ts\n },\n {\n stub: 'rules/index.ts.stub',\n output: 'lib/rules/index.ts',\n indexExport: '', // Already exported via form-validation\n },\n] as const;\n\nexport interface CopyStubsOptions {\n /** Target directory (e.g., 'resources/ts/omnify') */\n targetDir: string;\n /** Skip if file exists (default: false - always overwrite library files) */\n skipIfExists?: boolean;\n}\n\nexport interface CopyStubsResult {\n copied: string[];\n skipped: string[];\n}\n\n/**\n * Copy React utility stubs to the target directory.\n *\n * @example\n * copyStubs({\n * targetDir: 'resources/ts/omnify',\n * skipIfExists: true,\n * });\n */\nexport function copyStubs(options: CopyStubsOptions): CopyStubsResult {\n const { targetDir, skipIfExists = false } = options;\n const stubsDir = path.join(__dirname, '..', 'stubs');\n const result: CopyStubsResult = { copied: [], skipped: [] };\n\n // Group stubs by directory for index file generation\n const directories = new Map<string, string>();\n\n for (const { stub, output, indexExport } of STUB_FILES) {\n const stubPath = path.join(stubsDir, stub);\n const outputPath = path.join(targetDir, output);\n const outputDir = path.dirname(outputPath);\n const dirName = path.dirname(output).split('/')[0]; // e.g., 'components', 'hooks', 'lib'\n\n // Track index exports per directory\n if (!directories.has(dirName)) {\n directories.set(dirName, '');\n }\n directories.set(dirName, directories.get(dirName)! + indexExport);\n\n // Create directory if not exists\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // Skip if file exists and skipIfExists is true\n if (skipIfExists && fs.existsSync(outputPath)) {\n result.skipped.push(output);\n continue;\n }\n\n // Copy stub file\n if (fs.existsSync(stubPath)) {\n const content = fs.readFileSync(stubPath, 'utf-8');\n fs.writeFileSync(outputPath, content);\n result.copied.push(output);\n }\n }\n\n // Generate index files for each directory\n for (const [dirName, exports] of directories) {\n const indexPath = path.join(targetDir, dirName, 'index.ts');\n if (skipIfExists && fs.existsSync(indexPath)) {\n continue;\n }\n fs.writeFileSync(indexPath, exports);\n result.copied.push(`${dirName}/index.ts`);\n }\n\n return result;\n}\n\n/**\n * Get list of stub files that would be generated.\n */\nexport function getStubPaths(): string[] {\n return STUB_FILES.map(s => s.output);\n}\n","/**\n * AI Guides Generator for TypeScript/Frontend\n *\n * TypeScript/Reactプロジェクト用のAIガイド生成\n * @famgia/omnify-coreの統一ジェネレーターを使用\n */\n\nimport { existsSync, readdirSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport {\n generateAIGuides as coreGenerateAIGuides,\n} from '@famgia/omnify-core';\n\n/**\n * Options for AI guides generation\n */\nexport interface AIGuidesOptions {\n /**\n * TypeScript output path from config (e.g., 'resources/ts/omnify')\n * Used to extract the base path for glob replacement\n */\n typescriptPath?: string;\n\n /**\n * Base path for TypeScript files (default: extracted from typescriptPath or 'src')\n * Used for placeholder replacement in Cursor rules\n */\n typescriptBasePath?: string;\n}\n\n/**\n * Result of AI guides generation\n */\nexport interface AIGuidesResult {\n claudeGuides: number;\n claudeChecklists: number;\n cursorRules: number;\n files: string[];\n}\n\n/**\n * Extract TypeScript base path from typescriptPath\n * e.g., 'resources/ts/omnify' -> 'resources/ts'\n * e.g., 'src/generated' -> 'src'\n */\nfunction extractTypescriptBasePath(typescriptPath?: string): string {\n if (!typescriptPath) return 'src';\n\n const normalized = typescriptPath.replace(/\\\\/g, '/');\n\n // Remove last segment (omnify, generated, etc.)\n const parts = normalized.split('/').filter(Boolean);\n if (parts.length > 1) {\n return parts.slice(0, -1).join('/');\n }\n\n return 'src';\n}\n\n/**\n * Generate AI guides for Claude and Cursor\n */\nexport function generateAIGuides(\n rootDir: string,\n options: AIGuidesOptions = {}\n): AIGuidesResult {\n const basePath = options.typescriptBasePath || extractTypescriptBasePath(options.typescriptPath);\n\n // Coreジェネレーターを呼び出し\n const coreResult = coreGenerateAIGuides(rootDir, {\n placeholders: {\n TYPESCRIPT_BASE: basePath,\n LARAVEL_BASE: 'app',\n LARAVEL_ROOT: '',\n },\n // TypeScriptプロジェクトではReact関連のみ\n adapters: ['cursor', 'claude'],\n });\n\n // 結果を変換 (後方互換性のため)\n const result: AIGuidesResult = {\n claudeGuides: 0,\n claudeChecklists: 0,\n cursorRules: 0,\n files: coreResult.files,\n };\n\n // ファイル数をカウント\n const claudeCount = coreResult.counts['claude'] || 0;\n const cursorCount = coreResult.counts['cursor'] || 0;\n\n result.claudeGuides = Math.floor(claudeCount * 0.8);\n result.claudeChecklists = claudeCount - result.claudeGuides;\n result.cursorRules = cursorCount;\n\n return result;\n}\n\n/**\n * Check if AI guides need to be generated\n */\nexport function shouldGenerateAIGuides(rootDir: string): boolean {\n const claudeDir = resolve(rootDir, '.claude/omnify/guides/react');\n const cursorDir = resolve(rootDir, '.cursor/rules/omnify');\n\n if (!existsSync(claudeDir) || !existsSync(cursorDir)) {\n return true;\n }\n\n try {\n const claudeFiles = readdirSync(claudeDir);\n const cursorFiles = readdirSync(cursorDir);\n\n return claudeFiles.length === 0 || cursorFiles.length === 0;\n } catch {\n return true;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,KAAK,QAAQ,UAAU;AAKlC,IAAM,aAAa;AAAA;AAAA,EAExB;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA,EACf;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA,EACf;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA;AAAA,EACf;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA,EACf;AACF;AAuBO,SAAS,UAAU,SAA4C;AACpE,QAAM,EAAE,WAAW,eAAe,MAAM,IAAI;AAC5C,QAAM,WAAW,KAAK,KAAK,WAAW,MAAM,OAAO;AACnD,QAAM,SAA0B,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC,EAAE;AAG1D,QAAM,cAAc,oBAAI,IAAoB;AAE5C,aAAW,EAAE,MAAM,QAAQ,YAAY,KAAK,YAAY;AACtD,UAAM,WAAW,KAAK,KAAK,UAAU,IAAI;AACzC,UAAM,aAAa,KAAK,KAAK,WAAW,MAAM;AAC9C,UAAM,YAAY,KAAK,QAAQ,UAAU;AACzC,UAAM,UAAU,KAAK,QAAQ,MAAM,EAAE,MAAM,GAAG,EAAE,CAAC;AAGjD,QAAI,CAAC,YAAY,IAAI,OAAO,GAAG;AAC7B,kBAAY,IAAI,SAAS,EAAE;AAAA,IAC7B;AACA,gBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,WAAW;AAGhE,QAAI,CAAC,GAAG,WAAW,SAAS,GAAG;AAC7B,SAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAC7C;AAGA,QAAI,gBAAgB,GAAG,WAAW,UAAU,GAAG;AAC7C,aAAO,QAAQ,KAAK,MAAM;AAC1B;AAAA,IACF;AAGA,QAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,YAAM,UAAU,GAAG,aAAa,UAAU,OAAO;AACjD,SAAG,cAAc,YAAY,OAAO;AACpC,aAAO,OAAO,KAAK,MAAM;AAAA,IAC3B;AAAA,EACF;AAGA,aAAW,CAAC,SAAS,OAAO,KAAK,aAAa;AAC5C,UAAM,YAAY,KAAK,KAAK,WAAW,SAAS,UAAU;AAC1D,QAAI,gBAAgB,GAAG,WAAW,SAAS,GAAG;AAC5C;AAAA,IACF;AACA,OAAG,cAAc,WAAW,OAAO;AACnC,WAAO,OAAO,KAAK,GAAG,OAAO,WAAW;AAAA,EAC1C;AAEA,SAAO;AACT;AAKO,SAAS,eAAyB;AACvC,SAAO,WAAW,IAAI,OAAK,EAAE,MAAM;AACrC;;;ACzIA,SAAS,YAAY,mBAAmB;AACxC,SAAS,eAAe;AACxB;AAAA,EACI,oBAAoB;AAAA,OACjB;AAkCP,SAAS,0BAA0B,gBAAiC;AAChE,MAAI,CAAC,eAAgB,QAAO;AAE5B,QAAM,aAAa,eAAe,QAAQ,OAAO,GAAG;AAGpD,QAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO;AAClD,MAAI,MAAM,SAAS,GAAG;AAClB,WAAO,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAAA,EACtC;AAEA,SAAO;AACX;AAKO,SAAS,iBACZ,SACA,UAA2B,CAAC,GACd;AACd,QAAM,WAAW,QAAQ,sBAAsB,0BAA0B,QAAQ,cAAc;AAG/F,QAAM,aAAa,qBAAqB,SAAS;AAAA,IAC7C,cAAc;AAAA,MACV,iBAAiB;AAAA,MACjB,cAAc;AAAA,MACd,cAAc;AAAA,IAClB;AAAA;AAAA,IAEA,UAAU,CAAC,UAAU,QAAQ;AAAA,EACjC,CAAC;AAGD,QAAM,SAAyB;AAAA,IAC3B,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,OAAO,WAAW;AAAA,EACtB;AAGA,QAAM,cAAc,WAAW,OAAO,QAAQ,KAAK;AACnD,QAAM,cAAc,WAAW,OAAO,QAAQ,KAAK;AAEnD,SAAO,eAAe,KAAK,MAAM,cAAc,GAAG;AAClD,SAAO,mBAAmB,cAAc,OAAO;AAC/C,SAAO,cAAc;AAErB,SAAO;AACX;AAKO,SAAS,uBAAuB,SAA0B;AAC7D,QAAM,YAAY,QAAQ,SAAS,6BAA6B;AAChE,QAAM,YAAY,QAAQ,SAAS,sBAAsB;AAEzD,MAAI,CAAC,WAAW,SAAS,KAAK,CAAC,WAAW,SAAS,GAAG;AAClD,WAAO;AAAA,EACX;AAEA,MAAI;AACA,UAAM,cAAc,YAAY,SAAS;AACzC,UAAM,cAAc,YAAY,SAAS;AAEzC,WAAO,YAAY,WAAW,KAAK,YAAY,WAAW;AAAA,EAC9D,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@famgia/omnify-typescript",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.128",
|
|
4
4
|
"description": "TypeScript type definitions generator for Omnify schemas",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
"directory": "packages/typescript-generator"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@famgia/omnify-
|
|
51
|
+
"@famgia/omnify-core": "0.0.140",
|
|
52
|
+
"@famgia/omnify-types": "0.0.138"
|
|
52
53
|
},
|
|
53
54
|
"peerDependencies": {
|
|
54
55
|
"zod": "^3.25.0 || ^4.0.0"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# ⚠️ Deprecated
|
|
2
|
+
|
|
3
|
+
This folder is deprecated. AI guides are now generated from:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
packages/core/src/ai-guides/
|
|
7
|
+
├── knowledge/ # Source content (single source of truth)
|
|
8
|
+
├── config/ # Metadata and rules
|
|
9
|
+
└── adapters/ # AI-specific transformers (Cursor, Claude, etc.)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Migration
|
|
13
|
+
|
|
14
|
+
The new system provides:
|
|
15
|
+
- Single source of truth for all AI models
|
|
16
|
+
- Easy addition of new AI models (just add an adapter)
|
|
17
|
+
- Consistent content across Cursor, Claude, and future AI assistants
|
|
18
|
+
|
|
19
|
+
These stubs are kept for backward compatibility but are no longer used by the generator.
|