@bobbykim/manguito-cms-api 0.8.2 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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":[]}
@@ -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":"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","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":";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;AAMA,SAAS,YAAY,GAAyB;AAC5C,MAAI,oBAAoB,CAAC,MAAM,OAAQ,QAAO;AAC9C,SAAO,EAAE,YAAY,EAAE,UAAU,WAAW,EAAE;AAChD;AAIA,SAAS,iBAAiB,GAAgB,UAAmC;AAC3E,MAAI,IAAI,iBAAiB,GAAG,QAAQ;AACpC,MAAI,YAAY,CAAC,EAAG,MAAK;AACzB,MAAI,CAAC,EAAE,SAAU,MAAK;AACtB,SAAO;AACT;AAGA,SAAS,8BACP,WACA,UACQ;AACR,QAAM,UAAU,UAAU,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,iBAAiB,GAAG,QAAQ,CAAC,EAAE;AACzF,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,KAAK,EAAE,IAAI,KAAK,iBAAiB,GAAG,QAAQ,CAAC,EAAE;AAC1E;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;AAIlB,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAK7B,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,WAEhB,oBAAoB;AAAA;AAAA;AAAA,IAG3B;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,WAEhB,oBAAoB;AAAA;AAAA;AAAA,EAG7B;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":[]}
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.2";
4179
+ return "0.8.4";
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.2";
2954
+ return "0.8.4";
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.2",
3
+ "version": "0.8.4",
4
4
  "license": "MIT",
5
5
  "author": "Bobby Kim <bobby.sihun.kim@gmail.com>",
6
6
  "homepage": "https://github.com/bobbykim89/manguito-cms",
@@ -58,8 +58,8 @@
58
58
  "graphql-yoga": "^5.21.2",
59
59
  "hono": "^4.12.28",
60
60
  "zod": "^4.4.3",
61
- "@bobbykim/manguito-cms-core": "0.8.0",
62
- "@bobbykim/manguito-cms-db": "0.1.8"
61
+ "@bobbykim/manguito-cms-core": "0.9.0",
62
+ "@bobbykim/manguito-cms-db": "0.1.9"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@types/bcryptjs": "^2.4.6",
@@ -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
  }