@kyro-cms/core 0.9.7 → 0.9.9

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.
Files changed (101) hide show
  1. package/dist/{WebhookService-BKszZlG0.d.cts → WebhookService-Dj8pJ3sp.d.cts} +1 -1
  2. package/dist/{WebhookService-Ccf1j-IN.d.ts → WebhookService-DpRB940h.d.ts} +1 -1
  3. package/dist/api-handler-graphql.cjs +18 -13
  4. package/dist/api-handler-graphql.cjs.map +1 -1
  5. package/dist/api-handler-graphql.js +14 -9
  6. package/dist/api-handler-graphql.js.map +1 -1
  7. package/dist/api-handler-trpc.cjs +9 -9
  8. package/dist/api-handler-trpc.js +7 -7
  9. package/dist/api-handler.cjs +10 -10
  10. package/dist/api-handler.js +7 -7
  11. package/dist/{base-CIuXkrH4.d.cts → base-BjyoF6da.d.cts} +2 -2
  12. package/dist/{base-fFo4lqER.d.ts → base-C2YR8lWt.d.ts} +2 -2
  13. package/dist/{chunk-NZEUU7QB.js → chunk-3AKCVYDB.js} +4 -109
  14. package/dist/chunk-3AKCVYDB.js.map +1 -0
  15. package/dist/{chunk-FKKQUMXR.cjs → chunk-4OCMVGEY.cjs} +4 -110
  16. package/dist/chunk-4OCMVGEY.cjs.map +1 -0
  17. package/dist/{chunk-VLK5SJRI.js → chunk-5RFGYEQ3.js} +133 -46
  18. package/dist/chunk-5RFGYEQ3.js.map +1 -0
  19. package/dist/chunk-5RPRLTTN.js +861 -0
  20. package/dist/chunk-5RPRLTTN.js.map +1 -0
  21. package/dist/{chunk-AX2TZRQJ.js → chunk-BVUDFKKS.js} +16 -3
  22. package/dist/chunk-BVUDFKKS.js.map +1 -0
  23. package/dist/{chunk-DRVOUQMT.cjs → chunk-E4JZ73FY.cjs} +54 -79
  24. package/dist/chunk-E4JZ73FY.cjs.map +1 -0
  25. package/dist/{chunk-E5UJBLQ7.js → chunk-FIAMXNTH.js} +2 -2
  26. package/dist/chunk-FIAMXNTH.js.map +1 -0
  27. package/dist/{chunk-QVJNSAQL.cjs → chunk-IEIHABVR.cjs} +152 -65
  28. package/dist/chunk-IEIHABVR.cjs.map +1 -0
  29. package/dist/{chunk-QFLB4EIJ.cjs → chunk-LNTFRAHF.cjs} +118 -9
  30. package/dist/chunk-LNTFRAHF.cjs.map +1 -0
  31. package/dist/chunk-N4GN6Q3V.cjs +869 -0
  32. package/dist/chunk-N4GN6Q3V.cjs.map +1 -0
  33. package/dist/{chunk-FSKONGCX.cjs → chunk-OJ2AM75W.cjs} +2 -2
  34. package/dist/chunk-OJ2AM75W.cjs.map +1 -0
  35. package/dist/{chunk-QX3WNQ7V.js → chunk-OX6GOIPH.js} +4 -4
  36. package/dist/{chunk-QX3WNQ7V.js.map → chunk-OX6GOIPH.js.map} +1 -1
  37. package/dist/{chunk-OZ3CCTTA.cjs → chunk-OXYSOU6Z.cjs} +18 -5
  38. package/dist/chunk-OXYSOU6Z.cjs.map +1 -0
  39. package/dist/{chunk-CMXVTUYV.js → chunk-OYCICW4B.js} +38 -63
  40. package/dist/chunk-OYCICW4B.js.map +1 -0
  41. package/dist/{chunk-HVCUIII2.cjs → chunk-TQG7G7YI.cjs} +13 -13
  42. package/dist/{chunk-HVCUIII2.cjs.map → chunk-TQG7G7YI.cjs.map} +1 -1
  43. package/dist/{chunk-3UK5XBVJ.js → chunk-WDTTHKDS.js} +117 -10
  44. package/dist/chunk-WDTTHKDS.js.map +1 -0
  45. package/dist/cli/index.cjs +148 -14
  46. package/dist/cli/index.cjs.map +1 -1
  47. package/dist/cli/index.js +148 -14
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/client.cjs +3 -3
  50. package/dist/client.d.cts +2 -2
  51. package/dist/client.d.ts +2 -2
  52. package/dist/client.js +1 -1
  53. package/dist/drizzle/index.d.cts +3 -3
  54. package/dist/drizzle/index.d.ts +3 -3
  55. package/dist/fields/index.cjs +21 -21
  56. package/dist/fields/index.d.cts +1 -1
  57. package/dist/fields/index.d.ts +1 -1
  58. package/dist/fields/index.js +1 -1
  59. package/dist/graphql/index.cjs +13 -5
  60. package/dist/graphql/index.d.cts +37 -7
  61. package/dist/graphql/index.d.ts +37 -7
  62. package/dist/graphql/index.js +2 -2
  63. package/dist/{index-BKta3cBH.d.cts → index-DHbywDs-.d.cts} +2 -2
  64. package/dist/{index-ClOqnkTO.d.ts → index-jLs0zlft.d.ts} +2 -2
  65. package/dist/index.cjs +90 -90
  66. package/dist/index.d.cts +15 -14
  67. package/dist/index.d.ts +15 -14
  68. package/dist/index.js +8 -8
  69. package/dist/mongodb/index.d.cts +3 -3
  70. package/dist/mongodb/index.d.ts +3 -3
  71. package/dist/rest/index.cjs +5 -5
  72. package/dist/rest/index.d.cts +4 -4
  73. package/dist/rest/index.d.ts +4 -4
  74. package/dist/rest/index.js +3 -3
  75. package/dist/templates/index.d.cts +2 -2
  76. package/dist/templates/index.d.ts +2 -2
  77. package/dist/trpc/index.cjs +12 -12
  78. package/dist/trpc/index.d.cts +3 -3
  79. package/dist/trpc/index.d.ts +3 -3
  80. package/dist/trpc/index.js +3 -3
  81. package/dist/{types-Dgzlftb7.d.ts → types-BzH3_rtP.d.ts} +7 -7
  82. package/dist/{types-Ds0tCA3L.d.cts → types-CY_iNunL.d.cts} +7 -7
  83. package/dist/{types-DeSApf9T.d.ts → types-C_rVxU2T.d.cts} +4 -4
  84. package/dist/{types-DeSApf9T.d.cts → types-C_rVxU2T.d.ts} +4 -4
  85. package/package.json +2 -1
  86. package/dist/chunk-3UK5XBVJ.js.map +0 -1
  87. package/dist/chunk-AX2TZRQJ.js.map +0 -1
  88. package/dist/chunk-CMXVTUYV.js.map +0 -1
  89. package/dist/chunk-DRVOUQMT.cjs.map +0 -1
  90. package/dist/chunk-E5UJBLQ7.js.map +0 -1
  91. package/dist/chunk-FKKQUMXR.cjs.map +0 -1
  92. package/dist/chunk-FSKONGCX.cjs.map +0 -1
  93. package/dist/chunk-NZEUU7QB.js.map +0 -1
  94. package/dist/chunk-OZ3CCTTA.cjs.map +0 -1
  95. package/dist/chunk-PONTBXR5.js +0 -842
  96. package/dist/chunk-PONTBXR5.js.map +0 -1
  97. package/dist/chunk-QFLB4EIJ.cjs.map +0 -1
  98. package/dist/chunk-QVJNSAQL.cjs.map +0 -1
  99. package/dist/chunk-RRKCIAPU.cjs +0 -848
  100. package/dist/chunk-RRKCIAPU.cjs.map +0 -1
  101. package/dist/chunk-VLK5SJRI.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/fields/types.ts","../src/fields/richtext.ts"],"names":[],"mappings":"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","file":"chunk-FIAMXNTH.js","sourcesContent":["\n\n// ============================================================================\n// Base Field Interface\n// ============================================================================\n\n/**\n * Serializable condition for conditional field visibility.\n * Unlike function conditions, these survive JSON serialization\n * and can be used in admin configs that are built at compile time.\n */\nexport interface DeclarativeCondition {\n /** The field name to evaluate (resolved from root form data) */\n field: string;\n /** Show the field when the target field equals this value */\n equals?: string | number | boolean;\n /** Show the field when the target field does NOT equal this value */\n notEquals?: string | number | boolean;\n /** Show the field when the target field's value is one of these */\n in?: (string | number | boolean)[];\n}\n\nexport interface FieldAdmin {\n description?: string;\n placeholder?: string;\n readOnly?: boolean | ((\n data: Record<string, unknown>,\n siblingData: Record<string, unknown>,\n ) => boolean);\n hidden?: boolean | ((\n data: Record<string, unknown>,\n siblingData: Record<string, unknown>,\n ) => boolean);\n width?: string;\n position?: \"sidebar\" | \"main\";\n autoGenerate?: string;\n action?: string;\n method?: string;\n inline?: boolean;\n pickerMode?: \"drawer\" | \"dropdown\";\n condition?:\n | ((\n data: Record<string, unknown>,\n siblingData: Record<string, unknown>,\n ) => boolean)\n | DeclarativeCondition;\n}\n\nexport interface BaseField {\n name: string;\n label?: string;\n required?: boolean;\n unique?: boolean;\n indexed?: boolean;\n defaultValue?: any;\n admin?: FieldAdmin;\n validate?: (\n value: any,\n options: ValidateOptions,\n ) => string | true | Promise<string | true>;\n hooks?: {\n beforeValidate?: Hook[];\n beforeChange?: Hook[];\n afterChange?: Hook[];\n afterRead?: Hook[];\n };\n}\n\nexport interface ValidateOptions {\n data?: Record<string, any>;\n siblingData?: Record<string, any>;\n user?: unknown;\n operation?: string;\n required?: boolean;\n}\n\nexport type Hook = (args: any) => Promise<any> | any;\n\n// ============================================================================\n// Primitive Fields\n// ============================================================================\n\nexport type TextFieldVariant = \"text\" | \"email\" | \"password\" | \"url\" | \"id\";\n\nexport interface TextField extends BaseField {\n type: \"text\";\n variant?: TextFieldVariant;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n hasMany?: boolean;\n localized?: boolean;\n}\n\nexport interface NumberField extends BaseField {\n type: \"number\";\n min?: number;\n max?: number;\n step?: number;\n integer?: boolean;\n hasMany?: boolean;\n}\n\nexport interface CheckboxField extends BaseField {\n type: \"checkbox\";\n}\n\nexport interface DateField extends BaseField {\n type: \"date\";\n minDate?: string;\n maxDate?: string;\n time?: boolean;\n}\n\nexport interface EmailField extends BaseField {\n type: \"email\";\n}\n\nexport interface PasswordField extends BaseField {\n type: \"password\";\n}\n\nexport interface TextareaField extends BaseField {\n type: \"textarea\";\n minLength?: number;\n maxLength?: number;\n rows?: number;\n localized?: boolean;\n}\n\nexport interface SelectField extends BaseField {\n type: \"select\";\n options?: Array<{ label: string; value: string }>;\n dynamicOptions?: string;\n hasMany?: boolean;\n defaultValue?: string | string[];\n}\n\nexport interface RadioField extends BaseField {\n type: \"radio\";\n options: Array<{ label: string; value: string }>;\n defaultValue?: string;\n}\n\nexport interface ColorField extends BaseField {\n type: \"color\";\n format?: \"hex\" | \"rgb\" | \"hsl\";\n defaultValue?: string;\n}\n\nexport interface ImageField extends BaseField {\n type: \"image\";\n minCount?: number;\n maxCount?: number;\n allowedTypes?: string[];\n maxSize?: number;\n}\n\n// ============================================================================\n// Complex Fields\n// ============================================================================\n\nexport type RichTextBlock = Record<string, any>; // TipTap JSONContent\n\nexport interface RichTextField extends BaseField {\n type: \"richtext\";\n defaultValue?: Record<string, any>;\n localized?: boolean;\n}\n\nexport interface JSONField extends BaseField {\n type: \"json\";\n defaultValue?: Record<string, any>;\n}\n\nexport interface CodeField extends BaseField {\n type: \"code\";\n language?: string;\n defaultValue?: string;\n}\n\nexport interface UploadField extends BaseField {\n type: \"upload\";\n relationTo: string;\n hasMany?: boolean;\n maxDepth?: number;\n defaultValue?: string;\n}\n\nexport interface MarkdownField extends BaseField {\n type: \"markdown\";\n localized?: boolean;\n defaultValue?: string;\n}\n\n// ============================================================================\n// Relational Fields\n// ============================================================================\n\nexport interface RelationshipField extends BaseField {\n type: \"relationship\";\n relationTo: string | string[];\n hasMany?: boolean;\n maxDepth?: number;\n filterOptions?: (args: { data: any; user: any }) => Record<string, any>;\n defaultValue?: string | string[];\n}\n\nexport interface ArrayField extends BaseField {\n type: \"array\";\n fields: Field[];\n minRows?: number;\n maxRows?: number;\n labels?: { singular?: string; plural?: string };\n defaultValue?: Record<string, any>[];\n}\n\nexport interface ListField extends BaseField {\n type: \"list\";\n defaultValue?: string[];\n}\n\nexport interface GroupField extends BaseField {\n type: \"group\";\n fields: Field[];\n defaultValue?: Record<string, any>;\n}\n\nexport interface BlockImage {\n url: string;\n alt?: string;\n}\n\nexport interface BlockAdmin {\n group?: string;\n description?: string;\n images?: {\n icon?: BlockImage | string;\n thumbnail?: BlockImage | string;\n };\n}\n\nexport interface Block {\n slug: string;\n label: string;\n fields: Field[];\n imageURL?: string;\n admin?: BlockAdmin;\n}\n\nexport interface BlocksField extends BaseField {\n type: \"blocks\";\n blocks?: Block[];\n minRows?: number;\n maxRows?: number;\n defaultValue?: Array<{ blockType: string; [key: string]: any }>;\n}\n\nexport interface RowField extends Omit<BaseField, \"name\"> {\n type: \"row\";\n fields: Field[];\n name?: string;\n}\n\nexport interface CollapsibleField extends Omit<BaseField, \"name\"> {\n type: \"collapsible\";\n fields: Field[];\n label: string;\n name?: string;\n}\n\nexport interface TabsField extends Omit<BaseField, \"name\"> {\n type: \"tabs\";\n tabs: Array<{\n label: string;\n fields: Field[];\n name?: string;\n }>;\n name?: string;\n}\n\nexport interface ButtonField extends BaseField {\n type: \"button\";\n label: string;\n action?: string;\n method?: string;\n inline?: boolean;\n}\n\nexport interface ActionField extends BaseField {\n type: \"action\";\n label: string;\n action?: string;\n method?: string;\n inline?: boolean;\n}\n\nexport interface SecretField extends BaseField {\n type: \"secret\";\n}\n\n// ============================================================================\n// Union Type\n// ============================================================================\n\nexport type Field =\n | TextField\n | NumberField\n | CheckboxField\n | DateField\n | EmailField\n | PasswordField\n | TextareaField\n | SelectField\n | RadioField\n | ColorField\n | ImageField\n | RichTextField\n | JSONField\n | CodeField\n | UploadField\n | MarkdownField\n | RelationshipField\n | ArrayField\n | ListField\n | GroupField\n | BlocksField\n | RowField\n | CollapsibleField\n | TabsField\n | ButtonField\n | ActionField\n | SecretField;\n\nexport type FieldType = Field[\"type\"];\n\n// ============================================================================\n// Field Type Guards\n// ============================================================================\n\nexport function isTextField(field: Field): field is TextField {\n return field.type === \"text\";\n}\n\nexport function isNumberField(field: Field): field is NumberField {\n return field.type === \"number\";\n}\n\nexport function isRelationshipField(field: Field): field is RelationshipField {\n return field.type === \"relationship\";\n}\n\nexport function isArrayField(field: Field): field is ArrayField {\n return field.type === \"array\";\n}\n\nexport function isGroupField(field: Field): field is GroupField {\n return field.type === \"group\";\n}\n\nexport function isBlocksField(field: Field): field is BlocksField {\n return field.type === \"blocks\";\n}\n\nexport function isUploadField(field: Field): field is UploadField {\n return field.type === \"upload\";\n}\n\nexport function isImageField(field: Field): field is ImageField {\n return field.type === \"image\";\n}\n\nexport function isRichTextField(field: Field): field is RichTextField {\n return field.type === \"richtext\";\n}\n\nexport function isSelectField(field: Field): field is SelectField {\n return field.type === \"select\";\n}\n\nexport function isLayoutField(\n field: Field,\n): field is RowField | CollapsibleField | TabsField {\n return (\n field.type === \"row\" ||\n field.type === \"collapsible\" ||\n field.type === \"tabs\"\n );\n}\n\n// ============================================================================\n// Field Type List\n// ============================================================================\n\nexport const PRIMITIVE_FIELD_TYPES = [\n \"text\",\n \"number\",\n \"checkbox\",\n \"date\",\n \"email\",\n \"password\",\n \"textarea\",\n \"select\",\n \"radio\",\n \"color\",\n] as const;\n\nexport const COMPLEX_FIELD_TYPES = [\n \"richtext\",\n \"json\",\n \"code\",\n \"upload\",\n \"image\",\n \"markdown\",\n] as const;\n\nexport const RELATIONAL_FIELD_TYPES = [\n \"relationship\",\n \"array\",\n \"group\",\n \"blocks\",\n] as const;\n\nexport const LAYOUT_FIELD_TYPES = [\"row\", \"collapsible\", \"tabs\"] as const;\n\nexport const ALL_FIELD_TYPES = [\n ...PRIMITIVE_FIELD_TYPES,\n ...COMPLEX_FIELD_TYPES,\n ...RELATIONAL_FIELD_TYPES,\n ...LAYOUT_FIELD_TYPES,\n] as const;\n\n// ============================================================================\n// Field Factory Functions\n// ============================================================================\n\nexport function createRelationshipFieldConfig(\n name: string,\n relationTo: string | string[],\n options?: Partial<Omit<RelationshipField, \"type\" | \"name\" | \"relationTo\">>,\n): RelationshipField {\n return {\n name,\n type: \"relationship\",\n relationTo,\n ...options,\n required: options?.required ?? false,\n };\n}\n","import { generateHTML } from \"@tiptap/html\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Link from \"@tiptap/extension-link\";\nimport Image from \"@tiptap/extension-image\";\nimport TextAlign from \"@tiptap/extension-text-align\";\nimport Underline from \"@tiptap/extension-underline\";\nimport Highlight from \"@tiptap/extension-highlight\";\nimport TaskList from \"@tiptap/extension-task-list\";\nimport TaskItem from \"@tiptap/extension-task-item\";\nimport { TextStyle } from \"@tiptap/extension-text-style\";\nimport Color from \"@tiptap/extension-color\";\n\nexport const richTextStyles = `\n.kyro-richtext {\n color: inherit;\n line-height: 1.7;\n}\n\n.kyro-richtext > *:first-child {\n margin-top: 0;\n}\n\n.kyro-richtext > *:last-child {\n margin-bottom: 0;\n}\n\n.kyro-richtext p,\n.kyro-richtext ul,\n.kyro-richtext ol,\n.kyro-richtext blockquote,\n.kyro-richtext pre {\n margin: 0 0 1rem;\n}\n\n.kyro-richtext h1,\n.kyro-richtext h2,\n.kyro-richtext h3,\n.kyro-richtext h4,\n.kyro-richtext h5,\n.kyro-richtext h6 {\n margin: 0 0 0.75rem;\n line-height: 1.2;\n}\n\n.kyro-richtext ul,\n.kyro-richtext ol {\n padding-left: 1.5rem;\n}\n\n.kyro-richtext blockquote {\n border-left: 4px solid rgba(148, 163, 184, 0.5);\n margin-left: 0;\n padding-left: 1rem;\n font-style: italic;\n}\n\n.kyro-richtext pre {\n overflow-x: auto;\n border-radius: 0.75rem;\n background: rgba(15, 23, 42, 0.92);\n color: #f8fafc;\n padding: 1rem;\n}\n\n.kyro-richtext code {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n}\n\n.kyro-richtext img {\n display: block;\n max-width: 100%;\n height: auto;\n border-radius: 0.75rem;\n}\n\n.kyro-richtext ul[data-type=\"taskList\"] {\n list-style: none;\n padding: 0;\n}\n\n.kyro-richtext li[data-type=\"taskItem\"] {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n}\n\n.kyro-richtext li[data-type=\"taskItem\"] > label {\n user-select: none;\n pointer-events: none;\n margin-top: 0.2rem;\n}\n\n.kyro-richtext li[data-type=\"taskItem\"] > div {\n flex: 1;\n}\n\n.kyro-richtext mark {\n background-color: #fef08a;\n border-radius: 0.25rem;\n padding: 0.125rem 0.25rem;\n}\n`.trim();\n\nconst extensions = [\n StarterKit,\n Link.configure({\n openOnClick: false,\n }),\n Image,\n TextAlign.configure({\n types: [\"heading\", \"paragraph\"],\n }),\n Underline,\n Highlight.configure({\n multicolor: true,\n }),\n TaskList,\n TaskItem.configure({\n nested: true,\n }),\n TextStyle,\n Color,\n];\n\nexport function normalizeRichTextValue<T>(value: T): T {\n // TipTap JSON is already standard JSON, so we just ensure it's an object.\n if (typeof value === \"object\" && value !== null) {\n return value;\n }\n return {} as T;\n}\n\nexport function renderRichText(value: unknown): string {\n if (typeof value !== \"object\" || value === null) {\n return \"\";\n }\n \n try {\n const html = generateHTML(value as Record<string, any>, extensions);\n return `<div class=\"kyro-richtext\">${html}</div>`;\n } catch (error) {\n console.error(\"Failed to render rich text:\", error);\n return \"\";\n }\n}\n"]}
