@bobbykim/manguito-cms-api 0.8.2 → 0.8.3
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/codegen/index.js +18 -8
- package/dist/codegen/index.js.map +1 -1
- package/dist/codegen/index.mjs +18 -8
- package/dist/codegen/index.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
package/dist/codegen/index.js
CHANGED
|
@@ -129,11 +129,18 @@ function fieldToZodSchema(field, registry) {
|
|
|
129
129
|
return "z.unknown()";
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
+
function acceptsNull(f) {
|
|
133
|
+
if ((0, import_manguito_cms_core.relationCardinality)(f) === "many") return false;
|
|
134
|
+
return f.db_column ? f.db_column.nullable : f.nullable;
|
|
135
|
+
}
|
|
136
|
+
function fieldEntrySchema(f, registry) {
|
|
137
|
+
let s = fieldToZodSchema(f, registry);
|
|
138
|
+
if (acceptsNull(f)) s += ".nullable()";
|
|
139
|
+
if (!f.required) s += ".optional()";
|
|
140
|
+
return s;
|
|
141
|
+
}
|
|
132
142
|
function generateParagraphObjectSchema(paragraph, registry) {
|
|
133
|
-
const entries = paragraph.fields.map((f) => {
|
|
134
|
-
const zodType = fieldToZodSchema(f, registry);
|
|
135
|
-
return `${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`;
|
|
136
|
-
});
|
|
143
|
+
const entries = paragraph.fields.map((f) => `${f.name}: ${fieldEntrySchema(f, registry)}`);
|
|
137
144
|
if (entries.length === 0) return "z.object({})";
|
|
138
145
|
return `z.object({ ${entries.join(", ")} })`;
|
|
139
146
|
}
|
|
@@ -148,10 +155,7 @@ function systemFieldEntries(schema) {
|
|
|
148
155
|
return entries;
|
|
149
156
|
}
|
|
150
157
|
function schemaFieldEntries(fields, registry) {
|
|
151
|
-
return fields.map((f) => {
|
|
152
|
-
const zodType = fieldToZodSchema(f, registry);
|
|
153
|
-
return ` ${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`;
|
|
154
|
-
});
|
|
158
|
+
return fields.map((f) => ` ${f.name}: ${fieldEntrySchema(f, registry)}`);
|
|
155
159
|
}
|
|
156
160
|
function generateContentSchema(schema, registry) {
|
|
157
161
|
const name = schemaVar(schema.name);
|
|
@@ -214,6 +218,10 @@ var ADMIN_LIST_QUERY = `z.object({
|
|
|
214
218
|
})`;
|
|
215
219
|
var SLUG_PARAMS = `z.object({ slug: z.string() })`;
|
|
216
220
|
var ID_PARAMS = `z.object({ id: z.string().uuid() })`;
|
|
221
|
+
var ITEM_IN_USE_RESPONSE = `{
|
|
222
|
+
content: { 'application/json': { schema: ErrorResponseSchema } },
|
|
223
|
+
description: 'ITEM_IN_USE: a required reference elsewhere still points at this item',
|
|
224
|
+
}`;
|
|
217
225
|
var INCLUDE_QUERY = `z.object({ include: z.string().optional().describe('Comma-separated relation field names to expand') })`;
|
|
218
226
|
function generateContentRoutes(contentType) {
|
|
219
227
|
const sVar = schemaVar(contentType.name);
|
|
@@ -373,6 +381,7 @@ function generateContentRoutes(contentType) {
|
|
|
373
381
|
content: { 'application/json': { schema: ErrorResponseSchema } },
|
|
374
382
|
description: '${label} not found',
|
|
375
383
|
},
|
|
384
|
+
409: ${ITEM_IN_USE_RESPONSE},
|
|
376
385
|
},
|
|
377
386
|
})`
|
|
378
387
|
);
|
|
@@ -634,6 +643,7 @@ function generateTaxonomyRoutes(taxonomyType) {
|
|
|
634
643
|
content: { 'application/json': { schema: ErrorResponseSchema } },
|
|
635
644
|
description: '${label} not found',
|
|
636
645
|
},
|
|
646
|
+
409: ${ITEM_IN_USE_RESPONSE},
|
|
637
647
|
},
|
|
638
648
|
})`
|
|
639
649
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/codegen/index.ts","../../src/codegen/routes.ts"],"sourcesContent":["export { generateRoutes, generateContentSchema, fieldToZodSchema } from './routes.js'\n","// generateRoutes() — pure function that returns a Hono route group from parsed schema\nimport type {\n SchemaRegistry,\n ParsedField,\n ParsedContentType,\n ParsedTaxonomyType,\n ParsedParagraphType,\n} from '@bobbykim/manguito-cms-core'\nimport { relationCardinality } from '@bobbykim/manguito-cms-core'\n\n// ─── Name helpers ─────────────────────────────────────────────────────────────\n\nfunction getSegment(machineName: string): string {\n const idx = machineName.indexOf('--')\n return idx !== -1 ? machineName.slice(idx + 2) : machineName\n}\n\nfunction toPascalCase(snakeOrKebab: string): string {\n return snakeOrKebab\n .split(/[_-]/)\n .filter(Boolean)\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join('')\n}\n\nfunction schemaVar(machineName: string): string {\n return toPascalCase(getSegment(machineName)) + 'Schema'\n}\n\nfunction routeVar(prefix: string, machineName: string, suffix: string): string {\n return `${prefix}${toPascalCase(getSegment(machineName))}${suffix}Route`\n}\n\n// Convert Hono :param notation to OpenAPI {param} notation\nfunction openApiPath(honoPath: string): string {\n return honoPath.replace(/:([^/]+)/g, '{$1}')\n}\n\n// ─── Field → Zod type string ──────────────────────────────────────────────────\n\nexport function fieldToZodSchema(field: ParsedField, registry?: SchemaRegistry): string {\n const { field_type, validation } = field\n\n switch (field_type) {\n case 'text/plain': {\n let s = 'z.string()'\n if (validation.limit !== undefined) s += `.max(${validation.limit})`\n if (validation.pattern !== undefined) s += `.regex(new RegExp(${JSON.stringify(validation.pattern)}))`\n return s\n }\n\n case 'text/rich':\n return 'z.string()'\n\n case 'integer': {\n let s = 'z.number().int()'\n if (validation.min !== undefined) s += `.min(${validation.min})`\n if (validation.max !== undefined) s += `.max(${validation.max})`\n return s\n }\n\n case 'float': {\n let s = 'z.number()'\n if (validation.min !== undefined) s += `.min(${validation.min})`\n if (validation.max !== undefined) s += `.max(${validation.max})`\n return s\n }\n\n case 'boolean':\n return 'z.boolean()'\n\n case 'date':\n return 'z.string().datetime()'\n\n case 'image': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n 'width: z.number().int().optional()',\n 'height: z.number().int().optional()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'video': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n 'width: z.number().int().optional()',\n 'height: z.number().int().optional()',\n 'duration: z.number().optional()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'file': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'enum': {\n const values = validation.allowed_values ?? []\n if (values.length === 0) return 'z.string()'\n const quoted = values.map((v) => JSON.stringify(v)).join(', ')\n return `z.enum([${quoted}])`\n }\n\n case 'paragraph': {\n const ui = field.ui_component\n if (ui.component !== 'paragraph-embed') return 'z.unknown()'\n const paragraphType = registry?.paragraph_types[ui.ref]\n if (!paragraphType) return 'z.unknown()'\n const inner = generateParagraphObjectSchema(paragraphType, registry)\n return relationCardinality(field) === 'many' ? `z.array(${inner})` : inner\n }\n\n case 'reference': {\n const ui = field.ui_component\n if (ui.component !== 'typeahead-select') return 'z.string().uuid()'\n return relationCardinality(field) === 'many' ? 'z.array(z.string().uuid())' : 'z.string().uuid()'\n }\n\n default:\n return 'z.unknown()'\n }\n}\n\n// Generates inline z.object({...}) for a paragraph type — used recursively inside fieldToZodSchema\nfunction generateParagraphObjectSchema(\n paragraph: ParsedParagraphType,\n registry?: SchemaRegistry\n): string {\n const entries = paragraph.fields.map((f) => {\n const zodType = fieldToZodSchema(f, registry)\n return `${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`\n })\n if (entries.length === 0) return 'z.object({})'\n return `z.object({ ${entries.join(', ')} })`\n}\n\n// ─── Schema declaration generators ───────────────────────────────────────────\n\nfunction systemFieldEntries(schema: ParsedContentType | ParsedTaxonomyType): string[] {\n const entries: string[] = ['id: z.string().uuid()']\n if (schema.schema_type === 'content-type' && !schema.only_one) {\n entries.push('slug: z.string()')\n }\n entries.push('published: z.boolean()')\n entries.push('created_at: z.string().datetime()')\n entries.push('updated_at: z.string().datetime()')\n return entries\n}\n\nfunction schemaFieldEntries(\n fields: ParsedField[],\n registry?: SchemaRegistry\n): string[] {\n return fields.map((f) => {\n const zodType = fieldToZodSchema(f, registry)\n return ` ${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`\n })\n}\n\nexport function generateContentSchema(\n schema: ParsedContentType | ParsedTaxonomyType,\n registry?: SchemaRegistry\n): string {\n const name = schemaVar(schema.name)\n const sysEntries = systemFieldEntries(schema).map((e) => ` ${e}`)\n const fieldEntries = schemaFieldEntries(schema.fields, registry)\n const allEntries = [...sysEntries, ...fieldEntries]\n return `const ${name} = z.object({\\n${allEntries.join(',\\n')},\\n})`\n}\n\n// Internal: paragraph schema const declaration (not exported but emitted into generated file)\nfunction generateParagraphSchemaDecl(\n paragraph: ParsedParagraphType,\n registry?: SchemaRegistry\n): string {\n const name = schemaVar(paragraph.name)\n const inner = generateParagraphObjectSchema(paragraph, registry)\n return `const ${name} = ${inner}`\n}\n\n// ─── Shared schemas block ─────────────────────────────────────────────────────\n\nconst SHARED_SCHEMAS_BLOCK = `const ErrorResponseSchema = z.object({\n ok: z.literal(false),\n error: z.object({\n code: z.string(),\n message: z.string(),\n details: z.unknown().optional(),\n }),\n})\n\nfunction listResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n ok: z.literal(true),\n data: z.array(dataSchema),\n meta: z.object({\n total: z.number().int(),\n page: z.number().int(),\n per_page: z.number().int(),\n total_pages: z.number().int(),\n has_next: z.boolean(),\n has_prev: z.boolean(),\n }),\n })\n}\n\nfunction itemResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n ok: z.literal(true),\n data: dataSchema,\n })\n}`\n\n// ─── Query param schema strings ───────────────────────────────────────────────\n\nconst PUBLIC_LIST_QUERY = `z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(10),\n include: z.string().optional().describe('Comma-separated relation field names to expand'),\n sort_by: z.enum(['title', 'created_at', 'updated_at']).optional().default('created_at'),\n sort_order: z.enum(['asc', 'desc']).optional().default('asc'),\n })`\n\nconst ADMIN_LIST_QUERY = `z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(10),\n include: z.string().optional().describe('Comma-separated relation field names to expand'),\n sort_by: z.enum(['title', 'created_at', 'updated_at']).optional().default('created_at'),\n sort_order: z.enum(['asc', 'desc']).optional().default('asc'),\n published: z.enum(['true', 'false']).optional().describe('Filter by published state'),\n })`\n\nconst SLUG_PARAMS = `z.object({ slug: z.string() })`\nconst ID_PARAMS = `z.object({ id: z.string().uuid() })`\nconst INCLUDE_QUERY = `z.object({ include: z.string().optional().describe('Comma-separated relation field names to expand') })`\n\n// ─── Content route generators ─────────────────────────────────────────────────\n\nfunction generateContentRoutes(contentType: ParsedContentType): string {\n const sVar = schemaVar(contentType.name)\n const label = contentType.label\n const tag = label\n const lines: string[] = []\n\n if (!contentType.only_one) {\n const collPath = contentType.api.collection_path!\n const itemPath = contentType.api.item_path\n\n // Public — GET list\n lines.push(\n `export const ${routeVar('get', contentType.name, 'List')} = createRoute({\n method: 'get',\n path: '${collPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${PUBLIC_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Public — GET single by slug\n lines.push(\n `export const ${routeVar('get', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${openApiPath(itemPath)}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${SLUG_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET list\n const adminCollPath = '/admin' + collPath\n const adminItemPath = adminCollPath + '/{id}'\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, 'List')} = createRoute({\n method: 'get',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${ADMIN_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Admin — GET single by id\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST\n lines.push(\n `export const ${routeVar('adminCreate', contentType.name, '')} = createRoute({\n method: 'post',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', contentType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — DELETE\n lines.push(\n `export const ${routeVar('adminDelete', contentType.name, '')} = createRoute({\n method: 'delete',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: z.object({ ok: z.literal(true) }) } },\n description: '${label} deleted',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n } else {\n // only_one: true — no list, no slug, fixed paths\n const itemPath = contentType.api.item_path\n const adminItemBase = '/admin' + itemPath\n const adminPatchPath = '/admin/api/' + contentType.default_base_path + '/{id}'\n\n // Public — GET singleton\n lines.push(\n `export const ${routeVar('get', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${itemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET singleton\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemBase}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST (create singleton)\n const adminPostPath = '/admin/api/' + contentType.default_base_path\n lines.push(\n `export const ${routeVar('adminCreate', contentType.name, '')} = createRoute({\n method: 'post',\n path: '${adminPostPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 409: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Singleton already exists',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', contentType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminPatchPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n }\n\n return lines.join('\\n\\n')\n}\n\n// ─── Taxonomy route generators ────────────────────────────────────────────────\n\nfunction generateTaxonomyRoutes(taxonomyType: ParsedTaxonomyType): string {\n const sVar = schemaVar(taxonomyType.name)\n const label = taxonomyType.label\n const tag = label\n const collPath = taxonomyType.api.collection_path\n const itemPath = taxonomyType.api.item_path\n const adminCollPath = '/admin' + collPath\n const adminItemPath = '/admin' + openApiPath(itemPath)\n const lines: string[] = []\n\n // Public — GET list\n lines.push(\n `export const ${routeVar('get', taxonomyType.name, 'List')} = createRoute({\n method: 'get',\n path: '${collPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${PUBLIC_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Public — GET single by id\n lines.push(\n `export const ${routeVar('get', taxonomyType.name, '')} = createRoute({\n method: 'get',\n path: '${openApiPath(itemPath)}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET list\n lines.push(\n `export const ${routeVar('adminGet', taxonomyType.name, 'List')} = createRoute({\n method: 'get',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${ADMIN_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Admin — GET single by id\n lines.push(\n `export const ${routeVar('adminGet', taxonomyType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST\n lines.push(\n `export const ${routeVar('adminCreate', taxonomyType.name, '')} = createRoute({\n method: 'post',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', taxonomyType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — DELETE\n lines.push(\n `export const ${routeVar('adminDelete', taxonomyType.name, '')} = createRoute({\n method: 'delete',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: z.object({ ok: z.literal(true) }) } },\n description: '${label} deleted',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n return lines.join('\\n\\n')\n}\n\n// ─── generateRoutes ───────────────────────────────────────────────────────────\n\nexport function generateRoutes(registry: SchemaRegistry): string {\n const parts: string[] = []\n\n parts.push('// Auto-generated by generateRoutes() — do not hand-edit')\n parts.push(\"import { createRoute, z } from '@hono/zod-openapi'\")\n parts.push('')\n parts.push('// ─── Shared schemas ──────────────────────────────────────────────────────────')\n parts.push('')\n parts.push(SHARED_SCHEMAS_BLOCK)\n parts.push('')\n\n const paragraphEntries = Object.entries(registry.paragraph_types)\n if (paragraphEntries.length > 0) {\n parts.push('// ─── Paragraph schemas ───────────────────────────────────────────────────────')\n parts.push('')\n for (const [, paragraphType] of paragraphEntries) {\n parts.push(generateParagraphSchemaDecl(paragraphType, registry))\n }\n parts.push('')\n }\n\n const contentEntries = Object.entries(registry.content_types)\n if (contentEntries.length > 0) {\n parts.push('// ─── Content type schemas ────────────────────────────────────────────────────')\n parts.push('')\n for (const [, contentType] of contentEntries) {\n parts.push(generateContentSchema(contentType, registry))\n parts.push('')\n }\n }\n\n const taxonomyEntries = Object.entries(registry.taxonomy_types)\n if (taxonomyEntries.length > 0) {\n parts.push('// ─── Taxonomy type schemas ───────────────────────────────────────────────────')\n parts.push('')\n for (const [, taxonomyType] of taxonomyEntries) {\n parts.push(generateContentSchema(taxonomyType, registry))\n parts.push('')\n }\n }\n\n if (contentEntries.length > 0) {\n parts.push('// ─── Content routes ─────────────────────────────────────────────────────────')\n parts.push('')\n for (const [, contentType] of contentEntries) {\n parts.push(generateContentRoutes(contentType))\n parts.push('')\n }\n }\n\n if (taxonomyEntries.length > 0) {\n parts.push('// ─── Taxonomy routes ────────────────────────────────────────────────────────')\n parts.push('')\n for (const [, taxonomyType] of taxonomyEntries) {\n parts.push(generateTaxonomyRoutes(taxonomyType))\n parts.push('')\n }\n }\n\n return parts.join('\\n')\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/codegen/index.ts","../../src/codegen/routes.ts"],"sourcesContent":["export { generateRoutes, generateContentSchema, fieldToZodSchema } from './routes.js'\n","// generateRoutes() — pure function that returns a Hono route group from parsed schema\nimport type {\n SchemaRegistry,\n ParsedField,\n ParsedContentType,\n ParsedTaxonomyType,\n ParsedParagraphType,\n} from '@bobbykim/manguito-cms-core'\nimport { relationCardinality } from '@bobbykim/manguito-cms-core'\n\n// ─── Name helpers ─────────────────────────────────────────────────────────────\n\nfunction getSegment(machineName: string): string {\n const idx = machineName.indexOf('--')\n return idx !== -1 ? machineName.slice(idx + 2) : machineName\n}\n\nfunction toPascalCase(snakeOrKebab: string): string {\n return snakeOrKebab\n .split(/[_-]/)\n .filter(Boolean)\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join('')\n}\n\nfunction schemaVar(machineName: string): string {\n return toPascalCase(getSegment(machineName)) + 'Schema'\n}\n\nfunction routeVar(prefix: string, machineName: string, suffix: string): string {\n return `${prefix}${toPascalCase(getSegment(machineName))}${suffix}Route`\n}\n\n// Convert Hono :param notation to OpenAPI {param} notation\nfunction openApiPath(honoPath: string): string {\n return honoPath.replace(/:([^/]+)/g, '{$1}')\n}\n\n// ─── Field → Zod type string ──────────────────────────────────────────────────\n\nexport function fieldToZodSchema(field: ParsedField, registry?: SchemaRegistry): string {\n const { field_type, validation } = field\n\n switch (field_type) {\n case 'text/plain': {\n let s = 'z.string()'\n if (validation.limit !== undefined) s += `.max(${validation.limit})`\n if (validation.pattern !== undefined) s += `.regex(new RegExp(${JSON.stringify(validation.pattern)}))`\n return s\n }\n\n case 'text/rich':\n return 'z.string()'\n\n case 'integer': {\n let s = 'z.number().int()'\n if (validation.min !== undefined) s += `.min(${validation.min})`\n if (validation.max !== undefined) s += `.max(${validation.max})`\n return s\n }\n\n case 'float': {\n let s = 'z.number()'\n if (validation.min !== undefined) s += `.min(${validation.min})`\n if (validation.max !== undefined) s += `.max(${validation.max})`\n return s\n }\n\n case 'boolean':\n return 'z.boolean()'\n\n case 'date':\n return 'z.string().datetime()'\n\n case 'image': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n 'width: z.number().int().optional()',\n 'height: z.number().int().optional()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'video': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n 'width: z.number().int().optional()',\n 'height: z.number().int().optional()',\n 'duration: z.number().optional()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'file': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'enum': {\n const values = validation.allowed_values ?? []\n if (values.length === 0) return 'z.string()'\n const quoted = values.map((v) => JSON.stringify(v)).join(', ')\n return `z.enum([${quoted}])`\n }\n\n case 'paragraph': {\n const ui = field.ui_component\n if (ui.component !== 'paragraph-embed') return 'z.unknown()'\n const paragraphType = registry?.paragraph_types[ui.ref]\n if (!paragraphType) return 'z.unknown()'\n const inner = generateParagraphObjectSchema(paragraphType, registry)\n return relationCardinality(field) === 'many' ? `z.array(${inner})` : inner\n }\n\n case 'reference': {\n const ui = field.ui_component\n if (ui.component !== 'typeahead-select') return 'z.string().uuid()'\n return relationCardinality(field) === 'many' ? 'z.array(z.string().uuid())' : 'z.string().uuid()'\n }\n\n default:\n return 'z.unknown()'\n }\n}\n\n// Whether the API stores and returns null for a field (#56). A column-backed\n// field follows its column, so an optional boolean (NOT NULL, default false)\n// does not. A list relation never does: it is [] when empty, and the API\n// refuses null for it. A column-less \"one\" paragraph is null when empty.\nfunction acceptsNull(f: ParsedField): boolean {\n if (relationCardinality(f) === 'many') return false\n return f.db_column ? f.db_column.nullable : f.nullable\n}\n\n// A field's schema as an object entry. A field that is not required may be\n// left out.\nfunction fieldEntrySchema(f: ParsedField, registry?: SchemaRegistry): string {\n let s = fieldToZodSchema(f, registry)\n if (acceptsNull(f)) s += '.nullable()'\n if (!f.required) s += '.optional()'\n return s\n}\n\n// Generates inline z.object({...}) for a paragraph type — used recursively inside fieldToZodSchema\nfunction generateParagraphObjectSchema(\n paragraph: ParsedParagraphType,\n registry?: SchemaRegistry\n): string {\n const entries = paragraph.fields.map((f) => `${f.name}: ${fieldEntrySchema(f, registry)}`)\n if (entries.length === 0) return 'z.object({})'\n return `z.object({ ${entries.join(', ')} })`\n}\n\n// ─── Schema declaration generators ───────────────────────────────────────────\n\nfunction systemFieldEntries(schema: ParsedContentType | ParsedTaxonomyType): string[] {\n const entries: string[] = ['id: z.string().uuid()']\n if (schema.schema_type === 'content-type' && !schema.only_one) {\n entries.push('slug: z.string()')\n }\n entries.push('published: z.boolean()')\n entries.push('created_at: z.string().datetime()')\n entries.push('updated_at: z.string().datetime()')\n return entries\n}\n\nfunction schemaFieldEntries(\n fields: ParsedField[],\n registry?: SchemaRegistry\n): string[] {\n return fields.map((f) => ` ${f.name}: ${fieldEntrySchema(f, registry)}`)\n}\n\nexport function generateContentSchema(\n schema: ParsedContentType | ParsedTaxonomyType,\n registry?: SchemaRegistry\n): string {\n const name = schemaVar(schema.name)\n const sysEntries = systemFieldEntries(schema).map((e) => ` ${e}`)\n const fieldEntries = schemaFieldEntries(schema.fields, registry)\n const allEntries = [...sysEntries, ...fieldEntries]\n return `const ${name} = z.object({\\n${allEntries.join(',\\n')},\\n})`\n}\n\n// Internal: paragraph schema const declaration (not exported but emitted into generated file)\nfunction generateParagraphSchemaDecl(\n paragraph: ParsedParagraphType,\n registry?: SchemaRegistry\n): string {\n const name = schemaVar(paragraph.name)\n const inner = generateParagraphObjectSchema(paragraph, registry)\n return `const ${name} = ${inner}`\n}\n\n// ─── Shared schemas block ─────────────────────────────────────────────────────\n\nconst SHARED_SCHEMAS_BLOCK = `const ErrorResponseSchema = z.object({\n ok: z.literal(false),\n error: z.object({\n code: z.string(),\n message: z.string(),\n details: z.unknown().optional(),\n }),\n})\n\nfunction listResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n ok: z.literal(true),\n data: z.array(dataSchema),\n meta: z.object({\n total: z.number().int(),\n page: z.number().int(),\n per_page: z.number().int(),\n total_pages: z.number().int(),\n has_next: z.boolean(),\n has_prev: z.boolean(),\n }),\n })\n}\n\nfunction itemResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n ok: z.literal(true),\n data: dataSchema,\n })\n}`\n\n// ─── Query param schema strings ───────────────────────────────────────────────\n\nconst PUBLIC_LIST_QUERY = `z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(10),\n include: z.string().optional().describe('Comma-separated relation field names to expand'),\n sort_by: z.enum(['title', 'created_at', 'updated_at']).optional().default('created_at'),\n sort_order: z.enum(['asc', 'desc']).optional().default('asc'),\n })`\n\nconst ADMIN_LIST_QUERY = `z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(10),\n include: z.string().optional().describe('Comma-separated relation field names to expand'),\n sort_by: z.enum(['title', 'created_at', 'updated_at']).optional().default('created_at'),\n sort_order: z.enum(['asc', 'desc']).optional().default('asc'),\n published: z.enum(['true', 'false']).optional().describe('Filter by published state'),\n })`\n\nconst SLUG_PARAMS = `z.object({ slug: z.string() })`\nconst ID_PARAMS = `z.object({ id: z.string().uuid() })`\n// The admin DELETE routes refuse with 409 ITEM_IN_USE while a required\n// reference elsewhere still points at the item. No label in the text: labels\n// are not quoted safely for a single-quoted string.\nconst ITEM_IN_USE_RESPONSE = `{\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'ITEM_IN_USE: a required reference elsewhere still points at this item',\n }`\n\nconst INCLUDE_QUERY = `z.object({ include: z.string().optional().describe('Comma-separated relation field names to expand') })`\n\n// ─── Content route generators ─────────────────────────────────────────────────\n\nfunction generateContentRoutes(contentType: ParsedContentType): string {\n const sVar = schemaVar(contentType.name)\n const label = contentType.label\n const tag = label\n const lines: string[] = []\n\n if (!contentType.only_one) {\n const collPath = contentType.api.collection_path!\n const itemPath = contentType.api.item_path\n\n // Public — GET list\n lines.push(\n `export const ${routeVar('get', contentType.name, 'List')} = createRoute({\n method: 'get',\n path: '${collPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${PUBLIC_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Public — GET single by slug\n lines.push(\n `export const ${routeVar('get', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${openApiPath(itemPath)}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${SLUG_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET list\n const adminCollPath = '/admin' + collPath\n const adminItemPath = adminCollPath + '/{id}'\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, 'List')} = createRoute({\n method: 'get',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${ADMIN_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Admin — GET single by id\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST\n lines.push(\n `export const ${routeVar('adminCreate', contentType.name, '')} = createRoute({\n method: 'post',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', contentType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — DELETE\n lines.push(\n `export const ${routeVar('adminDelete', contentType.name, '')} = createRoute({\n method: 'delete',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: z.object({ ok: z.literal(true) }) } },\n description: '${label} deleted',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 409: ${ITEM_IN_USE_RESPONSE},\n },\n})`\n )\n } else {\n // only_one: true — no list, no slug, fixed paths\n const itemPath = contentType.api.item_path\n const adminItemBase = '/admin' + itemPath\n const adminPatchPath = '/admin/api/' + contentType.default_base_path + '/{id}'\n\n // Public — GET singleton\n lines.push(\n `export const ${routeVar('get', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${itemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET singleton\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemBase}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST (create singleton)\n const adminPostPath = '/admin/api/' + contentType.default_base_path\n lines.push(\n `export const ${routeVar('adminCreate', contentType.name, '')} = createRoute({\n method: 'post',\n path: '${adminPostPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 409: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Singleton already exists',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', contentType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminPatchPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n }\n\n return lines.join('\\n\\n')\n}\n\n// ─── Taxonomy route generators ────────────────────────────────────────────────\n\nfunction generateTaxonomyRoutes(taxonomyType: ParsedTaxonomyType): string {\n const sVar = schemaVar(taxonomyType.name)\n const label = taxonomyType.label\n const tag = label\n const collPath = taxonomyType.api.collection_path\n const itemPath = taxonomyType.api.item_path\n const adminCollPath = '/admin' + collPath\n const adminItemPath = '/admin' + openApiPath(itemPath)\n const lines: string[] = []\n\n // Public — GET list\n lines.push(\n `export const ${routeVar('get', taxonomyType.name, 'List')} = createRoute({\n method: 'get',\n path: '${collPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${PUBLIC_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Public — GET single by id\n lines.push(\n `export const ${routeVar('get', taxonomyType.name, '')} = createRoute({\n method: 'get',\n path: '${openApiPath(itemPath)}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET list\n lines.push(\n `export const ${routeVar('adminGet', taxonomyType.name, 'List')} = createRoute({\n method: 'get',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${ADMIN_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Admin — GET single by id\n lines.push(\n `export const ${routeVar('adminGet', taxonomyType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST\n lines.push(\n `export const ${routeVar('adminCreate', taxonomyType.name, '')} = createRoute({\n method: 'post',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', taxonomyType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — DELETE\n lines.push(\n `export const ${routeVar('adminDelete', taxonomyType.name, '')} = createRoute({\n method: 'delete',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: z.object({ ok: z.literal(true) }) } },\n description: '${label} deleted',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 409: ${ITEM_IN_USE_RESPONSE},\n },\n})`\n )\n\n return lines.join('\\n\\n')\n}\n\n// ─── generateRoutes ───────────────────────────────────────────────────────────\n\nexport function generateRoutes(registry: SchemaRegistry): string {\n const parts: string[] = []\n\n parts.push('// Auto-generated by generateRoutes() — do not hand-edit')\n parts.push(\"import { createRoute, z } from '@hono/zod-openapi'\")\n parts.push('')\n parts.push('// ─── Shared schemas ──────────────────────────────────────────────────────────')\n parts.push('')\n parts.push(SHARED_SCHEMAS_BLOCK)\n parts.push('')\n\n const paragraphEntries = Object.entries(registry.paragraph_types)\n if (paragraphEntries.length > 0) {\n parts.push('// ─── Paragraph schemas ───────────────────────────────────────────────────────')\n parts.push('')\n for (const [, paragraphType] of paragraphEntries) {\n parts.push(generateParagraphSchemaDecl(paragraphType, registry))\n }\n parts.push('')\n }\n\n const contentEntries = Object.entries(registry.content_types)\n if (contentEntries.length > 0) {\n parts.push('// ─── Content type schemas ────────────────────────────────────────────────────')\n parts.push('')\n for (const [, contentType] of contentEntries) {\n parts.push(generateContentSchema(contentType, registry))\n parts.push('')\n }\n }\n\n const taxonomyEntries = Object.entries(registry.taxonomy_types)\n if (taxonomyEntries.length > 0) {\n parts.push('// ─── Taxonomy type schemas ───────────────────────────────────────────────────')\n parts.push('')\n for (const [, taxonomyType] of taxonomyEntries) {\n parts.push(generateContentSchema(taxonomyType, registry))\n parts.push('')\n }\n }\n\n if (contentEntries.length > 0) {\n parts.push('// ─── Content routes ─────────────────────────────────────────────────────────')\n parts.push('')\n for (const [, contentType] of contentEntries) {\n parts.push(generateContentRoutes(contentType))\n parts.push('')\n }\n }\n\n if (taxonomyEntries.length > 0) {\n parts.push('// ─── Taxonomy routes ────────────────────────────────────────────────────────')\n parts.push('')\n for (const [, taxonomyType] of taxonomyEntries) {\n parts.push(generateTaxonomyRoutes(taxonomyType))\n parts.push('')\n }\n }\n\n return parts.join('\\n')\n}\n"],"mappings":"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","names":[]}
|
package/dist/codegen/index.mjs
CHANGED
|
@@ -101,11 +101,18 @@ function fieldToZodSchema(field, registry) {
|
|
|
101
101
|
return "z.unknown()";
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
+
function acceptsNull(f) {
|
|
105
|
+
if (relationCardinality(f) === "many") return false;
|
|
106
|
+
return f.db_column ? f.db_column.nullable : f.nullable;
|
|
107
|
+
}
|
|
108
|
+
function fieldEntrySchema(f, registry) {
|
|
109
|
+
let s = fieldToZodSchema(f, registry);
|
|
110
|
+
if (acceptsNull(f)) s += ".nullable()";
|
|
111
|
+
if (!f.required) s += ".optional()";
|
|
112
|
+
return s;
|
|
113
|
+
}
|
|
104
114
|
function generateParagraphObjectSchema(paragraph, registry) {
|
|
105
|
-
const entries = paragraph.fields.map((f) => {
|
|
106
|
-
const zodType = fieldToZodSchema(f, registry);
|
|
107
|
-
return `${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`;
|
|
108
|
-
});
|
|
115
|
+
const entries = paragraph.fields.map((f) => `${f.name}: ${fieldEntrySchema(f, registry)}`);
|
|
109
116
|
if (entries.length === 0) return "z.object({})";
|
|
110
117
|
return `z.object({ ${entries.join(", ")} })`;
|
|
111
118
|
}
|
|
@@ -120,10 +127,7 @@ function systemFieldEntries(schema) {
|
|
|
120
127
|
return entries;
|
|
121
128
|
}
|
|
122
129
|
function schemaFieldEntries(fields, registry) {
|
|
123
|
-
return fields.map((f) => {
|
|
124
|
-
const zodType = fieldToZodSchema(f, registry);
|
|
125
|
-
return ` ${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`;
|
|
126
|
-
});
|
|
130
|
+
return fields.map((f) => ` ${f.name}: ${fieldEntrySchema(f, registry)}`);
|
|
127
131
|
}
|
|
128
132
|
function generateContentSchema(schema, registry) {
|
|
129
133
|
const name = schemaVar(schema.name);
|
|
@@ -186,6 +190,10 @@ var ADMIN_LIST_QUERY = `z.object({
|
|
|
186
190
|
})`;
|
|
187
191
|
var SLUG_PARAMS = `z.object({ slug: z.string() })`;
|
|
188
192
|
var ID_PARAMS = `z.object({ id: z.string().uuid() })`;
|
|
193
|
+
var ITEM_IN_USE_RESPONSE = `{
|
|
194
|
+
content: { 'application/json': { schema: ErrorResponseSchema } },
|
|
195
|
+
description: 'ITEM_IN_USE: a required reference elsewhere still points at this item',
|
|
196
|
+
}`;
|
|
189
197
|
var INCLUDE_QUERY = `z.object({ include: z.string().optional().describe('Comma-separated relation field names to expand') })`;
|
|
190
198
|
function generateContentRoutes(contentType) {
|
|
191
199
|
const sVar = schemaVar(contentType.name);
|
|
@@ -345,6 +353,7 @@ function generateContentRoutes(contentType) {
|
|
|
345
353
|
content: { 'application/json': { schema: ErrorResponseSchema } },
|
|
346
354
|
description: '${label} not found',
|
|
347
355
|
},
|
|
356
|
+
409: ${ITEM_IN_USE_RESPONSE},
|
|
348
357
|
},
|
|
349
358
|
})`
|
|
350
359
|
);
|
|
@@ -606,6 +615,7 @@ function generateTaxonomyRoutes(taxonomyType) {
|
|
|
606
615
|
content: { 'application/json': { schema: ErrorResponseSchema } },
|
|
607
616
|
description: '${label} not found',
|
|
608
617
|
},
|
|
618
|
+
409: ${ITEM_IN_USE_RESPONSE},
|
|
609
619
|
},
|
|
610
620
|
})`
|
|
611
621
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/codegen/routes.ts"],"sourcesContent":["// generateRoutes() — pure function that returns a Hono route group from parsed schema\nimport type {\n SchemaRegistry,\n ParsedField,\n ParsedContentType,\n ParsedTaxonomyType,\n ParsedParagraphType,\n} from '@bobbykim/manguito-cms-core'\nimport { relationCardinality } from '@bobbykim/manguito-cms-core'\n\n// ─── Name helpers ─────────────────────────────────────────────────────────────\n\nfunction getSegment(machineName: string): string {\n const idx = machineName.indexOf('--')\n return idx !== -1 ? machineName.slice(idx + 2) : machineName\n}\n\nfunction toPascalCase(snakeOrKebab: string): string {\n return snakeOrKebab\n .split(/[_-]/)\n .filter(Boolean)\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join('')\n}\n\nfunction schemaVar(machineName: string): string {\n return toPascalCase(getSegment(machineName)) + 'Schema'\n}\n\nfunction routeVar(prefix: string, machineName: string, suffix: string): string {\n return `${prefix}${toPascalCase(getSegment(machineName))}${suffix}Route`\n}\n\n// Convert Hono :param notation to OpenAPI {param} notation\nfunction openApiPath(honoPath: string): string {\n return honoPath.replace(/:([^/]+)/g, '{$1}')\n}\n\n// ─── Field → Zod type string ──────────────────────────────────────────────────\n\nexport function fieldToZodSchema(field: ParsedField, registry?: SchemaRegistry): string {\n const { field_type, validation } = field\n\n switch (field_type) {\n case 'text/plain': {\n let s = 'z.string()'\n if (validation.limit !== undefined) s += `.max(${validation.limit})`\n if (validation.pattern !== undefined) s += `.regex(new RegExp(${JSON.stringify(validation.pattern)}))`\n return s\n }\n\n case 'text/rich':\n return 'z.string()'\n\n case 'integer': {\n let s = 'z.number().int()'\n if (validation.min !== undefined) s += `.min(${validation.min})`\n if (validation.max !== undefined) s += `.max(${validation.max})`\n return s\n }\n\n case 'float': {\n let s = 'z.number()'\n if (validation.min !== undefined) s += `.min(${validation.min})`\n if (validation.max !== undefined) s += `.max(${validation.max})`\n return s\n }\n\n case 'boolean':\n return 'z.boolean()'\n\n case 'date':\n return 'z.string().datetime()'\n\n case 'image': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n 'width: z.number().int().optional()',\n 'height: z.number().int().optional()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'video': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n 'width: z.number().int().optional()',\n 'height: z.number().int().optional()',\n 'duration: z.number().optional()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'file': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'enum': {\n const values = validation.allowed_values ?? []\n if (values.length === 0) return 'z.string()'\n const quoted = values.map((v) => JSON.stringify(v)).join(', ')\n return `z.enum([${quoted}])`\n }\n\n case 'paragraph': {\n const ui = field.ui_component\n if (ui.component !== 'paragraph-embed') return 'z.unknown()'\n const paragraphType = registry?.paragraph_types[ui.ref]\n if (!paragraphType) return 'z.unknown()'\n const inner = generateParagraphObjectSchema(paragraphType, registry)\n return relationCardinality(field) === 'many' ? `z.array(${inner})` : inner\n }\n\n case 'reference': {\n const ui = field.ui_component\n if (ui.component !== 'typeahead-select') return 'z.string().uuid()'\n return relationCardinality(field) === 'many' ? 'z.array(z.string().uuid())' : 'z.string().uuid()'\n }\n\n default:\n return 'z.unknown()'\n }\n}\n\n// Generates inline z.object({...}) for a paragraph type — used recursively inside fieldToZodSchema\nfunction generateParagraphObjectSchema(\n paragraph: ParsedParagraphType,\n registry?: SchemaRegistry\n): string {\n const entries = paragraph.fields.map((f) => {\n const zodType = fieldToZodSchema(f, registry)\n return `${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`\n })\n if (entries.length === 0) return 'z.object({})'\n return `z.object({ ${entries.join(', ')} })`\n}\n\n// ─── Schema declaration generators ───────────────────────────────────────────\n\nfunction systemFieldEntries(schema: ParsedContentType | ParsedTaxonomyType): string[] {\n const entries: string[] = ['id: z.string().uuid()']\n if (schema.schema_type === 'content-type' && !schema.only_one) {\n entries.push('slug: z.string()')\n }\n entries.push('published: z.boolean()')\n entries.push('created_at: z.string().datetime()')\n entries.push('updated_at: z.string().datetime()')\n return entries\n}\n\nfunction schemaFieldEntries(\n fields: ParsedField[],\n registry?: SchemaRegistry\n): string[] {\n return fields.map((f) => {\n const zodType = fieldToZodSchema(f, registry)\n return ` ${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`\n })\n}\n\nexport function generateContentSchema(\n schema: ParsedContentType | ParsedTaxonomyType,\n registry?: SchemaRegistry\n): string {\n const name = schemaVar(schema.name)\n const sysEntries = systemFieldEntries(schema).map((e) => ` ${e}`)\n const fieldEntries = schemaFieldEntries(schema.fields, registry)\n const allEntries = [...sysEntries, ...fieldEntries]\n return `const ${name} = z.object({\\n${allEntries.join(',\\n')},\\n})`\n}\n\n// Internal: paragraph schema const declaration (not exported but emitted into generated file)\nfunction generateParagraphSchemaDecl(\n paragraph: ParsedParagraphType,\n registry?: SchemaRegistry\n): string {\n const name = schemaVar(paragraph.name)\n const inner = generateParagraphObjectSchema(paragraph, registry)\n return `const ${name} = ${inner}`\n}\n\n// ─── Shared schemas block ─────────────────────────────────────────────────────\n\nconst SHARED_SCHEMAS_BLOCK = `const ErrorResponseSchema = z.object({\n ok: z.literal(false),\n error: z.object({\n code: z.string(),\n message: z.string(),\n details: z.unknown().optional(),\n }),\n})\n\nfunction listResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n ok: z.literal(true),\n data: z.array(dataSchema),\n meta: z.object({\n total: z.number().int(),\n page: z.number().int(),\n per_page: z.number().int(),\n total_pages: z.number().int(),\n has_next: z.boolean(),\n has_prev: z.boolean(),\n }),\n })\n}\n\nfunction itemResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n ok: z.literal(true),\n data: dataSchema,\n })\n}`\n\n// ─── Query param schema strings ───────────────────────────────────────────────\n\nconst PUBLIC_LIST_QUERY = `z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(10),\n include: z.string().optional().describe('Comma-separated relation field names to expand'),\n sort_by: z.enum(['title', 'created_at', 'updated_at']).optional().default('created_at'),\n sort_order: z.enum(['asc', 'desc']).optional().default('asc'),\n })`\n\nconst ADMIN_LIST_QUERY = `z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(10),\n include: z.string().optional().describe('Comma-separated relation field names to expand'),\n sort_by: z.enum(['title', 'created_at', 'updated_at']).optional().default('created_at'),\n sort_order: z.enum(['asc', 'desc']).optional().default('asc'),\n published: z.enum(['true', 'false']).optional().describe('Filter by published state'),\n })`\n\nconst SLUG_PARAMS = `z.object({ slug: z.string() })`\nconst ID_PARAMS = `z.object({ id: z.string().uuid() })`\nconst INCLUDE_QUERY = `z.object({ include: z.string().optional().describe('Comma-separated relation field names to expand') })`\n\n// ─── Content route generators ─────────────────────────────────────────────────\n\nfunction generateContentRoutes(contentType: ParsedContentType): string {\n const sVar = schemaVar(contentType.name)\n const label = contentType.label\n const tag = label\n const lines: string[] = []\n\n if (!contentType.only_one) {\n const collPath = contentType.api.collection_path!\n const itemPath = contentType.api.item_path\n\n // Public — GET list\n lines.push(\n `export const ${routeVar('get', contentType.name, 'List')} = createRoute({\n method: 'get',\n path: '${collPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${PUBLIC_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Public — GET single by slug\n lines.push(\n `export const ${routeVar('get', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${openApiPath(itemPath)}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${SLUG_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET list\n const adminCollPath = '/admin' + collPath\n const adminItemPath = adminCollPath + '/{id}'\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, 'List')} = createRoute({\n method: 'get',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${ADMIN_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Admin — GET single by id\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST\n lines.push(\n `export const ${routeVar('adminCreate', contentType.name, '')} = createRoute({\n method: 'post',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', contentType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — DELETE\n lines.push(\n `export const ${routeVar('adminDelete', contentType.name, '')} = createRoute({\n method: 'delete',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: z.object({ ok: z.literal(true) }) } },\n description: '${label} deleted',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n } else {\n // only_one: true — no list, no slug, fixed paths\n const itemPath = contentType.api.item_path\n const adminItemBase = '/admin' + itemPath\n const adminPatchPath = '/admin/api/' + contentType.default_base_path + '/{id}'\n\n // Public — GET singleton\n lines.push(\n `export const ${routeVar('get', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${itemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET singleton\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemBase}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST (create singleton)\n const adminPostPath = '/admin/api/' + contentType.default_base_path\n lines.push(\n `export const ${routeVar('adminCreate', contentType.name, '')} = createRoute({\n method: 'post',\n path: '${adminPostPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 409: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Singleton already exists',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', contentType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminPatchPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n }\n\n return lines.join('\\n\\n')\n}\n\n// ─── Taxonomy route generators ────────────────────────────────────────────────\n\nfunction generateTaxonomyRoutes(taxonomyType: ParsedTaxonomyType): string {\n const sVar = schemaVar(taxonomyType.name)\n const label = taxonomyType.label\n const tag = label\n const collPath = taxonomyType.api.collection_path\n const itemPath = taxonomyType.api.item_path\n const adminCollPath = '/admin' + collPath\n const adminItemPath = '/admin' + openApiPath(itemPath)\n const lines: string[] = []\n\n // Public — GET list\n lines.push(\n `export const ${routeVar('get', taxonomyType.name, 'List')} = createRoute({\n method: 'get',\n path: '${collPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${PUBLIC_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Public — GET single by id\n lines.push(\n `export const ${routeVar('get', taxonomyType.name, '')} = createRoute({\n method: 'get',\n path: '${openApiPath(itemPath)}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET list\n lines.push(\n `export const ${routeVar('adminGet', taxonomyType.name, 'List')} = createRoute({\n method: 'get',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${ADMIN_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Admin — GET single by id\n lines.push(\n `export const ${routeVar('adminGet', taxonomyType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST\n lines.push(\n `export const ${routeVar('adminCreate', taxonomyType.name, '')} = createRoute({\n method: 'post',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', taxonomyType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — DELETE\n lines.push(\n `export const ${routeVar('adminDelete', taxonomyType.name, '')} = createRoute({\n method: 'delete',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: z.object({ ok: z.literal(true) }) } },\n description: '${label} deleted',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n return lines.join('\\n\\n')\n}\n\n// ─── generateRoutes ───────────────────────────────────────────────────────────\n\nexport function generateRoutes(registry: SchemaRegistry): string {\n const parts: string[] = []\n\n parts.push('// Auto-generated by generateRoutes() — do not hand-edit')\n parts.push(\"import { createRoute, z } from '@hono/zod-openapi'\")\n parts.push('')\n parts.push('// ─── Shared schemas ──────────────────────────────────────────────────────────')\n parts.push('')\n parts.push(SHARED_SCHEMAS_BLOCK)\n parts.push('')\n\n const paragraphEntries = Object.entries(registry.paragraph_types)\n if (paragraphEntries.length > 0) {\n parts.push('// ─── Paragraph schemas ───────────────────────────────────────────────────────')\n parts.push('')\n for (const [, paragraphType] of paragraphEntries) {\n parts.push(generateParagraphSchemaDecl(paragraphType, registry))\n }\n parts.push('')\n }\n\n const contentEntries = Object.entries(registry.content_types)\n if (contentEntries.length > 0) {\n parts.push('// ─── Content type schemas ────────────────────────────────────────────────────')\n parts.push('')\n for (const [, contentType] of contentEntries) {\n parts.push(generateContentSchema(contentType, registry))\n parts.push('')\n }\n }\n\n const taxonomyEntries = Object.entries(registry.taxonomy_types)\n if (taxonomyEntries.length > 0) {\n parts.push('// ─── Taxonomy type schemas ───────────────────────────────────────────────────')\n parts.push('')\n for (const [, taxonomyType] of taxonomyEntries) {\n parts.push(generateContentSchema(taxonomyType, registry))\n parts.push('')\n }\n }\n\n if (contentEntries.length > 0) {\n parts.push('// ─── Content routes ─────────────────────────────────────────────────────────')\n parts.push('')\n for (const [, contentType] of contentEntries) {\n parts.push(generateContentRoutes(contentType))\n parts.push('')\n }\n }\n\n if (taxonomyEntries.length > 0) {\n parts.push('// ─── Taxonomy routes ────────────────────────────────────────────────────────')\n parts.push('')\n for (const [, taxonomyType] of taxonomyEntries) {\n parts.push(generateTaxonomyRoutes(taxonomyType))\n parts.push('')\n }\n }\n\n return parts.join('\\n')\n}\n"],"mappings":";AAQA,SAAS,2BAA2B;AAIpC,SAAS,WAAW,aAA6B;AAC/C,QAAM,MAAM,YAAY,QAAQ,IAAI;AACpC,SAAO,QAAQ,KAAK,YAAY,MAAM,MAAM,CAAC,IAAI;AACnD;AAEA,SAAS,aAAa,cAA8B;AAClD,SAAO,aACJ,MAAM,MAAM,EACZ,OAAO,OAAO,EACd,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EACjD,KAAK,EAAE;AACZ;AAEA,SAAS,UAAU,aAA6B;AAC9C,SAAO,aAAa,WAAW,WAAW,CAAC,IAAI;AACjD;AAEA,SAAS,SAAS,QAAgB,aAAqB,QAAwB;AAC7E,SAAO,GAAG,MAAM,GAAG,aAAa,WAAW,WAAW,CAAC,CAAC,GAAG,MAAM;AACnE;AAGA,SAAS,YAAY,UAA0B;AAC7C,SAAO,SAAS,QAAQ,aAAa,MAAM;AAC7C;AAIO,SAAS,iBAAiB,OAAoB,UAAmC;AACtF,QAAM,EAAE,YAAY,WAAW,IAAI;AAEnC,UAAQ,YAAY;AAAA,IAClB,KAAK,cAAc;AACjB,UAAI,IAAI;AACR,UAAI,WAAW,UAAU,OAAW,MAAK,QAAQ,WAAW,KAAK;AACjE,UAAI,WAAW,YAAY,OAAW,MAAK,qBAAqB,KAAK,UAAU,WAAW,OAAO,CAAC;AAClG,aAAO;AAAA,IACT;AAAA,IAEA,KAAK;AACH,aAAO;AAAA,IAET,KAAK,WAAW;AACd,UAAI,IAAI;AACR,UAAI,WAAW,QAAQ,OAAW,MAAK,QAAQ,WAAW,GAAG;AAC7D,UAAI,WAAW,QAAQ,OAAW,MAAK,QAAQ,WAAW,GAAG;AAC7D,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,SAAS;AACZ,UAAI,IAAI;AACR,UAAI,WAAW,QAAQ,OAAW,MAAK,QAAQ,WAAW,GAAG;AAC7D,UAAI,WAAW,QAAQ,OAAW,MAAK,QAAQ,WAAW,GAAG;AAC7D,aAAO;AAAA,IACT;AAAA,IAEA,KAAK;AACH,aAAO;AAAA,IAET,KAAK;AACH,aAAO;AAAA,IAET,KAAK,SAAS;AACZ,YAAM,SAAS;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,cAAc,OAAO,KAAK,IAAI,CAAC;AAAA,IACxC;AAAA,IAEA,KAAK,SAAS;AACZ,YAAM,SAAS;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,cAAc,OAAO,KAAK,IAAI,CAAC;AAAA,IACxC;AAAA,IAEA,KAAK,QAAQ;AACX,YAAM,SAAS;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,cAAc,OAAO,KAAK,IAAI,CAAC;AAAA,IACxC;AAAA,IAEA,KAAK,QAAQ;AACX,YAAM,SAAS,WAAW,kBAAkB,CAAC;AAC7C,UAAI,OAAO,WAAW,EAAG,QAAO;AAChC,YAAM,SAAS,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI;AAC7D,aAAO,WAAW,MAAM;AAAA,IAC1B;AAAA,IAEA,KAAK,aAAa;AAChB,YAAM,KAAK,MAAM;AACjB,UAAI,GAAG,cAAc,kBAAmB,QAAO;AAC/C,YAAM,gBAAgB,UAAU,gBAAgB,GAAG,GAAG;AACtD,UAAI,CAAC,cAAe,QAAO;AAC3B,YAAM,QAAQ,8BAA8B,eAAe,QAAQ;AACnE,aAAO,oBAAoB,KAAK,MAAM,SAAS,WAAW,KAAK,MAAM;AAAA,IACvE;AAAA,IAEA,KAAK,aAAa;AAChB,YAAM,KAAK,MAAM;AACjB,UAAI,GAAG,cAAc,mBAAoB,QAAO;AAChD,aAAO,oBAAoB,KAAK,MAAM,SAAS,+BAA+B;AAAA,IAChF;AAAA,IAEA;AACE,aAAO;AAAA,EACX;AACF;AAGA,SAAS,8BACP,WACA,UACQ;AACR,QAAM,UAAU,UAAU,OAAO,IAAI,CAAC,MAAM;AAC1C,UAAM,UAAU,iBAAiB,GAAG,QAAQ;AAC5C,WAAO,GAAG,EAAE,IAAI,KAAK,EAAE,WAAW,UAAU,GAAG,OAAO,aAAa;AAAA,EACrE,CAAC;AACD,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SAAO,cAAc,QAAQ,KAAK,IAAI,CAAC;AACzC;AAIA,SAAS,mBAAmB,QAA0D;AACpF,QAAM,UAAoB,CAAC,uBAAuB;AAClD,MAAI,OAAO,gBAAgB,kBAAkB,CAAC,OAAO,UAAU;AAC7D,YAAQ,KAAK,kBAAkB;AAAA,EACjC;AACA,UAAQ,KAAK,wBAAwB;AACrC,UAAQ,KAAK,mCAAmC;AAChD,UAAQ,KAAK,mCAAmC;AAChD,SAAO;AACT;AAEA,SAAS,mBACP,QACA,UACU;AACV,SAAO,OAAO,IAAI,CAAC,MAAM;AACvB,UAAM,UAAU,iBAAiB,GAAG,QAAQ;AAC5C,WAAO,KAAK,EAAE,IAAI,KAAK,EAAE,WAAW,UAAU,GAAG,OAAO,aAAa;AAAA,EACvE,CAAC;AACH;AAEO,SAAS,sBACd,QACA,UACQ;AACR,QAAM,OAAO,UAAU,OAAO,IAAI;AAClC,QAAM,aAAa,mBAAmB,MAAM,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AACjE,QAAM,eAAe,mBAAmB,OAAO,QAAQ,QAAQ;AAC/D,QAAM,aAAa,CAAC,GAAG,YAAY,GAAG,YAAY;AAClD,SAAO,SAAS,IAAI;AAAA,EAAkB,WAAW,KAAK,KAAK,CAAC;AAAA;AAC9D;AAGA,SAAS,4BACP,WACA,UACQ;AACR,QAAM,OAAO,UAAU,UAAU,IAAI;AACrC,QAAM,QAAQ,8BAA8B,WAAW,QAAQ;AAC/D,SAAO,SAAS,IAAI,MAAM,KAAK;AACjC;AAIA,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiC7B,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ1B,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASzB,IAAM,cAAc;AACpB,IAAM,YAAY;AAClB,IAAM,gBAAgB;AAItB,SAAS,sBAAsB,aAAwC;AACrE,QAAM,OAAO,UAAU,YAAY,IAAI;AACvC,QAAM,QAAQ,YAAY;AAC1B,QAAM,MAAM;AACZ,QAAM,QAAkB,CAAC;AAEzB,MAAI,CAAC,YAAY,UAAU;AACzB,UAAM,WAAW,YAAY,IAAI;AACjC,UAAM,WAAW,YAAY,IAAI;AAGjC,UAAM;AAAA,MACJ,gBAAgB,SAAS,OAAO,YAAY,MAAM,MAAM,CAAC;AAAA;AAAA,WAEpD,QAAQ;AAAA,WACR,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,aAEjB,iBAAiB;AAAA;AAAA;AAAA;AAAA,oEAIsC,IAAI;AAAA,8BAC1C,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ/B;AAGA,UAAM;AAAA,MACJ,gBAAgB,SAAS,OAAO,YAAY,MAAM,EAAE,CAAC;AAAA;AAAA,WAEhD,YAAY,QAAQ,CAAC;AAAA,WACrB,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,cAEhB,WAAW;AAAA,aACZ,aAAa;AAAA;AAAA;AAAA;AAAA,oEAI0C,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA,IAIvB;AAGA,UAAM,gBAAgB,WAAW;AACjC,UAAM,gBAAgB,gBAAgB;AACtC,UAAM;AAAA,MACJ,gBAAgB,SAAS,YAAY,YAAY,MAAM,MAAM,CAAC;AAAA;AAAA,WAEzD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,aAEjB,gBAAgB;AAAA;AAAA;AAAA;AAAA,oEAIuC,IAAI;AAAA,8BAC1C,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ/B;AAGA,UAAM;AAAA,MACJ,gBAAgB,SAAS,YAAY,YAAY,MAAM,EAAE,CAAC;AAAA;AAAA,WAErD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,cAEhB,SAAS;AAAA,aACV,aAAa;AAAA;AAAA;AAAA;AAAA,oEAI0C,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA,IAIvB;AAGA,UAAM;AAAA,MACJ,gBAAgB,SAAS,eAAe,YAAY,MAAM,EAAE,CAAC;AAAA;AAAA,WAExD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA;AAAA,iDAGmB,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,oEAKe,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQvB;AAGA,UAAM;AAAA,MACJ,gBAAgB,SAAS,eAAe,YAAY,MAAM,EAAE,CAAC;AAAA;AAAA,WAExD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,cAEhB,SAAS;AAAA;AAAA,iDAE0B,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,oEAKe,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQvB;AAGA,UAAM;AAAA,MACJ,gBAAgB,SAAS,eAAe,YAAY,MAAM,EAAE,CAAC;AAAA;AAAA,WAExD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,cAEhB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,sBAKD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA,IAIvB;AAAA,EACF,OAAO;AAEL,UAAM,WAAW,YAAY,IAAI;AACjC,UAAM,gBAAgB,WAAW;AACjC,UAAM,iBAAiB,gBAAgB,YAAY,oBAAoB;AAGvE,UAAM;AAAA,MACJ,gBAAgB,SAAS,OAAO,YAAY,MAAM,EAAE,CAAC;AAAA;AAAA,WAEhD,QAAQ;AAAA,WACR,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,aAEjB,aAAa;AAAA;AAAA;AAAA;AAAA,oEAI0C,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA,IAIvB;AAGA,UAAM;AAAA,MACJ,gBAAgB,SAAS,YAAY,YAAY,MAAM,EAAE,CAAC;AAAA;AAAA,WAErD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,aAEjB,aAAa;AAAA;AAAA;AAAA;AAAA,oEAI0C,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA,IAIvB;AAGA,UAAM,gBAAgB,gBAAgB,YAAY;AAClD,UAAM;AAAA,MACJ,gBAAgB,SAAS,eAAe,YAAY,MAAM,EAAE,CAAC;AAAA;AAAA,WAExD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA;AAAA,iDAGmB,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,oEAKe,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYvB;AAGA,UAAM;AAAA,MACJ,gBAAgB,SAAS,eAAe,YAAY,MAAM,EAAE,CAAC;AAAA;AAAA,WAExD,cAAc;AAAA,WACd,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,cAEhB,SAAS;AAAA;AAAA,iDAE0B,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,oEAKe,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQvB;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAIA,SAAS,uBAAuB,cAA0C;AACxE,QAAM,OAAO,UAAU,aAAa,IAAI;AACxC,QAAM,QAAQ,aAAa;AAC3B,QAAM,MAAM;AACZ,QAAM,WAAW,aAAa,IAAI;AAClC,QAAM,WAAW,aAAa,IAAI;AAClC,QAAM,gBAAgB,WAAW;AACjC,QAAM,gBAAgB,WAAW,YAAY,QAAQ;AACrD,QAAM,QAAkB,CAAC;AAGzB,QAAM;AAAA,IACJ,gBAAgB,SAAS,OAAO,aAAa,MAAM,MAAM,CAAC;AAAA;AAAA,WAEnD,QAAQ;AAAA,WACR,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,aAEjB,iBAAiB;AAAA;AAAA;AAAA;AAAA,oEAIsC,IAAI;AAAA,8BAC1C,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjC;AAGA,QAAM;AAAA,IACJ,gBAAgB,SAAS,OAAO,aAAa,MAAM,EAAE,CAAC;AAAA;AAAA,WAE/C,YAAY,QAAQ,CAAC;AAAA,WACrB,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,cAEhB,SAAS;AAAA,aACV,aAAa;AAAA;AAAA;AAAA;AAAA,oEAI0C,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA,EAIzB;AAGA,QAAM;AAAA,IACJ,gBAAgB,SAAS,YAAY,aAAa,MAAM,MAAM,CAAC;AAAA;AAAA,WAExD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,aAEjB,gBAAgB;AAAA;AAAA;AAAA;AAAA,oEAIuC,IAAI;AAAA,8BAC1C,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjC;AAGA,QAAM;AAAA,IACJ,gBAAgB,SAAS,YAAY,aAAa,MAAM,EAAE,CAAC;AAAA;AAAA,WAEpD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,cAEhB,SAAS;AAAA,aACV,aAAa;AAAA;AAAA;AAAA;AAAA,oEAI0C,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA,EAIzB;AAGA,QAAM;AAAA,IACJ,gBAAgB,SAAS,eAAe,aAAa,MAAM,EAAE,CAAC;AAAA;AAAA,WAEvD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA;AAAA,iDAGmB,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,oEAKe,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzB;AAGA,QAAM;AAAA,IACJ,gBAAgB,SAAS,eAAe,aAAa,MAAM,EAAE,CAAC;AAAA;AAAA,WAEvD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,cAEhB,SAAS;AAAA;AAAA,iDAE0B,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,oEAKe,IAAI;AAAA,sBAClD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzB;AAGA,QAAM;AAAA,IACJ,gBAAgB,SAAS,eAAe,aAAa,MAAM,EAAE,CAAC;AAAA;AAAA,WAEvD,aAAa;AAAA,WACb,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA,cAEhB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,sBAKD,KAAK;AAAA;AAAA;AAAA;AAAA,sBAIL,KAAK;AAAA;AAAA;AAAA;AAAA,EAIzB;AAEA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAIO,SAAS,eAAe,UAAkC;AAC/D,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,+DAA0D;AACrE,QAAM,KAAK,oDAAoD;AAC/D,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,mYAAkF;AAC7F,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,oBAAoB;AAC/B,QAAM,KAAK,EAAE;AAEb,QAAM,mBAAmB,OAAO,QAAQ,SAAS,eAAe;AAChE,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,KAAK,oXAAkF;AAC7F,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,EAAE,aAAa,KAAK,kBAAkB;AAChD,YAAM,KAAK,4BAA4B,eAAe,QAAQ,CAAC;AAAA,IACjE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,iBAAiB,OAAO,QAAQ,SAAS,aAAa;AAC5D,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,KAAK,qWAAkF;AAC7F,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,EAAE,WAAW,KAAK,gBAAgB;AAC5C,YAAM,KAAK,sBAAsB,aAAa,QAAQ,CAAC;AACvD,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,QAAM,kBAAkB,OAAO,QAAQ,SAAS,cAAc;AAC9D,MAAI,gBAAgB,SAAS,GAAG;AAC9B,UAAM,KAAK,gWAAkF;AAC7F,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,EAAE,YAAY,KAAK,iBAAiB;AAC9C,YAAM,KAAK,sBAAsB,cAAc,QAAQ,CAAC;AACxD,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,KAAK,6XAAiF;AAC5F,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,EAAE,WAAW,KAAK,gBAAgB;AAC5C,YAAM,KAAK,sBAAsB,WAAW,CAAC;AAC7C,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,MAAI,gBAAgB,SAAS,GAAG;AAC9B,UAAM,KAAK,wXAAiF;AAC5F,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,EAAE,YAAY,KAAK,iBAAiB;AAC9C,YAAM,KAAK,uBAAuB,YAAY,CAAC;AAC/C,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/codegen/routes.ts"],"sourcesContent":["// generateRoutes() — pure function that returns a Hono route group from parsed schema\nimport type {\n SchemaRegistry,\n ParsedField,\n ParsedContentType,\n ParsedTaxonomyType,\n ParsedParagraphType,\n} from '@bobbykim/manguito-cms-core'\nimport { relationCardinality } from '@bobbykim/manguito-cms-core'\n\n// ─── Name helpers ─────────────────────────────────────────────────────────────\n\nfunction getSegment(machineName: string): string {\n const idx = machineName.indexOf('--')\n return idx !== -1 ? machineName.slice(idx + 2) : machineName\n}\n\nfunction toPascalCase(snakeOrKebab: string): string {\n return snakeOrKebab\n .split(/[_-]/)\n .filter(Boolean)\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join('')\n}\n\nfunction schemaVar(machineName: string): string {\n return toPascalCase(getSegment(machineName)) + 'Schema'\n}\n\nfunction routeVar(prefix: string, machineName: string, suffix: string): string {\n return `${prefix}${toPascalCase(getSegment(machineName))}${suffix}Route`\n}\n\n// Convert Hono :param notation to OpenAPI {param} notation\nfunction openApiPath(honoPath: string): string {\n return honoPath.replace(/:([^/]+)/g, '{$1}')\n}\n\n// ─── Field → Zod type string ──────────────────────────────────────────────────\n\nexport function fieldToZodSchema(field: ParsedField, registry?: SchemaRegistry): string {\n const { field_type, validation } = field\n\n switch (field_type) {\n case 'text/plain': {\n let s = 'z.string()'\n if (validation.limit !== undefined) s += `.max(${validation.limit})`\n if (validation.pattern !== undefined) s += `.regex(new RegExp(${JSON.stringify(validation.pattern)}))`\n return s\n }\n\n case 'text/rich':\n return 'z.string()'\n\n case 'integer': {\n let s = 'z.number().int()'\n if (validation.min !== undefined) s += `.min(${validation.min})`\n if (validation.max !== undefined) s += `.max(${validation.max})`\n return s\n }\n\n case 'float': {\n let s = 'z.number()'\n if (validation.min !== undefined) s += `.min(${validation.min})`\n if (validation.max !== undefined) s += `.max(${validation.max})`\n return s\n }\n\n case 'boolean':\n return 'z.boolean()'\n\n case 'date':\n return 'z.string().datetime()'\n\n case 'image': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n 'width: z.number().int().optional()',\n 'height: z.number().int().optional()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'video': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n 'width: z.number().int().optional()',\n 'height: z.number().int().optional()',\n 'duration: z.number().optional()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'file': {\n const fields = [\n 'id: z.string().uuid()',\n 'url: z.string().url()',\n 'mime_type: z.string()',\n 'alt: z.string().optional()',\n 'file_size: z.number().int()',\n ]\n return `z.object({ ${fields.join(', ')} })`\n }\n\n case 'enum': {\n const values = validation.allowed_values ?? []\n if (values.length === 0) return 'z.string()'\n const quoted = values.map((v) => JSON.stringify(v)).join(', ')\n return `z.enum([${quoted}])`\n }\n\n case 'paragraph': {\n const ui = field.ui_component\n if (ui.component !== 'paragraph-embed') return 'z.unknown()'\n const paragraphType = registry?.paragraph_types[ui.ref]\n if (!paragraphType) return 'z.unknown()'\n const inner = generateParagraphObjectSchema(paragraphType, registry)\n return relationCardinality(field) === 'many' ? `z.array(${inner})` : inner\n }\n\n case 'reference': {\n const ui = field.ui_component\n if (ui.component !== 'typeahead-select') return 'z.string().uuid()'\n return relationCardinality(field) === 'many' ? 'z.array(z.string().uuid())' : 'z.string().uuid()'\n }\n\n default:\n return 'z.unknown()'\n }\n}\n\n// Whether the API stores and returns null for a field (#56). A column-backed\n// field follows its column, so an optional boolean (NOT NULL, default false)\n// does not. A list relation never does: it is [] when empty, and the API\n// refuses null for it. A column-less \"one\" paragraph is null when empty.\nfunction acceptsNull(f: ParsedField): boolean {\n if (relationCardinality(f) === 'many') return false\n return f.db_column ? f.db_column.nullable : f.nullable\n}\n\n// A field's schema as an object entry. A field that is not required may be\n// left out.\nfunction fieldEntrySchema(f: ParsedField, registry?: SchemaRegistry): string {\n let s = fieldToZodSchema(f, registry)\n if (acceptsNull(f)) s += '.nullable()'\n if (!f.required) s += '.optional()'\n return s\n}\n\n// Generates inline z.object({...}) for a paragraph type — used recursively inside fieldToZodSchema\nfunction generateParagraphObjectSchema(\n paragraph: ParsedParagraphType,\n registry?: SchemaRegistry\n): string {\n const entries = paragraph.fields.map((f) => `${f.name}: ${fieldEntrySchema(f, registry)}`)\n if (entries.length === 0) return 'z.object({})'\n return `z.object({ ${entries.join(', ')} })`\n}\n\n// ─── Schema declaration generators ───────────────────────────────────────────\n\nfunction systemFieldEntries(schema: ParsedContentType | ParsedTaxonomyType): string[] {\n const entries: string[] = ['id: z.string().uuid()']\n if (schema.schema_type === 'content-type' && !schema.only_one) {\n entries.push('slug: z.string()')\n }\n entries.push('published: z.boolean()')\n entries.push('created_at: z.string().datetime()')\n entries.push('updated_at: z.string().datetime()')\n return entries\n}\n\nfunction schemaFieldEntries(\n fields: ParsedField[],\n registry?: SchemaRegistry\n): string[] {\n return fields.map((f) => ` ${f.name}: ${fieldEntrySchema(f, registry)}`)\n}\n\nexport function generateContentSchema(\n schema: ParsedContentType | ParsedTaxonomyType,\n registry?: SchemaRegistry\n): string {\n const name = schemaVar(schema.name)\n const sysEntries = systemFieldEntries(schema).map((e) => ` ${e}`)\n const fieldEntries = schemaFieldEntries(schema.fields, registry)\n const allEntries = [...sysEntries, ...fieldEntries]\n return `const ${name} = z.object({\\n${allEntries.join(',\\n')},\\n})`\n}\n\n// Internal: paragraph schema const declaration (not exported but emitted into generated file)\nfunction generateParagraphSchemaDecl(\n paragraph: ParsedParagraphType,\n registry?: SchemaRegistry\n): string {\n const name = schemaVar(paragraph.name)\n const inner = generateParagraphObjectSchema(paragraph, registry)\n return `const ${name} = ${inner}`\n}\n\n// ─── Shared schemas block ─────────────────────────────────────────────────────\n\nconst SHARED_SCHEMAS_BLOCK = `const ErrorResponseSchema = z.object({\n ok: z.literal(false),\n error: z.object({\n code: z.string(),\n message: z.string(),\n details: z.unknown().optional(),\n }),\n})\n\nfunction listResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n ok: z.literal(true),\n data: z.array(dataSchema),\n meta: z.object({\n total: z.number().int(),\n page: z.number().int(),\n per_page: z.number().int(),\n total_pages: z.number().int(),\n has_next: z.boolean(),\n has_prev: z.boolean(),\n }),\n })\n}\n\nfunction itemResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n ok: z.literal(true),\n data: dataSchema,\n })\n}`\n\n// ─── Query param schema strings ───────────────────────────────────────────────\n\nconst PUBLIC_LIST_QUERY = `z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(10),\n include: z.string().optional().describe('Comma-separated relation field names to expand'),\n sort_by: z.enum(['title', 'created_at', 'updated_at']).optional().default('created_at'),\n sort_order: z.enum(['asc', 'desc']).optional().default('asc'),\n })`\n\nconst ADMIN_LIST_QUERY = `z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(10),\n include: z.string().optional().describe('Comma-separated relation field names to expand'),\n sort_by: z.enum(['title', 'created_at', 'updated_at']).optional().default('created_at'),\n sort_order: z.enum(['asc', 'desc']).optional().default('asc'),\n published: z.enum(['true', 'false']).optional().describe('Filter by published state'),\n })`\n\nconst SLUG_PARAMS = `z.object({ slug: z.string() })`\nconst ID_PARAMS = `z.object({ id: z.string().uuid() })`\n// The admin DELETE routes refuse with 409 ITEM_IN_USE while a required\n// reference elsewhere still points at the item. No label in the text: labels\n// are not quoted safely for a single-quoted string.\nconst ITEM_IN_USE_RESPONSE = `{\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'ITEM_IN_USE: a required reference elsewhere still points at this item',\n }`\n\nconst INCLUDE_QUERY = `z.object({ include: z.string().optional().describe('Comma-separated relation field names to expand') })`\n\n// ─── Content route generators ─────────────────────────────────────────────────\n\nfunction generateContentRoutes(contentType: ParsedContentType): string {\n const sVar = schemaVar(contentType.name)\n const label = contentType.label\n const tag = label\n const lines: string[] = []\n\n if (!contentType.only_one) {\n const collPath = contentType.api.collection_path!\n const itemPath = contentType.api.item_path\n\n // Public — GET list\n lines.push(\n `export const ${routeVar('get', contentType.name, 'List')} = createRoute({\n method: 'get',\n path: '${collPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${PUBLIC_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Public — GET single by slug\n lines.push(\n `export const ${routeVar('get', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${openApiPath(itemPath)}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${SLUG_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET list\n const adminCollPath = '/admin' + collPath\n const adminItemPath = adminCollPath + '/{id}'\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, 'List')} = createRoute({\n method: 'get',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${ADMIN_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Admin — GET single by id\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST\n lines.push(\n `export const ${routeVar('adminCreate', contentType.name, '')} = createRoute({\n method: 'post',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', contentType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — DELETE\n lines.push(\n `export const ${routeVar('adminDelete', contentType.name, '')} = createRoute({\n method: 'delete',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: z.object({ ok: z.literal(true) }) } },\n description: '${label} deleted',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 409: ${ITEM_IN_USE_RESPONSE},\n },\n})`\n )\n } else {\n // only_one: true — no list, no slug, fixed paths\n const itemPath = contentType.api.item_path\n const adminItemBase = '/admin' + itemPath\n const adminPatchPath = '/admin/api/' + contentType.default_base_path + '/{id}'\n\n // Public — GET singleton\n lines.push(\n `export const ${routeVar('get', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${itemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET singleton\n lines.push(\n `export const ${routeVar('adminGet', contentType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemBase}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST (create singleton)\n const adminPostPath = '/admin/api/' + contentType.default_base_path\n lines.push(\n `export const ${routeVar('adminCreate', contentType.name, '')} = createRoute({\n method: 'post',\n path: '${adminPostPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 409: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Singleton already exists',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', contentType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminPatchPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n }\n\n return lines.join('\\n\\n')\n}\n\n// ─── Taxonomy route generators ────────────────────────────────────────────────\n\nfunction generateTaxonomyRoutes(taxonomyType: ParsedTaxonomyType): string {\n const sVar = schemaVar(taxonomyType.name)\n const label = taxonomyType.label\n const tag = label\n const collPath = taxonomyType.api.collection_path\n const itemPath = taxonomyType.api.item_path\n const adminCollPath = '/admin' + collPath\n const adminItemPath = '/admin' + openApiPath(itemPath)\n const lines: string[] = []\n\n // Public — GET list\n lines.push(\n `export const ${routeVar('get', taxonomyType.name, 'List')} = createRoute({\n method: 'get',\n path: '${collPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${PUBLIC_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Public — GET single by id\n lines.push(\n `export const ${routeVar('get', taxonomyType.name, '')} = createRoute({\n method: 'get',\n path: '${openApiPath(itemPath)}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — GET list\n lines.push(\n `export const ${routeVar('adminGet', taxonomyType.name, 'List')} = createRoute({\n method: 'get',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n query: ${ADMIN_LIST_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: listResponseSchema(${sVar}) } },\n description: 'List of ${label}',\n },\n 400: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Invalid query parameters',\n },\n },\n})`\n )\n\n // Admin — GET single by id\n lines.push(\n `export const ${routeVar('adminGet', taxonomyType.name, '')} = createRoute({\n method: 'get',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n query: ${INCLUDE_QUERY},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label}',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n },\n})`\n )\n\n // Admin — POST\n lines.push(\n `export const ${routeVar('adminCreate', taxonomyType.name, '')} = createRoute({\n method: 'post',\n path: '${adminCollPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n body: {\n content: { 'application/json': { schema: ${sVar} } },\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} created',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — PATCH\n lines.push(\n `export const ${routeVar('adminUpdate', taxonomyType.name, '')} = createRoute({\n method: 'patch',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n body: {\n content: { 'application/json': { schema: ${sVar}.partial().extend({ published: z.boolean().optional() }) } },\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: itemResponseSchema(${sVar}) } },\n description: '${label} updated',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 422: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: 'Validation error',\n },\n },\n})`\n )\n\n // Admin — DELETE\n lines.push(\n `export const ${routeVar('adminDelete', taxonomyType.name, '')} = createRoute({\n method: 'delete',\n path: '${adminItemPath}',\n tags: [${JSON.stringify(tag)}],\n request: {\n params: ${ID_PARAMS},\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: z.object({ ok: z.literal(true) }) } },\n description: '${label} deleted',\n },\n 404: {\n content: { 'application/json': { schema: ErrorResponseSchema } },\n description: '${label} not found',\n },\n 409: ${ITEM_IN_USE_RESPONSE},\n },\n})`\n )\n\n return lines.join('\\n\\n')\n}\n\n// ─── generateRoutes ───────────────────────────────────────────────────────────\n\nexport function generateRoutes(registry: SchemaRegistry): string {\n const parts: string[] = []\n\n parts.push('// Auto-generated by generateRoutes() — do not hand-edit')\n parts.push(\"import { createRoute, z } from '@hono/zod-openapi'\")\n parts.push('')\n parts.push('// ─── Shared schemas ──────────────────────────────────────────────────────────')\n parts.push('')\n parts.push(SHARED_SCHEMAS_BLOCK)\n parts.push('')\n\n const paragraphEntries = Object.entries(registry.paragraph_types)\n if (paragraphEntries.length > 0) {\n parts.push('// ─── Paragraph schemas ───────────────────────────────────────────────────────')\n parts.push('')\n for (const [, paragraphType] of paragraphEntries) {\n parts.push(generateParagraphSchemaDecl(paragraphType, registry))\n }\n parts.push('')\n }\n\n const contentEntries = Object.entries(registry.content_types)\n if (contentEntries.length > 0) {\n parts.push('// ─── Content type schemas ────────────────────────────────────────────────────')\n parts.push('')\n for (const [, contentType] of contentEntries) {\n parts.push(generateContentSchema(contentType, registry))\n parts.push('')\n }\n }\n\n const taxonomyEntries = Object.entries(registry.taxonomy_types)\n if (taxonomyEntries.length > 0) {\n parts.push('// ─── Taxonomy type schemas ───────────────────────────────────────────────────')\n parts.push('')\n for (const [, taxonomyType] of taxonomyEntries) {\n parts.push(generateContentSchema(taxonomyType, registry))\n parts.push('')\n }\n }\n\n if (contentEntries.length > 0) {\n parts.push('// ─── Content routes ─────────────────────────────────────────────────────────')\n parts.push('')\n for (const [, contentType] of contentEntries) {\n parts.push(generateContentRoutes(contentType))\n parts.push('')\n }\n }\n\n if (taxonomyEntries.length > 0) {\n parts.push('// ─── Taxonomy routes ────────────────────────────────────────────────────────')\n parts.push('')\n for (const [, taxonomyType] of taxonomyEntries) {\n parts.push(generateTaxonomyRoutes(taxonomyType))\n parts.push('')\n }\n }\n\n return parts.join('\\n')\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -4176,7 +4176,7 @@ function registerUserRoutes(app, db, requirePermission, requireHierarchy) {
|
|
|
4176
4176
|
var import_drizzle_orm8 = require("drizzle-orm");
|
|
4177
4177
|
var API_VERSION = (() => {
|
|
4178
4178
|
try {
|
|
4179
|
-
return "0.8.
|
|
4179
|
+
return "0.8.3";
|
|
4180
4180
|
} catch {
|
|
4181
4181
|
return "0.0.0";
|
|
4182
4182
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -2951,7 +2951,7 @@ function registerUserRoutes(app, db, requirePermission, requireHierarchy) {
|
|
|
2951
2951
|
import { sql as sql7 } from "drizzle-orm";
|
|
2952
2952
|
var API_VERSION = (() => {
|
|
2953
2953
|
try {
|
|
2954
|
-
return "0.8.
|
|
2954
|
+
return "0.8.3";
|
|
2955
2955
|
} catch {
|
|
2956
2956
|
return "0.0.0";
|
|
2957
2957
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobbykim/manguito-cms-api",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Bobby Kim <bobby.sihun.kim@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/bobbykim89/manguito-cms",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"build": "tsup",
|
|
75
75
|
"dev": "tsup --watch",
|
|
76
76
|
"test": "dotenv -e ../../.env.test -- vitest run",
|
|
77
|
-
"lint": "eslint src",
|
|
77
|
+
"lint": "eslint src tests",
|
|
78
78
|
"typecheck": "tsc --noEmit"
|
|
79
79
|
}
|
|
80
80
|
}
|