@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
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/fields/types.ts","../src/fields/richtext.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAoVO,SAAS,YAAY,KAAA,EAAkC;AAC5D,EAAA,OAAO,MAAM,IAAA,KAAS,MAAA;AACxB;AAEO,SAAS,cAAc,KAAA,EAAoC;AAChE,EAAA,OAAO,MAAM,IAAA,KAAS,QAAA;AACxB;AAEO,SAAS,oBAAoB,KAAA,EAA0C;AAC5E,EAAA,OAAO,MAAM,IAAA,KAAS,cAAA;AACxB;AAEO,SAAS,aAAa,KAAA,EAAmC;AAC9D,EAAA,OAAO,MAAM,IAAA,KAAS,OAAA;AACxB;AAEO,SAAS,aAAa,KAAA,EAAmC;AAC9D,EAAA,OAAO,MAAM,IAAA,KAAS,OAAA;AACxB;AAEO,SAAS,cAAc,KAAA,EAAoC;AAChE,EAAA,OAAO,MAAM,IAAA,KAAS,QAAA;AACxB;AAEO,SAAS,cAAc,KAAA,EAAoC;AAChE,EAAA,OAAO,MAAM,IAAA,KAAS,QAAA;AACxB;AAEO,SAAS,aAAa,KAAA,EAAmC;AAC9D,EAAA,OAAO,MAAM,IAAA,KAAS,OAAA;AACxB;AAEO,SAAS,gBAAgB,KAAA,EAAsC;AACpE,EAAA,OAAO,MAAM,IAAA,KAAS,UAAA;AACxB;AAEO,SAAS,cAAc,KAAA,EAAoC;AAChE,EAAA,OAAO,MAAM,IAAA,KAAS,QAAA;AACxB;AAEO,SAAS,cACd,KAAA,EACkD;AAClD,EAAA,OACE,MAAM,IAAA,KAAS,KAAA,IACf,MAAM,IAAA,KAAS,aAAA,IACf,MAAM,IAAA,KAAS,MAAA;AAEnB;AAMO,IAAM,qBAAA,GAAwB;AAAA,EACnC,MAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF;AAEO,IAAM,mBAAA,GAAsB;AAAA,EACjC,UAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF;AAEO,IAAM,sBAAA,GAAyB;AAAA,EACpC,cAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF;AAEO,IAAM,kBAAA,GAAqB,CAAC,KAAA,EAAO,aAAA,EAAe,MAAM;AAExD,IAAM,eAAA,GAAkB;AAAA,EAC7B,GAAG,qBAAA;AAAA,EACH,GAAG,mBAAA;AAAA,EACH,GAAG,sBAAA;AAAA,EACH,GAAG;AACL;AAMO,SAAS,6BAAA,CACd,IAAA,EACA,UAAA,EACA,OAAA,EACmB;AACnB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,IAAA,EAAM,cAAA;AAAA,IACN,UAAA;AAAA,IACA,GAAG,OAAA;AAAA,IACH,QAAA,EAAU,SAAS,QAAA,IAAY;AAAA,GACjC;AACF;ACpbO,IAAM,cAAA,GAAiB;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;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;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAyF5B,IAAA;AAEF,IAAM,UAAA,GAAa;AAAA,EACjB,UAAA;AAAA,EACA,KAAK,SAAA,CAAU;AAAA,IACb,WAAA,EAAa;AAAA,GACd,CAAA;AAAA,EACD,KAAA;AAAA,EACA,UAAU,SAAA,CAAU;AAAA,IAClB,KAAA,EAAO,CAAC,SAAA,EAAW,WAAW;AAAA,GAC/B,CAAA;AAAA,EACD,SAAA;AAAA,EACA,UAAU,SAAA,CAAU;AAAA,IAClB,UAAA,EAAY;AAAA,GACb,CAAA;AAAA,EACD,QAAA;AAAA,EACA,SAAS,SAAA,CAAU;AAAA,IACjB,MAAA,EAAQ;AAAA,GACT,CAAA;AAAA,EACD,SAAA;AAAA,EACA;AACF,CAAA;AAEO,SAAS,uBAA0B,KAAA,EAAa;AAErD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,EAAM;AAC/C,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,EAAC;AACV;AAEO,SAAS,eAAe,KAAA,EAAwB;AACrD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,EAAM;AAC/C,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,KAAA,EAA8B,UAAU,CAAA;AAClE,IAAA,OAAO,8BAA8B,IAAI,CAAA,MAAA,CAAA;AAAA,EAC3C,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAClD,IAAA,OAAO,EAAA;AAAA,EACT;AACF","file":"chunk-E5UJBLQ7.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, any>,\n siblingData: Record<string, any>,\n ) => boolean);\n hidden?: boolean | ((\n data: Record<string, any>,\n siblingData: Record<string, any>,\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, any>,\n siblingData: Record<string, any>,\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?: any;\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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/access/types.ts","../src/auth/api-key.ts","../src/access/checker.ts"],"names":["timingSafeEqual","hasPermission"],"mappings":"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","file":"chunk-FKKQUMXR.cjs","sourcesContent":["import type { User, Request } from '../hooks/types.js';\n\n// ============================================================================\n// Access Control Types\n// ============================================================================\n\nexport interface WhereClause {\n [field: string]: any;\n}\n\nexport interface AccessArgs {\n req: Request;\n user?: User;\n data?: any;\n doc?: any;\n id?: string;\n tenantID?: string;\n context?: Record<string, any>;\n}\n\nexport type AccessControl = boolean | ((args: AccessArgs) => Promise<boolean | WhereClause> | boolean | WhereClause);\n\nexport interface CollectionAccess {\n create?: AccessControl;\n read?: AccessControl;\n update?: AccessControl;\n delete?: AccessControl;\n admin?: AccessControl;\n unlock?: AccessControl;\n readVersions?: AccessControl;\n}\n\nexport interface GlobalAccess {\n read?: AccessControl;\n update?: AccessControl;\n}\n\nexport interface FieldAccess {\n create?: AccessControl;\n read?: AccessControl;\n update?: AccessControl;\n}\n\n// ============================================================================\n// Access Control Evaluation\n// ============================================================================\n\nexport async function evaluateAccess(\n access: AccessControl,\n args: AccessArgs\n): Promise<boolean | WhereClause> {\n if (typeof access === 'boolean') {\n return access;\n }\n if (typeof access === 'function') {\n return await access(args);\n }\n return true;\n}\n\nexport function mergeWhereClauses(\n ...whereClauses: (WhereClause | boolean | undefined)[]\n): WhereClause {\n const result: WhereClause = {};\n for (const clause of whereClauses) {\n if (clause && typeof clause === 'object') {\n Object.assign(result, clause);\n }\n }\n return result;\n}\n\nexport function getWhereClause(\n access: AccessControl,\n args: AccessArgs\n): Promise<WhereClause | undefined> {\n return evaluateAccess(access, args).then(result => {\n if (result === true) return undefined;\n if (result === false) return { _id: { $eq: null } };\n return result;\n });\n}\n","import { timingSafeEqual } from \"crypto\";\nimport type { BaseAdapter } from \"../registry/types.js\";\nimport type { AuthUser, UserRole } from \"./types.js\";\n\nexport interface ApiKeyRecord {\n id: string;\n userId: string;\n name: string;\n key: string;\n keyPrefix: string;\n permissions: string[];\n lastUsedAt?: string;\n expiresAt?: string;\n createdAt: string;\n}\n\nexport interface ApiKeyValidationResult {\n valid: boolean;\n userId?: string;\n user?: Partial<AuthUser>;\n permissions?: string[];\n apiKeyId?: string;\n error?: string;\n tenantId?: string;\n role?: UserRole;\n}\n\nexport interface ApiKeyContext {\n userId: string;\n user: Partial<AuthUser>;\n permissions: string[];\n apiKeyId: string;\n tenantId?: string;\n role?: UserRole;\n}\n\nexport const API_KEY_COLLECTION = \"_api_keys\";\n\nfunction generateKeyPrefix(key: string): string {\n return key.substring(0, 8);\n}\n\nfunction constantTimeCompare(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n try {\n return timingSafeEqual(Buffer.from(a), Buffer.from(b));\n } catch {\n return false;\n }\n}\n\nexport async function validateApiKey(\n rawKey: string,\n db: BaseAdapter,\n userLookup?: (userId: string) => Promise<Partial<AuthUser> | null>,\n): Promise<ApiKeyValidationResult> {\n if (!rawKey || typeof rawKey !== \"string\") {\n return { valid: false, error: \"No API key provided\" };\n }\n\n if (!rawKey.startsWith(\"kyro_\")) {\n return { valid: false, error: \"Invalid API key format\" };\n }\n\n const keyPrefix = generateKeyPrefix(rawKey);\n\n try {\n const result = await db.find({\n collection: API_KEY_COLLECTION,\n where: { keyPrefix: { equals: keyPrefix } },\n limit: 100,\n page: 1,\n });\n\n if (!result.docs || result.docs.length === 0) {\n return { valid: false, error: \"Invalid API key\" };\n }\n\n let matchedKey: ApiKeyRecord | null = null;\n for (const doc of result.docs) {\n const record = doc as unknown as ApiKeyRecord;\n if (constantTimeCompare(record.key, rawKey)) {\n matchedKey = record;\n break;\n }\n }\n\n if (!matchedKey) {\n return { valid: false, error: \"Invalid API key\" };\n }\n\n if (matchedKey.expiresAt) {\n const expiresAt = new Date(matchedKey.expiresAt);\n if (expiresAt < new Date()) {\n return { valid: false, error: \"API key has expired\" };\n }\n }\n\n try {\n await db.update({\n collection: API_KEY_COLLECTION,\n id: matchedKey.id,\n data: { lastUsedAt: new Date().toISOString() },\n });\n } catch {\n // Non-critical: don't fail if lastUsedAt update fails\n }\n\n const user: Partial<AuthUser> = {\n id: matchedKey.userId,\n role: (matchedKey as any).role || \"author\",\n tenantId: (matchedKey as any).tenantId,\n };\n\n if (userLookup) {\n const dbUser = await userLookup(matchedKey.userId);\n if (dbUser) {\n Object.assign(user, dbUser);\n }\n }\n\n return {\n valid: true,\n userId: matchedKey.userId,\n user,\n permissions: matchedKey.permissions || [],\n apiKeyId: matchedKey.id,\n tenantId: user.tenantId,\n role: user.role,\n };\n } catch (error) {\n console.error(\"[ApiKey] Validation error:\", error);\n return { valid: false, error: \"Failed to validate API key\" };\n }\n}\n\nexport function extractApiKeyFromRequest(request: Request): string | null {\n const authHeader = request.headers.get(\"Authorization\");\n if (authHeader) {\n if (authHeader.startsWith(\"ApiKey \")) {\n return authHeader.slice(7).trim();\n }\n if (authHeader.startsWith(\"Bearer \")) {\n return null;\n }\n }\n\n const xApiKey = request.headers.get(\"X-API-Key\");\n if (xApiKey) {\n return xApiKey.trim();\n }\n\n return null;\n}\n\nexport function createApiKeyContext(\n result: ApiKeyValidationResult,\n): ApiKeyContext | null {\n if (!result.valid || !result.userId) {\n return null;\n }\n return {\n userId: result.userId,\n user: result.user || {},\n permissions: result.permissions || [],\n apiKeyId: result.apiKeyId || \"\",\n tenantId: result.tenantId,\n role: result.role,\n };\n}\n\nexport function hasApiKeyPermission(\n permissions: string[],\n required: string,\n): boolean {\n if (permissions.length === 0) return false;\n if (permissions.includes(\"*\")) return true;\n if (permissions.includes(required)) return true;\n\n const [resource, action] = required.split(\":\");\n if (permissions.includes(`${resource}:*`)) return true;\n\n return false;\n}\n\nexport function generateApiKey(): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let suffix = \"\";\n for (let i = 0; i < 32; i++) {\n suffix += chars[Math.floor(Math.random() * chars.length)];\n }\n return `kyro_${suffix}`;\n}\n\nexport function generateApiKeyPrefix(key: string): string {\n return key.substring(0, 8);\n}\n","import type { User, Request } from '../hooks/types.js';\nimport { evaluateAccess, type WhereClause } from './types.js';\nimport { hasPermission } from '../auth/rbac/checker.js';\nimport { hasApiKeyPermission } from '../auth/api-key.js';\n\nexport interface AccessCheckResult {\n allowed: boolean;\n extraWhere?: WhereClause;\n error?: string;\n status?: number;\n}\n\nexport interface AccessContext {\n user?: User;\n req?: Request;\n tenantID?: string;\n apiKey?: any;\n}\n\nexport interface AccessOptions {\n enablePublicAccess?: boolean;\n defaultAccess?: string;\n}\n\nfunction actionToPermission(\n operation: \"read\" | \"create\" | \"update\" | \"delete\",\n): string {\n if (operation === \"read\") return \"read\";\n if (operation === \"create\") return \"create\";\n if (operation === \"update\") return \"update\";\n return \"delete\";\n}\n\nfunction isDefaultAllowed(\n operation: \"read\" | \"create\" | \"update\" | \"delete\",\n defaultAccess: string,\n): boolean {\n const levels: Record<string, boolean> = {\n none: false,\n read: operation === \"read\",\n create: operation === \"read\" || operation === \"create\",\n update: operation === \"read\" || operation === \"create\" || operation === \"update\",\n delete: operation === \"read\" || operation === \"create\" || operation === \"update\" || operation === \"delete\",\n admin: true,\n };\n return levels[defaultAccess] || false;\n}\n\nexport async function checkCollectionAccess(\n config: { access?: any; slug: string },\n operation: \"read\" | \"create\" | \"update\" | \"delete\",\n context: AccessContext,\n options: AccessOptions = {},\n): Promise<AccessCheckResult> {\n const { user, req, tenantID, apiKey } = context;\n const { enablePublicAccess = true, defaultAccess = \"none\" } = options;\n const accessRule = config.access?.[operation];\n\n // Custom access function (highest priority)\n if (accessRule) {\n const allowed = await evaluateAccess(accessRule, {\n req: req!,\n user,\n tenantID,\n });\n if (allowed === false) {\n return { allowed: false, error: \"Access denied\", status: 403 };\n }\n if (typeof allowed === \"object\") {\n return { allowed: true, extraWhere: allowed as WhereClause };\n }\n return { allowed: true };\n }\n\n // API key permission check\n if (apiKey?.permissions?.length > 0) {\n const resource = config.slug;\n const action = actionToPermission(operation);\n const permission = `${resource}:${action}`;\n if (\n !hasApiKeyPermission(apiKey.permissions, permission) &&\n !hasApiKeyPermission(apiKey.permissions, `${resource}:admin`)\n ) {\n return { allowed: false, error: \"Access denied: insufficient permissions\", status: 403 };\n }\n return { allowed: true };\n }\n\n // No accessRule, no apiKey — authenticated user RBAC\n if (user) {\n const resource = config.slug;\n const action = actionToPermission(operation);\n const permission = `${resource}:${action}`;\n\n const userHas = hasPermission(\n { id: user.id, email: user.email, role: user.role } as any,\n permission,\n );\n const adminHas = hasPermission(\n { id: user.id, email: user.email, role: user.role } as any,\n `${resource}:admin`,\n );\n\n if (userHas || adminHas) {\n return { allowed: true };\n }\n return { allowed: false, error: \"Access denied: missing RBAC permission\", status: 403 };\n }\n\n // Unauthenticated — check public access\n const defaultAllowed = isDefaultAllowed(operation, defaultAccess);\n if (enablePublicAccess && defaultAllowed) {\n return { allowed: true };\n }\n\n return { allowed: false, error: \"Authentication required\", status: 401 };\n}\n\nexport async function checkGlobalAccess(\n config: { access?: any; slug: string },\n operation: \"read\" | \"update\",\n context: AccessContext,\n options: AccessOptions = {},\n): Promise<AccessCheckResult> {\n const { user, req, tenantID } = context;\n const { enablePublicAccess = true } = options;\n const accessRule = config.access?.[operation];\n\n // Custom access function\n if (accessRule) {\n const allowed = await evaluateAccess(accessRule, {\n req: req!,\n user,\n tenantID,\n });\n if (allowed === false) {\n return { allowed: false, error: \"Access denied\", status: 403 };\n }\n return { allowed: true };\n }\n\n // Authenticated user RBAC\n if (user) {\n const permission = `globals:${operation}`;\n const userHas = hasPermission(\n { id: user.id, email: user.email, role: user.role } as any,\n permission,\n );\n const adminHas = hasPermission(\n { id: user.id, email: user.email, role: user.role } as any,\n \"globals:admin\",\n );\n if (userHas || adminHas) {\n return { allowed: true };\n }\n return { allowed: false, error: \"Access denied: missing RBAC permission\", status: 403 };\n }\n\n // Unauthenticated\n if (enablePublicAccess) {\n return { allowed: true };\n }\n\n return { allowed: false, error: \"Authentication required\", status: 401 };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/fields/types.ts","../src/fields/richtext.ts"],"names":["StarterKit","Link","Image","TextAlign","Underline","Highlight","TaskList","TaskItem","TextStyle","Color","html","generateHTML"],"mappings":"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","file":"chunk-FSKONGCX.cjs","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, any>,\n siblingData: Record<string, any>,\n ) => boolean);\n hidden?: boolean | ((\n data: Record<string, any>,\n siblingData: Record<string, any>,\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, any>,\n siblingData: Record<string, any>,\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?: any;\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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/access/types.ts","../src/auth/api-key.ts","../src/access/checker.ts"],"names":[],"mappings":";;;;AA+CA,eAAsB,cAAA,CACpB,QACA,IAAA,EACgC;AAChC,EAAA,IAAI,OAAO,WAAW,SAAA,EAAW;AAC/B,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,WAAW,UAAA,EAAY;AAChC,IAAA,OAAO,MAAM,OAAO,IAAI,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,qBACX,YAAA,EACU;AACb,EAAA,MAAM,SAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,UAAU,YAAA,EAAc;AACjC,IAAA,IAAI,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,EAAU;AACxC,MAAA,MAAA,CAAO,MAAA,CAAO,QAAQ,MAAM,CAAA;AAAA,IAC9B;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,cAAA,CACd,QACA,IAAA,EACkC;AAClC,EAAA,OAAO,cAAA,CAAe,MAAA,EAAQ,IAAI,CAAA,CAAE,KAAK,CAAA,MAAA,KAAU;AACjD,IAAA,IAAI,MAAA,KAAW,MAAM,OAAO,MAAA;AAC5B,IAAA,IAAI,MAAA,KAAW,OAAO,OAAO,EAAE,KAAK,EAAE,GAAA,EAAK,MAAK,EAAE;AAClD,IAAA,OAAO,MAAA;AAAA,EACT,CAAC,CAAA;AACH;AC7CO,IAAM,kBAAA,GAAqB;AAElC,SAAS,kBAAkB,GAAA,EAAqB;AAC9C,EAAA,OAAO,GAAA,CAAI,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA;AAC3B;AAEA,SAAS,mBAAA,CAAoB,GAAW,CAAA,EAAoB;AAC1D,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,EAAQ;AACzB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,OAAO,eAAA,CAAgB,OAAO,IAAA,CAAK,CAAC,GAAG,MAAA,CAAO,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,EACvD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,eAAsB,cAAA,CACpB,MAAA,EACA,EAAA,EACA,UAAA,EACiC;AACjC,EAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,EAAU;AACzC,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,qBAAA,EAAsB;AAAA,EACtD;AAEA,EAAA,IAAI,CAAC,MAAA,CAAO,UAAA,CAAW,OAAO,CAAA,EAAG;AAC/B,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,wBAAA,EAAyB;AAAA,EACzD;AAEA,EAAA,MAAM,SAAA,GAAY,kBAAkB,MAAM,CAAA;AAE1C,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,IAAA,CAAK;AAAA,MAC3B,UAAA,EAAY,kBAAA;AAAA,MACZ,OAAO,EAAE,SAAA,EAAW,EAAE,MAAA,EAAQ,WAAU,EAAE;AAAA,MAC1C,KAAA,EAAO,GAAA;AAAA,MACP,IAAA,EAAM;AAAA,KACP,CAAA;AAED,IAAA,IAAI,CAAC,MAAA,CAAO,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,EAAG;AAC5C,MAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,iBAAA,EAAkB;AAAA,IAClD;AAEA,IAAA,IAAI,UAAA,GAAkC,IAAA;AACtC,IAAA,KAAA,MAAW,GAAA,IAAO,OAAO,IAAA,EAAM;AAC7B,MAAA,MAAM,MAAA,GAAS,GAAA;AACf,MAAA,IAAI,mBAAA,CAAoB,MAAA,CAAO,GAAA,EAAK,MAAM,CAAA,EAAG;AAC3C,QAAA,UAAA,GAAa,MAAA;AACb,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,iBAAA,EAAkB;AAAA,IAClD;AAEA,IAAA,IAAI,WAAW,SAAA,EAAW;AACxB,MAAA,MAAM,SAAA,GAAY,IAAI,IAAA,CAAK,UAAA,CAAW,SAAS,CAAA;AAC/C,MAAA,IAAI,SAAA,mBAAY,IAAI,IAAA,EAAK,EAAG;AAC1B,QAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,qBAAA,EAAsB;AAAA,MACtD;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,GAAG,MAAA,CAAO;AAAA,QACd,UAAA,EAAY,kBAAA;AAAA,QACZ,IAAI,UAAA,CAAW,EAAA;AAAA,QACf,MAAM,EAAE,UAAA,EAAA,qBAAgB,IAAA,EAAK,EAAE,aAAY;AAAE,OAC9C,CAAA;AAAA,IACH,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,MAAM,IAAA,GAA0B;AAAA,MAC9B,IAAI,UAAA,CAAW,MAAA;AAAA,MACf,IAAA,EAAO,WAAmB,IAAA,IAAQ,QAAA;AAAA,MAClC,UAAW,UAAA,CAAmB;AAAA,KAChC;AAEA,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,UAAA,CAAW,MAAM,CAAA;AACjD,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAA,CAAO,MAAA,CAAO,MAAM,MAAM,CAAA;AAAA,MAC5B;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,IAAA;AAAA,MACP,QAAQ,UAAA,CAAW,MAAA;AAAA,MACnB,IAAA;AAAA,MACA,WAAA,EAAa,UAAA,CAAW,WAAA,IAAe,EAAC;AAAA,MACxC,UAAU,UAAA,CAAW,EAAA;AAAA,MACrB,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,MAAM,IAAA,CAAK;AAAA,KACb;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,8BAA8B,KAAK,CAAA;AACjD,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,4BAAA,EAA6B;AAAA,EAC7D;AACF;AAEO,SAAS,yBAAyB,OAAA,EAAiC;AACxE,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA;AACtD,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,IAAI,UAAA,CAAW,UAAA,CAAW,SAAS,CAAA,EAAG;AACpC,MAAA,OAAO,UAAA,CAAW,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,IAClC;AACA,IAAA,IAAI,UAAA,CAAW,UAAA,CAAW,SAAS,CAAA,EAAG;AACpC,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,WAAW,CAAA;AAC/C,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,OAAO,QAAQ,IAAA,EAAK;AAAA,EACtB;AAEA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,oBACd,MAAA,EACsB;AACtB,EAAA,IAAI,CAAC,MAAA,CAAO,KAAA,IAAS,CAAC,OAAO,MAAA,EAAQ;AACnC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO;AAAA,IACL,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,IAAA,EAAM,MAAA,CAAO,IAAA,IAAQ,EAAC;AAAA,IACtB,WAAA,EAAa,MAAA,CAAO,WAAA,IAAe,EAAC;AAAA,IACpC,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,IAC7B,UAAU,MAAA,CAAO,QAAA;AAAA,IACjB,MAAM,MAAA,CAAO;AAAA,GACf;AACF;AAEO,SAAS,mBAAA,CACd,aACA,QAAA,EACS;AACT,EAAA,IAAI,WAAA,CAAY,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AACrC,EAAA,IAAI,WAAA,CAAY,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,IAAA;AACtC,EAAA,IAAI,WAAA,CAAY,QAAA,CAAS,QAAQ,CAAA,EAAG,OAAO,IAAA;AAE3C,EAAA,MAAM,CAAC,QAAA,EAAU,MAAM,CAAA,GAAI,QAAA,CAAS,MAAM,GAAG,CAAA;AAC7C,EAAA,IAAI,YAAY,QAAA,CAAS,CAAA,EAAG,QAAQ,CAAA,EAAA,CAAI,GAAG,OAAO,IAAA;AAElD,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,cAAA,GAAyB;AACvC,EAAA,MAAM,KAAA,GAAQ,sCAAA;AACd,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAA,IAAU,KAAA,CAAM,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,KAAA,CAAM,MAAM,CAAC,CAAA;AAAA,EAC1D;AACA,EAAA,OAAO,QAAQ,MAAM,CAAA,CAAA;AACvB;AAEO,SAAS,qBAAqB,GAAA,EAAqB;AACxD,EAAA,OAAO,GAAA,CAAI,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA;AAC3B;;;AC9KA,SAAS,mBACP,SAAA,EACQ;AACR,EAAA,IAAI,SAAA,KAAc,QAAQ,OAAO,MAAA;AACjC,EAAA,IAAI,SAAA,KAAc,UAAU,OAAO,QAAA;AACnC,EAAA,IAAI,SAAA,KAAc,UAAU,OAAO,QAAA;AACnC,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,gBAAA,CACP,WACA,aAAA,EACS;AACT,EAAA,MAAM,MAAA,GAAkC;AAAA,IACtC,IAAA,EAAM,KAAA;AAAA,IACN,MAAM,SAAA,KAAc,MAAA;AAAA,IACpB,MAAA,EAAQ,SAAA,KAAc,MAAA,IAAU,SAAA,KAAc,QAAA;AAAA,IAC9C,MAAA,EAAQ,SAAA,KAAc,MAAA,IAAU,SAAA,KAAc,YAAY,SAAA,KAAc,QAAA;AAAA,IACxE,QAAQ,SAAA,KAAc,MAAA,IAAU,cAAc,QAAA,IAAY,SAAA,KAAc,YAAY,SAAA,KAAc,QAAA;AAAA,IAClG,KAAA,EAAO;AAAA,GACT;AACA,EAAA,OAAO,MAAA,CAAO,aAAa,CAAA,IAAK,KAAA;AAClC;AAEA,eAAsB,sBACpB,MAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,GAAyB,EAAC,EACE;AAC5B,EAAA,MAAM,EAAE,IAAA,EAAM,GAAA,EAAK,QAAA,EAAU,QAAO,GAAI,OAAA;AACxC,EAAA,MAAM,EAAE,kBAAA,GAAqB,IAAA,EAAM,aAAA,GAAgB,QAAO,GAAI,OAAA;AAC9D,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,MAAA,GAAS,SAAS,CAAA;AAG5C,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,UAAA,EAAY;AAAA,MAC/C,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,IAAI,YAAY,KAAA,EAAO;AACrB,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,eAAA,EAAiB,QAAQ,GAAA,EAAI;AAAA,IAC/D;AACA,IAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,OAAA,EAAuB;AAAA,IAC7D;AACA,IAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,EACzB;AAGA,EAAA,IAAI,MAAA,EAAQ,WAAA,EAAa,MAAA,GAAS,CAAA,EAAG;AACnC,IAAA,MAAM,WAAW,MAAA,CAAO,IAAA;AACxB,IAAA,MAAM,MAAA,GAAS,mBAAmB,SAAS,CAAA;AAC3C,IAAA,MAAM,UAAA,GAAa,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AACxC,IAAA,IACE,CAAC,mBAAA,CAAoB,MAAA,CAAO,WAAA,EAAa,UAAU,CAAA,IACnD,CAAC,mBAAA,CAAoB,MAAA,CAAO,WAAA,EAAa,CAAA,EAAG,QAAQ,QAAQ,CAAA,EAC5D;AACA,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,yCAAA,EAA2C,QAAQ,GAAA,EAAI;AAAA,IACzF;AACA,IAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,EACzB;AAGA,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,MAAM,WAAW,MAAA,CAAO,IAAA;AACxB,IAAA,MAAM,MAAA,GAAS,mBAAmB,SAAS,CAAA;AAC3C,IAAA,MAAM,UAAA,GAAa,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAExC,IAAA,MAAM,OAAA,GAAU,aAAA;AAAA,MACd,EAAE,IAAI,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA,CAAK,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAK;AAAA,MAClD;AAAA,KACF;AACA,IAAA,MAAM,QAAA,GAAW,aAAA;AAAA,MACf,EAAE,IAAI,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA,CAAK,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAK;AAAA,MAClD,GAAG,QAAQ,CAAA,MAAA;AAAA,KACb;AAEA,IAAA,IAAI,WAAW,QAAA,EAAU;AACvB,MAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,IACzB;AACA,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,wCAAA,EAA0C,QAAQ,GAAA,EAAI;AAAA,EACxF;AAGA,EAAA,MAAM,cAAA,GAAiB,gBAAA,CAAiB,SAAA,EAAW,aAAa,CAAA;AAChE,EAAA,IAAI,sBAAsB,cAAA,EAAgB;AACxC,IAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,EACzB;AAEA,EAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,yBAAA,EAA2B,QAAQ,GAAA,EAAI;AACzE;AAEA,eAAsB,kBACpB,MAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,GAAyB,EAAC,EACE;AAC5B,EAAA,MAAM,EAAE,IAAA,EAAM,GAAA,EAAK,QAAA,EAAS,GAAI,OAAA;AAChC,EAAA,MAAM,EAAE,kBAAA,GAAqB,IAAA,EAAK,GAAI,OAAA;AACtC,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,MAAA,GAAS,SAAS,CAAA;AAG5C,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,UAAA,EAAY;AAAA,MAC/C,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,IAAI,YAAY,KAAA,EAAO;AACrB,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,eAAA,EAAiB,QAAQ,GAAA,EAAI;AAAA,IAC/D;AACA,IAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,EACzB;AAGA,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,MAAM,UAAA,GAAa,WAAW,SAAS,CAAA,CAAA;AACvC,IAAA,MAAM,OAAA,GAAU,aAAA;AAAA,MACd,EAAE,IAAI,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA,CAAK,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAK;AAAA,MAClD;AAAA,KACF;AACA,IAAA,MAAM,QAAA,GAAW,aAAA;AAAA,MACf,EAAE,IAAI,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA,CAAK,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAK;AAAA,MAClD;AAAA,KACF;AACA,IAAA,IAAI,WAAW,QAAA,EAAU;AACvB,MAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,IACzB;AACA,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,wCAAA,EAA0C,QAAQ,GAAA,EAAI;AAAA,EACxF;AAGA,EAAA,IAAI,kBAAA,EAAoB;AACtB,IAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,EACzB;AAEA,EAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,yBAAA,EAA2B,QAAQ,GAAA,EAAI;AACzE","file":"chunk-NZEUU7QB.js","sourcesContent":["import type { User, Request } from '../hooks/types.js';\n\n// ============================================================================\n// Access Control Types\n// ============================================================================\n\nexport interface WhereClause {\n [field: string]: any;\n}\n\nexport interface AccessArgs {\n req: Request;\n user?: User;\n data?: any;\n doc?: any;\n id?: string;\n tenantID?: string;\n context?: Record<string, any>;\n}\n\nexport type AccessControl = boolean | ((args: AccessArgs) => Promise<boolean | WhereClause> | boolean | WhereClause);\n\nexport interface CollectionAccess {\n create?: AccessControl;\n read?: AccessControl;\n update?: AccessControl;\n delete?: AccessControl;\n admin?: AccessControl;\n unlock?: AccessControl;\n readVersions?: AccessControl;\n}\n\nexport interface GlobalAccess {\n read?: AccessControl;\n update?: AccessControl;\n}\n\nexport interface FieldAccess {\n create?: AccessControl;\n read?: AccessControl;\n update?: AccessControl;\n}\n\n// ============================================================================\n// Access Control Evaluation\n// ============================================================================\n\nexport async function evaluateAccess(\n access: AccessControl,\n args: AccessArgs\n): Promise<boolean | WhereClause> {\n if (typeof access === 'boolean') {\n return access;\n }\n if (typeof access === 'function') {\n return await access(args);\n }\n return true;\n}\n\nexport function mergeWhereClauses(\n ...whereClauses: (WhereClause | boolean | undefined)[]\n): WhereClause {\n const result: WhereClause = {};\n for (const clause of whereClauses) {\n if (clause && typeof clause === 'object') {\n Object.assign(result, clause);\n }\n }\n return result;\n}\n\nexport function getWhereClause(\n access: AccessControl,\n args: AccessArgs\n): Promise<WhereClause | undefined> {\n return evaluateAccess(access, args).then(result => {\n if (result === true) return undefined;\n if (result === false) return { _id: { $eq: null } };\n return result;\n });\n}\n","import { timingSafeEqual } from \"crypto\";\nimport type { BaseAdapter } from \"../registry/types.js\";\nimport type { AuthUser, UserRole } from \"./types.js\";\n\nexport interface ApiKeyRecord {\n id: string;\n userId: string;\n name: string;\n key: string;\n keyPrefix: string;\n permissions: string[];\n lastUsedAt?: string;\n expiresAt?: string;\n createdAt: string;\n}\n\nexport interface ApiKeyValidationResult {\n valid: boolean;\n userId?: string;\n user?: Partial<AuthUser>;\n permissions?: string[];\n apiKeyId?: string;\n error?: string;\n tenantId?: string;\n role?: UserRole;\n}\n\nexport interface ApiKeyContext {\n userId: string;\n user: Partial<AuthUser>;\n permissions: string[];\n apiKeyId: string;\n tenantId?: string;\n role?: UserRole;\n}\n\nexport const API_KEY_COLLECTION = \"_api_keys\";\n\nfunction generateKeyPrefix(key: string): string {\n return key.substring(0, 8);\n}\n\nfunction constantTimeCompare(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n try {\n return timingSafeEqual(Buffer.from(a), Buffer.from(b));\n } catch {\n return false;\n }\n}\n\nexport async function validateApiKey(\n rawKey: string,\n db: BaseAdapter,\n userLookup?: (userId: string) => Promise<Partial<AuthUser> | null>,\n): Promise<ApiKeyValidationResult> {\n if (!rawKey || typeof rawKey !== \"string\") {\n return { valid: false, error: \"No API key provided\" };\n }\n\n if (!rawKey.startsWith(\"kyro_\")) {\n return { valid: false, error: \"Invalid API key format\" };\n }\n\n const keyPrefix = generateKeyPrefix(rawKey);\n\n try {\n const result = await db.find({\n collection: API_KEY_COLLECTION,\n where: { keyPrefix: { equals: keyPrefix } },\n limit: 100,\n page: 1,\n });\n\n if (!result.docs || result.docs.length === 0) {\n return { valid: false, error: \"Invalid API key\" };\n }\n\n let matchedKey: ApiKeyRecord | null = null;\n for (const doc of result.docs) {\n const record = doc as unknown as ApiKeyRecord;\n if (constantTimeCompare(record.key, rawKey)) {\n matchedKey = record;\n break;\n }\n }\n\n if (!matchedKey) {\n return { valid: false, error: \"Invalid API key\" };\n }\n\n if (matchedKey.expiresAt) {\n const expiresAt = new Date(matchedKey.expiresAt);\n if (expiresAt < new Date()) {\n return { valid: false, error: \"API key has expired\" };\n }\n }\n\n try {\n await db.update({\n collection: API_KEY_COLLECTION,\n id: matchedKey.id,\n data: { lastUsedAt: new Date().toISOString() },\n });\n } catch {\n // Non-critical: don't fail if lastUsedAt update fails\n }\n\n const user: Partial<AuthUser> = {\n id: matchedKey.userId,\n role: (matchedKey as any).role || \"author\",\n tenantId: (matchedKey as any).tenantId,\n };\n\n if (userLookup) {\n const dbUser = await userLookup(matchedKey.userId);\n if (dbUser) {\n Object.assign(user, dbUser);\n }\n }\n\n return {\n valid: true,\n userId: matchedKey.userId,\n user,\n permissions: matchedKey.permissions || [],\n apiKeyId: matchedKey.id,\n tenantId: user.tenantId,\n role: user.role,\n };\n } catch (error) {\n console.error(\"[ApiKey] Validation error:\", error);\n return { valid: false, error: \"Failed to validate API key\" };\n }\n}\n\nexport function extractApiKeyFromRequest(request: Request): string | null {\n const authHeader = request.headers.get(\"Authorization\");\n if (authHeader) {\n if (authHeader.startsWith(\"ApiKey \")) {\n return authHeader.slice(7).trim();\n }\n if (authHeader.startsWith(\"Bearer \")) {\n return null;\n }\n }\n\n const xApiKey = request.headers.get(\"X-API-Key\");\n if (xApiKey) {\n return xApiKey.trim();\n }\n\n return null;\n}\n\nexport function createApiKeyContext(\n result: ApiKeyValidationResult,\n): ApiKeyContext | null {\n if (!result.valid || !result.userId) {\n return null;\n }\n return {\n userId: result.userId,\n user: result.user || {},\n permissions: result.permissions || [],\n apiKeyId: result.apiKeyId || \"\",\n tenantId: result.tenantId,\n role: result.role,\n };\n}\n\nexport function hasApiKeyPermission(\n permissions: string[],\n required: string,\n): boolean {\n if (permissions.length === 0) return false;\n if (permissions.includes(\"*\")) return true;\n if (permissions.includes(required)) return true;\n\n const [resource, action] = required.split(\":\");\n if (permissions.includes(`${resource}:*`)) return true;\n\n return false;\n}\n\nexport function generateApiKey(): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let suffix = \"\";\n for (let i = 0; i < 32; i++) {\n suffix += chars[Math.floor(Math.random() * chars.length)];\n }\n return `kyro_${suffix}`;\n}\n\nexport function generateApiKeyPrefix(key: string): string {\n return key.substring(0, 8);\n}\n","import type { User, Request } from '../hooks/types.js';\nimport { evaluateAccess, type WhereClause } from './types.js';\nimport { hasPermission } from '../auth/rbac/checker.js';\nimport { hasApiKeyPermission } from '../auth/api-key.js';\n\nexport interface AccessCheckResult {\n allowed: boolean;\n extraWhere?: WhereClause;\n error?: string;\n status?: number;\n}\n\nexport interface AccessContext {\n user?: User;\n req?: Request;\n tenantID?: string;\n apiKey?: any;\n}\n\nexport interface AccessOptions {\n enablePublicAccess?: boolean;\n defaultAccess?: string;\n}\n\nfunction actionToPermission(\n operation: \"read\" | \"create\" | \"update\" | \"delete\",\n): string {\n if (operation === \"read\") return \"read\";\n if (operation === \"create\") return \"create\";\n if (operation === \"update\") return \"update\";\n return \"delete\";\n}\n\nfunction isDefaultAllowed(\n operation: \"read\" | \"create\" | \"update\" | \"delete\",\n defaultAccess: string,\n): boolean {\n const levels: Record<string, boolean> = {\n none: false,\n read: operation === \"read\",\n create: operation === \"read\" || operation === \"create\",\n update: operation === \"read\" || operation === \"create\" || operation === \"update\",\n delete: operation === \"read\" || operation === \"create\" || operation === \"update\" || operation === \"delete\",\n admin: true,\n };\n return levels[defaultAccess] || false;\n}\n\nexport async function checkCollectionAccess(\n config: { access?: any; slug: string },\n operation: \"read\" | \"create\" | \"update\" | \"delete\",\n context: AccessContext,\n options: AccessOptions = {},\n): Promise<AccessCheckResult> {\n const { user, req, tenantID, apiKey } = context;\n const { enablePublicAccess = true, defaultAccess = \"none\" } = options;\n const accessRule = config.access?.[operation];\n\n // Custom access function (highest priority)\n if (accessRule) {\n const allowed = await evaluateAccess(accessRule, {\n req: req!,\n user,\n tenantID,\n });\n if (allowed === false) {\n return { allowed: false, error: \"Access denied\", status: 403 };\n }\n if (typeof allowed === \"object\") {\n return { allowed: true, extraWhere: allowed as WhereClause };\n }\n return { allowed: true };\n }\n\n // API key permission check\n if (apiKey?.permissions?.length > 0) {\n const resource = config.slug;\n const action = actionToPermission(operation);\n const permission = `${resource}:${action}`;\n if (\n !hasApiKeyPermission(apiKey.permissions, permission) &&\n !hasApiKeyPermission(apiKey.permissions, `${resource}:admin`)\n ) {\n return { allowed: false, error: \"Access denied: insufficient permissions\", status: 403 };\n }\n return { allowed: true };\n }\n\n // No accessRule, no apiKey — authenticated user RBAC\n if (user) {\n const resource = config.slug;\n const action = actionToPermission(operation);\n const permission = `${resource}:${action}`;\n\n const userHas = hasPermission(\n { id: user.id, email: user.email, role: user.role } as any,\n permission,\n );\n const adminHas = hasPermission(\n { id: user.id, email: user.email, role: user.role } as any,\n `${resource}:admin`,\n );\n\n if (userHas || adminHas) {\n return { allowed: true };\n }\n return { allowed: false, error: \"Access denied: missing RBAC permission\", status: 403 };\n }\n\n // Unauthenticated — check public access\n const defaultAllowed = isDefaultAllowed(operation, defaultAccess);\n if (enablePublicAccess && defaultAllowed) {\n return { allowed: true };\n }\n\n return { allowed: false, error: \"Authentication required\", status: 401 };\n}\n\nexport async function checkGlobalAccess(\n config: { access?: any; slug: string },\n operation: \"read\" | \"update\",\n context: AccessContext,\n options: AccessOptions = {},\n): Promise<AccessCheckResult> {\n const { user, req, tenantID } = context;\n const { enablePublicAccess = true } = options;\n const accessRule = config.access?.[operation];\n\n // Custom access function\n if (accessRule) {\n const allowed = await evaluateAccess(accessRule, {\n req: req!,\n user,\n tenantID,\n });\n if (allowed === false) {\n return { allowed: false, error: \"Access denied\", status: 403 };\n }\n return { allowed: true };\n }\n\n // Authenticated user RBAC\n if (user) {\n const permission = `globals:${operation}`;\n const userHas = hasPermission(\n { id: user.id, email: user.email, role: user.role } as any,\n permission,\n );\n const adminHas = hasPermission(\n { id: user.id, email: user.email, role: user.role } as any,\n \"globals:admin\",\n );\n if (userHas || adminHas) {\n return { allowed: true };\n }\n return { allowed: false, error: \"Access denied: missing RBAC permission\", status: 403 };\n }\n\n // Unauthenticated\n if (enablePublicAccess) {\n return { allowed: true };\n }\n\n return { allowed: false, error: \"Authentication required\", status: 401 };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/api-handler.ts"],"names":["kyroInstance","projectConfig","createKyro","DrizzleAdapter","PostgresAuthAdapter","SQLiteAuthAdapter","LocalAdapter","MongoDBAdapter","MongoDBAuthAdapter","autoBootstrap"],"mappings":";;;;;;;;;;;;;;;AAYWA,oBAAA,GAAoB;AAC/B,IAAI,WAAA,GAAoC,IAAA;AAExC,eAAe,MAAA,GAAwB;AACrC,EAAA,IAAIA,oBAAA,EAAc;AAElB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAASC,+BAAc,OAAA,IAAWA,8BAAA;AACxC,IAAAD,oBAAA,GAAeE,6BAAW,MAAM,CAAA;AAChC,IAAA,MAAMF,qBAAa,IAAA,EAAK;AACxB,IAAA,MAAMA,qBAAa,YAAA,EAAa;AAEhC,IAAA,MAAM,KAAKA,oBAAA,CAAa,EAAA;AACxB,IAAA,IAAI,oBAAA,GAA4B,KAAA,CAAA;AAEhC,IAAA,IAAI,cAAcG,gCAAA,EAAgB;AAChC,MAAA,IAAI,EAAA,CAAG,YAAY,UAAA,EAAY;AAC7B,QAAA,oBAAA,GAAuB,IAAIC,qCAAA,CAAoB,EAAE,EAAA,EAAI,EAAA,CAAG,QAAQ,CAAA;AAAA,MAClE,CAAA,MAAA,IAAW,EAAA,CAAG,OAAA,KAAY,QAAA,EAAU;AAClC,QAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,GAAA,CAAI,iBAAA,IAAqB,gBAAA;AACpD,QAAA,oBAAA,GAAuB,IAAIC,mCAAA,CAAkB,EAAE,IAAA,EAAM,YAAY,CAAA;AAAA,MACnE;AAAA,IACF,CAAA,MAAA,IAAW,cAAcC,8BAAA,EAAc;AACrC,MAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,GAAA,CAAI,iBAAA,IAAqB,gBAAA;AACpD,MAAA,oBAAA,GAAuB,IAAID,mCAAA,CAAkB,EAAE,IAAA,EAAM,YAAY,CAAA;AAAA,IACnE,CAAA,MAAA,IAAW,cAAcE,gCAAA,EAAgB;AACvC,MAAA,oBAAA,GAAuB,IAAIC,oCAAA,CAAmB,EAAE,EAAA,EAAI,EAAA,CAAG,IAAI,CAAA;AAAA,IAC7D;AAEA,IAAA,IAAI,sBAAsB,OAAA,EAAS;AACjC,MAAA,MAAM,qBAAqB,OAAA,EAAQ;AAAA,IACrC;AAEA,IAAA,MAAM,MAAA,GAAS,MAAMC,+BAAA,CAAc,oBAAoB,CAAA;AACvD,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,yCAAA,EAA4C,MAAA,CAAO,IAAA,EAAM,KAAK,CAAA,CAAE,CAAA;AAAA,IAC9E;AAGA,IAAA,IAAI,OAAOT,oBAAA,CAAa,cAAA,KAAmB,UAAA,EAAY;AACrD,MAAAA,oBAAA,CAAa,cAAA,EAAe,CAAE,KAAA,CAAM,CAAC,GAAA,KAAa;AAChD,QAAA,OAAA,CAAQ,KAAA,CAAM,uCAAuC,GAAG,CAAA;AAAA,MAC1D,CAAC,CAAA;AAAA,IACH;AAGA,IAAC,WAAmB,iBAAA,GAAoBA,oBAAA;AAExC,IAAA,OAAA,CAAQ,IAAI,sDAAsD,CAAA;AAAA,EACpE,SAAS,GAAA,EAAK;AACZ,IAAAA,oBAAA,GAAe,IAAA;AACf,IAAA,WAAA,GAAc,IAAA;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,uCAAuC,GAAG,CAAA;AACxD,IAAA,MAAM,GAAA;AAAA,EACR;AACF;AAEA,eAAsB,gBAAA,GAAkC;AACtD,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,WAAA,GAAc,MAAA,EAAO;AAAA,EACvB;AACA,EAAA,MAAM,WAAA;AACR;AAEO,IAAM,GAAA,GAAgB,OAAO,OAAA,KAAY;AAC9C,EAAA,IAAI,CAACA,oBAAA,EAAc;AACjB,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,WAAA,GAAc,MAAA,EAAO;AAAA,IACvB;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAQ,IAAA,CAAK;AAAA,QACjB,WAAA;AAAA,QACA,IAAI,OAAA;AAAA,UAAc,CAAC,CAAA,EAAG,MAAA,KACpB,UAAA,CAAW,MAAM,MAAA,CAAO,IAAI,KAAA,CAAM,wBAAwB,CAAC,CAAA,EAAG,GAAK;AAAA;AACrE,OACD,CAAA;AAAA,IACH,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU;AAAA,QACjC,KAAA,EAAO,qBAAA;AAAA,QACP,OAAA,EAAS;AAAA,OACV,CAAA,EAAG;AAAA,QACF,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,aAAA,EAAe;AAAA;AACjB,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,MAAM,GAAA,GAAMA,qBAAa,OAAA,EAAQ;AACjC,EAAA,OAAO,GAAA,CAAI,KAAA,CAAM,OAAA,CAAQ,OAAA,EAAS,QAAQ,MAAM,CAAA;AAClD","file":"chunk-OZ3CCTTA.cjs","sourcesContent":["import type { APIRoute } from \"astro\";\nimport { createKyro } from \"./createKyro.js\";\nimport { autoBootstrap } from \"./auth/bootstrap.js\";\nimport { DrizzleAdapter } from \"./database/drizzle/adapter.js\";\nimport { PostgresAuthAdapter } from \"./database/drizzle/postgres-auth-adapter.js\";\nimport { LocalAdapter } from \"./database/local/adapter.js\";\nimport { SQLiteAuthAdapter } from \"./auth/sqlite-adapter.js\";\nimport { MongoDBAdapter } from \"./database/mongodb/adapter.js\";\nimport { MongoDBAuthAdapter } from \"./database/mongodb/mongo-auth-adapter.js\";\n// @ts-ignore - handled by vite alias\nimport projectConfig from \"kyro:config\";\n\nexport let kyroInstance: any = null;\nlet initPromise: Promise<void> | null = null;\n\nasync function doInit(): Promise<void> {\n if (kyroInstance) return;\n\n try {\n const config = projectConfig.default || projectConfig;\n kyroInstance = createKyro(config);\n await kyroInstance.init();\n await kyroInstance.loadSettings();\n\n const db = kyroInstance.db;\n let bootstrapAuthAdapter: any = undefined;\n \n if (db instanceof DrizzleAdapter) {\n if (db.dialect === \"postgres\") {\n bootstrapAuthAdapter = new PostgresAuthAdapter({ db: db.client });\n } else if (db.dialect === \"sqlite\") {\n const authDbPath = process.env.KYRO_AUTH_DB_PATH || \"./data/auth.db\";\n bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });\n }\n } else if (db instanceof LocalAdapter) {\n const authDbPath = process.env.KYRO_AUTH_DB_PATH || \"./data/auth.db\";\n bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });\n } else if (db instanceof MongoDBAdapter) {\n bootstrapAuthAdapter = new MongoDBAuthAdapter({ db: db.db });\n }\n\n if (bootstrapAuthAdapter?.connect) {\n await bootstrapAuthAdapter.connect();\n }\n\n const result = await autoBootstrap(bootstrapAuthAdapter);\n if (result?.success) {\n console.log(`[Kyro] Admin user auto-created from env: ${result.user?.email}`);\n }\n\n // Auto-start WebSocket (checks settings.access.apiAccess.wsEnabled internally)\n if (typeof kyroInstance.startWebSocket === \"function\") {\n kyroInstance.startWebSocket().catch((err: any) => {\n console.error(\"[Kyro] WebSocket auto-start failed:\", err);\n });\n }\n\n // Expose instance globally so admin SSR can read DB directly\n (globalThis as any).__KYRO_INSTANCE__ = kyroInstance;\n\n console.log(\"[Kyro API] Backend initialized via Astro Integration\");\n } catch (err) {\n kyroInstance = null;\n initPromise = null;\n console.error(\"[Kyro API] Init failed, will retry:\", err);\n throw err;\n }\n}\n\nexport async function warmKyroInstance(): Promise<void> {\n if (!initPromise) {\n initPromise = doInit();\n }\n await initPromise;\n}\n\nexport const ALL: APIRoute = async (context) => {\n if (!kyroInstance) {\n if (!initPromise) {\n initPromise = doInit();\n }\n\n try {\n await Promise.race([\n initPromise,\n new Promise<void>((_, reject) =>\n setTimeout(() => reject(new Error(\"Initialization timeout\")), 30000)\n ),\n ]);\n } catch {\n return new Response(JSON.stringify({\n error: \"Service Unavailable\",\n message: \"Kyro CMS is still starting up. Please try again in a moment.\",\n }), {\n status: 503,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Retry-After\": \"5\",\n },\n });\n }\n }\n\n const app = kyroInstance.getREST();\n return app.fetch(context.request, context.locals);\n};\n"]}