@@ -4,8 +4,8 @@ var chunkY7AQK4R4_cjs = require('./chunk-Y7AQK4R4.cjs');
4
4
  var chunkKC2GDBLS_cjs = require('./chunk-KC2GDBLS.cjs');
5
5
  var chunkIDVRRRAK_cjs = require('./chunk-IDVRRRAK.cjs');
6
6
  var chunkADLJSJSN_cjs = require('./chunk-ADLJSJSN.cjs');
7
- var chunkQFLB4EIJ_cjs = require('./chunk-QFLB4EIJ.cjs');
8
- var chunkFKKQUMXR_cjs = require('./chunk-FKKQUMXR.cjs');
7
+ var chunkLNTFRAHF_cjs = require('./chunk-LNTFRAHF.cjs');
8
+ var chunk4OCMVGEY_cjs = require('./chunk-4OCMVGEY.cjs');
9
9
  var chunkRFFSZSCL_cjs = require('./chunk-RFFSZSCL.cjs');
10
10
  var chunk7OS7TX2Q_cjs = require('./chunk-7OS7TX2Q.cjs');
11
11
  var chunkQ23GAMLE_cjs = require('./chunk-Q23GAMLE.cjs');
@@ -391,14 +391,14 @@ function createAuthMiddleware(config) {
391
391
  userLookup
392
392
  } = config;
