@strapi2front/generators 0.1.2 → 0.1.4
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.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2064,6 +2064,7 @@ function generateTypeImports(attributes, schema, context) {
|
|
|
2064
2064
|
if (attributesStr.includes('"type":"blocks"')) {
|
|
2065
2065
|
utilsImports.push("BlocksContent");
|
|
2066
2066
|
}
|
|
2067
|
+
const relativePrefix = context === "component" ? ".." : "../..";
|
|
2067
2068
|
for (const attr of Object.values(attributes)) {
|
|
2068
2069
|
if (attr.type === "relation" && "target" in attr && attr.target) {
|
|
2069
2070
|
const targetName = attr.target.split(".").pop() || "";
|
|
@@ -2073,9 +2074,9 @@ function generateTypeImports(attributes, schema, context) {
|
|
|
2073
2074
|
const isCollection = schema.collections.some((c) => c.singularName === targetName);
|
|
2074
2075
|
const isSingle = schema.singles.some((s) => s.singularName === targetName);
|
|
2075
2076
|
if (isCollection) {
|
|
2076
|
-
relationImports.set(typeName,
|
|
2077
|
+
relationImports.set(typeName, `${relativePrefix}/collections/${fileName}/types`);
|
|
2077
2078
|
} else if (isSingle) {
|
|
2078
|
-
relationImports.set(typeName,
|
|
2079
|
+
relationImports.set(typeName, `${relativePrefix}/singles/${fileName}/types`);
|
|
2079
2080
|
}
|
|
2080
2081
|
}
|
|
2081
2082
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/formatter.ts","../src/utils/file.ts","../src/utils/naming.ts","../src/types/generator.ts","../src/services/generator.ts","../src/actions/generator.ts","../src/client/generator.ts","../src/locales/generator.ts","../src/by-feature/generator.ts"],"names":["path","generateUtilityTypes","generateClient","generateLocalesFile","generateCollectionService","generateCollectionActions","generateSingleService","generateAttributes","attributeToTsType"],"mappings":"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","file":"index.js","sourcesContent":["import * as prettier from 'prettier';\n\n/**\n * Format TypeScript code using Prettier\n */\nexport async function formatCode(code: string): Promise<string> {\n try {\n return await prettier.format(code, {\n parser: 'typescript',\n semi: true,\n singleQuote: true,\n trailingComma: 'es5',\n printWidth: 100,\n tabWidth: 2,\n useTabs: false,\n });\n } catch {\n // If formatting fails, return original code\n return code;\n }\n}\n\n/**\n * Format JSON code using Prettier\n */\nexport async function formatJson(code: string): Promise<string> {\n try {\n return await prettier.format(code, {\n parser: 'json',\n tabWidth: 2,\n });\n } catch {\n return code;\n }\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\n\n/**\n * Ensure a directory exists, creating it if necessary\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, { recursive: true });\n } catch (error) {\n // Ignore if directory already exists\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error;\n }\n }\n}\n\n/**\n * Write content to a file, creating parent directories if needed\n */\nexport async function writeFile(filePath: string, content: string): Promise<void> {\n const dir = path.dirname(filePath);\n await ensureDir(dir);\n await fs.writeFile(filePath, content, 'utf-8');\n}\n\n/**\n * Read a file's content\n */\nexport async function readFile(filePath: string): Promise<string> {\n return await fs.readFile(filePath, 'utf-8');\n}\n\n/**\n * Check if a file exists\n */\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Delete a file if it exists\n */\nexport async function deleteFile(filePath: string): Promise<void> {\n try {\n await fs.unlink(filePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n}\n\n/**\n * List files in a directory matching a pattern\n */\nexport async function listFiles(dirPath: string, extension?: string): Promise<string[]> {\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n let files = entries\n .filter((entry) => entry.isFile())\n .map((entry) => path.join(dirPath, entry.name));\n\n if (extension) {\n files = files.filter((file) => file.endsWith(extension));\n }\n\n return files;\n } catch {\n return [];\n }\n}\n","/**\n * Convert string to PascalCase\n */\nexport function toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Convert string to camelCase\n */\nexport function toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\n/**\n * Convert string to kebab-case\n */\nexport function toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\n/**\n * Pluralize a word (simple version)\n */\nexport function pluralize(word: string): string {\n if (word.endsWith('s') || word.endsWith('x') || word.endsWith('ch') || word.endsWith('sh')) {\n return word + 'es';\n }\n if (word.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(word.charAt(word.length - 2))) {\n return word.slice(0, -1) + 'ies';\n }\n return word + 's';\n}\n","import path from 'node:path';\nimport type { ParsedSchema, Attribute, CollectionType, SingleType, ComponentType } from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\nimport { toPascalCase, toKebabCase } from '../utils/naming.js';\n\nexport interface TypeGeneratorOptions {\n outputDir: string;\n blocksRendererInstalled?: boolean;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate TypeScript types from parsed schema\n */\nexport async function generateTypes(\n schema: ParsedSchema,\n options: TypeGeneratorOptions\n): Promise<string[]> {\n const { outputDir } = options;\n const generatedFiles: string[] = [];\n\n // Ensure directories exist\n await ensureDir(path.join(outputDir, 'collections'));\n await ensureDir(path.join(outputDir, 'components'));\n\n // Generate utility types\n const utilsPath = path.join(outputDir, 'utils.ts');\n const strapiVersion = options.strapiVersion ?? 'v5';\n await writeFile(utilsPath, await formatCode(generateUtilityTypes(options.blocksRendererInstalled ?? false, strapiVersion)));\n generatedFiles.push(utilsPath);\n\n // Generate collection types\n for (const collection of schema.collections) {\n const fileName = `${toKebabCase(collection.singularName)}.ts`;\n const filePath = path.join(outputDir, 'collections', fileName);\n const content = generateCollectionType(collection, schema.components);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n // Generate single types\n for (const single of schema.singles) {\n const fileName = `${toKebabCase(single.singularName)}.ts`;\n const filePath = path.join(outputDir, 'collections', fileName);\n const content = generateSingleType(single, schema.components);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n // Generate component types\n for (const component of schema.components) {\n const fileName = `${toKebabCase(component.name)}.ts`;\n const filePath = path.join(outputDir, 'components', fileName);\n const content = generateComponentType(component);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n return generatedFiles;\n}\n\n/**\n * Generate utility types\n */\nfunction generateUtilityTypes(blocksRendererInstalled: boolean, strapiVersion: \"v4\" | \"v5\"): string {\n const isV4 = strapiVersion === \"v4\";\n\n const blocksContentType = isV4\n ? `/**\n * Rich text content (Strapi v4)\n * Can be markdown string or custom JSON structure\n */\nexport type RichTextContent = string;`\n : blocksRendererInstalled\n ? `/**\n * Blocks content type (Strapi v5 rich text)\n * Re-exported from @strapi/blocks-react-renderer\n */\nexport type { BlocksContent } from '@strapi/blocks-react-renderer';`\n : `/**\n * Blocks content type (Strapi v5 rich text)\n *\n * For full type support and rendering, install:\n * npm install @strapi/blocks-react-renderer\n *\n * Then re-run: npx strapi2front sync\n */\nexport type BlocksContent = unknown[];`;\n\n const baseEntity = isV4\n ? `/**\n * Base entity fields (Strapi v4)\n */\nexport interface StrapiBaseEntity {\n id: number;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n}`\n : `/**\n * Base entity fields (Strapi v5)\n */\nexport interface StrapiBaseEntity {\n id: number;\n documentId: string;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n}`;\n\n const mediaType = isV4\n ? `/**\n * Strapi media object (v4)\n */\nexport interface StrapiMedia {\n id: number;\n name: string;\n alternativeText: string | null;\n caption: string | null;\n width: number;\n height: number;\n formats: {\n thumbnail?: StrapiMediaFormat;\n small?: StrapiMediaFormat;\n medium?: StrapiMediaFormat;\n large?: StrapiMediaFormat;\n } | null;\n hash: string;\n ext: string;\n mime: string;\n size: number;\n url: string;\n previewUrl: string | null;\n provider: string;\n createdAt: string;\n updatedAt: string;\n}`\n : `/**\n * Strapi media object (v5)\n */\nexport interface StrapiMedia {\n id: number;\n documentId: string;\n name: string;\n alternativeText: string | null;\n caption: string | null;\n width: number;\n height: number;\n formats: {\n thumbnail?: StrapiMediaFormat;\n small?: StrapiMediaFormat;\n medium?: StrapiMediaFormat;\n large?: StrapiMediaFormat;\n } | null;\n hash: string;\n ext: string;\n mime: string;\n size: number;\n url: string;\n previewUrl: string | null;\n provider: string;\n createdAt: string;\n updatedAt: string;\n}`;\n\n const rawResponseTypes = isV4\n ? `\n/**\n * Strapi v4 raw API response (with nested attributes)\n */\nexport interface StrapiV4RawItem<T> {\n id: number;\n attributes: Omit<T, 'id'>;\n}\n\nexport interface StrapiV4RawResponse<T> {\n data: StrapiV4RawItem<T>;\n meta: Record<string, unknown>;\n}\n\nexport interface StrapiV4RawListResponse<T> {\n data: StrapiV4RawItem<T>[];\n meta: {\n pagination: StrapiPagination;\n };\n}\n\n/**\n * Flatten Strapi v4 response item\n */\nexport function flattenV4Response<T>(item: StrapiV4RawItem<T>): T {\n return { id: item.id, ...item.attributes } as T;\n}\n\n/**\n * Flatten Strapi v4 list response\n */\nexport function flattenV4ListResponse<T>(items: StrapiV4RawItem<T>[]): T[] {\n return items.map(item => flattenV4Response<T>(item));\n}`\n : '';\n\n return `/**\n * Strapi utility types\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${mediaType}\n\nexport interface StrapiMediaFormat {\n name: string;\n hash: string;\n ext: string;\n mime: string;\n width: number;\n height: number;\n size: number;\n url: string;\n}\n\n/**\n * Strapi pagination\n */\nexport interface StrapiPagination {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n}\n\n/**\n * Strapi response wrapper\n */\nexport interface StrapiResponse<T> {\n data: T;\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\n/**\n * Strapi list response\n */\nexport interface StrapiListResponse<T> {\n data: T[];\n meta: {\n pagination: StrapiPagination;\n };\n}\n\n${baseEntity}\n${rawResponseTypes}\n${blocksContentType}\n`;\n}\n\n/**\n * Extract dependencies (relations and components) from attributes\n */\nfunction extractDependencies(\n attributes: Record<string, Attribute>,\n selfName: string\n): { relations: Set<string>; components: Set<string> } {\n const relations = new Set<string>();\n const components = new Set<string>();\n\n for (const attr of Object.values(attributes)) {\n if (attr.type === 'relation' && 'target' in attr && attr.target) {\n const targetName = attr.target.split('.').pop() || '';\n const typeName = toPascalCase(targetName);\n // Don't import self\n if (typeName !== selfName && targetName) {\n relations.add(targetName);\n }\n }\n\n if (attr.type === 'component' && 'component' in attr && attr.component) {\n const componentName = attr.component.split('.').pop() || '';\n if (componentName) {\n components.add(componentName);\n }\n }\n\n if (attr.type === 'dynamiczone' && 'components' in attr && attr.components) {\n for (const comp of attr.components) {\n const componentName = comp.split('.').pop() || '';\n if (componentName) {\n components.add(componentName);\n }\n }\n }\n }\n\n return { relations, components };\n}\n\n/**\n * Generate import statements for dependencies\n */\nfunction generateDependencyImports(\n relations: Set<string>,\n components: Set<string>\n): string {\n const imports: string[] = [];\n\n // Import relations (other collections/singles)\n for (const relation of relations) {\n const typeName = toPascalCase(relation);\n const fileName = toKebabCase(relation);\n imports.push(`import type { ${typeName} } from './${fileName}';`);\n }\n\n // Import components\n for (const component of components) {\n const typeName = toPascalCase(component);\n const fileName = toKebabCase(component);\n imports.push(`import type { ${typeName} } from '../components/${fileName}';`);\n }\n\n return imports.join('\\n');\n}\n\n/**\n * Generate type for a collection\n */\nfunction generateCollectionType(collection: CollectionType, components: ComponentType[]): string {\n const typeName = toPascalCase(collection.singularName);\n const attributes = generateAttributes(collection.attributes, components);\n const { relations, components: componentDeps } = extractDependencies(collection.attributes, typeName);\n const dependencyImports = generateDependencyImports(relations, componentDeps);\n\n // Build utils imports based on what's actually used\n const utilsImports: string[] = ['StrapiBaseEntity'];\n const attributesStr = JSON.stringify(collection.attributes);\n if (attributesStr.includes('\"type\":\"media\"')) {\n utilsImports.push('StrapiMedia');\n }\n if (attributesStr.includes('\"type\":\"blocks\"')) {\n utilsImports.push('BlocksContent');\n }\n\n return `/**\n * ${collection.displayName}\n * ${collection.description || ''}\n * Generated by strapi2front\n */\n\nimport type { ${utilsImports.join(', ')} } from '../utils';\n${dependencyImports ? dependencyImports + '\\n' : ''}\nexport interface ${typeName} extends StrapiBaseEntity {\n${attributes}\n}\n\nexport interface ${typeName}Filters {\n id?: number | { $eq?: number; $ne?: number; $in?: number[]; $notIn?: number[] };\n documentId?: string | { $eq?: string; $ne?: string };\n createdAt?: string | { $eq?: string; $gt?: string; $gte?: string; $lt?: string; $lte?: string };\n updatedAt?: string | { $eq?: string; $gt?: string; $gte?: string; $lt?: string; $lte?: string };\n publishedAt?: string | null | { $eq?: string; $ne?: string; $null?: boolean };\n $and?: ${typeName}Filters[];\n $or?: ${typeName}Filters[];\n $not?: ${typeName}Filters;\n}\n\nexport interface ${typeName}Sort {\n field: keyof ${typeName};\n order: 'asc' | 'desc';\n}\n`;\n}\n\n/**\n * Generate type for a single type\n */\nfunction generateSingleType(single: SingleType, components: ComponentType[]): string {\n const typeName = toPascalCase(single.singularName);\n const attributes = generateAttributes(single.attributes, components);\n const { relations, components: componentDeps } = extractDependencies(single.attributes, typeName);\n const dependencyImports = generateDependencyImports(relations, componentDeps);\n\n // Build utils imports based on what's actually used\n const utilsImports: string[] = ['StrapiBaseEntity'];\n const attributesStr = JSON.stringify(single.attributes);\n if (attributesStr.includes('\"type\":\"media\"')) {\n utilsImports.push('StrapiMedia');\n }\n if (attributesStr.includes('\"type\":\"blocks\"')) {\n utilsImports.push('BlocksContent');\n }\n\n return `/**\n * ${single.displayName}\n * ${single.description || ''}\n * Generated by strapi2front\n */\n\nimport type { ${utilsImports.join(', ')} } from '../utils';\n${dependencyImports ? dependencyImports + '\\n' : ''}\nexport interface ${typeName} extends StrapiBaseEntity {\n${attributes}\n}\n`;\n}\n\n/**\n * Generate type for a component\n */\nfunction generateComponentType(component: ComponentType): string {\n const typeName = toPascalCase(component.name);\n const attributes = generateAttributes(component.attributes, []);\n const { relations, components: componentDeps } = extractDependencies(component.attributes, typeName);\n\n // For components, relations import from collections and other components import from same folder\n const imports: string[] = [];\n\n for (const relation of relations) {\n const relTypeName = toPascalCase(relation);\n const fileName = toKebabCase(relation);\n imports.push(`import type { ${relTypeName} } from '../collections/${fileName}';`);\n }\n\n for (const comp of componentDeps) {\n const compTypeName = toPascalCase(comp);\n const fileName = toKebabCase(comp);\n // Don't import self\n if (compTypeName !== typeName) {\n imports.push(`import type { ${compTypeName} } from './${fileName}';`);\n }\n }\n\n // Build utils imports based on what's actually used\n const utilsImports: string[] = [];\n const attributesStr = JSON.stringify(component.attributes);\n if (attributesStr.includes('\"type\":\"media\"')) {\n utilsImports.push('StrapiMedia');\n }\n if (attributesStr.includes('\"type\":\"blocks\"')) {\n utilsImports.push('BlocksContent');\n }\n\n const utilsImportLine = utilsImports.length > 0\n ? `import type { ${utilsImports.join(', ')} } from '../utils';\\n`\n : '';\n const dependencyImports = imports.length > 0 ? imports.join('\\n') + '\\n' : '';\n\n return `/**\n * ${component.displayName} component\n * Category: ${component.category}\n * ${component.description || ''}\n * Generated by strapi2front\n */\n\n${utilsImportLine}${dependencyImports}\nexport interface ${typeName} {\n id: number;\n${attributes}\n}\n`;\n}\n\n/**\n * Generate TypeScript properties from Strapi attributes\n */\nfunction generateAttributes(\n attributes: Record<string, Attribute>,\n components: ComponentType[]\n): string {\n const lines: string[] = [];\n\n for (const [name, attr] of Object.entries(attributes)) {\n const tsType = attributeToTsType(attr, components);\n const optional = attr.required ? '' : '?';\n const comment = getAttributeComment(attr);\n\n if (comment) {\n lines.push(` /** ${comment} */`);\n }\n lines.push(` ${name}${optional}: ${tsType};`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Convert Strapi attribute to TypeScript type\n */\nfunction attributeToTsType(attr: Attribute, _components: ComponentType[]): string {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'password':\n case 'uid':\n return 'string';\n\n case 'blocks':\n return 'BlocksContent';\n\n case 'integer':\n case 'biginteger':\n case 'float':\n case 'decimal':\n return 'number';\n\n case 'boolean':\n return 'boolean';\n\n case 'date':\n case 'time':\n case 'datetime':\n case 'timestamp':\n return 'string';\n\n case 'json':\n return 'unknown';\n\n case 'enumeration':\n if ('enum' in attr && attr.enum) {\n return attr.enum.map((v) => `'${v}'`).join(' | ');\n }\n return 'string';\n\n case 'media':\n if ('multiple' in attr && attr.multiple) {\n return 'StrapiMedia[]';\n }\n return 'StrapiMedia | null';\n\n case 'relation':\n if ('target' in attr && attr.target) {\n const targetName = toPascalCase(attr.target.split('.').pop() || 'unknown');\n const isMany = attr.relation === 'oneToMany' || attr.relation === 'manyToMany';\n return isMany ? `${targetName}[]` : `${targetName} | null`;\n }\n return 'unknown';\n\n case 'component':\n if ('component' in attr && attr.component) {\n const componentName = toPascalCase(attr.component.split('.').pop() || 'unknown');\n if ('repeatable' in attr && attr.repeatable) {\n return `${componentName}[]`;\n }\n return `${componentName} | null`;\n }\n return 'unknown';\n\n case 'dynamiczone':\n if ('components' in attr && attr.components) {\n const types = attr.components.map((c) => toPascalCase(c.split('.').pop() || 'unknown'));\n return `(${types.join(' | ')})[]`;\n }\n return 'unknown[]';\n\n default:\n return 'unknown';\n }\n}\n\n/**\n * Get comment for attribute\n */\nfunction getAttributeComment(attr: Attribute): string | null {\n const parts: string[] = [];\n\n if (attr.required) {\n parts.push('Required');\n }\n\n if ('minLength' in attr && attr.minLength !== undefined) {\n parts.push(`Min length: ${attr.minLength}`);\n }\n\n if ('maxLength' in attr && attr.maxLength !== undefined) {\n parts.push(`Max length: ${attr.maxLength}`);\n }\n\n if ('min' in attr && attr.min !== undefined) {\n parts.push(`Min: ${attr.min}`);\n }\n\n if ('max' in attr && attr.max !== undefined) {\n parts.push(`Max: ${attr.max}`);\n }\n\n return parts.length > 0 ? parts.join(', ') : null;\n}\n\n","import path from 'node:path';\nimport type { ParsedSchema, CollectionType, SingleType } from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\nimport { toPascalCase, toCamelCase, toKebabCase } from '../utils/naming.js';\n\nexport interface ServiceGeneratorOptions {\n outputDir: string;\n typesImportPath: string;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate service files from parsed schema\n */\nexport async function generateServices(\n schema: ParsedSchema,\n options: ServiceGeneratorOptions\n): Promise<string[]> {\n const { outputDir, typesImportPath, strapiVersion = \"v5\" } = options;\n const generatedFiles: string[] = [];\n\n await ensureDir(outputDir);\n\n // Generate services for collections\n for (const collection of schema.collections) {\n const fileName = `${toKebabCase(collection.singularName)}.service.ts`;\n const filePath = path.join(outputDir, fileName);\n const content = generateCollectionService(collection, typesImportPath, strapiVersion);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n // Generate services for single types\n for (const single of schema.singles) {\n const fileName = `${toKebabCase(single.singularName)}.service.ts`;\n const filePath = path.join(outputDir, fileName);\n const content = generateSingleService(single, typesImportPath, strapiVersion);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n return generatedFiles;\n}\n\n/**\n * Generate service for a collection type\n */\nfunction generateCollectionService(collection: CollectionType, typesImportPath: string, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(collection.singularName);\n const serviceName = toCamelCase(collection.singularName) + 'Service';\n const fileName = toKebabCase(collection.singularName);\n const endpoint = collection.pluralName;\n const isV4 = strapiVersion === \"v4\";\n\n // V4 uses `id: number`, V5 uses `documentId: string`\n const idParam = isV4 ? 'id: number' : 'documentId: string';\n const idName = isV4 ? 'id' : 'documentId';\n const omitFields = isV4\n ? \"'id' | 'createdAt' | 'updatedAt' | 'publishedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt' | 'publishedAt'\";\n\n // Feature flags\n const hasSlug = 'slug' in collection.attributes;\n const { localized, draftAndPublish } = collection;\n\n // Build imports\n const imports: string[] = [\n `import { collection } from '../client';`,\n `import type { ${typeName}, ${typeName}Filters } from '${typesImportPath}/collections/${fileName}';`,\n `import type { StrapiPagination } from '${typesImportPath}/utils';`,\n ];\n if (localized) {\n imports.push(`import type { Locale } from '../locales';`);\n }\n\n // Build FindManyOptions interface\n const findManyOptionsFields: string[] = [\n ` filters?: ${typeName}Filters;`,\n ` pagination?: {`,\n ` /** Page number (1-indexed) - use with pageSize */`,\n ` page?: number;`,\n ` /** Number of items per page (default: 25) - use with page */`,\n ` pageSize?: number;`,\n ` /** Offset to start from (0-indexed) - use with limit */`,\n ` start?: number;`,\n ` /** Maximum number of items to return - use with start */`,\n ` limit?: number;`,\n ` };`,\n ` sort?: string | string[];`,\n ` populate?: string | string[] | Record<string, unknown>;`,\n ];\n if (localized) {\n findManyOptionsFields.push(` locale?: Locale;`);\n }\n if (draftAndPublish) {\n findManyOptionsFields.push(` status?: 'draft' | 'published';`);\n }\n\n // Build FindOneOptions interface\n const findOneOptionsFields: string[] = [\n ` populate?: string | string[] | Record<string, unknown>;`,\n ];\n if (localized) {\n findOneOptionsFields.push(` locale?: Locale;`);\n }\n if (draftAndPublish) {\n findOneOptionsFields.push(` status?: 'draft' | 'published';`);\n }\n\n // Build find params\n const findParams: string[] = [\n ` filters: options.filters,`,\n ` pagination: options.pagination,`,\n ` sort: options.sort,`,\n ` populate: options.populate,`,\n ];\n if (localized) {\n findParams.push(` locale: options.locale,`);\n }\n if (draftAndPublish) {\n findParams.push(` status: options.status,`);\n }\n\n // Build findOne params\n const findOneParams: string[] = [\n ` populate: options.populate,`,\n ];\n if (localized) {\n findOneParams.push(` locale: options.locale,`);\n }\n if (draftAndPublish) {\n findOneParams.push(` status: options.status,`);\n }\n\n // Build findBySlug params\n const findBySlugParams: string[] = [\n ` populate: options.populate,`,\n ];\n if (localized) {\n findBySlugParams.push(` locale: options.locale,`);\n }\n if (draftAndPublish) {\n findBySlugParams.push(` status: options.status,`);\n }\n\n return `/**\n * ${collection.displayName} Service\n * ${collection.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${imports.join('\\n')}\n\nexport interface FindManyOptions {\n${findManyOptionsFields.join('\\n')}\n}\n\nexport interface FindOneOptions {\n${findOneOptionsFields.join('\\n')}\n}\n\n// Create typed collection helper\nconst ${toCamelCase(collection.singularName)}Collection = collection<${typeName}>('${endpoint}');\n\nexport const ${serviceName} = {\n /**\n * Find multiple ${collection.pluralName}\n */\n async findMany(options: FindManyOptions = {}): Promise<{ data: ${typeName}[]; pagination: StrapiPagination }> {\n const response = await ${toCamelCase(collection.singularName)}Collection.find({\n${findParams.join('\\n')}\n });\n\n return {\n data: response.data,\n pagination: response.meta.pagination,\n };\n },\n\n /**\n * Find all ${collection.pluralName} (handles pagination automatically)\n */\n async findAll(options: Omit<FindManyOptions, 'pagination'> = {}): Promise<${typeName}[]> {\n const allItems: ${typeName}[] = [];\n let page = 1;\n let hasMore = true;\n\n while (hasMore) {\n const { data, pagination } = await this.findMany({\n ...options,\n pagination: { page, pageSize: 100 },\n });\n\n allItems.push(...data);\n hasMore = page < pagination.pageCount;\n page++;\n }\n\n return allItems;\n },\n\n /**\n * Find one ${collection.singularName} by ${idName}\n */\n async findOne(${idParam}, options: FindOneOptions = {}): Promise<${typeName} | null> {\n try {\n const response = await ${toCamelCase(collection.singularName)}Collection.findOne(${idName}, {\n${findOneParams.join('\\n')}\n });\n\n return response.data;\n } catch (error) {\n // Return null if not found\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw error;\n }\n },\n${hasSlug ? `\n /**\n * Find one ${collection.singularName} by slug\n */\n async findBySlug(slug: string, options: FindOneOptions = {}): Promise<${typeName} | null> {\n const { data } = await this.findMany({\n filters: { slug: { $eq: slug } } as ${typeName}Filters,\n pagination: { pageSize: 1 },\n${findBySlugParams.join('\\n')}\n });\n\n return data[0] || null;\n },\n` : ''}\n /**\n * Create a new ${collection.singularName}\n */\n async create(data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(collection.singularName)}Collection.create({ data });\n return response.data;\n },\n\n /**\n * Update a ${collection.singularName}\n */\n async update(${idParam}, data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(collection.singularName)}Collection.update(${idName}, { data });\n return response.data;\n },\n\n /**\n * Delete a ${collection.singularName}\n */\n async delete(${idParam}): Promise<void> {\n await ${toCamelCase(collection.singularName)}Collection.delete(${idName});\n },\n\n /**\n * Count ${collection.pluralName}\n */\n async count(filters?: ${typeName}Filters): Promise<number> {\n const { pagination } = await this.findMany({\n filters,\n pagination: { pageSize: 1 },\n });\n\n return pagination.total;\n },\n};\n`;\n}\n\n/**\n * Generate service for a single type\n */\nfunction generateSingleService(single: SingleType, typesImportPath: string, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(single.singularName);\n const serviceName = toCamelCase(single.singularName) + 'Service';\n const fileName = toKebabCase(single.singularName);\n const endpoint = single.singularName;\n const isV4 = strapiVersion === \"v4\";\n\n // V4 doesn't have documentId\n const omitFields = isV4\n ? \"'id' | 'createdAt' | 'updatedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt'\";\n\n // Feature flags\n const { localized, draftAndPublish } = single;\n\n // Build imports\n const imports: string[] = [\n `import { single } from '../client';`,\n `import type { ${typeName} } from '${typesImportPath}/collections/${fileName}';`,\n ];\n if (localized) {\n imports.push(`import type { Locale } from '../locales';`);\n }\n\n // Build FindOptions interface\n const findOptionsFields: string[] = [\n ` populate?: string | string[] | Record<string, unknown>;`,\n ];\n if (localized) {\n findOptionsFields.push(` locale?: Locale;`);\n }\n if (draftAndPublish) {\n findOptionsFields.push(` status?: 'draft' | 'published';`);\n }\n\n // Build find params\n const findParams: string[] = [\n ` populate: options.populate,`,\n ];\n if (localized) {\n findParams.push(` locale: options.locale,`);\n }\n if (draftAndPublish) {\n findParams.push(` status: options.status,`);\n }\n\n return `/**\n * ${single.displayName} Service (Single Type)\n * ${single.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${imports.join('\\n')}\n\nexport interface FindOptions {\n${findOptionsFields.join('\\n')}\n}\n\n// Create typed single helper\nconst ${toCamelCase(single.singularName)}Single = single<${typeName}>('${endpoint}');\n\nexport const ${serviceName} = {\n /**\n * Get ${single.displayName}\n */\n async find(options: FindOptions = {}): Promise<${typeName} | null> {\n try {\n const response = await ${toCamelCase(single.singularName)}Single.find({\n${findParams.join('\\n')}\n });\n\n return response.data;\n } catch (error) {\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw error;\n }\n },\n\n /**\n * Update ${single.displayName}\n */\n async update(data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(single.singularName)}Single.update({ data });\n return response.data;\n },\n\n /**\n * Delete ${single.displayName}\n */\n async delete(): Promise<void> {\n await ${toCamelCase(single.singularName)}Single.delete();\n },\n};\n`;\n}\n\n","import path from 'node:path';\nimport type { ParsedSchema, CollectionType, SingleType } from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\nimport { toCamelCase, toKebabCase } from '../utils/naming.js';\n\nexport interface ActionsGeneratorOptions {\n outputDir: string;\n servicesImportPath: string;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate Astro Actions from parsed schema\n */\nexport async function generateActions(\n schema: ParsedSchema,\n options: ActionsGeneratorOptions\n): Promise<string[]> {\n const { outputDir, servicesImportPath, strapiVersion = \"v5\" } = options;\n const generatedFiles: string[] = [];\n\n await ensureDir(outputDir);\n\n // Generate actions for collections\n for (const collection of schema.collections) {\n const fileName = `${toKebabCase(collection.singularName)}.ts`;\n const filePath = path.join(outputDir, fileName);\n const content = generateCollectionActions(collection, servicesImportPath, strapiVersion);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n // Generate actions for single types\n for (const single of schema.singles) {\n const fileName = `${toKebabCase(single.singularName)}.ts`;\n const filePath = path.join(outputDir, fileName);\n const content = generateSingleActions(single, servicesImportPath);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n return generatedFiles;\n}\n\n/**\n * Generate actions for a collection type\n */\nfunction generateCollectionActions(\n collection: CollectionType,\n servicesImportPath: string,\n strapiVersion: \"v4\" | \"v5\"\n): string {\n const serviceName = toCamelCase(collection.singularName) + 'Service';\n const actionsName = toCamelCase(collection.singularName);\n const fileName = toKebabCase(collection.singularName);\n const isV4 = strapiVersion === \"v4\";\n\n // V4 uses `id: number`, V5 uses `documentId: string`\n const idInputSchema = isV4 ? 'z.number().int().positive()' : 'z.string().min(1)';\n const idParamName = isV4 ? 'id' : 'documentId';\n const idComment = isV4 ? 'id' : 'documentId';\n\n // Detect if collection has a slug field\n const hasSlug = 'slug' in collection.attributes;\n\n return `/**\n * ${collection.displayName} Actions\n * ${collection.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\nimport { defineAction, ActionError } from 'astro:actions';\nimport { z } from 'astro:schema';\nimport { ${serviceName} } from '${servicesImportPath}/${fileName}.service';\n\n/**\n * Pagination input schema\n */\nconst paginationSchema = z.object({\n page: z.number().int().positive().optional().default(1),\n pageSize: z.number().int().positive().max(100).optional().default(25),\n}).optional();\n\n/**\n * ${collection.displayName} actions\n */\nexport const ${actionsName} = {\n /**\n * Get all ${collection.pluralName} with pagination\n */\n getAll: defineAction({\n input: z.object({\n pagination: paginationSchema,\n sort: z.union([z.string(), z.array(z.string())]).optional(),\n }).optional(),\n handler: async (input) => {\n try {\n const result = await ${serviceName}.findMany({\n pagination: input?.pagination,\n sort: input?.sort,\n });\n\n return result;\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to fetch ${collection.pluralName}',\n });\n }\n },\n }),\n\n /**\n * Get a single ${collection.singularName} by ${idComment}\n */\n getOne: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n populate: z.union([z.string(), z.array(z.string())]).optional(),\n }),\n handler: async ({ ${idParamName}, populate }) => {\n try {\n const result = await ${serviceName}.findOne(${idParamName}, { populate });\n\n if (!result) {\n throw new ActionError({\n code: 'NOT_FOUND',\n message: '${collection.displayName} not found',\n });\n }\n\n return result;\n } catch (error) {\n if (error instanceof ActionError) throw error;\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to fetch ${collection.singularName}',\n });\n }\n },\n }),\n${hasSlug ? `\n /**\n * Get a single ${collection.singularName} by slug\n */\n getBySlug: defineAction({\n input: z.object({\n slug: z.string().min(1),\n populate: z.union([z.string(), z.array(z.string())]).optional(),\n }),\n handler: async ({ slug, populate }) => {\n try {\n const result = await ${serviceName}.findBySlug(slug, { populate });\n\n if (!result) {\n throw new ActionError({\n code: 'NOT_FOUND',\n message: '${collection.displayName} not found',\n });\n }\n\n return result;\n } catch (error) {\n if (error instanceof ActionError) throw error;\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to fetch ${collection.singularName}',\n });\n }\n },\n }),\n` : ''}\n /**\n * Create a new ${collection.singularName}\n */\n create: defineAction({\n input: z.object({\n data: z.record(z.unknown()),\n }),\n handler: async ({ data }) => {\n try {\n const result = await ${serviceName}.create(data);\n return result;\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to create ${collection.singularName}',\n });\n }\n },\n }),\n\n /**\n * Update a ${collection.singularName}\n */\n update: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n data: z.record(z.unknown()),\n }),\n handler: async ({ ${idParamName}, data }) => {\n try {\n const result = await ${serviceName}.update(${idParamName}, data);\n return result;\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to update ${collection.singularName}',\n });\n }\n },\n }),\n\n /**\n * Delete a ${collection.singularName}\n */\n delete: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n }),\n handler: async ({ ${idParamName} }) => {\n try {\n await ${serviceName}.delete(${idParamName});\n return { success: true };\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to delete ${collection.singularName}',\n });\n }\n },\n }),\n\n /**\n * Count ${collection.pluralName}\n */\n count: defineAction({\n input: z.object({\n filters: z.record(z.unknown()).optional(),\n }).optional(),\n handler: async (input) => {\n try {\n const count = await ${serviceName}.count(input?.filters as any);\n return { count };\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to count ${collection.pluralName}',\n });\n }\n },\n }),\n};\n`;\n}\n\n/**\n * Generate actions for a single type\n */\nfunction generateSingleActions(\n single: SingleType,\n servicesImportPath: string\n): string {\n const serviceName = toCamelCase(single.singularName) + 'Service';\n const actionsName = toCamelCase(single.singularName);\n const fileName = toKebabCase(single.singularName);\n\n return `/**\n * ${single.displayName} Actions (Single Type)\n * ${single.description || ''}\n * Generated by strapi2front\n */\n\nimport { defineAction, ActionError } from 'astro:actions';\nimport { z } from 'astro:schema';\nimport { ${serviceName} } from '${servicesImportPath}/${fileName}.service';\n\n/**\n * ${single.displayName} actions\n */\nexport const ${actionsName} = {\n /**\n * Get ${single.displayName}\n */\n get: defineAction({\n input: z.object({\n populate: z.union([z.string(), z.array(z.string())]).optional(),\n }).optional(),\n handler: async (input) => {\n try {\n const result = await ${serviceName}.find({\n populate: input?.populate,\n });\n\n if (!result) {\n throw new ActionError({\n code: 'NOT_FOUND',\n message: '${single.displayName} not found',\n });\n }\n\n return result;\n } catch (error) {\n if (error instanceof ActionError) throw error;\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to fetch ${single.singularName}',\n });\n }\n },\n }),\n\n /**\n * Update ${single.displayName}\n */\n update: defineAction({\n input: z.object({\n data: z.record(z.unknown()),\n }),\n handler: async ({ data }) => {\n try {\n const result = await ${serviceName}.update(data);\n return result;\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to update ${single.singularName}',\n });\n }\n },\n }),\n};\n`;\n}\n\n","import path from 'node:path';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\n\nexport interface ClientGeneratorOptions {\n outputDir: string;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate the Strapi client file\n */\nexport async function generateClient(\n options: ClientGeneratorOptions\n): Promise<string[]> {\n const { outputDir, strapiVersion = \"v5\" } = options;\n const generatedFiles: string[] = [];\n\n await ensureDir(outputDir);\n\n const filePath = path.join(outputDir, 'client.ts');\n const content = generateClientFile(strapiVersion);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n\n return generatedFiles;\n}\n\n/**\n * Generate the client file content\n */\nfunction generateClientFile(strapiVersion: \"v4\" | \"v5\"): string {\n const isV4 = strapiVersion === \"v4\";\n\n if (isV4) {\n return generateV4ClientFile();\n }\n return generateV5ClientFile();\n}\n\n/**\n * Generate client for Strapi v5 (flat response structure)\n */\nfunction generateV5ClientFile(): string {\n return `/**\n * Strapi Client (v5)\n * Generated by strapi2front\n */\n\nimport Strapi from 'strapi-sdk-js';\n\n// Initialize the Strapi client\nconst strapiUrl = import.meta.env.STRAPI_URL || process.env.STRAPI_URL || 'http://localhost:1337';\nconst strapiToken = import.meta.env.STRAPI_TOKEN || process.env.STRAPI_TOKEN;\n\nexport const strapi = new Strapi({\n url: strapiUrl,\n axiosOptions: {\n headers: strapiToken ? {\n Authorization: \\`Bearer \\${strapiToken}\\`,\n } : {},\n },\n});\n\n// Pagination type\nexport interface StrapiPagination {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n}\n\n// Default pagination for fallback\nconst defaultPagination: StrapiPagination = {\n page: 1,\n pageSize: 25,\n pageCount: 1,\n total: 0,\n};\n\n// Response types\ninterface StrapiListResponse<T> {\n data: T[];\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\ninterface StrapiSingleResponse<T> {\n data: T;\n meta?: Record<string, unknown>;\n}\n\n// Helper to get typed collection\nexport function collection<T>(pluralName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T[]; meta: { pagination: StrapiPagination } }> {\n const response = await strapi.find(pluralName, params) as unknown as StrapiListResponse<T>;\n return {\n data: Array.isArray(response.data) ? response.data : [],\n meta: {\n pagination: response.meta?.pagination || defaultPagination,\n },\n };\n },\n async findOne(documentId: string, params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.findOne(pluralName, documentId, params) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async create(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.create(pluralName, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async update(documentId: string, data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(pluralName, documentId, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async delete(documentId: string): Promise<void> {\n await strapi.delete(pluralName, documentId);\n },\n };\n}\n\n// Helper to get typed single type\nexport function single<T>(singularName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.find(singularName, params) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async update(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(singularName, 1 as unknown as string, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async delete(): Promise<void> {\n await strapi.delete(singularName, 1 as unknown as string);\n },\n };\n}\n`;\n}\n\n/**\n * Generate client for Strapi v4 (nested attributes structure)\n */\nfunction generateV4ClientFile(): string {\n return `/**\n * Strapi Client (v4)\n * Generated by strapi2front\n */\n\nimport Strapi from 'strapi-sdk-js';\n\n// Initialize the Strapi client\nconst strapiUrl = import.meta.env.STRAPI_URL || process.env.STRAPI_URL || 'http://localhost:1337';\nconst strapiToken = import.meta.env.STRAPI_TOKEN || process.env.STRAPI_TOKEN;\n\nexport const strapi = new Strapi({\n url: strapiUrl,\n axiosOptions: {\n headers: strapiToken ? {\n Authorization: \\`Bearer \\${strapiToken}\\`,\n } : {},\n },\n});\n\n// Pagination type\nexport interface StrapiPagination {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n}\n\n// Default pagination for fallback\nconst defaultPagination: StrapiPagination = {\n page: 1,\n pageSize: 25,\n pageCount: 1,\n total: 0,\n};\n\n// Strapi v4 raw response types (with nested attributes)\ninterface StrapiV4RawItem<T> {\n id: number;\n attributes: Omit<T, 'id'>;\n}\n\ninterface StrapiV4RawListResponse<T> {\n data: StrapiV4RawItem<T>[];\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\ninterface StrapiV4RawSingleResponse<T> {\n data: StrapiV4RawItem<T>;\n meta?: Record<string, unknown>;\n}\n\n/**\n * Flatten a Strapi v4 response item (merges id with attributes)\n */\nfunction flattenItem<T>(item: StrapiV4RawItem<T>): T {\n return { id: item.id, ...item.attributes } as T;\n}\n\n/**\n * Recursively flatten nested relations in Strapi v4 response\n */\nfunction flattenRelations<T>(data: T): T {\n if (data === null || data === undefined) return data;\n if (Array.isArray(data)) {\n return data.map(item => flattenRelations(item)) as unknown as T;\n }\n if (typeof data === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n // Check if this is a Strapi v4 relation response { data: { id, attributes } }\n if (value && typeof value === 'object' && 'data' in value) {\n const relationData = (value as { data: unknown }).data;\n if (relationData === null) {\n result[key] = null;\n } else if (Array.isArray(relationData)) {\n // To-many relation\n result[key] = relationData.map((item: StrapiV4RawItem<unknown>) =>\n flattenRelations(flattenItem(item))\n );\n } else if (typeof relationData === 'object' && 'id' in relationData && 'attributes' in relationData) {\n // To-one relation\n result[key] = flattenRelations(flattenItem(relationData as StrapiV4RawItem<unknown>));\n } else {\n result[key] = flattenRelations(value);\n }\n } else {\n result[key] = flattenRelations(value);\n }\n }\n return result as T;\n }\n return data;\n}\n\n// Helper to get typed collection\nexport function collection<T>(pluralName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T[]; meta: { pagination: StrapiPagination } }> {\n const response = await strapi.find(pluralName, params) as unknown as StrapiV4RawListResponse<T>;\n const flattenedData = Array.isArray(response.data)\n ? response.data.map(item => flattenRelations(flattenItem<T>(item)))\n : [];\n return {\n data: flattenedData,\n meta: {\n pagination: response.meta?.pagination || defaultPagination,\n },\n };\n },\n async findOne(id: number | string, params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.findOne(pluralName, String(id), params) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async create(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.create(pluralName, data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async update(id: number | string, data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(pluralName, String(id), data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async delete(id: number | string): Promise<void> {\n await strapi.delete(pluralName, String(id));\n },\n };\n}\n\n// Helper to get typed single type\nexport function single<T>(singularName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.find(singularName, params) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async update(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(singularName, 1 as unknown as string, data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async delete(): Promise<void> {\n await strapi.delete(singularName, 1 as unknown as string);\n },\n };\n}\n`;\n}\n","import path from 'node:path';\nimport type { StrapiLocale } from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\n\nexport interface LocalesGeneratorOptions {\n outputDir: string;\n}\n\n/**\n * Generate locales file from Strapi i18n configuration\n */\nexport async function generateLocales(\n locales: StrapiLocale[],\n options: LocalesGeneratorOptions\n): Promise<string[]> {\n const { outputDir } = options;\n const generatedFiles: string[] = [];\n\n await ensureDir(outputDir);\n\n const filePath = path.join(outputDir, 'locales.ts');\n const content = generateLocalesFile(locales);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n\n return generatedFiles;\n}\n\n/**\n * Generate the locales file content\n */\nfunction generateLocalesFile(locales: StrapiLocale[]): string {\n if (locales.length === 0) {\n return `/**\n * Strapi Locales\n * Generated by strapi2front\n *\n * Note: No locales found. i18n might not be enabled in Strapi.\n */\n\nexport const locales = [] as const;\n\nexport type Locale = string;\n\nexport const defaultLocale: Locale = 'en';\n\nexport const localeNames: Record<string, string> = {};\n`;\n }\n\n const defaultLocale = locales.find(l => l.isDefault)?.code || locales[0]?.code || 'en';\n const localeCodes = locales.map(l => `'${l.code}'`).join(' | ');\n const localeArray = locales.map(l => `'${l.code}'`).join(', ');\n const localeNames = locales.map(l => ` '${l.code}': '${l.name}'`).join(',\\n');\n\n return `/**\n * Strapi Locales\n * Generated by strapi2front\n */\n\n/**\n * Available locale codes\n */\nexport const locales = [${localeArray}] as const;\n\n/**\n * Locale type - union of all available locales\n */\nexport type Locale = ${localeCodes};\n\n/**\n * Default locale\n */\nexport const defaultLocale: Locale = '${defaultLocale}';\n\n/**\n * Locale display names\n */\nexport const localeNames: Record<Locale, string> = {\n${localeNames}\n};\n\n/**\n * Check if a string is a valid locale\n */\nexport function isValidLocale(code: string): code is Locale {\n return locales.includes(code as Locale);\n}\n\n/**\n * Get locale name by code\n */\nexport function getLocaleName(code: Locale): string {\n return localeNames[code] || code;\n}\n`;\n}\n","import path from 'node:path';\nimport type {\n ParsedSchema,\n CollectionType,\n SingleType,\n ComponentType,\n Attribute,\n StrapiLocale,\n} from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\nimport { toPascalCase, toCamelCase, toKebabCase } from '../utils/naming.js';\n\nexport interface ByFeatureGeneratorOptions {\n outputDir: string;\n features: {\n types: boolean;\n services: boolean;\n actions: boolean;\n };\n blocksRendererInstalled?: boolean;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate all files using 'by-feature' structure\n *\n * Output structure:\n * strapi/\n * collections/\n * article/\n * types.ts\n * service.ts\n * actions.ts\n * singles/\n * homepage/\n * types.ts\n * service.ts\n * components/\n * seo.ts\n * shared/\n * utils.ts\n * client.ts\n * locales.ts\n */\nexport async function generateByFeature(\n schema: ParsedSchema,\n locales: StrapiLocale[],\n options: ByFeatureGeneratorOptions\n): Promise<string[]> {\n const { outputDir, features, blocksRendererInstalled = false, strapiVersion = \"v5\" } = options;\n const generatedFiles: string[] = [];\n\n // Ensure directories exist\n await ensureDir(path.join(outputDir, 'collections'));\n await ensureDir(path.join(outputDir, 'singles'));\n await ensureDir(path.join(outputDir, 'components'));\n await ensureDir(path.join(outputDir, 'shared'));\n\n // Generate shared files\n const sharedDir = path.join(outputDir, 'shared');\n\n // Utils\n const utilsPath = path.join(sharedDir, 'utils.ts');\n await writeFile(utilsPath, await formatCode(generateUtilityTypes(blocksRendererInstalled, strapiVersion)));\n generatedFiles.push(utilsPath);\n\n // Client\n const clientPath = path.join(sharedDir, 'client.ts');\n await writeFile(clientPath, await formatCode(generateClient(strapiVersion)));\n generatedFiles.push(clientPath);\n\n // Locales\n const localesPath = path.join(sharedDir, 'locales.ts');\n await writeFile(localesPath, await formatCode(generateLocalesFile(locales)));\n generatedFiles.push(localesPath);\n\n // Generate collection files\n for (const collection of schema.collections) {\n const featureDir = path.join(outputDir, 'collections', toKebabCase(collection.singularName));\n await ensureDir(featureDir);\n\n if (features.types) {\n const typesPath = path.join(featureDir, 'types.ts');\n await writeFile(typesPath, await formatCode(generateCollectionTypes(collection, schema)));\n generatedFiles.push(typesPath);\n }\n\n if (features.services) {\n const servicePath = path.join(featureDir, 'service.ts');\n await writeFile(servicePath, await formatCode(generateCollectionService(collection, strapiVersion)));\n generatedFiles.push(servicePath);\n }\n\n if (features.actions) {\n const actionsPath = path.join(featureDir, 'actions.ts');\n await writeFile(actionsPath, await formatCode(generateCollectionActions(collection, strapiVersion)));\n generatedFiles.push(actionsPath);\n }\n }\n\n // Generate single type files\n for (const single of schema.singles) {\n const featureDir = path.join(outputDir, 'singles', toKebabCase(single.singularName));\n await ensureDir(featureDir);\n\n if (features.types) {\n const typesPath = path.join(featureDir, 'types.ts');\n await writeFile(typesPath, await formatCode(generateSingleTypes(single, schema)));\n generatedFiles.push(typesPath);\n }\n\n if (features.services) {\n const servicePath = path.join(featureDir, 'service.ts');\n await writeFile(servicePath, await formatCode(generateSingleService(single, strapiVersion)));\n generatedFiles.push(servicePath);\n }\n }\n\n // Generate component files\n for (const component of schema.components) {\n const componentPath = path.join(outputDir, 'components', `${toKebabCase(component.name)}.ts`);\n await writeFile(componentPath, await formatCode(generateComponentTypes(component, schema)));\n generatedFiles.push(componentPath);\n }\n\n return generatedFiles;\n}\n\n// ============================================\n// Shared Files Generation\n// ============================================\n\nfunction generateUtilityTypes(blocksRendererInstalled: boolean, strapiVersion: \"v4\" | \"v5\"): string {\n const isV4 = strapiVersion === \"v4\";\n\n const blocksContentType = isV4\n ? `/**\n * Rich text content (Strapi v4)\n * Can be markdown string or custom JSON structure\n */\nexport type RichTextContent = string;`\n : blocksRendererInstalled\n ? `/**\n * Blocks content type (Strapi v5 rich text)\n * Re-exported from @strapi/blocks-react-renderer\n */\nexport type { BlocksContent } from '@strapi/blocks-react-renderer';`\n : `/**\n * Blocks content type (Strapi v5 rich text)\n *\n * For full type support and rendering, install:\n * npm install @strapi/blocks-react-renderer\n *\n * Then re-run: npx strapi2front sync\n */\nexport type BlocksContent = unknown[];`;\n\n const baseEntity = isV4\n ? `export interface StrapiBaseEntity {\n id: number;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n}`\n : `export interface StrapiBaseEntity {\n id: number;\n documentId: string;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n}`;\n\n const mediaType = isV4\n ? `export interface StrapiMedia {\n id: number;\n name: string;\n alternativeText: string | null;\n caption: string | null;\n width: number;\n height: number;\n formats: {\n thumbnail?: StrapiMediaFormat;\n small?: StrapiMediaFormat;\n medium?: StrapiMediaFormat;\n large?: StrapiMediaFormat;\n } | null;\n hash: string;\n ext: string;\n mime: string;\n size: number;\n url: string;\n previewUrl: string | null;\n provider: string;\n createdAt: string;\n updatedAt: string;\n}`\n : `export interface StrapiMedia {\n id: number;\n documentId: string;\n name: string;\n alternativeText: string | null;\n caption: string | null;\n width: number;\n height: number;\n formats: {\n thumbnail?: StrapiMediaFormat;\n small?: StrapiMediaFormat;\n medium?: StrapiMediaFormat;\n large?: StrapiMediaFormat;\n } | null;\n hash: string;\n ext: string;\n mime: string;\n size: number;\n url: string;\n previewUrl: string | null;\n provider: string;\n createdAt: string;\n updatedAt: string;\n}`;\n\n const v4RawResponseTypes = isV4 ? `\n\n/**\n * Strapi v4 raw API response (with nested attributes)\n */\nexport interface StrapiV4RawItem<T> {\n id: number;\n attributes: Omit<T, 'id'>;\n}\n\nexport interface StrapiV4RawResponse<T> {\n data: StrapiV4RawItem<T>;\n meta: Record<string, unknown>;\n}\n\nexport interface StrapiV4RawListResponse<T> {\n data: StrapiV4RawItem<T>[];\n meta: {\n pagination: StrapiPagination;\n };\n}\n\n/**\n * Flatten Strapi v4 response item\n */\nexport function flattenV4Response<T>(item: StrapiV4RawItem<T>): T {\n return { id: item.id, ...item.attributes } as T;\n}\n\n/**\n * Flatten Strapi v4 list response\n */\nexport function flattenV4ListResponse<T>(items: StrapiV4RawItem<T>[]): T[] {\n return items.map(item => flattenV4Response<T>(item));\n}` : '';\n\n return `/**\n * Strapi utility types\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${mediaType}\n\nexport interface StrapiMediaFormat {\n name: string;\n hash: string;\n ext: string;\n mime: string;\n width: number;\n height: number;\n size: number;\n url: string;\n}\n\nexport interface StrapiPagination {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n}\n\nexport interface StrapiResponse<T> {\n data: T;\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\nexport interface StrapiListResponse<T> {\n data: T[];\n meta: {\n pagination: StrapiPagination;\n };\n}\n\n${baseEntity}\n${v4RawResponseTypes}\n${blocksContentType}\n`;\n}\n\nfunction generateClient(strapiVersion: \"v4\" | \"v5\"): string {\n const isV4 = strapiVersion === \"v4\";\n\n if (isV4) {\n return `/**\n * Strapi Client (v4)\n * Generated by strapi2front\n */\n\nimport Strapi from 'strapi-sdk-js';\nimport type { StrapiPagination } from './utils';\n\n// Initialize the Strapi client\nconst strapiUrl = import.meta.env.STRAPI_URL || process.env.STRAPI_URL || 'http://localhost:1337';\nconst strapiToken = import.meta.env.STRAPI_TOKEN || process.env.STRAPI_TOKEN;\n\nexport const strapi = new Strapi({\n url: strapiUrl,\n axiosOptions: {\n headers: strapiToken ? {\n Authorization: \\`Bearer \\${strapiToken}\\`,\n } : {},\n },\n});\n\n// Default pagination for fallback\nconst defaultPagination: StrapiPagination = {\n page: 1,\n pageSize: 25,\n pageCount: 1,\n total: 0,\n};\n\n// Strapi v4 raw response types (with nested attributes)\ninterface StrapiV4RawItem<T> {\n id: number;\n attributes: Omit<T, 'id'>;\n}\n\ninterface StrapiV4RawListResponse<T> {\n data: StrapiV4RawItem<T>[];\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\ninterface StrapiV4RawSingleResponse<T> {\n data: StrapiV4RawItem<T>;\n meta?: Record<string, unknown>;\n}\n\n/**\n * Flatten a Strapi v4 response item (merges id with attributes)\n */\nfunction flattenItem<T>(item: StrapiV4RawItem<T>): T {\n return { id: item.id, ...item.attributes } as T;\n}\n\n/**\n * Recursively flatten nested relations in Strapi v4 response\n */\nfunction flattenRelations<T>(data: T): T {\n if (data === null || data === undefined) return data;\n if (Array.isArray(data)) {\n return data.map(item => flattenRelations(item)) as unknown as T;\n }\n if (typeof data === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n // Check if this is a Strapi v4 relation response { data: { id, attributes } }\n if (value && typeof value === 'object' && 'data' in value) {\n const relationData = (value as { data: unknown }).data;\n if (relationData === null) {\n result[key] = null;\n } else if (Array.isArray(relationData)) {\n // To-many relation\n result[key] = relationData.map((item: StrapiV4RawItem<unknown>) =>\n flattenRelations(flattenItem(item))\n );\n } else if (typeof relationData === 'object' && 'id' in relationData && 'attributes' in relationData) {\n // To-one relation\n result[key] = flattenRelations(flattenItem(relationData as StrapiV4RawItem<unknown>));\n } else {\n result[key] = flattenRelations(value);\n }\n } else {\n result[key] = flattenRelations(value);\n }\n }\n return result as T;\n }\n return data;\n}\n\n// Helper to get typed collection\nexport function collection<T>(pluralName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T[]; meta: { pagination: StrapiPagination } }> {\n const response = await strapi.find(pluralName, params) as unknown as StrapiV4RawListResponse<T>;\n const flattenedData = Array.isArray(response.data)\n ? response.data.map(item => flattenRelations(flattenItem<T>(item)))\n : [];\n return {\n data: flattenedData,\n meta: {\n pagination: response.meta?.pagination || defaultPagination,\n },\n };\n },\n async findOne(id: number | string, params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.findOne(pluralName, String(id), params) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async create(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.create(pluralName, data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async update(id: number | string, data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(pluralName, String(id), data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async delete(id: number | string): Promise<void> {\n await strapi.delete(pluralName, String(id));\n },\n };\n}\n\n// Helper to get typed single type\nexport function single<T>(singularName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.find(singularName, params) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async update(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(singularName, 1 as unknown as string, data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async delete(): Promise<void> {\n await strapi.delete(singularName, 1 as unknown as string);\n },\n };\n}\n`;\n }\n\n return `/**\n * Strapi Client (v5)\n * Generated by strapi2front\n */\n\nimport Strapi from 'strapi-sdk-js';\nimport type { StrapiPagination } from './utils';\n\n// Initialize the Strapi client\nconst strapiUrl = import.meta.env.STRAPI_URL || process.env.STRAPI_URL || 'http://localhost:1337';\nconst strapiToken = import.meta.env.STRAPI_TOKEN || process.env.STRAPI_TOKEN;\n\nexport const strapi = new Strapi({\n url: strapiUrl,\n axiosOptions: {\n headers: strapiToken ? {\n Authorization: \\`Bearer \\${strapiToken}\\`,\n } : {},\n },\n});\n\n// Default pagination for fallback\nconst defaultPagination: StrapiPagination = {\n page: 1,\n pageSize: 25,\n pageCount: 1,\n total: 0,\n};\n\n// Response types from strapi-sdk-js\ninterface StrapiListResponse<T> {\n data: T[];\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\ninterface StrapiSingleResponse<T> {\n data: T;\n meta?: Record<string, unknown>;\n}\n\n// Helper to get typed collection\nexport function collection<T>(pluralName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T[]; meta: { pagination: StrapiPagination } }> {\n const response = await strapi.find(pluralName, params) as unknown as StrapiListResponse<T>;\n return {\n data: Array.isArray(response.data) ? response.data : [],\n meta: {\n pagination: response.meta?.pagination || defaultPagination,\n },\n };\n },\n async findOne(documentId: string, params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.findOne(pluralName, documentId, params) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async create(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.create(pluralName, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async update(documentId: string, data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(pluralName, documentId, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async delete(documentId: string): Promise<void> {\n await strapi.delete(pluralName, documentId);\n },\n };\n}\n\n// Helper to get typed single type\nexport function single<T>(singularName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.find(singularName, params) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async update(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(singularName, 1 as unknown as string, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async delete(): Promise<void> {\n await strapi.delete(singularName, 1 as unknown as string);\n },\n };\n}\n`;\n}\n\nfunction generateLocalesFile(locales: StrapiLocale[]): string {\n if (locales.length === 0) {\n return `/**\n * Strapi locales\n * Generated by strapi2front\n * Note: i18n is not enabled in Strapi\n */\n\nexport const locales = [] as const;\nexport type Locale = string;\nexport const defaultLocale: Locale = 'en';\nexport const localeNames: Record<string, string> = {};\n\nexport function isValidLocale(_code: string): _code is Locale {\n return true;\n}\n\nexport function getLocaleName(code: string): string {\n return code;\n}\n`;\n }\n\n const localeCodes = locales.map(l => l.code);\n const defaultLocale = locales.find(l => l.isDefault)?.code || locales[0]?.code || 'en';\n\n return `/**\n * Strapi locales\n * Generated by strapi2front\n */\n\nexport const locales = [${localeCodes.map(c => `'${c}'`).join(', ')}] as const;\n\nexport type Locale = typeof locales[number];\n\nexport const defaultLocale: Locale = '${defaultLocale}';\n\nexport const localeNames: Record<Locale, string> = {\n${locales.map(l => ` '${l.code}': '${l.name}'`).join(',\\n')}\n};\n\nexport function isValidLocale(code: string): code is Locale {\n return locales.includes(code as Locale);\n}\n\nexport function getLocaleName(code: Locale): string {\n return localeNames[code] || code;\n}\n`;\n}\n\n// ============================================\n// Collection Types Generation\n// ============================================\n\nfunction generateCollectionTypes(collection: CollectionType, schema: ParsedSchema): string {\n const typeName = toPascalCase(collection.singularName);\n const attributes = generateAttributes(collection.attributes);\n const imports = generateTypeImports(collection.attributes, schema, 'collection');\n\n return `/**\n * ${collection.displayName}\n * ${collection.description || ''}\n * Generated by strapi2front\n */\n\n${imports}\n\nexport interface ${typeName} extends StrapiBaseEntity {\n${attributes}\n}\n\nexport interface ${typeName}Filters {\n id?: number | { $eq?: number; $ne?: number; $in?: number[]; $notIn?: number[] };\n documentId?: string | { $eq?: string; $ne?: string };\n createdAt?: string | { $eq?: string; $gt?: string; $gte?: string; $lt?: string; $lte?: string };\n updatedAt?: string | { $eq?: string; $gt?: string; $gte?: string; $lt?: string; $lte?: string };\n publishedAt?: string | null | { $eq?: string; $ne?: string; $null?: boolean };\n $and?: ${typeName}Filters[];\n $or?: ${typeName}Filters[];\n $not?: ${typeName}Filters;\n}\n`;\n}\n\nfunction generateSingleTypes(single: SingleType, schema: ParsedSchema): string {\n const typeName = toPascalCase(single.singularName);\n const attributes = generateAttributes(single.attributes);\n const imports = generateTypeImports(single.attributes, schema, 'single');\n\n return `/**\n * ${single.displayName}\n * ${single.description || ''}\n * Generated by strapi2front\n */\n\n${imports}\n\nexport interface ${typeName} extends StrapiBaseEntity {\n${attributes}\n}\n`;\n}\n\nfunction generateComponentTypes(component: ComponentType, schema: ParsedSchema): string {\n const typeName = toPascalCase(component.name);\n const attributes = generateAttributes(component.attributes);\n const imports = generateTypeImports(component.attributes, schema, 'component');\n\n return `/**\n * ${component.displayName} component\n * Category: ${component.category}\n * ${component.description || ''}\n * Generated by strapi2front\n */\n\n${imports}\n\nexport interface ${typeName} {\n id: number;\n${attributes}\n}\n`;\n}\n\nfunction generateTypeImports(\n attributes: Record<string, Attribute>,\n schema: ParsedSchema,\n context: 'collection' | 'single' | 'component'\n): string {\n const utilsImports: string[] = [];\n const relationImports: Map<string, string> = new Map();\n const componentImports: Map<string, string> = new Map();\n\n // Check what utils we need\n const attributesStr = JSON.stringify(attributes);\n if (context !== 'component') {\n utilsImports.push('StrapiBaseEntity');\n }\n if (attributesStr.includes('\"type\":\"media\"')) {\n utilsImports.push('StrapiMedia');\n }\n if (attributesStr.includes('\"type\":\"blocks\"')) {\n utilsImports.push('BlocksContent');\n }\n\n // Extract relations and components\n for (const attr of Object.values(attributes)) {\n if (attr.type === 'relation' && 'target' in attr && attr.target) {\n const targetName = attr.target.split('.').pop() || '';\n if (targetName) {\n const typeName = toPascalCase(targetName);\n const fileName = toKebabCase(targetName);\n // Check if it's a collection or single\n const isCollection = schema.collections.some(c => c.singularName === targetName);\n const isSingle = schema.singles.some(s => s.singularName === targetName);\n if (isCollection) {\n relationImports.set(typeName, `../../collections/${fileName}/types`);\n } else if (isSingle) {\n relationImports.set(typeName, `../../singles/${fileName}/types`);\n }\n }\n }\n\n if (attr.type === 'component' && 'component' in attr && attr.component) {\n const componentName = attr.component.split('.').pop() || '';\n if (componentName) {\n const typeName = toPascalCase(componentName);\n const fileName = toKebabCase(componentName);\n if (context === 'component') {\n componentImports.set(typeName, `./${fileName}`);\n } else {\n componentImports.set(typeName, `../../components/${fileName}`);\n }\n }\n }\n\n if (attr.type === 'dynamiczone' && 'components' in attr && attr.components) {\n for (const comp of attr.components) {\n const componentName = comp.split('.').pop() || '';\n if (componentName) {\n const typeName = toPascalCase(componentName);\n const fileName = toKebabCase(componentName);\n if (context === 'component') {\n componentImports.set(typeName, `./${fileName}`);\n } else {\n componentImports.set(typeName, `../../components/${fileName}`);\n }\n }\n }\n }\n }\n\n const lines: string[] = [];\n\n // Utils import\n if (utilsImports.length > 0) {\n const utilsPath = context === 'component' ? '../shared/utils' : '../../shared/utils';\n lines.push(`import type { ${utilsImports.join(', ')} } from '${utilsPath}';`);\n }\n\n // Relation imports\n for (const [typeName, importPath] of relationImports) {\n lines.push(`import type { ${typeName} } from '${importPath}';`);\n }\n\n // Component imports\n for (const [typeName, importPath] of componentImports) {\n lines.push(`import type { ${typeName} } from '${importPath}';`);\n }\n\n return lines.join('\\n');\n}\n\nfunction generateAttributes(attributes: Record<string, Attribute>): string {\n const lines: string[] = [];\n\n for (const [name, attr] of Object.entries(attributes)) {\n const tsType = attributeToTsType(attr);\n const optional = attr.required ? '' : '?';\n lines.push(` ${name}${optional}: ${tsType};`);\n }\n\n return lines.join('\\n');\n}\n\nfunction attributeToTsType(attr: Attribute): string {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'password':\n case 'uid':\n return 'string';\n case 'blocks':\n return 'BlocksContent';\n case 'integer':\n case 'biginteger':\n case 'float':\n case 'decimal':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'date':\n case 'time':\n case 'datetime':\n case 'timestamp':\n return 'string';\n case 'json':\n return 'unknown';\n case 'enumeration':\n if ('enum' in attr && attr.enum) {\n return attr.enum.map(v => `'${v}'`).join(' | ');\n }\n return 'string';\n case 'media':\n if ('multiple' in attr && attr.multiple) {\n return 'StrapiMedia[]';\n }\n return 'StrapiMedia | null';\n case 'relation':\n if ('target' in attr && attr.target) {\n const targetName = toPascalCase(attr.target.split('.').pop() || 'unknown');\n const isMany = attr.relation === 'oneToMany' || attr.relation === 'manyToMany';\n return isMany ? `${targetName}[]` : `${targetName} | null`;\n }\n return 'unknown';\n case 'component':\n if ('component' in attr && attr.component) {\n const componentName = toPascalCase(attr.component.split('.').pop() || 'unknown');\n if ('repeatable' in attr && attr.repeatable) {\n return `${componentName}[]`;\n }\n return `${componentName} | null`;\n }\n return 'unknown';\n case 'dynamiczone':\n if ('components' in attr && attr.components) {\n const types = attr.components.map(c => toPascalCase(c.split('.').pop() || 'unknown'));\n return `(${types.join(' | ')})[]`;\n }\n return 'unknown[]';\n default:\n return 'unknown';\n }\n}\n\n// ============================================\n// Collection Service Generation\n// ============================================\n\nfunction generateCollectionService(collection: CollectionType, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(collection.singularName);\n const serviceName = toCamelCase(collection.singularName) + 'Service';\n const endpoint = collection.pluralName;\n const hasSlug = 'slug' in collection.attributes;\n const { localized, draftAndPublish } = collection;\n const isV4 = strapiVersion === \"v4\";\n\n // V4 uses `id: number`, V5 uses `documentId: string`\n const idParam = isV4 ? 'id: number' : 'documentId: string';\n const idName = isV4 ? 'id' : 'documentId';\n const omitFields = isV4\n ? \"'id' | 'createdAt' | 'updatedAt' | 'publishedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt' | 'publishedAt'\";\n const omitFieldsUpdate = isV4\n ? \"'id' | 'createdAt' | 'updatedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt'\";\n\n // Build imports\n const imports = [\n `import { collection } from '../../shared/client';`,\n `import type { ${typeName}, ${typeName}Filters } from './types';`,\n `import type { StrapiPagination } from '../../shared/utils';`,\n ];\n if (localized) {\n imports.push(`import type { Locale } from '../../shared/locales';`);\n }\n\n // Build options interfaces\n const paginationFields = `\n /** Page number (1-indexed) - use with pageSize */\n page?: number;\n /** Number of items per page (default: 25) - use with page */\n pageSize?: number;\n /** Offset to start from (0-indexed) - use with limit */\n start?: number;\n /** Maximum number of items to return - use with start */\n limit?: number;`;\n\n let findManyOptionsFields = ` filters?: ${typeName}Filters;\n pagination?: {${paginationFields}\n };\n sort?: string | string[];\n populate?: string | string[] | Record<string, unknown>;`;\n\n let findOneOptionsFields = ` populate?: string | string[] | Record<string, unknown>;`;\n\n if (localized) {\n findManyOptionsFields += `\\n locale?: Locale;`;\n findOneOptionsFields += `\\n locale?: Locale;`;\n }\n if (draftAndPublish) {\n findManyOptionsFields += `\\n status?: 'draft' | 'published';`;\n findOneOptionsFields += `\\n status?: 'draft' | 'published';`;\n }\n\n // Build find params\n let findParams = ` filters: options.filters,\n pagination: options.pagination,\n sort: options.sort,\n populate: options.populate,`;\n let findOneParams = ` populate: options.populate,`;\n\n if (localized) {\n findParams += `\\n locale: options.locale,`;\n findOneParams += `\\n locale: options.locale,`;\n }\n if (draftAndPublish) {\n findParams += `\\n status: options.status,`;\n findOneParams += `\\n status: options.status,`;\n }\n\n return `/**\n * ${collection.displayName} Service\n * ${collection.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${imports.join('\\n')}\n\nexport interface FindManyOptions {\n${findManyOptionsFields}\n}\n\nexport interface FindOneOptions {\n${findOneOptionsFields}\n}\n\n// Create typed collection helper\nconst ${toCamelCase(collection.singularName)}Collection = collection<${typeName}>('${endpoint}');\n\nexport const ${serviceName} = {\n async findMany(options: FindManyOptions = {}): Promise<{ data: ${typeName}[]; pagination: StrapiPagination }> {\n const response = await ${toCamelCase(collection.singularName)}Collection.find({\n${findParams}\n });\n\n return {\n data: response.data,\n pagination: response.meta.pagination,\n };\n },\n\n async findAll(options: Omit<FindManyOptions, 'pagination'> = {}): Promise<${typeName}[]> {\n const allItems: ${typeName}[] = [];\n let page = 1;\n let hasMore = true;\n\n while (hasMore) {\n const { data, pagination } = await this.findMany({\n ...options,\n pagination: { page, pageSize: 100 },\n });\n\n allItems.push(...data);\n hasMore = page < pagination.pageCount;\n page++;\n }\n\n return allItems;\n },\n\n async findOne(${idParam}, options: FindOneOptions = {}): Promise<${typeName} | null> {\n try {\n const response = await ${toCamelCase(collection.singularName)}Collection.findOne(${idName}, {\n${findOneParams}\n });\n\n return response.data;\n } catch (error) {\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw error;\n }\n },\n${hasSlug ? `\n async findBySlug(slug: string, options: FindOneOptions = {}): Promise<${typeName} | null> {\n const { data } = await this.findMany({\n filters: { slug: { $eq: slug } } as ${typeName}Filters,\n pagination: { pageSize: 1 },\n populate: options.populate,${localized ? '\\n locale: options.locale,' : ''}${draftAndPublish ? '\\n status: options.status,' : ''}\n });\n\n return data[0] || null;\n },\n` : ''}\n async create(data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(collection.singularName)}Collection.create({ data });\n return response.data;\n },\n\n async update(${idParam}, data: Partial<Omit<${typeName}, ${omitFieldsUpdate}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(collection.singularName)}Collection.update(${idName}, { data });\n return response.data;\n },\n\n async delete(${idParam}): Promise<void> {\n await ${toCamelCase(collection.singularName)}Collection.delete(${idName});\n },\n\n async count(filters?: ${typeName}Filters): Promise<number> {\n const { pagination } = await this.findMany({\n filters,\n pagination: { pageSize: 1 },\n });\n\n return pagination.total;\n },\n};\n`;\n}\n\n// ============================================\n// Single Service Generation\n// ============================================\n\nfunction generateSingleService(single: SingleType, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(single.singularName);\n const serviceName = toCamelCase(single.singularName) + 'Service';\n const endpoint = single.singularName;\n const { localized, draftAndPublish } = single;\n const isV4 = strapiVersion === \"v4\";\n\n // V4 doesn't have documentId\n const omitFields = isV4\n ? \"'id' | 'createdAt' | 'updatedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt'\";\n\n // Build imports\n const imports = [\n `import { single } from '../../shared/client';`,\n `import type { ${typeName} } from './types';`,\n ];\n if (localized) {\n imports.push(`import type { Locale } from '../../shared/locales';`);\n }\n\n // Build options interface\n let findOptionsFields = ` populate?: string | string[] | Record<string, unknown>;`;\n if (localized) {\n findOptionsFields += `\\n locale?: Locale;`;\n }\n if (draftAndPublish) {\n findOptionsFields += `\\n status?: 'draft' | 'published';`;\n }\n\n // Build find params\n let findParams = ` populate: options.populate,`;\n if (localized) {\n findParams += `\\n locale: options.locale,`;\n }\n if (draftAndPublish) {\n findParams += `\\n status: options.status,`;\n }\n\n return `/**\n * ${single.displayName} Service (Single Type)\n * ${single.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${imports.join('\\n')}\n\nexport interface FindOptions {\n${findOptionsFields}\n}\n\n// Create typed single helper\nconst ${toCamelCase(single.singularName)}Single = single<${typeName}>('${endpoint}');\n\nexport const ${serviceName} = {\n async find(options: FindOptions = {}): Promise<${typeName} | null> {\n try {\n const response = await ${toCamelCase(single.singularName)}Single.find({\n${findParams}\n });\n\n return response.data;\n } catch (error) {\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw error;\n }\n },\n\n async update(data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(single.singularName)}Single.update({ data });\n return response.data;\n },\n\n async delete(): Promise<void> {\n await ${toCamelCase(single.singularName)}Single.delete();\n },\n};\n`;\n}\n\n// ============================================\n// Collection Actions Generation\n// ============================================\n\nfunction generateCollectionActions(collection: CollectionType, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(collection.singularName);\n const serviceName = toCamelCase(collection.singularName) + 'Service';\n const actionPrefix = toCamelCase(collection.singularName);\n const isV4 = strapiVersion === \"v4\";\n\n // V4 uses `id: number`, V5 uses `documentId: string`\n const idInputSchema = isV4 ? 'z.number().int().positive()' : 'z.string()';\n const idParamName = isV4 ? 'id' : 'documentId';\n\n return `/**\n * ${collection.displayName} Astro Actions\n * ${collection.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\nimport { defineAction } from 'astro:actions';\nimport { z } from 'astro:schema';\nimport { ${serviceName} } from './service';\nimport type { ${typeName} } from './types';\n\nexport const ${actionPrefix}Actions = {\n getMany: defineAction({\n input: z.object({\n page: z.number().optional(),\n pageSize: z.number().optional(),\n sort: z.string().optional(),\n }).optional(),\n handler: async (input) => {\n const { data, pagination } = await ${serviceName}.findMany({\n pagination: input ? { page: input.page, pageSize: input.pageSize } : undefined,\n sort: input?.sort,\n });\n return { data, pagination };\n },\n }),\n\n getOne: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n }),\n handler: async (input) => {\n const data = await ${serviceName}.findOne(input.${idParamName});\n return { data };\n },\n }),\n\n create: defineAction({\n input: z.object({\n data: z.record(z.unknown()),\n }),\n handler: async (input) => {\n const data = await ${serviceName}.create(input.data as Partial<${typeName}>);\n return { data };\n },\n }),\n\n update: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n data: z.record(z.unknown()),\n }),\n handler: async (input) => {\n const data = await ${serviceName}.update(input.${idParamName}, input.data as Partial<${typeName}>);\n return { data };\n },\n }),\n\n delete: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n }),\n handler: async (input) => {\n await ${serviceName}.delete(input.${idParamName});\n return { success: true };\n },\n }),\n};\n`;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/formatter.ts","../src/utils/file.ts","../src/utils/naming.ts","../src/types/generator.ts","../src/services/generator.ts","../src/actions/generator.ts","../src/client/generator.ts","../src/locales/generator.ts","../src/by-feature/generator.ts"],"names":["path","generateUtilityTypes","generateClient","generateLocalesFile","generateCollectionService","generateCollectionActions","generateSingleService","generateAttributes","attributeToTsType"],"mappings":"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","file":"index.js","sourcesContent":["import * as prettier from 'prettier';\n\n/**\n * Format TypeScript code using Prettier\n */\nexport async function formatCode(code: string): Promise<string> {\n try {\n return await prettier.format(code, {\n parser: 'typescript',\n semi: true,\n singleQuote: true,\n trailingComma: 'es5',\n printWidth: 100,\n tabWidth: 2,\n useTabs: false,\n });\n } catch {\n // If formatting fails, return original code\n return code;\n }\n}\n\n/**\n * Format JSON code using Prettier\n */\nexport async function formatJson(code: string): Promise<string> {\n try {\n return await prettier.format(code, {\n parser: 'json',\n tabWidth: 2,\n });\n } catch {\n return code;\n }\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\n\n/**\n * Ensure a directory exists, creating it if necessary\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, { recursive: true });\n } catch (error) {\n // Ignore if directory already exists\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error;\n }\n }\n}\n\n/**\n * Write content to a file, creating parent directories if needed\n */\nexport async function writeFile(filePath: string, content: string): Promise<void> {\n const dir = path.dirname(filePath);\n await ensureDir(dir);\n await fs.writeFile(filePath, content, 'utf-8');\n}\n\n/**\n * Read a file's content\n */\nexport async function readFile(filePath: string): Promise<string> {\n return await fs.readFile(filePath, 'utf-8');\n}\n\n/**\n * Check if a file exists\n */\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Delete a file if it exists\n */\nexport async function deleteFile(filePath: string): Promise<void> {\n try {\n await fs.unlink(filePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n}\n\n/**\n * List files in a directory matching a pattern\n */\nexport async function listFiles(dirPath: string, extension?: string): Promise<string[]> {\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n let files = entries\n .filter((entry) => entry.isFile())\n .map((entry) => path.join(dirPath, entry.name));\n\n if (extension) {\n files = files.filter((file) => file.endsWith(extension));\n }\n\n return files;\n } catch {\n return [];\n }\n}\n","/**\n * Convert string to PascalCase\n */\nexport function toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Convert string to camelCase\n */\nexport function toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\n/**\n * Convert string to kebab-case\n */\nexport function toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\n/**\n * Pluralize a word (simple version)\n */\nexport function pluralize(word: string): string {\n if (word.endsWith('s') || word.endsWith('x') || word.endsWith('ch') || word.endsWith('sh')) {\n return word + 'es';\n }\n if (word.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(word.charAt(word.length - 2))) {\n return word.slice(0, -1) + 'ies';\n }\n return word + 's';\n}\n","import path from 'node:path';\nimport type { ParsedSchema, Attribute, CollectionType, SingleType, ComponentType } from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\nimport { toPascalCase, toKebabCase } from '../utils/naming.js';\n\nexport interface TypeGeneratorOptions {\n outputDir: string;\n blocksRendererInstalled?: boolean;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate TypeScript types from parsed schema\n */\nexport async function generateTypes(\n schema: ParsedSchema,\n options: TypeGeneratorOptions\n): Promise<string[]> {\n const { outputDir } = options;\n const generatedFiles: string[] = [];\n\n // Ensure directories exist\n await ensureDir(path.join(outputDir, 'collections'));\n await ensureDir(path.join(outputDir, 'components'));\n\n // Generate utility types\n const utilsPath = path.join(outputDir, 'utils.ts');\n const strapiVersion = options.strapiVersion ?? 'v5';\n await writeFile(utilsPath, await formatCode(generateUtilityTypes(options.blocksRendererInstalled ?? false, strapiVersion)));\n generatedFiles.push(utilsPath);\n\n // Generate collection types\n for (const collection of schema.collections) {\n const fileName = `${toKebabCase(collection.singularName)}.ts`;\n const filePath = path.join(outputDir, 'collections', fileName);\n const content = generateCollectionType(collection, schema.components);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n // Generate single types\n for (const single of schema.singles) {\n const fileName = `${toKebabCase(single.singularName)}.ts`;\n const filePath = path.join(outputDir, 'collections', fileName);\n const content = generateSingleType(single, schema.components);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n // Generate component types\n for (const component of schema.components) {\n const fileName = `${toKebabCase(component.name)}.ts`;\n const filePath = path.join(outputDir, 'components', fileName);\n const content = generateComponentType(component);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n return generatedFiles;\n}\n\n/**\n * Generate utility types\n */\nfunction generateUtilityTypes(blocksRendererInstalled: boolean, strapiVersion: \"v4\" | \"v5\"): string {\n const isV4 = strapiVersion === \"v4\";\n\n const blocksContentType = isV4\n ? `/**\n * Rich text content (Strapi v4)\n * Can be markdown string or custom JSON structure\n */\nexport type RichTextContent = string;`\n : blocksRendererInstalled\n ? `/**\n * Blocks content type (Strapi v5 rich text)\n * Re-exported from @strapi/blocks-react-renderer\n */\nexport type { BlocksContent } from '@strapi/blocks-react-renderer';`\n : `/**\n * Blocks content type (Strapi v5 rich text)\n *\n * For full type support and rendering, install:\n * npm install @strapi/blocks-react-renderer\n *\n * Then re-run: npx strapi2front sync\n */\nexport type BlocksContent = unknown[];`;\n\n const baseEntity = isV4\n ? `/**\n * Base entity fields (Strapi v4)\n */\nexport interface StrapiBaseEntity {\n id: number;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n}`\n : `/**\n * Base entity fields (Strapi v5)\n */\nexport interface StrapiBaseEntity {\n id: number;\n documentId: string;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n}`;\n\n const mediaType = isV4\n ? `/**\n * Strapi media object (v4)\n */\nexport interface StrapiMedia {\n id: number;\n name: string;\n alternativeText: string | null;\n caption: string | null;\n width: number;\n height: number;\n formats: {\n thumbnail?: StrapiMediaFormat;\n small?: StrapiMediaFormat;\n medium?: StrapiMediaFormat;\n large?: StrapiMediaFormat;\n } | null;\n hash: string;\n ext: string;\n mime: string;\n size: number;\n url: string;\n previewUrl: string | null;\n provider: string;\n createdAt: string;\n updatedAt: string;\n}`\n : `/**\n * Strapi media object (v5)\n */\nexport interface StrapiMedia {\n id: number;\n documentId: string;\n name: string;\n alternativeText: string | null;\n caption: string | null;\n width: number;\n height: number;\n formats: {\n thumbnail?: StrapiMediaFormat;\n small?: StrapiMediaFormat;\n medium?: StrapiMediaFormat;\n large?: StrapiMediaFormat;\n } | null;\n hash: string;\n ext: string;\n mime: string;\n size: number;\n url: string;\n previewUrl: string | null;\n provider: string;\n createdAt: string;\n updatedAt: string;\n}`;\n\n const rawResponseTypes = isV4\n ? `\n/**\n * Strapi v4 raw API response (with nested attributes)\n */\nexport interface StrapiV4RawItem<T> {\n id: number;\n attributes: Omit<T, 'id'>;\n}\n\nexport interface StrapiV4RawResponse<T> {\n data: StrapiV4RawItem<T>;\n meta: Record<string, unknown>;\n}\n\nexport interface StrapiV4RawListResponse<T> {\n data: StrapiV4RawItem<T>[];\n meta: {\n pagination: StrapiPagination;\n };\n}\n\n/**\n * Flatten Strapi v4 response item\n */\nexport function flattenV4Response<T>(item: StrapiV4RawItem<T>): T {\n return { id: item.id, ...item.attributes } as T;\n}\n\n/**\n * Flatten Strapi v4 list response\n */\nexport function flattenV4ListResponse<T>(items: StrapiV4RawItem<T>[]): T[] {\n return items.map(item => flattenV4Response<T>(item));\n}`\n : '';\n\n return `/**\n * Strapi utility types\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${mediaType}\n\nexport interface StrapiMediaFormat {\n name: string;\n hash: string;\n ext: string;\n mime: string;\n width: number;\n height: number;\n size: number;\n url: string;\n}\n\n/**\n * Strapi pagination\n */\nexport interface StrapiPagination {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n}\n\n/**\n * Strapi response wrapper\n */\nexport interface StrapiResponse<T> {\n data: T;\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\n/**\n * Strapi list response\n */\nexport interface StrapiListResponse<T> {\n data: T[];\n meta: {\n pagination: StrapiPagination;\n };\n}\n\n${baseEntity}\n${rawResponseTypes}\n${blocksContentType}\n`;\n}\n\n/**\n * Extract dependencies (relations and components) from attributes\n */\nfunction extractDependencies(\n attributes: Record<string, Attribute>,\n selfName: string\n): { relations: Set<string>; components: Set<string> } {\n const relations = new Set<string>();\n const components = new Set<string>();\n\n for (const attr of Object.values(attributes)) {\n if (attr.type === 'relation' && 'target' in attr && attr.target) {\n const targetName = attr.target.split('.').pop() || '';\n const typeName = toPascalCase(targetName);\n // Don't import self\n if (typeName !== selfName && targetName) {\n relations.add(targetName);\n }\n }\n\n if (attr.type === 'component' && 'component' in attr && attr.component) {\n const componentName = attr.component.split('.').pop() || '';\n if (componentName) {\n components.add(componentName);\n }\n }\n\n if (attr.type === 'dynamiczone' && 'components' in attr && attr.components) {\n for (const comp of attr.components) {\n const componentName = comp.split('.').pop() || '';\n if (componentName) {\n components.add(componentName);\n }\n }\n }\n }\n\n return { relations, components };\n}\n\n/**\n * Generate import statements for dependencies\n */\nfunction generateDependencyImports(\n relations: Set<string>,\n components: Set<string>\n): string {\n const imports: string[] = [];\n\n // Import relations (other collections/singles)\n for (const relation of relations) {\n const typeName = toPascalCase(relation);\n const fileName = toKebabCase(relation);\n imports.push(`import type { ${typeName} } from './${fileName}';`);\n }\n\n // Import components\n for (const component of components) {\n const typeName = toPascalCase(component);\n const fileName = toKebabCase(component);\n imports.push(`import type { ${typeName} } from '../components/${fileName}';`);\n }\n\n return imports.join('\\n');\n}\n\n/**\n * Generate type for a collection\n */\nfunction generateCollectionType(collection: CollectionType, components: ComponentType[]): string {\n const typeName = toPascalCase(collection.singularName);\n const attributes = generateAttributes(collection.attributes, components);\n const { relations, components: componentDeps } = extractDependencies(collection.attributes, typeName);\n const dependencyImports = generateDependencyImports(relations, componentDeps);\n\n // Build utils imports based on what's actually used\n const utilsImports: string[] = ['StrapiBaseEntity'];\n const attributesStr = JSON.stringify(collection.attributes);\n if (attributesStr.includes('\"type\":\"media\"')) {\n utilsImports.push('StrapiMedia');\n }\n if (attributesStr.includes('\"type\":\"blocks\"')) {\n utilsImports.push('BlocksContent');\n }\n\n return `/**\n * ${collection.displayName}\n * ${collection.description || ''}\n * Generated by strapi2front\n */\n\nimport type { ${utilsImports.join(', ')} } from '../utils';\n${dependencyImports ? dependencyImports + '\\n' : ''}\nexport interface ${typeName} extends StrapiBaseEntity {\n${attributes}\n}\n\nexport interface ${typeName}Filters {\n id?: number | { $eq?: number; $ne?: number; $in?: number[]; $notIn?: number[] };\n documentId?: string | { $eq?: string; $ne?: string };\n createdAt?: string | { $eq?: string; $gt?: string; $gte?: string; $lt?: string; $lte?: string };\n updatedAt?: string | { $eq?: string; $gt?: string; $gte?: string; $lt?: string; $lte?: string };\n publishedAt?: string | null | { $eq?: string; $ne?: string; $null?: boolean };\n $and?: ${typeName}Filters[];\n $or?: ${typeName}Filters[];\n $not?: ${typeName}Filters;\n}\n\nexport interface ${typeName}Sort {\n field: keyof ${typeName};\n order: 'asc' | 'desc';\n}\n`;\n}\n\n/**\n * Generate type for a single type\n */\nfunction generateSingleType(single: SingleType, components: ComponentType[]): string {\n const typeName = toPascalCase(single.singularName);\n const attributes = generateAttributes(single.attributes, components);\n const { relations, components: componentDeps } = extractDependencies(single.attributes, typeName);\n const dependencyImports = generateDependencyImports(relations, componentDeps);\n\n // Build utils imports based on what's actually used\n const utilsImports: string[] = ['StrapiBaseEntity'];\n const attributesStr = JSON.stringify(single.attributes);\n if (attributesStr.includes('\"type\":\"media\"')) {\n utilsImports.push('StrapiMedia');\n }\n if (attributesStr.includes('\"type\":\"blocks\"')) {\n utilsImports.push('BlocksContent');\n }\n\n return `/**\n * ${single.displayName}\n * ${single.description || ''}\n * Generated by strapi2front\n */\n\nimport type { ${utilsImports.join(', ')} } from '../utils';\n${dependencyImports ? dependencyImports + '\\n' : ''}\nexport interface ${typeName} extends StrapiBaseEntity {\n${attributes}\n}\n`;\n}\n\n/**\n * Generate type for a component\n */\nfunction generateComponentType(component: ComponentType): string {\n const typeName = toPascalCase(component.name);\n const attributes = generateAttributes(component.attributes, []);\n const { relations, components: componentDeps } = extractDependencies(component.attributes, typeName);\n\n // For components, relations import from collections and other components import from same folder\n const imports: string[] = [];\n\n for (const relation of relations) {\n const relTypeName = toPascalCase(relation);\n const fileName = toKebabCase(relation);\n imports.push(`import type { ${relTypeName} } from '../collections/${fileName}';`);\n }\n\n for (const comp of componentDeps) {\n const compTypeName = toPascalCase(comp);\n const fileName = toKebabCase(comp);\n // Don't import self\n if (compTypeName !== typeName) {\n imports.push(`import type { ${compTypeName} } from './${fileName}';`);\n }\n }\n\n // Build utils imports based on what's actually used\n const utilsImports: string[] = [];\n const attributesStr = JSON.stringify(component.attributes);\n if (attributesStr.includes('\"type\":\"media\"')) {\n utilsImports.push('StrapiMedia');\n }\n if (attributesStr.includes('\"type\":\"blocks\"')) {\n utilsImports.push('BlocksContent');\n }\n\n const utilsImportLine = utilsImports.length > 0\n ? `import type { ${utilsImports.join(', ')} } from '../utils';\\n`\n : '';\n const dependencyImports = imports.length > 0 ? imports.join('\\n') + '\\n' : '';\n\n return `/**\n * ${component.displayName} component\n * Category: ${component.category}\n * ${component.description || ''}\n * Generated by strapi2front\n */\n\n${utilsImportLine}${dependencyImports}\nexport interface ${typeName} {\n id: number;\n${attributes}\n}\n`;\n}\n\n/**\n * Generate TypeScript properties from Strapi attributes\n */\nfunction generateAttributes(\n attributes: Record<string, Attribute>,\n components: ComponentType[]\n): string {\n const lines: string[] = [];\n\n for (const [name, attr] of Object.entries(attributes)) {\n const tsType = attributeToTsType(attr, components);\n const optional = attr.required ? '' : '?';\n const comment = getAttributeComment(attr);\n\n if (comment) {\n lines.push(` /** ${comment} */`);\n }\n lines.push(` ${name}${optional}: ${tsType};`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Convert Strapi attribute to TypeScript type\n */\nfunction attributeToTsType(attr: Attribute, _components: ComponentType[]): string {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'password':\n case 'uid':\n return 'string';\n\n case 'blocks':\n return 'BlocksContent';\n\n case 'integer':\n case 'biginteger':\n case 'float':\n case 'decimal':\n return 'number';\n\n case 'boolean':\n return 'boolean';\n\n case 'date':\n case 'time':\n case 'datetime':\n case 'timestamp':\n return 'string';\n\n case 'json':\n return 'unknown';\n\n case 'enumeration':\n if ('enum' in attr && attr.enum) {\n return attr.enum.map((v) => `'${v}'`).join(' | ');\n }\n return 'string';\n\n case 'media':\n if ('multiple' in attr && attr.multiple) {\n return 'StrapiMedia[]';\n }\n return 'StrapiMedia | null';\n\n case 'relation':\n if ('target' in attr && attr.target) {\n const targetName = toPascalCase(attr.target.split('.').pop() || 'unknown');\n const isMany = attr.relation === 'oneToMany' || attr.relation === 'manyToMany';\n return isMany ? `${targetName}[]` : `${targetName} | null`;\n }\n return 'unknown';\n\n case 'component':\n if ('component' in attr && attr.component) {\n const componentName = toPascalCase(attr.component.split('.').pop() || 'unknown');\n if ('repeatable' in attr && attr.repeatable) {\n return `${componentName}[]`;\n }\n return `${componentName} | null`;\n }\n return 'unknown';\n\n case 'dynamiczone':\n if ('components' in attr && attr.components) {\n const types = attr.components.map((c) => toPascalCase(c.split('.').pop() || 'unknown'));\n return `(${types.join(' | ')})[]`;\n }\n return 'unknown[]';\n\n default:\n return 'unknown';\n }\n}\n\n/**\n * Get comment for attribute\n */\nfunction getAttributeComment(attr: Attribute): string | null {\n const parts: string[] = [];\n\n if (attr.required) {\n parts.push('Required');\n }\n\n if ('minLength' in attr && attr.minLength !== undefined) {\n parts.push(`Min length: ${attr.minLength}`);\n }\n\n if ('maxLength' in attr && attr.maxLength !== undefined) {\n parts.push(`Max length: ${attr.maxLength}`);\n }\n\n if ('min' in attr && attr.min !== undefined) {\n parts.push(`Min: ${attr.min}`);\n }\n\n if ('max' in attr && attr.max !== undefined) {\n parts.push(`Max: ${attr.max}`);\n }\n\n return parts.length > 0 ? parts.join(', ') : null;\n}\n\n","import path from 'node:path';\nimport type { ParsedSchema, CollectionType, SingleType } from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\nimport { toPascalCase, toCamelCase, toKebabCase } from '../utils/naming.js';\n\nexport interface ServiceGeneratorOptions {\n outputDir: string;\n typesImportPath: string;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate service files from parsed schema\n */\nexport async function generateServices(\n schema: ParsedSchema,\n options: ServiceGeneratorOptions\n): Promise<string[]> {\n const { outputDir, typesImportPath, strapiVersion = \"v5\" } = options;\n const generatedFiles: string[] = [];\n\n await ensureDir(outputDir);\n\n // Generate services for collections\n for (const collection of schema.collections) {\n const fileName = `${toKebabCase(collection.singularName)}.service.ts`;\n const filePath = path.join(outputDir, fileName);\n const content = generateCollectionService(collection, typesImportPath, strapiVersion);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n // Generate services for single types\n for (const single of schema.singles) {\n const fileName = `${toKebabCase(single.singularName)}.service.ts`;\n const filePath = path.join(outputDir, fileName);\n const content = generateSingleService(single, typesImportPath, strapiVersion);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n return generatedFiles;\n}\n\n/**\n * Generate service for a collection type\n */\nfunction generateCollectionService(collection: CollectionType, typesImportPath: string, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(collection.singularName);\n const serviceName = toCamelCase(collection.singularName) + 'Service';\n const fileName = toKebabCase(collection.singularName);\n const endpoint = collection.pluralName;\n const isV4 = strapiVersion === \"v4\";\n\n // V4 uses `id: number`, V5 uses `documentId: string`\n const idParam = isV4 ? 'id: number' : 'documentId: string';\n const idName = isV4 ? 'id' : 'documentId';\n const omitFields = isV4\n ? \"'id' | 'createdAt' | 'updatedAt' | 'publishedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt' | 'publishedAt'\";\n\n // Feature flags\n const hasSlug = 'slug' in collection.attributes;\n const { localized, draftAndPublish } = collection;\n\n // Build imports\n const imports: string[] = [\n `import { collection } from '../client';`,\n `import type { ${typeName}, ${typeName}Filters } from '${typesImportPath}/collections/${fileName}';`,\n `import type { StrapiPagination } from '${typesImportPath}/utils';`,\n ];\n if (localized) {\n imports.push(`import type { Locale } from '../locales';`);\n }\n\n // Build FindManyOptions interface\n const findManyOptionsFields: string[] = [\n ` filters?: ${typeName}Filters;`,\n ` pagination?: {`,\n ` /** Page number (1-indexed) - use with pageSize */`,\n ` page?: number;`,\n ` /** Number of items per page (default: 25) - use with page */`,\n ` pageSize?: number;`,\n ` /** Offset to start from (0-indexed) - use with limit */`,\n ` start?: number;`,\n ` /** Maximum number of items to return - use with start */`,\n ` limit?: number;`,\n ` };`,\n ` sort?: string | string[];`,\n ` populate?: string | string[] | Record<string, unknown>;`,\n ];\n if (localized) {\n findManyOptionsFields.push(` locale?: Locale;`);\n }\n if (draftAndPublish) {\n findManyOptionsFields.push(` status?: 'draft' | 'published';`);\n }\n\n // Build FindOneOptions interface\n const findOneOptionsFields: string[] = [\n ` populate?: string | string[] | Record<string, unknown>;`,\n ];\n if (localized) {\n findOneOptionsFields.push(` locale?: Locale;`);\n }\n if (draftAndPublish) {\n findOneOptionsFields.push(` status?: 'draft' | 'published';`);\n }\n\n // Build find params\n const findParams: string[] = [\n ` filters: options.filters,`,\n ` pagination: options.pagination,`,\n ` sort: options.sort,`,\n ` populate: options.populate,`,\n ];\n if (localized) {\n findParams.push(` locale: options.locale,`);\n }\n if (draftAndPublish) {\n findParams.push(` status: options.status,`);\n }\n\n // Build findOne params\n const findOneParams: string[] = [\n ` populate: options.populate,`,\n ];\n if (localized) {\n findOneParams.push(` locale: options.locale,`);\n }\n if (draftAndPublish) {\n findOneParams.push(` status: options.status,`);\n }\n\n // Build findBySlug params\n const findBySlugParams: string[] = [\n ` populate: options.populate,`,\n ];\n if (localized) {\n findBySlugParams.push(` locale: options.locale,`);\n }\n if (draftAndPublish) {\n findBySlugParams.push(` status: options.status,`);\n }\n\n return `/**\n * ${collection.displayName} Service\n * ${collection.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${imports.join('\\n')}\n\nexport interface FindManyOptions {\n${findManyOptionsFields.join('\\n')}\n}\n\nexport interface FindOneOptions {\n${findOneOptionsFields.join('\\n')}\n}\n\n// Create typed collection helper\nconst ${toCamelCase(collection.singularName)}Collection = collection<${typeName}>('${endpoint}');\n\nexport const ${serviceName} = {\n /**\n * Find multiple ${collection.pluralName}\n */\n async findMany(options: FindManyOptions = {}): Promise<{ data: ${typeName}[]; pagination: StrapiPagination }> {\n const response = await ${toCamelCase(collection.singularName)}Collection.find({\n${findParams.join('\\n')}\n });\n\n return {\n data: response.data,\n pagination: response.meta.pagination,\n };\n },\n\n /**\n * Find all ${collection.pluralName} (handles pagination automatically)\n */\n async findAll(options: Omit<FindManyOptions, 'pagination'> = {}): Promise<${typeName}[]> {\n const allItems: ${typeName}[] = [];\n let page = 1;\n let hasMore = true;\n\n while (hasMore) {\n const { data, pagination } = await this.findMany({\n ...options,\n pagination: { page, pageSize: 100 },\n });\n\n allItems.push(...data);\n hasMore = page < pagination.pageCount;\n page++;\n }\n\n return allItems;\n },\n\n /**\n * Find one ${collection.singularName} by ${idName}\n */\n async findOne(${idParam}, options: FindOneOptions = {}): Promise<${typeName} | null> {\n try {\n const response = await ${toCamelCase(collection.singularName)}Collection.findOne(${idName}, {\n${findOneParams.join('\\n')}\n });\n\n return response.data;\n } catch (error) {\n // Return null if not found\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw error;\n }\n },\n${hasSlug ? `\n /**\n * Find one ${collection.singularName} by slug\n */\n async findBySlug(slug: string, options: FindOneOptions = {}): Promise<${typeName} | null> {\n const { data } = await this.findMany({\n filters: { slug: { $eq: slug } } as ${typeName}Filters,\n pagination: { pageSize: 1 },\n${findBySlugParams.join('\\n')}\n });\n\n return data[0] || null;\n },\n` : ''}\n /**\n * Create a new ${collection.singularName}\n */\n async create(data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(collection.singularName)}Collection.create({ data });\n return response.data;\n },\n\n /**\n * Update a ${collection.singularName}\n */\n async update(${idParam}, data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(collection.singularName)}Collection.update(${idName}, { data });\n return response.data;\n },\n\n /**\n * Delete a ${collection.singularName}\n */\n async delete(${idParam}): Promise<void> {\n await ${toCamelCase(collection.singularName)}Collection.delete(${idName});\n },\n\n /**\n * Count ${collection.pluralName}\n */\n async count(filters?: ${typeName}Filters): Promise<number> {\n const { pagination } = await this.findMany({\n filters,\n pagination: { pageSize: 1 },\n });\n\n return pagination.total;\n },\n};\n`;\n}\n\n/**\n * Generate service for a single type\n */\nfunction generateSingleService(single: SingleType, typesImportPath: string, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(single.singularName);\n const serviceName = toCamelCase(single.singularName) + 'Service';\n const fileName = toKebabCase(single.singularName);\n const endpoint = single.singularName;\n const isV4 = strapiVersion === \"v4\";\n\n // V4 doesn't have documentId\n const omitFields = isV4\n ? \"'id' | 'createdAt' | 'updatedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt'\";\n\n // Feature flags\n const { localized, draftAndPublish } = single;\n\n // Build imports\n const imports: string[] = [\n `import { single } from '../client';`,\n `import type { ${typeName} } from '${typesImportPath}/collections/${fileName}';`,\n ];\n if (localized) {\n imports.push(`import type { Locale } from '../locales';`);\n }\n\n // Build FindOptions interface\n const findOptionsFields: string[] = [\n ` populate?: string | string[] | Record<string, unknown>;`,\n ];\n if (localized) {\n findOptionsFields.push(` locale?: Locale;`);\n }\n if (draftAndPublish) {\n findOptionsFields.push(` status?: 'draft' | 'published';`);\n }\n\n // Build find params\n const findParams: string[] = [\n ` populate: options.populate,`,\n ];\n if (localized) {\n findParams.push(` locale: options.locale,`);\n }\n if (draftAndPublish) {\n findParams.push(` status: options.status,`);\n }\n\n return `/**\n * ${single.displayName} Service (Single Type)\n * ${single.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${imports.join('\\n')}\n\nexport interface FindOptions {\n${findOptionsFields.join('\\n')}\n}\n\n// Create typed single helper\nconst ${toCamelCase(single.singularName)}Single = single<${typeName}>('${endpoint}');\n\nexport const ${serviceName} = {\n /**\n * Get ${single.displayName}\n */\n async find(options: FindOptions = {}): Promise<${typeName} | null> {\n try {\n const response = await ${toCamelCase(single.singularName)}Single.find({\n${findParams.join('\\n')}\n });\n\n return response.data;\n } catch (error) {\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw error;\n }\n },\n\n /**\n * Update ${single.displayName}\n */\n async update(data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(single.singularName)}Single.update({ data });\n return response.data;\n },\n\n /**\n * Delete ${single.displayName}\n */\n async delete(): Promise<void> {\n await ${toCamelCase(single.singularName)}Single.delete();\n },\n};\n`;\n}\n\n","import path from 'node:path';\nimport type { ParsedSchema, CollectionType, SingleType } from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\nimport { toCamelCase, toKebabCase } from '../utils/naming.js';\n\nexport interface ActionsGeneratorOptions {\n outputDir: string;\n servicesImportPath: string;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate Astro Actions from parsed schema\n */\nexport async function generateActions(\n schema: ParsedSchema,\n options: ActionsGeneratorOptions\n): Promise<string[]> {\n const { outputDir, servicesImportPath, strapiVersion = \"v5\" } = options;\n const generatedFiles: string[] = [];\n\n await ensureDir(outputDir);\n\n // Generate actions for collections\n for (const collection of schema.collections) {\n const fileName = `${toKebabCase(collection.singularName)}.ts`;\n const filePath = path.join(outputDir, fileName);\n const content = generateCollectionActions(collection, servicesImportPath, strapiVersion);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n // Generate actions for single types\n for (const single of schema.singles) {\n const fileName = `${toKebabCase(single.singularName)}.ts`;\n const filePath = path.join(outputDir, fileName);\n const content = generateSingleActions(single, servicesImportPath);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n }\n\n return generatedFiles;\n}\n\n/**\n * Generate actions for a collection type\n */\nfunction generateCollectionActions(\n collection: CollectionType,\n servicesImportPath: string,\n strapiVersion: \"v4\" | \"v5\"\n): string {\n const serviceName = toCamelCase(collection.singularName) + 'Service';\n const actionsName = toCamelCase(collection.singularName);\n const fileName = toKebabCase(collection.singularName);\n const isV4 = strapiVersion === \"v4\";\n\n // V4 uses `id: number`, V5 uses `documentId: string`\n const idInputSchema = isV4 ? 'z.number().int().positive()' : 'z.string().min(1)';\n const idParamName = isV4 ? 'id' : 'documentId';\n const idComment = isV4 ? 'id' : 'documentId';\n\n // Detect if collection has a slug field\n const hasSlug = 'slug' in collection.attributes;\n\n return `/**\n * ${collection.displayName} Actions\n * ${collection.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\nimport { defineAction, ActionError } from 'astro:actions';\nimport { z } from 'astro:schema';\nimport { ${serviceName} } from '${servicesImportPath}/${fileName}.service';\n\n/**\n * Pagination input schema\n */\nconst paginationSchema = z.object({\n page: z.number().int().positive().optional().default(1),\n pageSize: z.number().int().positive().max(100).optional().default(25),\n}).optional();\n\n/**\n * ${collection.displayName} actions\n */\nexport const ${actionsName} = {\n /**\n * Get all ${collection.pluralName} with pagination\n */\n getAll: defineAction({\n input: z.object({\n pagination: paginationSchema,\n sort: z.union([z.string(), z.array(z.string())]).optional(),\n }).optional(),\n handler: async (input) => {\n try {\n const result = await ${serviceName}.findMany({\n pagination: input?.pagination,\n sort: input?.sort,\n });\n\n return result;\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to fetch ${collection.pluralName}',\n });\n }\n },\n }),\n\n /**\n * Get a single ${collection.singularName} by ${idComment}\n */\n getOne: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n populate: z.union([z.string(), z.array(z.string())]).optional(),\n }),\n handler: async ({ ${idParamName}, populate }) => {\n try {\n const result = await ${serviceName}.findOne(${idParamName}, { populate });\n\n if (!result) {\n throw new ActionError({\n code: 'NOT_FOUND',\n message: '${collection.displayName} not found',\n });\n }\n\n return result;\n } catch (error) {\n if (error instanceof ActionError) throw error;\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to fetch ${collection.singularName}',\n });\n }\n },\n }),\n${hasSlug ? `\n /**\n * Get a single ${collection.singularName} by slug\n */\n getBySlug: defineAction({\n input: z.object({\n slug: z.string().min(1),\n populate: z.union([z.string(), z.array(z.string())]).optional(),\n }),\n handler: async ({ slug, populate }) => {\n try {\n const result = await ${serviceName}.findBySlug(slug, { populate });\n\n if (!result) {\n throw new ActionError({\n code: 'NOT_FOUND',\n message: '${collection.displayName} not found',\n });\n }\n\n return result;\n } catch (error) {\n if (error instanceof ActionError) throw error;\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to fetch ${collection.singularName}',\n });\n }\n },\n }),\n` : ''}\n /**\n * Create a new ${collection.singularName}\n */\n create: defineAction({\n input: z.object({\n data: z.record(z.unknown()),\n }),\n handler: async ({ data }) => {\n try {\n const result = await ${serviceName}.create(data);\n return result;\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to create ${collection.singularName}',\n });\n }\n },\n }),\n\n /**\n * Update a ${collection.singularName}\n */\n update: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n data: z.record(z.unknown()),\n }),\n handler: async ({ ${idParamName}, data }) => {\n try {\n const result = await ${serviceName}.update(${idParamName}, data);\n return result;\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to update ${collection.singularName}',\n });\n }\n },\n }),\n\n /**\n * Delete a ${collection.singularName}\n */\n delete: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n }),\n handler: async ({ ${idParamName} }) => {\n try {\n await ${serviceName}.delete(${idParamName});\n return { success: true };\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to delete ${collection.singularName}',\n });\n }\n },\n }),\n\n /**\n * Count ${collection.pluralName}\n */\n count: defineAction({\n input: z.object({\n filters: z.record(z.unknown()).optional(),\n }).optional(),\n handler: async (input) => {\n try {\n const count = await ${serviceName}.count(input?.filters as any);\n return { count };\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to count ${collection.pluralName}',\n });\n }\n },\n }),\n};\n`;\n}\n\n/**\n * Generate actions for a single type\n */\nfunction generateSingleActions(\n single: SingleType,\n servicesImportPath: string\n): string {\n const serviceName = toCamelCase(single.singularName) + 'Service';\n const actionsName = toCamelCase(single.singularName);\n const fileName = toKebabCase(single.singularName);\n\n return `/**\n * ${single.displayName} Actions (Single Type)\n * ${single.description || ''}\n * Generated by strapi2front\n */\n\nimport { defineAction, ActionError } from 'astro:actions';\nimport { z } from 'astro:schema';\nimport { ${serviceName} } from '${servicesImportPath}/${fileName}.service';\n\n/**\n * ${single.displayName} actions\n */\nexport const ${actionsName} = {\n /**\n * Get ${single.displayName}\n */\n get: defineAction({\n input: z.object({\n populate: z.union([z.string(), z.array(z.string())]).optional(),\n }).optional(),\n handler: async (input) => {\n try {\n const result = await ${serviceName}.find({\n populate: input?.populate,\n });\n\n if (!result) {\n throw new ActionError({\n code: 'NOT_FOUND',\n message: '${single.displayName} not found',\n });\n }\n\n return result;\n } catch (error) {\n if (error instanceof ActionError) throw error;\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to fetch ${single.singularName}',\n });\n }\n },\n }),\n\n /**\n * Update ${single.displayName}\n */\n update: defineAction({\n input: z.object({\n data: z.record(z.unknown()),\n }),\n handler: async ({ data }) => {\n try {\n const result = await ${serviceName}.update(data);\n return result;\n } catch (error) {\n throw new ActionError({\n code: 'INTERNAL_SERVER_ERROR',\n message: error instanceof Error ? error.message : 'Failed to update ${single.singularName}',\n });\n }\n },\n }),\n};\n`;\n}\n\n","import path from 'node:path';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\n\nexport interface ClientGeneratorOptions {\n outputDir: string;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate the Strapi client file\n */\nexport async function generateClient(\n options: ClientGeneratorOptions\n): Promise<string[]> {\n const { outputDir, strapiVersion = \"v5\" } = options;\n const generatedFiles: string[] = [];\n\n await ensureDir(outputDir);\n\n const filePath = path.join(outputDir, 'client.ts');\n const content = generateClientFile(strapiVersion);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n\n return generatedFiles;\n}\n\n/**\n * Generate the client file content\n */\nfunction generateClientFile(strapiVersion: \"v4\" | \"v5\"): string {\n const isV4 = strapiVersion === \"v4\";\n\n if (isV4) {\n return generateV4ClientFile();\n }\n return generateV5ClientFile();\n}\n\n/**\n * Generate client for Strapi v5 (flat response structure)\n */\nfunction generateV5ClientFile(): string {\n return `/**\n * Strapi Client (v5)\n * Generated by strapi2front\n */\n\nimport Strapi from 'strapi-sdk-js';\n\n// Initialize the Strapi client\nconst strapiUrl = import.meta.env.STRAPI_URL || process.env.STRAPI_URL || 'http://localhost:1337';\nconst strapiToken = import.meta.env.STRAPI_TOKEN || process.env.STRAPI_TOKEN;\n\nexport const strapi = new Strapi({\n url: strapiUrl,\n axiosOptions: {\n headers: strapiToken ? {\n Authorization: \\`Bearer \\${strapiToken}\\`,\n } : {},\n },\n});\n\n// Pagination type\nexport interface StrapiPagination {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n}\n\n// Default pagination for fallback\nconst defaultPagination: StrapiPagination = {\n page: 1,\n pageSize: 25,\n pageCount: 1,\n total: 0,\n};\n\n// Response types\ninterface StrapiListResponse<T> {\n data: T[];\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\ninterface StrapiSingleResponse<T> {\n data: T;\n meta?: Record<string, unknown>;\n}\n\n// Helper to get typed collection\nexport function collection<T>(pluralName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T[]; meta: { pagination: StrapiPagination } }> {\n const response = await strapi.find(pluralName, params) as unknown as StrapiListResponse<T>;\n return {\n data: Array.isArray(response.data) ? response.data : [],\n meta: {\n pagination: response.meta?.pagination || defaultPagination,\n },\n };\n },\n async findOne(documentId: string, params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.findOne(pluralName, documentId, params) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async create(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.create(pluralName, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async update(documentId: string, data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(pluralName, documentId, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async delete(documentId: string): Promise<void> {\n await strapi.delete(pluralName, documentId);\n },\n };\n}\n\n// Helper to get typed single type\nexport function single<T>(singularName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.find(singularName, params) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async update(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(singularName, 1 as unknown as string, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async delete(): Promise<void> {\n await strapi.delete(singularName, 1 as unknown as string);\n },\n };\n}\n`;\n}\n\n/**\n * Generate client for Strapi v4 (nested attributes structure)\n */\nfunction generateV4ClientFile(): string {\n return `/**\n * Strapi Client (v4)\n * Generated by strapi2front\n */\n\nimport Strapi from 'strapi-sdk-js';\n\n// Initialize the Strapi client\nconst strapiUrl = import.meta.env.STRAPI_URL || process.env.STRAPI_URL || 'http://localhost:1337';\nconst strapiToken = import.meta.env.STRAPI_TOKEN || process.env.STRAPI_TOKEN;\n\nexport const strapi = new Strapi({\n url: strapiUrl,\n axiosOptions: {\n headers: strapiToken ? {\n Authorization: \\`Bearer \\${strapiToken}\\`,\n } : {},\n },\n});\n\n// Pagination type\nexport interface StrapiPagination {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n}\n\n// Default pagination for fallback\nconst defaultPagination: StrapiPagination = {\n page: 1,\n pageSize: 25,\n pageCount: 1,\n total: 0,\n};\n\n// Strapi v4 raw response types (with nested attributes)\ninterface StrapiV4RawItem<T> {\n id: number;\n attributes: Omit<T, 'id'>;\n}\n\ninterface StrapiV4RawListResponse<T> {\n data: StrapiV4RawItem<T>[];\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\ninterface StrapiV4RawSingleResponse<T> {\n data: StrapiV4RawItem<T>;\n meta?: Record<string, unknown>;\n}\n\n/**\n * Flatten a Strapi v4 response item (merges id with attributes)\n */\nfunction flattenItem<T>(item: StrapiV4RawItem<T>): T {\n return { id: item.id, ...item.attributes } as T;\n}\n\n/**\n * Recursively flatten nested relations in Strapi v4 response\n */\nfunction flattenRelations<T>(data: T): T {\n if (data === null || data === undefined) return data;\n if (Array.isArray(data)) {\n return data.map(item => flattenRelations(item)) as unknown as T;\n }\n if (typeof data === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n // Check if this is a Strapi v4 relation response { data: { id, attributes } }\n if (value && typeof value === 'object' && 'data' in value) {\n const relationData = (value as { data: unknown }).data;\n if (relationData === null) {\n result[key] = null;\n } else if (Array.isArray(relationData)) {\n // To-many relation\n result[key] = relationData.map((item: StrapiV4RawItem<unknown>) =>\n flattenRelations(flattenItem(item))\n );\n } else if (typeof relationData === 'object' && 'id' in relationData && 'attributes' in relationData) {\n // To-one relation\n result[key] = flattenRelations(flattenItem(relationData as StrapiV4RawItem<unknown>));\n } else {\n result[key] = flattenRelations(value);\n }\n } else {\n result[key] = flattenRelations(value);\n }\n }\n return result as T;\n }\n return data;\n}\n\n// Helper to get typed collection\nexport function collection<T>(pluralName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T[]; meta: { pagination: StrapiPagination } }> {\n const response = await strapi.find(pluralName, params) as unknown as StrapiV4RawListResponse<T>;\n const flattenedData = Array.isArray(response.data)\n ? response.data.map(item => flattenRelations(flattenItem<T>(item)))\n : [];\n return {\n data: flattenedData,\n meta: {\n pagination: response.meta?.pagination || defaultPagination,\n },\n };\n },\n async findOne(id: number | string, params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.findOne(pluralName, String(id), params) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async create(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.create(pluralName, data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async update(id: number | string, data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(pluralName, String(id), data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async delete(id: number | string): Promise<void> {\n await strapi.delete(pluralName, String(id));\n },\n };\n}\n\n// Helper to get typed single type\nexport function single<T>(singularName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.find(singularName, params) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async update(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(singularName, 1 as unknown as string, data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async delete(): Promise<void> {\n await strapi.delete(singularName, 1 as unknown as string);\n },\n };\n}\n`;\n}\n","import path from 'node:path';\nimport type { StrapiLocale } from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\n\nexport interface LocalesGeneratorOptions {\n outputDir: string;\n}\n\n/**\n * Generate locales file from Strapi i18n configuration\n */\nexport async function generateLocales(\n locales: StrapiLocale[],\n options: LocalesGeneratorOptions\n): Promise<string[]> {\n const { outputDir } = options;\n const generatedFiles: string[] = [];\n\n await ensureDir(outputDir);\n\n const filePath = path.join(outputDir, 'locales.ts');\n const content = generateLocalesFile(locales);\n await writeFile(filePath, await formatCode(content));\n generatedFiles.push(filePath);\n\n return generatedFiles;\n}\n\n/**\n * Generate the locales file content\n */\nfunction generateLocalesFile(locales: StrapiLocale[]): string {\n if (locales.length === 0) {\n return `/**\n * Strapi Locales\n * Generated by strapi2front\n *\n * Note: No locales found. i18n might not be enabled in Strapi.\n */\n\nexport const locales = [] as const;\n\nexport type Locale = string;\n\nexport const defaultLocale: Locale = 'en';\n\nexport const localeNames: Record<string, string> = {};\n`;\n }\n\n const defaultLocale = locales.find(l => l.isDefault)?.code || locales[0]?.code || 'en';\n const localeCodes = locales.map(l => `'${l.code}'`).join(' | ');\n const localeArray = locales.map(l => `'${l.code}'`).join(', ');\n const localeNames = locales.map(l => ` '${l.code}': '${l.name}'`).join(',\\n');\n\n return `/**\n * Strapi Locales\n * Generated by strapi2front\n */\n\n/**\n * Available locale codes\n */\nexport const locales = [${localeArray}] as const;\n\n/**\n * Locale type - union of all available locales\n */\nexport type Locale = ${localeCodes};\n\n/**\n * Default locale\n */\nexport const defaultLocale: Locale = '${defaultLocale}';\n\n/**\n * Locale display names\n */\nexport const localeNames: Record<Locale, string> = {\n${localeNames}\n};\n\n/**\n * Check if a string is a valid locale\n */\nexport function isValidLocale(code: string): code is Locale {\n return locales.includes(code as Locale);\n}\n\n/**\n * Get locale name by code\n */\nexport function getLocaleName(code: Locale): string {\n return localeNames[code] || code;\n}\n`;\n}\n","import path from 'node:path';\nimport type {\n ParsedSchema,\n CollectionType,\n SingleType,\n ComponentType,\n Attribute,\n StrapiLocale,\n} from '@strapi2front/core';\nimport { formatCode } from '../utils/formatter.js';\nimport { writeFile, ensureDir } from '../utils/file.js';\nimport { toPascalCase, toCamelCase, toKebabCase } from '../utils/naming.js';\n\nexport interface ByFeatureGeneratorOptions {\n outputDir: string;\n features: {\n types: boolean;\n services: boolean;\n actions: boolean;\n };\n blocksRendererInstalled?: boolean;\n strapiVersion?: \"v4\" | \"v5\";\n}\n\n/**\n * Generate all files using 'by-feature' structure\n *\n * Output structure:\n * strapi/\n * collections/\n * article/\n * types.ts\n * service.ts\n * actions.ts\n * singles/\n * homepage/\n * types.ts\n * service.ts\n * components/\n * seo.ts\n * shared/\n * utils.ts\n * client.ts\n * locales.ts\n */\nexport async function generateByFeature(\n schema: ParsedSchema,\n locales: StrapiLocale[],\n options: ByFeatureGeneratorOptions\n): Promise<string[]> {\n const { outputDir, features, blocksRendererInstalled = false, strapiVersion = \"v5\" } = options;\n const generatedFiles: string[] = [];\n\n // Ensure directories exist\n await ensureDir(path.join(outputDir, 'collections'));\n await ensureDir(path.join(outputDir, 'singles'));\n await ensureDir(path.join(outputDir, 'components'));\n await ensureDir(path.join(outputDir, 'shared'));\n\n // Generate shared files\n const sharedDir = path.join(outputDir, 'shared');\n\n // Utils\n const utilsPath = path.join(sharedDir, 'utils.ts');\n await writeFile(utilsPath, await formatCode(generateUtilityTypes(blocksRendererInstalled, strapiVersion)));\n generatedFiles.push(utilsPath);\n\n // Client\n const clientPath = path.join(sharedDir, 'client.ts');\n await writeFile(clientPath, await formatCode(generateClient(strapiVersion)));\n generatedFiles.push(clientPath);\n\n // Locales\n const localesPath = path.join(sharedDir, 'locales.ts');\n await writeFile(localesPath, await formatCode(generateLocalesFile(locales)));\n generatedFiles.push(localesPath);\n\n // Generate collection files\n for (const collection of schema.collections) {\n const featureDir = path.join(outputDir, 'collections', toKebabCase(collection.singularName));\n await ensureDir(featureDir);\n\n if (features.types) {\n const typesPath = path.join(featureDir, 'types.ts');\n await writeFile(typesPath, await formatCode(generateCollectionTypes(collection, schema)));\n generatedFiles.push(typesPath);\n }\n\n if (features.services) {\n const servicePath = path.join(featureDir, 'service.ts');\n await writeFile(servicePath, await formatCode(generateCollectionService(collection, strapiVersion)));\n generatedFiles.push(servicePath);\n }\n\n if (features.actions) {\n const actionsPath = path.join(featureDir, 'actions.ts');\n await writeFile(actionsPath, await formatCode(generateCollectionActions(collection, strapiVersion)));\n generatedFiles.push(actionsPath);\n }\n }\n\n // Generate single type files\n for (const single of schema.singles) {\n const featureDir = path.join(outputDir, 'singles', toKebabCase(single.singularName));\n await ensureDir(featureDir);\n\n if (features.types) {\n const typesPath = path.join(featureDir, 'types.ts');\n await writeFile(typesPath, await formatCode(generateSingleTypes(single, schema)));\n generatedFiles.push(typesPath);\n }\n\n if (features.services) {\n const servicePath = path.join(featureDir, 'service.ts');\n await writeFile(servicePath, await formatCode(generateSingleService(single, strapiVersion)));\n generatedFiles.push(servicePath);\n }\n }\n\n // Generate component files\n for (const component of schema.components) {\n const componentPath = path.join(outputDir, 'components', `${toKebabCase(component.name)}.ts`);\n await writeFile(componentPath, await formatCode(generateComponentTypes(component, schema)));\n generatedFiles.push(componentPath);\n }\n\n return generatedFiles;\n}\n\n// ============================================\n// Shared Files Generation\n// ============================================\n\nfunction generateUtilityTypes(blocksRendererInstalled: boolean, strapiVersion: \"v4\" | \"v5\"): string {\n const isV4 = strapiVersion === \"v4\";\n\n const blocksContentType = isV4\n ? `/**\n * Rich text content (Strapi v4)\n * Can be markdown string or custom JSON structure\n */\nexport type RichTextContent = string;`\n : blocksRendererInstalled\n ? `/**\n * Blocks content type (Strapi v5 rich text)\n * Re-exported from @strapi/blocks-react-renderer\n */\nexport type { BlocksContent } from '@strapi/blocks-react-renderer';`\n : `/**\n * Blocks content type (Strapi v5 rich text)\n *\n * For full type support and rendering, install:\n * npm install @strapi/blocks-react-renderer\n *\n * Then re-run: npx strapi2front sync\n */\nexport type BlocksContent = unknown[];`;\n\n const baseEntity = isV4\n ? `export interface StrapiBaseEntity {\n id: number;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n}`\n : `export interface StrapiBaseEntity {\n id: number;\n documentId: string;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n}`;\n\n const mediaType = isV4\n ? `export interface StrapiMedia {\n id: number;\n name: string;\n alternativeText: string | null;\n caption: string | null;\n width: number;\n height: number;\n formats: {\n thumbnail?: StrapiMediaFormat;\n small?: StrapiMediaFormat;\n medium?: StrapiMediaFormat;\n large?: StrapiMediaFormat;\n } | null;\n hash: string;\n ext: string;\n mime: string;\n size: number;\n url: string;\n previewUrl: string | null;\n provider: string;\n createdAt: string;\n updatedAt: string;\n}`\n : `export interface StrapiMedia {\n id: number;\n documentId: string;\n name: string;\n alternativeText: string | null;\n caption: string | null;\n width: number;\n height: number;\n formats: {\n thumbnail?: StrapiMediaFormat;\n small?: StrapiMediaFormat;\n medium?: StrapiMediaFormat;\n large?: StrapiMediaFormat;\n } | null;\n hash: string;\n ext: string;\n mime: string;\n size: number;\n url: string;\n previewUrl: string | null;\n provider: string;\n createdAt: string;\n updatedAt: string;\n}`;\n\n const v4RawResponseTypes = isV4 ? `\n\n/**\n * Strapi v4 raw API response (with nested attributes)\n */\nexport interface StrapiV4RawItem<T> {\n id: number;\n attributes: Omit<T, 'id'>;\n}\n\nexport interface StrapiV4RawResponse<T> {\n data: StrapiV4RawItem<T>;\n meta: Record<string, unknown>;\n}\n\nexport interface StrapiV4RawListResponse<T> {\n data: StrapiV4RawItem<T>[];\n meta: {\n pagination: StrapiPagination;\n };\n}\n\n/**\n * Flatten Strapi v4 response item\n */\nexport function flattenV4Response<T>(item: StrapiV4RawItem<T>): T {\n return { id: item.id, ...item.attributes } as T;\n}\n\n/**\n * Flatten Strapi v4 list response\n */\nexport function flattenV4ListResponse<T>(items: StrapiV4RawItem<T>[]): T[] {\n return items.map(item => flattenV4Response<T>(item));\n}` : '';\n\n return `/**\n * Strapi utility types\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${mediaType}\n\nexport interface StrapiMediaFormat {\n name: string;\n hash: string;\n ext: string;\n mime: string;\n width: number;\n height: number;\n size: number;\n url: string;\n}\n\nexport interface StrapiPagination {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n}\n\nexport interface StrapiResponse<T> {\n data: T;\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\nexport interface StrapiListResponse<T> {\n data: T[];\n meta: {\n pagination: StrapiPagination;\n };\n}\n\n${baseEntity}\n${v4RawResponseTypes}\n${blocksContentType}\n`;\n}\n\nfunction generateClient(strapiVersion: \"v4\" | \"v5\"): string {\n const isV4 = strapiVersion === \"v4\";\n\n if (isV4) {\n return `/**\n * Strapi Client (v4)\n * Generated by strapi2front\n */\n\nimport Strapi from 'strapi-sdk-js';\nimport type { StrapiPagination } from './utils';\n\n// Initialize the Strapi client\nconst strapiUrl = import.meta.env.STRAPI_URL || process.env.STRAPI_URL || 'http://localhost:1337';\nconst strapiToken = import.meta.env.STRAPI_TOKEN || process.env.STRAPI_TOKEN;\n\nexport const strapi = new Strapi({\n url: strapiUrl,\n axiosOptions: {\n headers: strapiToken ? {\n Authorization: \\`Bearer \\${strapiToken}\\`,\n } : {},\n },\n});\n\n// Default pagination for fallback\nconst defaultPagination: StrapiPagination = {\n page: 1,\n pageSize: 25,\n pageCount: 1,\n total: 0,\n};\n\n// Strapi v4 raw response types (with nested attributes)\ninterface StrapiV4RawItem<T> {\n id: number;\n attributes: Omit<T, 'id'>;\n}\n\ninterface StrapiV4RawListResponse<T> {\n data: StrapiV4RawItem<T>[];\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\ninterface StrapiV4RawSingleResponse<T> {\n data: StrapiV4RawItem<T>;\n meta?: Record<string, unknown>;\n}\n\n/**\n * Flatten a Strapi v4 response item (merges id with attributes)\n */\nfunction flattenItem<T>(item: StrapiV4RawItem<T>): T {\n return { id: item.id, ...item.attributes } as T;\n}\n\n/**\n * Recursively flatten nested relations in Strapi v4 response\n */\nfunction flattenRelations<T>(data: T): T {\n if (data === null || data === undefined) return data;\n if (Array.isArray(data)) {\n return data.map(item => flattenRelations(item)) as unknown as T;\n }\n if (typeof data === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n // Check if this is a Strapi v4 relation response { data: { id, attributes } }\n if (value && typeof value === 'object' && 'data' in value) {\n const relationData = (value as { data: unknown }).data;\n if (relationData === null) {\n result[key] = null;\n } else if (Array.isArray(relationData)) {\n // To-many relation\n result[key] = relationData.map((item: StrapiV4RawItem<unknown>) =>\n flattenRelations(flattenItem(item))\n );\n } else if (typeof relationData === 'object' && 'id' in relationData && 'attributes' in relationData) {\n // To-one relation\n result[key] = flattenRelations(flattenItem(relationData as StrapiV4RawItem<unknown>));\n } else {\n result[key] = flattenRelations(value);\n }\n } else {\n result[key] = flattenRelations(value);\n }\n }\n return result as T;\n }\n return data;\n}\n\n// Helper to get typed collection\nexport function collection<T>(pluralName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T[]; meta: { pagination: StrapiPagination } }> {\n const response = await strapi.find(pluralName, params) as unknown as StrapiV4RawListResponse<T>;\n const flattenedData = Array.isArray(response.data)\n ? response.data.map(item => flattenRelations(flattenItem<T>(item)))\n : [];\n return {\n data: flattenedData,\n meta: {\n pagination: response.meta?.pagination || defaultPagination,\n },\n };\n },\n async findOne(id: number | string, params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.findOne(pluralName, String(id), params) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async create(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.create(pluralName, data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async update(id: number | string, data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(pluralName, String(id), data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async delete(id: number | string): Promise<void> {\n await strapi.delete(pluralName, String(id));\n },\n };\n}\n\n// Helper to get typed single type\nexport function single<T>(singularName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.find(singularName, params) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async update(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(singularName, 1 as unknown as string, data.data as Record<string, unknown>) as unknown as StrapiV4RawSingleResponse<T>;\n return { data: flattenRelations(flattenItem<T>(response.data)) };\n },\n async delete(): Promise<void> {\n await strapi.delete(singularName, 1 as unknown as string);\n },\n };\n}\n`;\n }\n\n return `/**\n * Strapi Client (v5)\n * Generated by strapi2front\n */\n\nimport Strapi from 'strapi-sdk-js';\nimport type { StrapiPagination } from './utils';\n\n// Initialize the Strapi client\nconst strapiUrl = import.meta.env.STRAPI_URL || process.env.STRAPI_URL || 'http://localhost:1337';\nconst strapiToken = import.meta.env.STRAPI_TOKEN || process.env.STRAPI_TOKEN;\n\nexport const strapi = new Strapi({\n url: strapiUrl,\n axiosOptions: {\n headers: strapiToken ? {\n Authorization: \\`Bearer \\${strapiToken}\\`,\n } : {},\n },\n});\n\n// Default pagination for fallback\nconst defaultPagination: StrapiPagination = {\n page: 1,\n pageSize: 25,\n pageCount: 1,\n total: 0,\n};\n\n// Response types from strapi-sdk-js\ninterface StrapiListResponse<T> {\n data: T[];\n meta: {\n pagination?: StrapiPagination;\n };\n}\n\ninterface StrapiSingleResponse<T> {\n data: T;\n meta?: Record<string, unknown>;\n}\n\n// Helper to get typed collection\nexport function collection<T>(pluralName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T[]; meta: { pagination: StrapiPagination } }> {\n const response = await strapi.find(pluralName, params) as unknown as StrapiListResponse<T>;\n return {\n data: Array.isArray(response.data) ? response.data : [],\n meta: {\n pagination: response.meta?.pagination || defaultPagination,\n },\n };\n },\n async findOne(documentId: string, params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.findOne(pluralName, documentId, params) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async create(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.create(pluralName, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async update(documentId: string, data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(pluralName, documentId, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async delete(documentId: string): Promise<void> {\n await strapi.delete(pluralName, documentId);\n },\n };\n}\n\n// Helper to get typed single type\nexport function single<T>(singularName: string) {\n return {\n async find(params?: Record<string, unknown>): Promise<{ data: T }> {\n const response = await strapi.find(singularName, params) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async update(data: { data: Partial<T> }): Promise<{ data: T }> {\n const response = await strapi.update(singularName, 1 as unknown as string, data.data as Record<string, unknown>) as unknown as StrapiSingleResponse<T>;\n return { data: response.data };\n },\n async delete(): Promise<void> {\n await strapi.delete(singularName, 1 as unknown as string);\n },\n };\n}\n`;\n}\n\nfunction generateLocalesFile(locales: StrapiLocale[]): string {\n if (locales.length === 0) {\n return `/**\n * Strapi locales\n * Generated by strapi2front\n * Note: i18n is not enabled in Strapi\n */\n\nexport const locales = [] as const;\nexport type Locale = string;\nexport const defaultLocale: Locale = 'en';\nexport const localeNames: Record<string, string> = {};\n\nexport function isValidLocale(_code: string): _code is Locale {\n return true;\n}\n\nexport function getLocaleName(code: string): string {\n return code;\n}\n`;\n }\n\n const localeCodes = locales.map(l => l.code);\n const defaultLocale = locales.find(l => l.isDefault)?.code || locales[0]?.code || 'en';\n\n return `/**\n * Strapi locales\n * Generated by strapi2front\n */\n\nexport const locales = [${localeCodes.map(c => `'${c}'`).join(', ')}] as const;\n\nexport type Locale = typeof locales[number];\n\nexport const defaultLocale: Locale = '${defaultLocale}';\n\nexport const localeNames: Record<Locale, string> = {\n${locales.map(l => ` '${l.code}': '${l.name}'`).join(',\\n')}\n};\n\nexport function isValidLocale(code: string): code is Locale {\n return locales.includes(code as Locale);\n}\n\nexport function getLocaleName(code: Locale): string {\n return localeNames[code] || code;\n}\n`;\n}\n\n// ============================================\n// Collection Types Generation\n// ============================================\n\nfunction generateCollectionTypes(collection: CollectionType, schema: ParsedSchema): string {\n const typeName = toPascalCase(collection.singularName);\n const attributes = generateAttributes(collection.attributes);\n const imports = generateTypeImports(collection.attributes, schema, 'collection');\n\n return `/**\n * ${collection.displayName}\n * ${collection.description || ''}\n * Generated by strapi2front\n */\n\n${imports}\n\nexport interface ${typeName} extends StrapiBaseEntity {\n${attributes}\n}\n\nexport interface ${typeName}Filters {\n id?: number | { $eq?: number; $ne?: number; $in?: number[]; $notIn?: number[] };\n documentId?: string | { $eq?: string; $ne?: string };\n createdAt?: string | { $eq?: string; $gt?: string; $gte?: string; $lt?: string; $lte?: string };\n updatedAt?: string | { $eq?: string; $gt?: string; $gte?: string; $lt?: string; $lte?: string };\n publishedAt?: string | null | { $eq?: string; $ne?: string; $null?: boolean };\n $and?: ${typeName}Filters[];\n $or?: ${typeName}Filters[];\n $not?: ${typeName}Filters;\n}\n`;\n}\n\nfunction generateSingleTypes(single: SingleType, schema: ParsedSchema): string {\n const typeName = toPascalCase(single.singularName);\n const attributes = generateAttributes(single.attributes);\n const imports = generateTypeImports(single.attributes, schema, 'single');\n\n return `/**\n * ${single.displayName}\n * ${single.description || ''}\n * Generated by strapi2front\n */\n\n${imports}\n\nexport interface ${typeName} extends StrapiBaseEntity {\n${attributes}\n}\n`;\n}\n\nfunction generateComponentTypes(component: ComponentType, schema: ParsedSchema): string {\n const typeName = toPascalCase(component.name);\n const attributes = generateAttributes(component.attributes);\n const imports = generateTypeImports(component.attributes, schema, 'component');\n\n return `/**\n * ${component.displayName} component\n * Category: ${component.category}\n * ${component.description || ''}\n * Generated by strapi2front\n */\n\n${imports}\n\nexport interface ${typeName} {\n id: number;\n${attributes}\n}\n`;\n}\n\nfunction generateTypeImports(\n attributes: Record<string, Attribute>,\n schema: ParsedSchema,\n context: 'collection' | 'single' | 'component'\n): string {\n const utilsImports: string[] = [];\n const relationImports: Map<string, string> = new Map();\n const componentImports: Map<string, string> = new Map();\n\n // Check what utils we need\n const attributesStr = JSON.stringify(attributes);\n if (context !== 'component') {\n utilsImports.push('StrapiBaseEntity');\n }\n if (attributesStr.includes('\"type\":\"media\"')) {\n utilsImports.push('StrapiMedia');\n }\n if (attributesStr.includes('\"type\":\"blocks\"')) {\n utilsImports.push('BlocksContent');\n }\n\n // Extract relations and components\n // Components are in strapi/components/, collections/singles are in strapi/collections/xxx/ or strapi/singles/xxx/\n // From component: ../collections/xxx/types (one level up)\n // From collection/single: ../../collections/xxx/types (two levels up, since they're in a subfolder)\n const relativePrefix = context === 'component' ? '..' : '../..';\n\n for (const attr of Object.values(attributes)) {\n if (attr.type === 'relation' && 'target' in attr && attr.target) {\n const targetName = attr.target.split('.').pop() || '';\n if (targetName) {\n const typeName = toPascalCase(targetName);\n const fileName = toKebabCase(targetName);\n // Check if it's a collection or single\n const isCollection = schema.collections.some(c => c.singularName === targetName);\n const isSingle = schema.singles.some(s => s.singularName === targetName);\n if (isCollection) {\n relationImports.set(typeName, `${relativePrefix}/collections/${fileName}/types`);\n } else if (isSingle) {\n relationImports.set(typeName, `${relativePrefix}/singles/${fileName}/types`);\n }\n }\n }\n\n if (attr.type === 'component' && 'component' in attr && attr.component) {\n const componentName = attr.component.split('.').pop() || '';\n if (componentName) {\n const typeName = toPascalCase(componentName);\n const fileName = toKebabCase(componentName);\n if (context === 'component') {\n componentImports.set(typeName, `./${fileName}`);\n } else {\n componentImports.set(typeName, `../../components/${fileName}`);\n }\n }\n }\n\n if (attr.type === 'dynamiczone' && 'components' in attr && attr.components) {\n for (const comp of attr.components) {\n const componentName = comp.split('.').pop() || '';\n if (componentName) {\n const typeName = toPascalCase(componentName);\n const fileName = toKebabCase(componentName);\n if (context === 'component') {\n componentImports.set(typeName, `./${fileName}`);\n } else {\n componentImports.set(typeName, `../../components/${fileName}`);\n }\n }\n }\n }\n }\n\n const lines: string[] = [];\n\n // Utils import\n if (utilsImports.length > 0) {\n const utilsPath = context === 'component' ? '../shared/utils' : '../../shared/utils';\n lines.push(`import type { ${utilsImports.join(', ')} } from '${utilsPath}';`);\n }\n\n // Relation imports\n for (const [typeName, importPath] of relationImports) {\n lines.push(`import type { ${typeName} } from '${importPath}';`);\n }\n\n // Component imports\n for (const [typeName, importPath] of componentImports) {\n lines.push(`import type { ${typeName} } from '${importPath}';`);\n }\n\n return lines.join('\\n');\n}\n\nfunction generateAttributes(attributes: Record<string, Attribute>): string {\n const lines: string[] = [];\n\n for (const [name, attr] of Object.entries(attributes)) {\n const tsType = attributeToTsType(attr);\n const optional = attr.required ? '' : '?';\n lines.push(` ${name}${optional}: ${tsType};`);\n }\n\n return lines.join('\\n');\n}\n\nfunction attributeToTsType(attr: Attribute): string {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'password':\n case 'uid':\n return 'string';\n case 'blocks':\n return 'BlocksContent';\n case 'integer':\n case 'biginteger':\n case 'float':\n case 'decimal':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'date':\n case 'time':\n case 'datetime':\n case 'timestamp':\n return 'string';\n case 'json':\n return 'unknown';\n case 'enumeration':\n if ('enum' in attr && attr.enum) {\n return attr.enum.map(v => `'${v}'`).join(' | ');\n }\n return 'string';\n case 'media':\n if ('multiple' in attr && attr.multiple) {\n return 'StrapiMedia[]';\n }\n return 'StrapiMedia | null';\n case 'relation':\n if ('target' in attr && attr.target) {\n const targetName = toPascalCase(attr.target.split('.').pop() || 'unknown');\n const isMany = attr.relation === 'oneToMany' || attr.relation === 'manyToMany';\n return isMany ? `${targetName}[]` : `${targetName} | null`;\n }\n return 'unknown';\n case 'component':\n if ('component' in attr && attr.component) {\n const componentName = toPascalCase(attr.component.split('.').pop() || 'unknown');\n if ('repeatable' in attr && attr.repeatable) {\n return `${componentName}[]`;\n }\n return `${componentName} | null`;\n }\n return 'unknown';\n case 'dynamiczone':\n if ('components' in attr && attr.components) {\n const types = attr.components.map(c => toPascalCase(c.split('.').pop() || 'unknown'));\n return `(${types.join(' | ')})[]`;\n }\n return 'unknown[]';\n default:\n return 'unknown';\n }\n}\n\n// ============================================\n// Collection Service Generation\n// ============================================\n\nfunction generateCollectionService(collection: CollectionType, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(collection.singularName);\n const serviceName = toCamelCase(collection.singularName) + 'Service';\n const endpoint = collection.pluralName;\n const hasSlug = 'slug' in collection.attributes;\n const { localized, draftAndPublish } = collection;\n const isV4 = strapiVersion === \"v4\";\n\n // V4 uses `id: number`, V5 uses `documentId: string`\n const idParam = isV4 ? 'id: number' : 'documentId: string';\n const idName = isV4 ? 'id' : 'documentId';\n const omitFields = isV4\n ? \"'id' | 'createdAt' | 'updatedAt' | 'publishedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt' | 'publishedAt'\";\n const omitFieldsUpdate = isV4\n ? \"'id' | 'createdAt' | 'updatedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt'\";\n\n // Build imports\n const imports = [\n `import { collection } from '../../shared/client';`,\n `import type { ${typeName}, ${typeName}Filters } from './types';`,\n `import type { StrapiPagination } from '../../shared/utils';`,\n ];\n if (localized) {\n imports.push(`import type { Locale } from '../../shared/locales';`);\n }\n\n // Build options interfaces\n const paginationFields = `\n /** Page number (1-indexed) - use with pageSize */\n page?: number;\n /** Number of items per page (default: 25) - use with page */\n pageSize?: number;\n /** Offset to start from (0-indexed) - use with limit */\n start?: number;\n /** Maximum number of items to return - use with start */\n limit?: number;`;\n\n let findManyOptionsFields = ` filters?: ${typeName}Filters;\n pagination?: {${paginationFields}\n };\n sort?: string | string[];\n populate?: string | string[] | Record<string, unknown>;`;\n\n let findOneOptionsFields = ` populate?: string | string[] | Record<string, unknown>;`;\n\n if (localized) {\n findManyOptionsFields += `\\n locale?: Locale;`;\n findOneOptionsFields += `\\n locale?: Locale;`;\n }\n if (draftAndPublish) {\n findManyOptionsFields += `\\n status?: 'draft' | 'published';`;\n findOneOptionsFields += `\\n status?: 'draft' | 'published';`;\n }\n\n // Build find params\n let findParams = ` filters: options.filters,\n pagination: options.pagination,\n sort: options.sort,\n populate: options.populate,`;\n let findOneParams = ` populate: options.populate,`;\n\n if (localized) {\n findParams += `\\n locale: options.locale,`;\n findOneParams += `\\n locale: options.locale,`;\n }\n if (draftAndPublish) {\n findParams += `\\n status: options.status,`;\n findOneParams += `\\n status: options.status,`;\n }\n\n return `/**\n * ${collection.displayName} Service\n * ${collection.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${imports.join('\\n')}\n\nexport interface FindManyOptions {\n${findManyOptionsFields}\n}\n\nexport interface FindOneOptions {\n${findOneOptionsFields}\n}\n\n// Create typed collection helper\nconst ${toCamelCase(collection.singularName)}Collection = collection<${typeName}>('${endpoint}');\n\nexport const ${serviceName} = {\n async findMany(options: FindManyOptions = {}): Promise<{ data: ${typeName}[]; pagination: StrapiPagination }> {\n const response = await ${toCamelCase(collection.singularName)}Collection.find({\n${findParams}\n });\n\n return {\n data: response.data,\n pagination: response.meta.pagination,\n };\n },\n\n async findAll(options: Omit<FindManyOptions, 'pagination'> = {}): Promise<${typeName}[]> {\n const allItems: ${typeName}[] = [];\n let page = 1;\n let hasMore = true;\n\n while (hasMore) {\n const { data, pagination } = await this.findMany({\n ...options,\n pagination: { page, pageSize: 100 },\n });\n\n allItems.push(...data);\n hasMore = page < pagination.pageCount;\n page++;\n }\n\n return allItems;\n },\n\n async findOne(${idParam}, options: FindOneOptions = {}): Promise<${typeName} | null> {\n try {\n const response = await ${toCamelCase(collection.singularName)}Collection.findOne(${idName}, {\n${findOneParams}\n });\n\n return response.data;\n } catch (error) {\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw error;\n }\n },\n${hasSlug ? `\n async findBySlug(slug: string, options: FindOneOptions = {}): Promise<${typeName} | null> {\n const { data } = await this.findMany({\n filters: { slug: { $eq: slug } } as ${typeName}Filters,\n pagination: { pageSize: 1 },\n populate: options.populate,${localized ? '\\n locale: options.locale,' : ''}${draftAndPublish ? '\\n status: options.status,' : ''}\n });\n\n return data[0] || null;\n },\n` : ''}\n async create(data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(collection.singularName)}Collection.create({ data });\n return response.data;\n },\n\n async update(${idParam}, data: Partial<Omit<${typeName}, ${omitFieldsUpdate}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(collection.singularName)}Collection.update(${idName}, { data });\n return response.data;\n },\n\n async delete(${idParam}): Promise<void> {\n await ${toCamelCase(collection.singularName)}Collection.delete(${idName});\n },\n\n async count(filters?: ${typeName}Filters): Promise<number> {\n const { pagination } = await this.findMany({\n filters,\n pagination: { pageSize: 1 },\n });\n\n return pagination.total;\n },\n};\n`;\n}\n\n// ============================================\n// Single Service Generation\n// ============================================\n\nfunction generateSingleService(single: SingleType, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(single.singularName);\n const serviceName = toCamelCase(single.singularName) + 'Service';\n const endpoint = single.singularName;\n const { localized, draftAndPublish } = single;\n const isV4 = strapiVersion === \"v4\";\n\n // V4 doesn't have documentId\n const omitFields = isV4\n ? \"'id' | 'createdAt' | 'updatedAt'\"\n : \"'id' | 'documentId' | 'createdAt' | 'updatedAt'\";\n\n // Build imports\n const imports = [\n `import { single } from '../../shared/client';`,\n `import type { ${typeName} } from './types';`,\n ];\n if (localized) {\n imports.push(`import type { Locale } from '../../shared/locales';`);\n }\n\n // Build options interface\n let findOptionsFields = ` populate?: string | string[] | Record<string, unknown>;`;\n if (localized) {\n findOptionsFields += `\\n locale?: Locale;`;\n }\n if (draftAndPublish) {\n findOptionsFields += `\\n status?: 'draft' | 'published';`;\n }\n\n // Build find params\n let findParams = ` populate: options.populate,`;\n if (localized) {\n findParams += `\\n locale: options.locale,`;\n }\n if (draftAndPublish) {\n findParams += `\\n status: options.status,`;\n }\n\n return `/**\n * ${single.displayName} Service (Single Type)\n * ${single.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\n${imports.join('\\n')}\n\nexport interface FindOptions {\n${findOptionsFields}\n}\n\n// Create typed single helper\nconst ${toCamelCase(single.singularName)}Single = single<${typeName}>('${endpoint}');\n\nexport const ${serviceName} = {\n async find(options: FindOptions = {}): Promise<${typeName} | null> {\n try {\n const response = await ${toCamelCase(single.singularName)}Single.find({\n${findParams}\n });\n\n return response.data;\n } catch (error) {\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw error;\n }\n },\n\n async update(data: Partial<Omit<${typeName}, ${omitFields}>>): Promise<${typeName}> {\n const response = await ${toCamelCase(single.singularName)}Single.update({ data });\n return response.data;\n },\n\n async delete(): Promise<void> {\n await ${toCamelCase(single.singularName)}Single.delete();\n },\n};\n`;\n}\n\n// ============================================\n// Collection Actions Generation\n// ============================================\n\nfunction generateCollectionActions(collection: CollectionType, strapiVersion: \"v4\" | \"v5\"): string {\n const typeName = toPascalCase(collection.singularName);\n const serviceName = toCamelCase(collection.singularName) + 'Service';\n const actionPrefix = toCamelCase(collection.singularName);\n const isV4 = strapiVersion === \"v4\";\n\n // V4 uses `id: number`, V5 uses `documentId: string`\n const idInputSchema = isV4 ? 'z.number().int().positive()' : 'z.string()';\n const idParamName = isV4 ? 'id' : 'documentId';\n\n return `/**\n * ${collection.displayName} Astro Actions\n * ${collection.description || ''}\n * Generated by strapi2front\n * Strapi version: ${strapiVersion}\n */\n\nimport { defineAction } from 'astro:actions';\nimport { z } from 'astro:schema';\nimport { ${serviceName} } from './service';\nimport type { ${typeName} } from './types';\n\nexport const ${actionPrefix}Actions = {\n getMany: defineAction({\n input: z.object({\n page: z.number().optional(),\n pageSize: z.number().optional(),\n sort: z.string().optional(),\n }).optional(),\n handler: async (input) => {\n const { data, pagination } = await ${serviceName}.findMany({\n pagination: input ? { page: input.page, pageSize: input.pageSize } : undefined,\n sort: input?.sort,\n });\n return { data, pagination };\n },\n }),\n\n getOne: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n }),\n handler: async (input) => {\n const data = await ${serviceName}.findOne(input.${idParamName});\n return { data };\n },\n }),\n\n create: defineAction({\n input: z.object({\n data: z.record(z.unknown()),\n }),\n handler: async (input) => {\n const data = await ${serviceName}.create(input.data as Partial<${typeName}>);\n return { data };\n },\n }),\n\n update: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n data: z.record(z.unknown()),\n }),\n handler: async (input) => {\n const data = await ${serviceName}.update(input.${idParamName}, input.data as Partial<${typeName}>);\n return { data };\n },\n }),\n\n delete: defineAction({\n input: z.object({\n ${idParamName}: ${idInputSchema},\n }),\n handler: async (input) => {\n await ${serviceName}.delete(input.${idParamName});\n return { success: true };\n },\n }),\n};\n`;\n}\n"]}
|