@famgia/omnify-typescript 0.0.98 → 0.0.100
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 +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin.cjs +5 -5
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.js +5 -5
- package/dist/plugin.js.map +1 -1
- package/package.json +2 -2
- package/stubs/form-validation.ts.stub +3 -1
- package/stubs/rules/index.ts.stub +3 -0
- package/stubs/rules/kana.ts.stub +3 -0
- package/stubs/use-form-mutation.ts.stub +3 -1
- package/stubs/zod-i18n.ts.stub +3 -1
package/dist/index.d.cts
CHANGED
|
@@ -392,7 +392,7 @@ declare const STUB_FILES: readonly [{
|
|
|
392
392
|
interface CopyStubsOptions {
|
|
393
393
|
/** Target directory (e.g., 'resources/ts/omnify') */
|
|
394
394
|
targetDir: string;
|
|
395
|
-
/** Skip if file exists (default:
|
|
395
|
+
/** Skip if file exists (default: false - always overwrite library files) */
|
|
396
396
|
skipIfExists?: boolean;
|
|
397
397
|
}
|
|
398
398
|
interface CopyStubsResult {
|
package/dist/index.d.ts
CHANGED
|
@@ -392,7 +392,7 @@ declare const STUB_FILES: readonly [{
|
|
|
392
392
|
interface CopyStubsOptions {
|
|
393
393
|
/** Target directory (e.g., 'resources/ts/omnify') */
|
|
394
394
|
targetDir: string;
|
|
395
|
-
/** Skip if file exists (default:
|
|
395
|
+
/** Skip if file exists (default: false - always overwrite library files) */
|
|
396
396
|
skipIfExists?: boolean;
|
|
397
397
|
}
|
|
398
398
|
interface CopyStubsResult {
|
package/dist/index.js
CHANGED
|
@@ -94,7 +94,7 @@ export * from './rules';
|
|
|
94
94
|
}
|
|
95
95
|
];
|
|
96
96
|
function copyStubs(options) {
|
|
97
|
-
const { targetDir, skipIfExists =
|
|
97
|
+
const { targetDir, skipIfExists = false } = options;
|
|
98
98
|
const stubsDir = path.join(__dirname, "..", "stubs");
|
|
99
99
|
const result = { copied: [], skipped: [] };
|
|
100
100
|
const directories = /* @__PURE__ */ new Map();
|
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: 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,KAAK,IAAI;AAC3C,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,WAAW,aAAa,cAAc,qBAAqB;AAChF,SAAS,SAAS,SAAS,YAAY;AACvC,SAAS,iBAAAA,sBAAqB;AAE9B,IAAMC,cAAaD,eAAc,YAAY,GAAG;AAChD,IAAME,aAAY,QAAQD,WAAU;AAgCpC,SAAS,cAAsB;AAE3B,QAAM,UAAU,QAAQC,YAAW,uBAAuB;AAC1D,MAAI,WAAW,OAAO,GAAG;AACrB,WAAO;AAAA,EACX;AAGA,QAAM,WAAW,QAAQA,YAAW,oBAAoB;AACxD,MAAI,WAAW,QAAQ,GAAG;AACtB,WAAO;AAAA,EACX;AAEA,QAAM,IAAI,MAAM,2BAA2B;AAC/C;AAOA,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;AAMA,SAAS,oBAAoB,SAAiB,UAA0B;AACpE,SAAO,QAAQ,QAAQ,4BAA4B,QAAQ;AAC/D;AAKA,SAASC,WACL,QACA,SACA,WACQ;AACR,QAAM,eAAyB,CAAC;AAEhC,MAAI,CAAC,WAAW,MAAM,GAAG;AACrB,WAAO;AAAA,EACX;AAEA,MAAI,CAAC,WAAW,OAAO,GAAG;AACtB,cAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,EAC1C;AAEA,QAAM,UAAU,YAAY,QAAQ,EAAE,eAAe,KAAK,CAAC;AAE3D,aAAW,SAAS,SAAS;AACzB,UAAM,UAAU,KAAK,QAAQ,MAAM,IAAI;AAEvC,QAAI,MAAM,YAAY,GAAG;AAErB,YAAM,aAAa,KAAK,SAAS,MAAM,IAAI;AAC3C,YAAM,WAAWA,WAAU,SAAS,YAAY,SAAS;AACzD,mBAAa,KAAK,GAAG,QAAQ;AAAA,IACjC,WAAW,MAAM,OAAO,KAAK,MAAM,KAAK,SAAS,OAAO,GAAG;AAEvD,YAAM,WAAW,MAAM,KAAK,MAAM,GAAG,EAAE;AACvC,YAAM,WAAW,KAAK,SAAS,QAAQ;AAEvC,UAAI,UAAU,aAAa,SAAS,OAAO;AAE3C,UAAI,WAAW;AACX,kBAAU,UAAU,OAAO;AAAA,MAC/B;AAEA,oBAAc,UAAU,OAAO;AAC/B,mBAAa,KAAK,QAAQ;AAAA,IAC9B;AAAA,EACJ;AAEA,SAAO;AACX;AAKO,SAAS,iBACZ,SACA,UAA2B,CAAC,GACd;AACd,QAAM,WAAW,YAAY;AAC7B,QAAM,WAAW,QAAQ,sBAAsB,0BAA0B,QAAQ,cAAc;AAE/F,QAAM,SAAyB;AAAA,IAC3B,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,OAAO,CAAC;AAAA,EACZ;AAKA,QAAM,eAAe,KAAK,UAAU,OAAO;AAC3C,QAAM,gBAAgB,QAAQ,SAAS,6BAA6B;AAEpE,MAAI,WAAW,YAAY,GAAG;AAC1B,UAAM,QAAQA,WAAU,cAAc,aAAa;AACnD,WAAO,eAAe,MAAM;AAC5B,WAAO,MAAM,KAAK,GAAG,KAAK;AAAA,EAC9B;AAGA,QAAM,yBAAyB,KAAK,UAAU,YAAY;AAC1D,QAAM,0BAA0B,QAAQ,SAAS,2BAA2B;AAE5E,MAAI,WAAW,sBAAsB,GAAG;AACpC,UAAM,QAAQA,WAAU,wBAAwB,uBAAuB;AACvE,WAAO,mBAAmB,MAAM;AAChC,WAAO,MAAM,KAAK,GAAG,KAAK;AAAA,EAC9B;AAGA,QAAM,eAAe,KAAK,UAAU,QAAQ;AAC5C,QAAM,gBAAgB,QAAQ,SAAS,sBAAsB;AAE7D,MAAI,WAAW,YAAY,GAAG;AAC1B,UAAM,QAAQA;AAAA,MAAU;AAAA,MAAc;AAAA,MAAe,CAAC,YAClD,oBAAoB,SAAS,QAAQ;AAAA,IACzC;AACA,WAAO,cAAc,MAAM;AAC3B,WAAO,MAAM,KAAK,GAAG,KAAK;AAAA,EAC9B;AAEA,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;AACzC,UAAM,gBAAgB,YAAY,KAAK,CAAC,MAAM,EAAE,WAAW,OAAO,CAAC;AAEnE,WAAO,YAAY,WAAW,KAAK,CAAC;AAAA,EACxC,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;","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 * 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"]}
|
package/dist/plugin.cjs
CHANGED
|
@@ -2332,8 +2332,8 @@ function typescriptPlugin(options) {
|
|
|
2332
2332
|
path: `${resolved.stubsPath}/${output}`,
|
|
2333
2333
|
content,
|
|
2334
2334
|
type: "other",
|
|
2335
|
-
skipIfExists:
|
|
2336
|
-
//
|
|
2335
|
+
skipIfExists: false
|
|
2336
|
+
// Always overwrite - library files should stay in sync
|
|
2337
2337
|
});
|
|
2338
2338
|
}
|
|
2339
2339
|
}
|
|
@@ -2342,21 +2342,21 @@ function typescriptPlugin(options) {
|
|
|
2342
2342
|
content: `export { CompoundField, type FieldConfig } from './CompoundField';
|
|
2343
2343
|
`,
|
|
2344
2344
|
type: "other",
|
|
2345
|
-
skipIfExists:
|
|
2345
|
+
skipIfExists: false
|
|
2346
2346
|
});
|
|
2347
2347
|
outputs.push({
|
|
2348
2348
|
path: `${resolved.stubsPath}/hooks/index.ts`,
|
|
2349
2349
|
content: `export { useFormMutation } from './use-form-mutation';
|
|
2350
2350
|
`,
|
|
2351
2351
|
type: "other",
|
|
2352
|
-
skipIfExists:
|
|
2352
|
+
skipIfExists: false
|
|
2353
2353
|
});
|
|
2354
2354
|
outputs.push({
|
|
2355
2355
|
path: `${resolved.stubsPath}/lib/index.ts`,
|
|
2356
2356
|
content: `export { zodRule, requiredRule } from './form-validation';
|
|
2357
2357
|
`,
|
|
2358
2358
|
type: "other",
|
|
2359
|
-
skipIfExists:
|
|
2359
|
+
skipIfExists: false
|
|
2360
2360
|
});
|
|
2361
2361
|
return outputs;
|
|
2362
2362
|
}
|