@famgia/omnify-typescript 0.0.66 → 0.0.68
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/ai-guides/react-form-guide.md +259 -0
- package/ai-guides/typescript-guide.md +53 -0
- package/dist/{chunk-4L77AHAC.js → chunk-6I4O23X6.js} +521 -66
- package/dist/chunk-6I4O23X6.js.map +1 -0
- package/dist/index.cjs +761 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +138 -2
- package/dist/index.d.ts +138 -2
- package/dist/index.js +227 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin.cjs +624 -75
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +6 -0
- package/dist/plugin.d.ts +6 -0
- package/dist/plugin.js +96 -11
- package/dist/plugin.js.map +1 -1
- package/package.json +4 -3
- package/scripts/postinstall.js +29 -40
- package/stubs/JapaneseAddressField.tsx.stub +289 -0
- package/stubs/JapaneseBankField.tsx.stub +212 -0
- package/stubs/JapaneseNameField.tsx.stub +194 -0
- package/stubs/ai-guides/checklists/react.md.stub +108 -0
- package/stubs/ai-guides/cursor/react-design.mdc.stub +289 -0
- package/stubs/ai-guides/cursor/react-form.mdc.stub +277 -0
- package/stubs/ai-guides/cursor/react-services.mdc.stub +304 -0
- package/stubs/ai-guides/cursor/react.mdc.stub +305 -0
- package/stubs/ai-guides/react/README.md.stub +221 -0
- package/stubs/ai-guides/react/antd-guide.md.stub +294 -0
- package/stubs/ai-guides/react/checklist.md.stub +108 -0
- package/stubs/ai-guides/react/datetime-guide.md.stub +137 -0
- package/stubs/ai-guides/react/design-philosophy.md.stub +363 -0
- package/stubs/ai-guides/react/i18n-guide.md.stub +211 -0
- package/stubs/ai-guides/react/laravel-integration.md.stub +181 -0
- package/stubs/ai-guides/react/service-pattern.md.stub +180 -0
- package/stubs/ai-guides/react/tanstack-query.md.stub +339 -0
- package/stubs/ai-guides/react/types-guide.md.stub +524 -0
- package/stubs/components-index.ts.stub +13 -0
- package/stubs/form-validation.ts.stub +106 -0
- package/stubs/rules/index.ts.stub +48 -0
- package/stubs/rules/kana.ts.stub +291 -0
- package/stubs/use-form-mutation.ts.stub +117 -0
- package/stubs/zod-i18n.ts.stub +32 -0
- package/dist/chunk-4L77AHAC.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LocaleConfig, CustomTypeDefinition, PropertyDefinition, SchemaCollection, LoadedSchema } from '@famgia/omnify-types';
|
|
1
|
+
import { LocaleConfig, CustomTypeDefinition, PluginEnumDefinition, PropertyDefinition, SchemaCollection, LoadedSchema } from '@famgia/omnify-types';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @famgia/omnify-typescript - TypeScript Types
|
|
@@ -6,6 +6,10 @@ import { LocaleConfig, CustomTypeDefinition, PropertyDefinition, SchemaCollectio
|
|
|
6
6
|
* Types for TypeScript code generation.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* File category for organizing output.
|
|
11
|
+
*/
|
|
12
|
+
type FileCategory = 'schema' | 'enum';
|
|
9
13
|
/**
|
|
10
14
|
* Generated TypeScript file.
|
|
11
15
|
*/
|
|
@@ -18,6 +22,8 @@ interface TypeScriptFile {
|
|
|
18
22
|
readonly types: readonly string[];
|
|
19
23
|
/** Whether this file can be overwritten (base files) or should be preserved (model files) */
|
|
20
24
|
readonly overwrite: boolean;
|
|
25
|
+
/** File category for organizing output (default: 'schema') */
|
|
26
|
+
readonly category?: FileCategory;
|
|
21
27
|
}
|
|
22
28
|
/**
|
|
23
29
|
* TypeScript generation options.
|
|
@@ -64,6 +70,18 @@ interface TypeScriptOptions {
|
|
|
64
70
|
* @default true
|
|
65
71
|
*/
|
|
66
72
|
readonly generateZodSchemas?: boolean | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Import path prefix for enums when enumPath is separate from schemasPath.
|
|
75
|
+
* Used when enums are placed outside the schemas folder.
|
|
76
|
+
* @example '../enum' - for structure like omnify/schemas/ and omnify/enum/
|
|
77
|
+
* @default './enum' - enums inside schemas folder (legacy)
|
|
78
|
+
*/
|
|
79
|
+
readonly enumImportPrefix?: string | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Plugin-provided enums (e.g., Prefecture, BankAccountType from japan-types).
|
|
82
|
+
* These are generated alongside schema enums in the enum/ folder.
|
|
83
|
+
*/
|
|
84
|
+
readonly pluginEnums?: ReadonlyMap<string, PluginEnumDefinition> | undefined;
|
|
67
85
|
}
|
|
68
86
|
/**
|
|
69
87
|
* TypeScript property definition.
|
|
@@ -94,6 +112,8 @@ interface TSInterface {
|
|
|
94
112
|
readonly comment?: string | undefined;
|
|
95
113
|
/** Dependencies - other interfaces that need to be imported */
|
|
96
114
|
readonly dependencies?: readonly string[] | undefined;
|
|
115
|
+
/** Enum dependencies - enums that need to be imported from enum/ folder */
|
|
116
|
+
readonly enumDependencies?: readonly string[] | undefined;
|
|
97
117
|
}
|
|
98
118
|
/**
|
|
99
119
|
* TypeScript enum definition.
|
|
@@ -199,6 +219,15 @@ declare function schemaToEnum(schema: LoadedSchema, options?: TypeScriptOptions)
|
|
|
199
219
|
* Generates enums for all enum schemas.
|
|
200
220
|
*/
|
|
201
221
|
declare function generateEnums(schemas: SchemaCollection, options?: TypeScriptOptions): TSEnum[];
|
|
222
|
+
/**
|
|
223
|
+
* Converts a plugin enum definition to TSEnum.
|
|
224
|
+
* Plugin enums come from plugins like @famgia/omnify-japan (e.g., Prefecture, BankAccountType).
|
|
225
|
+
*/
|
|
226
|
+
declare function pluginEnumToTSEnum(enumDef: PluginEnumDefinition, options?: TypeScriptOptions): TSEnum;
|
|
227
|
+
/**
|
|
228
|
+
* Generates enums from plugin enum definitions.
|
|
229
|
+
*/
|
|
230
|
+
declare function generatePluginEnums(pluginEnums: ReadonlyMap<string, PluginEnumDefinition>, options?: TypeScriptOptions): TSEnum[];
|
|
202
231
|
/**
|
|
203
232
|
* Formats a TypeScript enum with helper methods.
|
|
204
233
|
*/
|
|
@@ -310,4 +339,111 @@ declare function generateModelRules(schema: LoadedSchema, locales: string[], fal
|
|
|
310
339
|
*/
|
|
311
340
|
declare function generateRulesFiles(schemas: SchemaCollection, options?: TypeScriptOptions): TypeScriptFile[];
|
|
312
341
|
|
|
313
|
-
|
|
342
|
+
/**
|
|
343
|
+
* Stub file utilities for React/Ant Design/TanStack Query utilities.
|
|
344
|
+
*/
|
|
345
|
+
/**
|
|
346
|
+
* Stub file definitions
|
|
347
|
+
*/
|
|
348
|
+
declare const STUB_FILES: readonly [{
|
|
349
|
+
readonly stub: "JapaneseNameField.tsx.stub";
|
|
350
|
+
readonly output: "components/JapaneseNameField.tsx";
|
|
351
|
+
readonly indexExport: "";
|
|
352
|
+
}, {
|
|
353
|
+
readonly stub: "JapaneseAddressField.tsx.stub";
|
|
354
|
+
readonly output: "components/JapaneseAddressField.tsx";
|
|
355
|
+
readonly indexExport: "";
|
|
356
|
+
}, {
|
|
357
|
+
readonly stub: "JapaneseBankField.tsx.stub";
|
|
358
|
+
readonly output: "components/JapaneseBankField.tsx";
|
|
359
|
+
readonly indexExport: "";
|
|
360
|
+
}, {
|
|
361
|
+
readonly stub: "components-index.ts.stub";
|
|
362
|
+
readonly output: "components/index.ts";
|
|
363
|
+
readonly indexExport: "";
|
|
364
|
+
}, {
|
|
365
|
+
readonly stub: "use-form-mutation.ts.stub";
|
|
366
|
+
readonly output: "hooks/use-form-mutation.ts";
|
|
367
|
+
readonly indexExport: "export { useFormMutation } from './use-form-mutation';\n";
|
|
368
|
+
}, {
|
|
369
|
+
readonly stub: "zod-i18n.ts.stub";
|
|
370
|
+
readonly output: "lib/zod-i18n.ts";
|
|
371
|
+
readonly indexExport: "export { setZodLocale, getZodLocale, getZodMessage } from './zod-i18n';\n";
|
|
372
|
+
}, {
|
|
373
|
+
readonly stub: "form-validation.ts.stub";
|
|
374
|
+
readonly output: "lib/form-validation.ts";
|
|
375
|
+
readonly indexExport: "export { zodRule, requiredRule } from './form-validation';\nexport * from './rules';\n";
|
|
376
|
+
}, {
|
|
377
|
+
readonly stub: "rules/kana.ts.stub";
|
|
378
|
+
readonly output: "lib/rules/kana.ts";
|
|
379
|
+
readonly indexExport: "";
|
|
380
|
+
}, {
|
|
381
|
+
readonly stub: "rules/index.ts.stub";
|
|
382
|
+
readonly output: "lib/rules/index.ts";
|
|
383
|
+
readonly indexExport: "";
|
|
384
|
+
}];
|
|
385
|
+
interface CopyStubsOptions {
|
|
386
|
+
/** Target directory (e.g., 'resources/ts/omnify') */
|
|
387
|
+
targetDir: string;
|
|
388
|
+
/** Skip if file exists (default: true) */
|
|
389
|
+
skipIfExists?: boolean;
|
|
390
|
+
}
|
|
391
|
+
interface CopyStubsResult {
|
|
392
|
+
copied: string[];
|
|
393
|
+
skipped: string[];
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Copy React utility stubs to the target directory.
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* copyStubs({
|
|
400
|
+
* targetDir: 'resources/ts/omnify',
|
|
401
|
+
* skipIfExists: true,
|
|
402
|
+
* });
|
|
403
|
+
*/
|
|
404
|
+
declare function copyStubs(options: CopyStubsOptions): CopyStubsResult;
|
|
405
|
+
/**
|
|
406
|
+
* Get list of stub files that would be generated.
|
|
407
|
+
*/
|
|
408
|
+
declare function getStubPaths(): string[];
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* AI Guides Generator for TypeScript/Frontend
|
|
412
|
+
*
|
|
413
|
+
* Generates AI assistant guides (Claude, Cursor) for TypeScript/React projects.
|
|
414
|
+
* Simply copies .stub files, removes .stub extension, and replaces placeholders.
|
|
415
|
+
*/
|
|
416
|
+
/**
|
|
417
|
+
* Options for AI guides generation
|
|
418
|
+
*/
|
|
419
|
+
interface AIGuidesOptions {
|
|
420
|
+
/**
|
|
421
|
+
* TypeScript output path from config (e.g., 'resources/ts/omnify')
|
|
422
|
+
* Used to extract the base path for glob replacement
|
|
423
|
+
*/
|
|
424
|
+
typescriptPath?: string;
|
|
425
|
+
/**
|
|
426
|
+
* Base path for TypeScript files (default: extracted from typescriptPath or 'src')
|
|
427
|
+
* Used for placeholder replacement in Cursor rules
|
|
428
|
+
*/
|
|
429
|
+
typescriptBasePath?: string;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Result of AI guides generation
|
|
433
|
+
*/
|
|
434
|
+
interface AIGuidesResult {
|
|
435
|
+
claudeGuides: number;
|
|
436
|
+
claudeChecklists: number;
|
|
437
|
+
cursorRules: number;
|
|
438
|
+
files: string[];
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Generate AI guides for Claude and Cursor
|
|
442
|
+
*/
|
|
443
|
+
declare function generateAIGuides(rootDir: string, options?: AIGuidesOptions): AIGuidesResult;
|
|
444
|
+
/**
|
|
445
|
+
* Check if AI guides need to be generated
|
|
446
|
+
*/
|
|
447
|
+
declare function shouldGenerateAIGuides(rootDir: string): boolean;
|
|
448
|
+
|
|
449
|
+
export { type AIGuidesOptions, type AIGuidesResult, type CopyStubsOptions, type CopyStubsResult, DEFAULT_VALIDATION_TEMPLATES, type LocaleMap, STUB_FILES, type TSEnum, type TSEnumValue, type TSInterface, type TSProperty, type TSTypeAlias, type TypeScriptFile, type TypeScriptOptions, type ValidationTemplates, copyStubs, enumToUnionType, extractInlineEnums, formatEnum, formatInterface, formatProperty, formatTypeAlias, formatValidationMessage, generateAIGuides, generateEnums, generateInterfaces, generateModelRules, generatePluginEnums, generateRulesFiles, generateTypeScript, generateTypeScript as generateTypeScriptFiles, getPropertyType, getStubPaths, getValidationMessages, mergeValidationTemplates, pluginEnumToTSEnum, propertyToTSProperty, schemaToEnum, schemaToInterface, shouldGenerateAIGuides, toEnumMemberName, toEnumName, toInterfaceName, toPropertyName };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LocaleConfig, CustomTypeDefinition, PropertyDefinition, SchemaCollection, LoadedSchema } from '@famgia/omnify-types';
|
|
1
|
+
import { LocaleConfig, CustomTypeDefinition, PluginEnumDefinition, PropertyDefinition, SchemaCollection, LoadedSchema } from '@famgia/omnify-types';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @famgia/omnify-typescript - TypeScript Types
|
|
@@ -6,6 +6,10 @@ import { LocaleConfig, CustomTypeDefinition, PropertyDefinition, SchemaCollectio
|
|
|
6
6
|
* Types for TypeScript code generation.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* File category for organizing output.
|
|
11
|
+
*/
|
|
12
|
+
type FileCategory = 'schema' | 'enum';
|
|
9
13
|
/**
|
|
10
14
|
* Generated TypeScript file.
|
|
11
15
|
*/
|
|
@@ -18,6 +22,8 @@ interface TypeScriptFile {
|
|
|
18
22
|
readonly types: readonly string[];
|
|
19
23
|
/** Whether this file can be overwritten (base files) or should be preserved (model files) */
|
|
20
24
|
readonly overwrite: boolean;
|
|
25
|
+
/** File category for organizing output (default: 'schema') */
|
|
26
|
+
readonly category?: FileCategory;
|
|
21
27
|
}
|
|
22
28
|
/**
|
|
23
29
|
* TypeScript generation options.
|
|
@@ -64,6 +70,18 @@ interface TypeScriptOptions {
|
|
|
64
70
|
* @default true
|
|
65
71
|
*/
|
|
66
72
|
readonly generateZodSchemas?: boolean | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Import path prefix for enums when enumPath is separate from schemasPath.
|
|
75
|
+
* Used when enums are placed outside the schemas folder.
|
|
76
|
+
* @example '../enum' - for structure like omnify/schemas/ and omnify/enum/
|
|
77
|
+
* @default './enum' - enums inside schemas folder (legacy)
|
|
78
|
+
*/
|
|
79
|
+
readonly enumImportPrefix?: string | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Plugin-provided enums (e.g., Prefecture, BankAccountType from japan-types).
|
|
82
|
+
* These are generated alongside schema enums in the enum/ folder.
|
|
83
|
+
*/
|
|
84
|
+
readonly pluginEnums?: ReadonlyMap<string, PluginEnumDefinition> | undefined;
|
|
67
85
|
}
|
|
68
86
|
/**
|
|
69
87
|
* TypeScript property definition.
|
|
@@ -94,6 +112,8 @@ interface TSInterface {
|
|
|
94
112
|
readonly comment?: string | undefined;
|
|
95
113
|
/** Dependencies - other interfaces that need to be imported */
|
|
96
114
|
readonly dependencies?: readonly string[] | undefined;
|
|
115
|
+
/** Enum dependencies - enums that need to be imported from enum/ folder */
|
|
116
|
+
readonly enumDependencies?: readonly string[] | undefined;
|
|
97
117
|
}
|
|
98
118
|
/**
|
|
99
119
|
* TypeScript enum definition.
|
|
@@ -199,6 +219,15 @@ declare function schemaToEnum(schema: LoadedSchema, options?: TypeScriptOptions)
|
|
|
199
219
|
* Generates enums for all enum schemas.
|
|
200
220
|
*/
|
|
201
221
|
declare function generateEnums(schemas: SchemaCollection, options?: TypeScriptOptions): TSEnum[];
|
|
222
|
+
/**
|
|
223
|
+
* Converts a plugin enum definition to TSEnum.
|
|
224
|
+
* Plugin enums come from plugins like @famgia/omnify-japan (e.g., Prefecture, BankAccountType).
|
|
225
|
+
*/
|
|
226
|
+
declare function pluginEnumToTSEnum(enumDef: PluginEnumDefinition, options?: TypeScriptOptions): TSEnum;
|
|
227
|
+
/**
|
|
228
|
+
* Generates enums from plugin enum definitions.
|
|
229
|
+
*/
|
|
230
|
+
declare function generatePluginEnums(pluginEnums: ReadonlyMap<string, PluginEnumDefinition>, options?: TypeScriptOptions): TSEnum[];
|
|
202
231
|
/**
|
|
203
232
|
* Formats a TypeScript enum with helper methods.
|
|
204
233
|
*/
|
|
@@ -310,4 +339,111 @@ declare function generateModelRules(schema: LoadedSchema, locales: string[], fal
|
|
|
310
339
|
*/
|
|
311
340
|
declare function generateRulesFiles(schemas: SchemaCollection, options?: TypeScriptOptions): TypeScriptFile[];
|
|
312
341
|
|
|
313
|
-
|
|
342
|
+
/**
|
|
343
|
+
* Stub file utilities for React/Ant Design/TanStack Query utilities.
|
|
344
|
+
*/
|
|
345
|
+
/**
|
|
346
|
+
* Stub file definitions
|
|
347
|
+
*/
|
|
348
|
+
declare const STUB_FILES: readonly [{
|
|
349
|
+
readonly stub: "JapaneseNameField.tsx.stub";
|
|
350
|
+
readonly output: "components/JapaneseNameField.tsx";
|
|
351
|
+
readonly indexExport: "";
|
|
352
|
+
}, {
|
|
353
|
+
readonly stub: "JapaneseAddressField.tsx.stub";
|
|
354
|
+
readonly output: "components/JapaneseAddressField.tsx";
|
|
355
|
+
readonly indexExport: "";
|
|
356
|
+
}, {
|
|
357
|
+
readonly stub: "JapaneseBankField.tsx.stub";
|
|
358
|
+
readonly output: "components/JapaneseBankField.tsx";
|
|
359
|
+
readonly indexExport: "";
|
|
360
|
+
}, {
|
|
361
|
+
readonly stub: "components-index.ts.stub";
|
|
362
|
+
readonly output: "components/index.ts";
|
|
363
|
+
readonly indexExport: "";
|
|
364
|
+
}, {
|
|
365
|
+
readonly stub: "use-form-mutation.ts.stub";
|
|
366
|
+
readonly output: "hooks/use-form-mutation.ts";
|
|
367
|
+
readonly indexExport: "export { useFormMutation } from './use-form-mutation';\n";
|
|
368
|
+
}, {
|
|
369
|
+
readonly stub: "zod-i18n.ts.stub";
|
|
370
|
+
readonly output: "lib/zod-i18n.ts";
|
|
371
|
+
readonly indexExport: "export { setZodLocale, getZodLocale, getZodMessage } from './zod-i18n';\n";
|
|
372
|
+
}, {
|
|
373
|
+
readonly stub: "form-validation.ts.stub";
|
|
374
|
+
readonly output: "lib/form-validation.ts";
|
|
375
|
+
readonly indexExport: "export { zodRule, requiredRule } from './form-validation';\nexport * from './rules';\n";
|
|
376
|
+
}, {
|
|
377
|
+
readonly stub: "rules/kana.ts.stub";
|
|
378
|
+
readonly output: "lib/rules/kana.ts";
|
|
379
|
+
readonly indexExport: "";
|
|
380
|
+
}, {
|
|
381
|
+
readonly stub: "rules/index.ts.stub";
|
|
382
|
+
readonly output: "lib/rules/index.ts";
|
|
383
|
+
readonly indexExport: "";
|
|
384
|
+
}];
|
|
385
|
+
interface CopyStubsOptions {
|
|
386
|
+
/** Target directory (e.g., 'resources/ts/omnify') */
|
|
387
|
+
targetDir: string;
|
|
388
|
+
/** Skip if file exists (default: true) */
|
|
389
|
+
skipIfExists?: boolean;
|
|
390
|
+
}
|
|
391
|
+
interface CopyStubsResult {
|
|
392
|
+
copied: string[];
|
|
393
|
+
skipped: string[];
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Copy React utility stubs to the target directory.
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* copyStubs({
|
|
400
|
+
* targetDir: 'resources/ts/omnify',
|
|
401
|
+
* skipIfExists: true,
|
|
402
|
+
* });
|
|
403
|
+
*/
|
|
404
|
+
declare function copyStubs(options: CopyStubsOptions): CopyStubsResult;
|
|
405
|
+
/**
|
|
406
|
+
* Get list of stub files that would be generated.
|
|
407
|
+
*/
|
|
408
|
+
declare function getStubPaths(): string[];
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* AI Guides Generator for TypeScript/Frontend
|
|
412
|
+
*
|
|
413
|
+
* Generates AI assistant guides (Claude, Cursor) for TypeScript/React projects.
|
|
414
|
+
* Simply copies .stub files, removes .stub extension, and replaces placeholders.
|
|
415
|
+
*/
|
|
416
|
+
/**
|
|
417
|
+
* Options for AI guides generation
|
|
418
|
+
*/
|
|
419
|
+
interface AIGuidesOptions {
|
|
420
|
+
/**
|
|
421
|
+
* TypeScript output path from config (e.g., 'resources/ts/omnify')
|
|
422
|
+
* Used to extract the base path for glob replacement
|
|
423
|
+
*/
|
|
424
|
+
typescriptPath?: string;
|
|
425
|
+
/**
|
|
426
|
+
* Base path for TypeScript files (default: extracted from typescriptPath or 'src')
|
|
427
|
+
* Used for placeholder replacement in Cursor rules
|
|
428
|
+
*/
|
|
429
|
+
typescriptBasePath?: string;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Result of AI guides generation
|
|
433
|
+
*/
|
|
434
|
+
interface AIGuidesResult {
|
|
435
|
+
claudeGuides: number;
|
|
436
|
+
claudeChecklists: number;
|
|
437
|
+
cursorRules: number;
|
|
438
|
+
files: string[];
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Generate AI guides for Claude and Cursor
|
|
442
|
+
*/
|
|
443
|
+
declare function generateAIGuides(rootDir: string, options?: AIGuidesOptions): AIGuidesResult;
|
|
444
|
+
/**
|
|
445
|
+
* Check if AI guides need to be generated
|
|
446
|
+
*/
|
|
447
|
+
declare function shouldGenerateAIGuides(rootDir: string): boolean;
|
|
448
|
+
|
|
449
|
+
export { type AIGuidesOptions, type AIGuidesResult, type CopyStubsOptions, type CopyStubsResult, DEFAULT_VALIDATION_TEMPLATES, type LocaleMap, STUB_FILES, type TSEnum, type TSEnumValue, type TSInterface, type TSProperty, type TSTypeAlias, type TypeScriptFile, type TypeScriptOptions, type ValidationTemplates, copyStubs, enumToUnionType, extractInlineEnums, formatEnum, formatInterface, formatProperty, formatTypeAlias, formatValidationMessage, generateAIGuides, generateEnums, generateInterfaces, generateModelRules, generatePluginEnums, generateRulesFiles, generateTypeScript, generateTypeScript as generateTypeScriptFiles, getPropertyType, getStubPaths, getValidationMessages, mergeValidationTemplates, pluginEnumToTSEnum, propertyToTSProperty, schemaToEnum, schemaToInterface, shouldGenerateAIGuides, toEnumMemberName, toEnumName, toInterfaceName, toPropertyName };
|
package/dist/index.js
CHANGED
|
@@ -10,11 +10,13 @@ import {
|
|
|
10
10
|
generateEnums,
|
|
11
11
|
generateInterfaces,
|
|
12
12
|
generateModelRules,
|
|
13
|
+
generatePluginEnums,
|
|
13
14
|
generateRulesFiles,
|
|
14
15
|
generateTypeScript,
|
|
15
16
|
getPropertyType,
|
|
16
17
|
getValidationMessages,
|
|
17
18
|
mergeValidationTemplates,
|
|
19
|
+
pluginEnumToTSEnum,
|
|
18
20
|
propertyToTSProperty,
|
|
19
21
|
schemaToEnum,
|
|
20
22
|
schemaToInterface,
|
|
@@ -22,9 +24,228 @@ import {
|
|
|
22
24
|
toEnumName,
|
|
23
25
|
toInterfaceName,
|
|
24
26
|
toPropertyName
|
|
25
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-6I4O23X6.js";
|
|
28
|
+
|
|
29
|
+
// src/stubs.ts
|
|
30
|
+
import fs from "fs";
|
|
31
|
+
import path from "path";
|
|
32
|
+
import { fileURLToPath } from "url";
|
|
33
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
34
|
+
var __dirname = path.dirname(__filename);
|
|
35
|
+
var STUB_FILES = [
|
|
36
|
+
// Components
|
|
37
|
+
{
|
|
38
|
+
stub: "JapaneseNameField.tsx.stub",
|
|
39
|
+
output: "components/JapaneseNameField.tsx",
|
|
40
|
+
indexExport: ""
|
|
41
|
+
// Handled by components-index.ts.stub
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
stub: "JapaneseAddressField.tsx.stub",
|
|
45
|
+
output: "components/JapaneseAddressField.tsx",
|
|
46
|
+
indexExport: ""
|
|
47
|
+
// Handled by components-index.ts.stub
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
stub: "JapaneseBankField.tsx.stub",
|
|
51
|
+
output: "components/JapaneseBankField.tsx",
|
|
52
|
+
indexExport: ""
|
|
53
|
+
// Handled by components-index.ts.stub
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
stub: "components-index.ts.stub",
|
|
57
|
+
output: "components/index.ts",
|
|
58
|
+
indexExport: ""
|
|
59
|
+
// This IS the index
|
|
60
|
+
},
|
|
61
|
+
// Hooks
|
|
62
|
+
{
|
|
63
|
+
stub: "use-form-mutation.ts.stub",
|
|
64
|
+
output: "hooks/use-form-mutation.ts",
|
|
65
|
+
indexExport: `export { useFormMutation } from './use-form-mutation';
|
|
66
|
+
`
|
|
67
|
+
},
|
|
68
|
+
// Lib
|
|
69
|
+
{
|
|
70
|
+
stub: "zod-i18n.ts.stub",
|
|
71
|
+
output: "lib/zod-i18n.ts",
|
|
72
|
+
indexExport: `export { setZodLocale, getZodLocale, getZodMessage } from './zod-i18n';
|
|
73
|
+
`
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
stub: "form-validation.ts.stub",
|
|
77
|
+
output: "lib/form-validation.ts",
|
|
78
|
+
indexExport: `export { zodRule, requiredRule } from './form-validation';
|
|
79
|
+
export * from './rules';
|
|
80
|
+
`
|
|
81
|
+
},
|
|
82
|
+
// Rules
|
|
83
|
+
{
|
|
84
|
+
stub: "rules/kana.ts.stub",
|
|
85
|
+
output: "lib/rules/kana.ts",
|
|
86
|
+
indexExport: ""
|
|
87
|
+
// Will be handled by rules/index.ts
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
stub: "rules/index.ts.stub",
|
|
91
|
+
output: "lib/rules/index.ts",
|
|
92
|
+
indexExport: ""
|
|
93
|
+
// Already exported via form-validation
|
|
94
|
+
}
|
|
95
|
+
];
|
|
96
|
+
function copyStubs(options) {
|
|
97
|
+
const { targetDir, skipIfExists = true } = options;
|
|
98
|
+
const stubsDir = path.join(__dirname, "..", "stubs");
|
|
99
|
+
const result = { copied: [], skipped: [] };
|
|
100
|
+
const directories = /* @__PURE__ */ new Map();
|
|
101
|
+
for (const { stub, output, indexExport } of STUB_FILES) {
|
|
102
|
+
const stubPath = path.join(stubsDir, stub);
|
|
103
|
+
const outputPath = path.join(targetDir, output);
|
|
104
|
+
const outputDir = path.dirname(outputPath);
|
|
105
|
+
const dirName = path.dirname(output).split("/")[0];
|
|
106
|
+
if (!directories.has(dirName)) {
|
|
107
|
+
directories.set(dirName, "");
|
|
108
|
+
}
|
|
109
|
+
directories.set(dirName, directories.get(dirName) + indexExport);
|
|
110
|
+
if (!fs.existsSync(outputDir)) {
|
|
111
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
112
|
+
}
|
|
113
|
+
if (skipIfExists && fs.existsSync(outputPath)) {
|
|
114
|
+
result.skipped.push(output);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (fs.existsSync(stubPath)) {
|
|
118
|
+
const content = fs.readFileSync(stubPath, "utf-8");
|
|
119
|
+
fs.writeFileSync(outputPath, content);
|
|
120
|
+
result.copied.push(output);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
for (const [dirName, exports] of directories) {
|
|
124
|
+
const indexPath = path.join(targetDir, dirName, "index.ts");
|
|
125
|
+
if (skipIfExists && fs.existsSync(indexPath)) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
fs.writeFileSync(indexPath, exports);
|
|
129
|
+
result.copied.push(`${dirName}/index.ts`);
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
function getStubPaths() {
|
|
134
|
+
return STUB_FILES.map((s) => s.output);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/ai-guides/generator.ts
|
|
138
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "fs";
|
|
139
|
+
import { resolve, dirname, join } from "path";
|
|
140
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
141
|
+
var __filename2 = fileURLToPath2(import.meta.url);
|
|
142
|
+
var __dirname2 = dirname(__filename2);
|
|
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
|
+
}
|
|
154
|
+
function extractTypescriptBasePath(typescriptPath) {
|
|
155
|
+
if (!typescriptPath) return "src";
|
|
156
|
+
const normalized = typescriptPath.replace(/\\/g, "/");
|
|
157
|
+
const parts = normalized.split("/").filter(Boolean);
|
|
158
|
+
if (parts.length > 1) {
|
|
159
|
+
return parts.slice(0, -1).join("/");
|
|
160
|
+
}
|
|
161
|
+
return "src";
|
|
162
|
+
}
|
|
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
|
+
function generateAIGuides(rootDir, options = {}) {
|
|
195
|
+
const stubsDir = getStubsDir();
|
|
196
|
+
const basePath = options.typescriptBasePath || extractTypescriptBasePath(options.typescriptPath);
|
|
197
|
+
const result = {
|
|
198
|
+
claudeGuides: 0,
|
|
199
|
+
claudeChecklists: 0,
|
|
200
|
+
cursorRules: 0,
|
|
201
|
+
files: []
|
|
202
|
+
};
|
|
203
|
+
const claudeSrcDir = join(stubsDir, "react");
|
|
204
|
+
const claudeDestDir = resolve(rootDir, ".claude/omnify/guides/react");
|
|
205
|
+
if (existsSync(claudeSrcDir)) {
|
|
206
|
+
const files = copyStubs2(claudeSrcDir, claudeDestDir);
|
|
207
|
+
result.claudeGuides = files.length;
|
|
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
|
+
}
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
230
|
+
function shouldGenerateAIGuides(rootDir) {
|
|
231
|
+
const claudeDir = resolve(rootDir, ".claude/omnify/guides/react");
|
|
232
|
+
const cursorDir = resolve(rootDir, ".cursor/rules/omnify");
|
|
233
|
+
if (!existsSync(claudeDir) || !existsSync(cursorDir)) {
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
try {
|
|
237
|
+
const claudeFiles = readdirSync(claudeDir);
|
|
238
|
+
const cursorFiles = readdirSync(cursorDir);
|
|
239
|
+
const hasReactRules = cursorFiles.some((f) => f.startsWith("react"));
|
|
240
|
+
return claudeFiles.length === 0 || !hasReactRules;
|
|
241
|
+
} catch {
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
26
245
|
export {
|
|
27
246
|
DEFAULT_VALIDATION_TEMPLATES,
|
|
247
|
+
STUB_FILES,
|
|
248
|
+
copyStubs,
|
|
28
249
|
enumToUnionType,
|
|
29
250
|
extractInlineEnums,
|
|
30
251
|
formatEnum,
|
|
@@ -32,18 +253,23 @@ export {
|
|
|
32
253
|
formatProperty,
|
|
33
254
|
formatTypeAlias,
|
|
34
255
|
formatValidationMessage,
|
|
256
|
+
generateAIGuides,
|
|
35
257
|
generateEnums,
|
|
36
258
|
generateInterfaces,
|
|
37
259
|
generateModelRules,
|
|
260
|
+
generatePluginEnums,
|
|
38
261
|
generateRulesFiles,
|
|
39
262
|
generateTypeScript,
|
|
40
263
|
generateTypeScript as generateTypeScriptFiles,
|
|
41
264
|
getPropertyType,
|
|
265
|
+
getStubPaths,
|
|
42
266
|
getValidationMessages,
|
|
43
267
|
mergeValidationTemplates,
|
|
268
|
+
pluginEnumToTSEnum,
|
|
44
269
|
propertyToTSProperty,
|
|
45
270
|
schemaToEnum,
|
|
46
271
|
schemaToInterface,
|
|
272
|
+
shouldGenerateAIGuides,
|
|
47
273
|
toEnumMemberName,
|
|
48
274
|
toEnumName,
|
|
49
275
|
toInterfaceName,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
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: true) */\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 = true } = 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"]}
|