393
393
  return async function authMiddleware(req) {
394
- const apiKeyRaw = chunkFKKQUMXR_cjs.extractApiKeyFromRequest(req);
394
+ const apiKeyRaw = chunk4OCMVGEY_cjs.extractApiKeyFromRequest(req);
395
395
  if (apiKeyRaw && db) {
396
- const result = await chunkFKKQUMXR_cjs.validateApiKey(apiKeyRaw, db, userLookup);
396
+ const result = await chunk4OCMVGEY_cjs.validateApiKey(apiKeyRaw, db, userLookup);
397
397
  if (result.valid && result.user) {
398
398
  return {
399
399
  user: result.user,
400
400
  tenantContext: createTenantContextFromUser(result.user),
401
- apiKeyContext: chunkFKKQUMXR_cjs.createApiKeyContext(result),
401
+ apiKeyContext: chunk4OCMVGEY_cjs.createApiKeyContext(result),
402
402
  status: 200,
403
403
  authType: "apikey"
404
404
  };
@@ -1681,22 +1681,11 @@ function createLocalStorage(config) {
1681
1681
  }
1682
1682
  };
1683
1683
  }
1684
-
1685
- // src/storage/imgix.ts
1686
1684
  function createImgixStorage(config) {
1687
1685
  const signUrl = (path3, params) => {
1688
1686
  if (!config.signKey) return path3;
1689
- const signer = new TextEncoder();
1690
- const key = signer.encode(config.signKey);
1691
- const data = signer.encode(path3 + params.toString());
1692
- let hash = 0;
1693
- const combined = new Uint8Array(key.length + data.length);
1694
- combined.set(key);
1695
- combined.set(data, key.length);
1696
- for (let i = 0; i < combined.length; i++) {
1697
- hash = (hash << 5) - hash + combined[i] | 0;
1698
- }
1699
- params.set("s", Math.abs(hash).toString(16));
1687
+ const signature = crypto.createHmac("sha256", config.signKey).update(path3 + params.toString()).digest("hex");
1688
+ params.set("s", signature);
1700
1689
  return path3;
1701
1690
  };
1702
1691
  return {
@@ -2969,7 +2958,7 @@ var MediaService = class _MediaService {
2969
2958
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2970
2959
  return { where, params: p, orderBy: sortDir, sortCol };
2971
2960
  }
2972
- rowToMedia(row) {
2961
+ rowToMedia(row, origin) {
2973
2962
  return {
2974
2963
  id: row.id,
2975
2964
  filename: row.filename,
@@ -2979,8 +2968,8 @@ var MediaService = class _MediaService {
2979
2968
  fileSize: row.file_size ?? row.fileSize,
2980
2969
  width: row.width ?? null,
2981
2970
  height: row.height ?? null,
2982
- url: row.url,
2983
- thumbnailUrl: row.thumbnail_url ?? row.thumbnailUrl ?? null,
2971
+ url: _MediaService.resolveMediaUrl(row.url, origin),
2972
+ thumbnailUrl: _MediaService.resolveMediaUrl(row.thumbnail_url ?? row.thumbnailUrl ?? null, origin),
2984
2973
  folder: row.folder ?? null,
2985
2974
  provider: row.provider,
2986
2975
  alt: row.alt ?? null,
@@ -2990,6 +2979,12 @@ var MediaService = class _MediaService {
2990
2979
  updatedAt: row.updated_at ?? row.updatedAt
2991
2980
  };
2992
2981
  }
2982
+ static resolveMediaUrl(url, origin) {
2983
+ if (!url) return null;
2984
+ if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("blob:") || url.startsWith("data:")) return url;
2985
+ const base = (process.env.KYRO_BASE_URL || origin || "http://localhost:4321").replace(/\/+$/, "");
2986
+ return `${base}${url.startsWith("/") ? "" : "/"}${url}`;
2987
+ }
2993
2988
  async sqliteRun(sql, params = []) {
2994
2989
  const stmt = this.db.prepare(sql);
2995
2990
  const sqlLower = sql.trim().toLowerCase();
@@ -3117,17 +3112,19 @@ var MediaService = class _MediaService {
3117
3112
  const file = new File([blob], originalName, { type: mimeType });
3118
3113
  return this.upload(file, folder);
3119
3114
  }
3120
- async delete(id) {
3115
+ async delete(id, origin) {
3121
3116
  let item = null;
3122
3117
  if (this.dialect === "sqlite") {
3123
- item = this.sqliteGet(`SELECT * FROM ${this.mediaTable} WHERE id = ?`, [
3124
- id
3125
- ]);
3118
+ const row = this.sqliteGet(
3119
+ `SELECT * FROM ${this.mediaTable} WHERE id = ?`,
3120
+ [id]
3121
+ );
3122
+ if (row) item = this.rowToMedia(row, origin);
3126
3123
  } else {
3127
3124
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3128
3125
  const { eq } = await import('drizzle-orm');
3129
3126
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3130
- if (row) item = this.rowToMedia(row);
3127
+ if (row) item = this.rowToMedia(row, origin);
3131
3128
  }
3132
3129
  if (!item) return;
3133
3130
  await this.deleteFile(item.url);
@@ -3148,7 +3145,7 @@ var MediaService = class _MediaService {
3148
3145
  async deleteFile(url) {
3149
3146
  await this.storage.delete(url);
3150
3147
  }
3151
- async rename(id, newKey) {
3148
+ async rename(id, newKey, origin) {
3152
3149
  let item = null;
3153
3150
  if (this.dialect === "sqlite") {
3154
3151
  item = this.sqliteGet(`SELECT * FROM ${this.mediaTable} WHERE id = ?`, [
@@ -3158,7 +3155,7 @@ var MediaService = class _MediaService {
3158
3155
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3159
3156
  const { eq } = await import('drizzle-orm');
3160
3157
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3161
- if (row) item = this.rowToMedia(row);
3158
+ if (row) item = this.rowToMedia(row, origin);
3162
3159
  }
3163
3160
  if (!item) return null;
3164
3161
  const newUrl = await this.storage.rename(item.url, newKey);
@@ -3201,20 +3198,20 @@ var MediaService = class _MediaService {
3201
3198
  thumbnailUrl: updateData.thumbnailUrl ?? null
3202
3199
  };
3203
3200
  }
3204
- async findById(id) {
3201
+ async findById(id, origin) {
3205
3202
  if (this.dialect === "sqlite") {
3206
3203
  const row2 = this.sqliteGet(
3207
3204
  `SELECT * FROM ${this.mediaTable} WHERE id = ?`,
3208
3205
  [id]
3209
3206
  );
3210
- return row2 ? this.rowToMedia(row2) : null;
3207
+ return row2 ? this.rowToMedia(row2, origin) : null;
3211
3208
  }
3212
3209
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3213
3210
  const { eq } = await import('drizzle-orm');
3214
3211
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3215
- return row ? this.rowToMedia(row) : null;
3212
+ return row ? this.rowToMedia(row, origin) : null;
3216
3213
  }
3217
- async find(params = {}) {
3214
+ async find(params = {}, origin) {
3218
3215
  const {
3219
3216
  page = 1,
3220
3217
  limit = 30,
@@ -3250,7 +3247,7 @@ var MediaService = class _MediaService {
3250
3247
  [...p, limit, offset]
3251
3248
  );
3252
3249
  return {
3253
- docs: rows.map((r) => this.rowToMedia(r)),
3250
+ docs: rows.map((r) => this.rowToMedia(r, origin)),
3254
3251
  totalDocs: totalDocs2,
3255
3252
  page,
3256
3253
  limit,
@@ -3297,14 +3294,14 @@ var MediaService = class _MediaService {
3297
3294
  const [{ count }] = await this.db.select({ count: sql`count(*)` }).from(mediaSchema).where(whereClause);
3298
3295
  const totalDocs = Number(count);
3299
3296
  return {
3300
- docs: docs.map((r) => this.rowToMedia(r)),
3297
+ docs: docs.map((r) => this.rowToMedia(r, origin)),
3301
3298
  totalDocs,
3302
3299
  page,
3303
3300
  limit,
3304
3301
  totalPages: Math.ceil(totalDocs / limit)
3305
3302
  };
3306
3303
  }
3307
- async update(id, data) {
3304
+ async update(id, data, origin) {
3308
3305
  const now = this.now();
3309
3306
  if (this.dialect === "sqlite") {
3310
3307
  const sets = ["updated_at = ?"];
@@ -3323,7 +3320,7 @@ var MediaService = class _MediaService {
3323
3320
  }
3324
3321
  if (data.folder !== void 0) {
3325
3322
  sets.push("folder = ?");
3326
- p.push(data.folder || null);
3323
+ p.push(data.folder);
3327
3324
  }
3328
3325
  p.push(id);
3329
3326
  await this.sqliteRun(
@@ -3334,12 +3331,12 @@ var MediaService = class _MediaService {
3334
3331
  `SELECT * FROM ${this.mediaTable} WHERE id = ?`,
3335
3332
  [id]
3336
3333
  );
3337
- return row ? this.rowToMedia(row) : null;
3334
+ return row ? this.rowToMedia(row, origin) : null;
3338
3335
  }
3339
3336
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3340
3337
  const { eq } = await import('drizzle-orm');
3341
3338
  const [updated] = await this.db.update(mediaSchema).set({ ...data, updatedAt: /* @__PURE__ */ new Date() }).where(eq(mediaSchema.id, id)).returning();
3342
- return updated ? this.rowToMedia(updated) : null;
3339
+ return updated ? this.rowToMedia(updated, origin) : null;
3343
3340
  }
3344
3341
  async updateMany(ids, data) {
3345
3342
  const now = this.now();
@@ -3496,9 +3493,9 @@ function convertRichtextFields(fields, data) {
3496
3493
  }
3497
3494
  var COLLECTION_EVENT_MAP = {
3498
3495
  _media: {
3499
- create: chunkQFLB4EIJ_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3500
- update: chunkQFLB4EIJ_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3501
- delete: chunkQFLB4EIJ_cjs.WEBHOOK_EVENTS.MEDIA_DELETE
3496
+ create: chunkLNTFRAHF_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3497
+ update: chunkLNTFRAHF_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3498
+ delete: chunkLNTFRAHF_cjs.WEBHOOK_EVENTS.MEDIA_DELETE
3502
3499
  }
3503
3500
  };
3504
3501
  function getWebhookEvent(collection, operation) {
@@ -3546,7 +3543,7 @@ function buildConflictResponse(expectedUpdatedAt, currentDoc) {
3546
3543
  };
3547
3544
  }
3548
3545
  async function checkCollectionAccess2(collection, operation, req, ctxUser, ctxTenantID, apiKeyContext, enablePublicAccess = true, defaultCollectionAccess = "none") {
3549
- const result = await chunkFKKQUMXR_cjs.checkCollectionAccess(collection, operation, {
3546
+ const result = await chunkLNTFRAHF_cjs.checkCollectionAccess(collection, operation, {
3550
3547
  user: ctxUser,
3551
3548
  req,
3552
3549
  tenantID: ctxTenantID,
@@ -3558,7 +3555,7 @@ async function checkCollectionAccess2(collection, operation, req, ctxUser, ctxTe
3558
3555
  return result;
3559
3556
  }
3560
3557
  async function checkGlobalAccess2(global, operation, req, ctxUser, ctxTenantID, enablePublicAccess = true) {
3561
- const result = await chunkFKKQUMXR_cjs.checkGlobalAccess(global, operation, {
3558
+ const result = await chunkLNTFRAHF_cjs.checkGlobalAccess(global, operation, {
3562
3559
  user: ctxUser,
3563
3560
  req,
3564
3561
  tenantID: ctxTenantID
@@ -4126,12 +4123,13 @@ function createHonoApp(options) {
4126
4123
  const { user: ctxUser } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
4127
4124
  if (!ctxUser) return c.json({ error: "Authentication required" }, 401);
4128
4125
  const service = await getMedia();
4126
+ const origin = new URL(c.req.url).origin;
4129
4127
  const page = parseInt(c.req.query("page") || "1");
4130
4128
  const limit = parseInt(c.req.query("limit") || "30");
4131
4129
  const search = c.req.query("search") || "";
4132
4130
  const type = c.req.query("type") || "";
4133
4131
  const folder = c.req.query("folder") || "";
4134
- const result = await service.find({ page, limit, search, type, folder });
4132
+ const result = await service.find({ page, limit, search, type, folder }, origin);
4135
4133
  return c.json(result);
4136
4134
  } catch (error) {
4137
4135
  console.error("[Media] find error:", error);
@@ -4215,7 +4213,8 @@ function createHonoApp(options) {
4215
4213
  if (!ctxUser) return c.json({ error: "Authentication required" }, 401);
4216
4214
  const service = await getMedia();
4217
4215
  const id = c.req.param("id");
4218
- await service.delete(id);
4216
+ const origin = new URL(c.req.url).origin;
4217
+ await service.delete(id, origin);
4219
4218
  return c.json({ success: true });
4220
4219
  } catch (error) {
4221
4220
  console.error("[Media] delete error:", error);
@@ -4271,7 +4270,8 @@ function createHonoApp(options) {
4271
4270
  if (!ctxUser) return c.json({ error: "Authentication required" }, 401);
4272
4271
  const service = await getMedia();
4273
4272
  const id = c.req.param("id");
4274
- const doc = await service.findById(id);
4273
+ const origin = new URL(c.req.url).origin;
4274
+ const doc = await service.findById(id, origin);
4275
4275
  if (!doc) return c.json({ error: "Media not found" }, 404);
4276
4276
  return c.json(doc);
4277
4277
  } catch (error) {
@@ -4286,8 +4286,9 @@ function createHonoApp(options) {
4286
4286
  const service = await getMedia();
4287
4287
  const id = c.req.param("id");
4288
4288
  const body = await c.req.json();
4289
+ const origin = new URL(c.req.url).origin;
4289
4290
  if (body.folder !== void 0) {
4290
- const updated = await service.update(id, { folder: body.folder });
4291
+ const updated = await service.update(id, { folder: body.folder }, origin);
4291
4292
  return c.json({ doc: updated });
4292
4293
  }
4293
4294
  return c.json({ error: "No valid fields to update" }, 400);
@@ -4793,7 +4794,7 @@ function createHonoApp(options) {
4793
4794
  }
4794
4795
  const page = parseInt(c.req.query("page") || "1");
4795
4796
  const limit = Math.min(parseInt(c.req.query("limit") || "50"), 100);
4796
- const result = await db.find({ collection: chunkFKKQUMXR_cjs.API_KEY_COLLECTION, where: {}, page, limit, tenantID: ctxTenantID });
4797
+ const result = await db.find({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, where: {}, page, limit, tenantID: ctxTenantID });
4797
4798
  const docs = (result.docs || []).map((doc) => ({
4798
4799
  id: doc.id,
4799
4800
  name: doc.name,
@@ -4818,14 +4819,14 @@ function createHonoApp(options) {
4818
4819
  if (!body.name || typeof body.name !== "string") {
4819
4820
  return c.json({ error: "name is required" }, 400);
4820
4821
  }
4821
- const rawKey = chunkFKKQUMXR_cjs.generateApiKey();
4822
+ const rawKey = chunk4OCMVGEY_cjs.generateApiKey();
4822
4823
  const doc = await db.create({
4823
- collection: chunkFKKQUMXR_cjs.API_KEY_COLLECTION,
4824
+ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION,
4824
4825
  data: {
4825
4826
  userId: ctxUser.id,
4826
4827
  name: body.name,
4827
4828
  key: rawKey,
4828
- keyPrefix: chunkFKKQUMXR_cjs.generateApiKeyPrefix(rawKey),
4829
+ keyPrefix: chunk4OCMVGEY_cjs.generateApiKeyPrefix(rawKey),
4829
4830
  permissions: Array.isArray(body.permissions) ? body.permissions : ["*"],
4830
4831
  expiresAt: body.expiresAt || null,
4831
4832
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -4856,9 +4857,9 @@ function createHonoApp(options) {
4856
4857
  return c.json({ error: "Forbidden" }, 403);
4857
4858
  }
4858
4859
  const id = c.req.param("id");
4859
- const existing = await db.findByID({ collection: chunkFKKQUMXR_cjs.API_KEY_COLLECTION, id });
4860
+ const existing = await db.findByID({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4860
4861
  if (!existing) return c.json({ error: "API key not found" }, 404);
4861
- await db.delete({ collection: chunkFKKQUMXR_cjs.API_KEY_COLLECTION, id });
4862
+ await db.delete({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4862
4863
  await sessionAuthAdapter?.createAuditLog({
4863
4864
  action: "api_key_delete",
4864
4865
  userId: ctxUser.id,
@@ -4881,14 +4882,14 @@ function createHonoApp(options) {
4881
4882
  }
4882
4883
  const id = c.req.param("id");
4883
4884
  const body = await c.req.json();
4884
- const existing = await db.findByID({ collection: chunkFKKQUMXR_cjs.API_KEY_COLLECTION, id });
4885
+ const existing = await db.findByID({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4885
4886
  if (!existing) return c.json({ error: "API key not found" }, 404);
4886
4887
  const updateData = {};
4887
4888
  if (typeof body.name === "string" && body.name.trim()) updateData.name = body.name.trim();
4888
4889
  if (Array.isArray(body.permissions)) updateData.permissions = body.permissions;
4889
4890
  if (body.expiresAt !== void 0) updateData.expiresAt = body.expiresAt || null;
4890
4891
  if (Object.keys(updateData).length === 0) return c.json({ error: "Nothing to update" }, 400);
4891
- const updated = await db.update({ collection: chunkFKKQUMXR_cjs.API_KEY_COLLECTION, id, data: updateData });
4892
+ const updated = await db.update({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id, data: updateData });
4892
4893
  return c.json({ ...updated, keyPrefix: existing.keyPrefix });
4893
4894
  } catch (error) {
4894
4895
  console.error("[ApiKeys] PATCH error:", error);
@@ -4902,15 +4903,15 @@ function createHonoApp(options) {
4902
4903
  return c.json({ error: "Forbidden" }, 403);
4903
4904
  }
4904
4905
  const id = c.req.param("id");
4905
- const existing = await db.findByID({ collection: chunkFKKQUMXR_cjs.API_KEY_COLLECTION, id });
4906
+ const existing = await db.findByID({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4906
4907
  if (!existing) return c.json({ error: "API key not found" }, 404);
4907
- const rawKey = chunkFKKQUMXR_cjs.generateApiKey();
4908
+ const rawKey = chunk4OCMVGEY_cjs.generateApiKey();
4908
4909
  const updated = await db.update({
4909
- collection: chunkFKKQUMXR_cjs.API_KEY_COLLECTION,
4910
+ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION,
4910
4911
  id,
4911
4912
  data: {
4912
4913
  key: rawKey,
4913
- keyPrefix: chunkFKKQUMXR_cjs.generateApiKeyPrefix(rawKey),
4914
+ keyPrefix: chunk4OCMVGEY_cjs.generateApiKeyPrefix(rawKey),
4914
4915
  lastUsedAt: null
4915
4916
  }
4916
4917
  });
@@ -5068,6 +5069,75 @@ function createHonoApp(options) {
5068
5069
  return c.json({ error: error.message }, 500);
5069
5070
  }
5070
5071
  });
5072
+ function serializeField(field) {
5073
+ const safe = {};
5074
+ const keys = [
5075
+ "name",
5076
+ "type",
5077
+ "required",
5078
+ "hasMany",
5079
+ "relationTo",
5080
+ "options",
5081
+ "min",
5082
+ "max",
5083
+ "minLength",
5084
+ "maxLength",
5085
+ "defaultValue",
5086
+ "label",
5087
+ "localized",
5088
+ "admin",
5089
+ "unique",
5090
+ "index",
5091
+ "hidden",
5092
+ "readOnly",
5093
+ "deprecated"
5094
+ ];
5095
+ for (const k of keys) {
5096
+ if (k in field) safe[k] = field[k];
5097
+ }
5098
+ if (field.fields) {
5099
+ safe.fields = field.fields.map(serializeField);
5100
+ }
5101
+ if (field.tabs) {
5102
+ safe.tabs = field.tabs.map((t) => ({
5103
+ label: t.label,
5104
+ name: t.name,
5105
+ fields: t.fields.map(serializeField)
5106
+ }));
5107
+ }
5108
+ return safe;
5109
+ }
5110
+ app.get("/api/__schema", async (c) => {
5111
+ try {
5112
+ const { user: ctxUser, apiKeyContext } = await resolveAuthContext(
5113
+ c.req.raw,
5114
+ authMw,
5115
+ user,
5116
+ tenantID
5117
+ );
5118
+ if (!ctxUser && !apiKeyContext) {
5119
+ return c.json({ error: "Unauthorized" }, 401);
5120
+ }
5121
+ const cols = registry.getCollections().filter(
5122
+ (col) => col.slug !== "users" && col.slug !== "audit_logs"
5123
+ );
5124
+ const serialized = cols.map((col) => ({
5125
+ slug: col.slug,
5126
+ label: col.label,
5127
+ labelPlural: col.labelPlural,
5128
+ singularLabel: col.singularLabel,
5129
+ timestamps: col.timestamps,
5130
+ auth: !!col.auth,
5131
+ tenantScoped: !!col.tenantScoped,
5132
+ upload: col.upload ? { staticDir: col.upload.staticDir, imageSizes: col.upload.imageSizes, mimeTypes: col.upload.mimeTypes } : void 0,
5133
+ fields: col.fields.map(serializeField)
5134
+ }));
5135
+ return c.json(serialized);
5136
+ } catch (error) {
5137
+ console.error("[Schema] error:", error);
5138
+ return c.json({ error: error.message }, 500);
5139
+ }
5140
+ });
5071
5141
  const collections = registry.getCollections();
5072
5142
  for (const collection of collections) {
5073
5143
  let computeDiff2 = function(a, b) {
@@ -5113,10 +5183,20 @@ function createHonoApp(options) {
5113
5183
  const sort = url.searchParams.get("sort") || void 0;
5114
5184
  const depth = parseInt(url.searchParams.get("depth") || "0");
5115
5185
  const select = url.searchParams.get("select")?.split(",") || void 0;
5116
- const isDraftRequest = !!ctxUser;
5186
+ const draftParam = url.searchParams.get("draft");
5187
+ const isDraftRequest = draftParam === "true" ? true : draftParam === "false" ? false : !!ctxUser;
5188
+ let where = {};
5189
+ const whereRaw = url.searchParams.get("where");
5190
+ if (whereRaw) {
5191
+ try {
5192
+ where = JSON.parse(whereRaw);
5193
+ } catch {
5194
+ return c.json({ error: "Invalid JSON in where parameter" }, 400);
5195
+ }
5196
+ }
5117
5197
  const result = await db.find({
5118
5198
  collection: slug,
5119
- where: {},
5199
+ where,
5120
5200
  sort,
5121
5201
  limit,
5122
5202
  page,
@@ -5305,7 +5385,8 @@ function createHonoApp(options) {
5305
5385
  const url = new URL(c.req.url);
5306
5386
  const depth = parseInt(url.searchParams.get("depth") || "0");
5307
5387
  const select = url.searchParams.get("select")?.split(",") || void 0;
5308
- const isDraftRequest = !!ctxUser;
5388
+ const draftParam = url.searchParams.get("draft");
5389
+ const isDraftRequest = draftParam === "true" ? true : draftParam === "false" ? false : !!ctxUser;
5309
5390
  let doc = await db.findByID({
5310
5391
  collection: slug,
5311
5392
  id,
@@ -6292,7 +6373,6 @@ function createHonoApp(options) {
6292
6373
  data: doc,
6293
6374
  message: "Version restored successfully"
6294
6375
  });
6295
- return c.json({ data: doc, message: "Restored successfully" });
6296
6376
  } catch (error) {
6297
6377
  return c.json({ error: error.message }, 500);
6298
6378
  }
@@ -6378,6 +6458,13 @@ Sent at: ${(/* @__PURE__ */ new Date()).toLocaleString()}`
6378
6458
  });
6379
6459
  }
6380
6460
  }
6461
+ app.onError((err, c) => {
6462
+ console.error(`[API Error] ${c.req.method} ${c.req.path}:`, err);
6463
+ return c.json(
6464
+ { error: err.message || "Internal server error", code: "INTERNAL_ERROR" },
6465
+ 500
6466
+ );
6467
+ });
6381
6468
  return app;
6382
6469
  }
6383
6470
  function createRESTAPI(registry, db, options) {
@@ -6413,5 +6500,5 @@ exports.init_secret = init_secret;
6413
6500
  exports.loadSecrets = loadSecrets;
6414
6501
  exports.resolveProvider = resolveProvider;
6415
6502
  exports.setDbAdapter = setDbAdapter;
6416
- //# sourceMappingURL=chunk-QVJNSAQL.cjs.map
6417
- //# sourceMappingURL=chunk-QVJNSAQL.cjs.map
6503
+ //# sourceMappingURL=chunk-IEIHABVR.cjs.map
6504
+ //# sourceMappingURL=chunk-IEIHABVR.cjs.map