@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.
- package/dist/{WebhookService-BKszZlG0.d.cts → WebhookService-Dj8pJ3sp.d.cts} +1 -1
- package/dist/{WebhookService-Ccf1j-IN.d.ts → WebhookService-DpRB940h.d.ts} +1 -1
- package/dist/api-handler-graphql.cjs +18 -13
- package/dist/api-handler-graphql.cjs.map +1 -1
- package/dist/api-handler-graphql.js +14 -9
- package/dist/api-handler-graphql.js.map +1 -1
- package/dist/api-handler-trpc.cjs +9 -9
- package/dist/api-handler-trpc.js +7 -7
- package/dist/api-handler.cjs +10 -10
- package/dist/api-handler.js +7 -7
- package/dist/{base-CIuXkrH4.d.cts → base-BjyoF6da.d.cts} +2 -2
- package/dist/{base-fFo4lqER.d.ts → base-C2YR8lWt.d.ts} +2 -2
- package/dist/{chunk-NZEUU7QB.js → chunk-3AKCVYDB.js} +4 -109
- package/dist/chunk-3AKCVYDB.js.map +1 -0
- package/dist/{chunk-FKKQUMXR.cjs → chunk-4OCMVGEY.cjs} +4 -110
- package/dist/chunk-4OCMVGEY.cjs.map +1 -0
- package/dist/{chunk-VLK5SJRI.js → chunk-5RFGYEQ3.js} +133 -46
- package/dist/chunk-5RFGYEQ3.js.map +1 -0
- package/dist/chunk-5RPRLTTN.js +861 -0
- package/dist/chunk-5RPRLTTN.js.map +1 -0
- package/dist/{chunk-AX2TZRQJ.js → chunk-BVUDFKKS.js} +16 -3
- package/dist/chunk-BVUDFKKS.js.map +1 -0
- package/dist/{chunk-DRVOUQMT.cjs → chunk-E4JZ73FY.cjs} +54 -79
- package/dist/chunk-E4JZ73FY.cjs.map +1 -0
- package/dist/{chunk-E5UJBLQ7.js → chunk-FIAMXNTH.js} +2 -2
- package/dist/chunk-FIAMXNTH.js.map +1 -0
- package/dist/{chunk-QVJNSAQL.cjs → chunk-IEIHABVR.cjs} +152 -65
- package/dist/chunk-IEIHABVR.cjs.map +1 -0
- package/dist/{chunk-QFLB4EIJ.cjs → chunk-LNTFRAHF.cjs} +118 -9
- package/dist/chunk-LNTFRAHF.cjs.map +1 -0
- package/dist/chunk-N4GN6Q3V.cjs +869 -0
- package/dist/chunk-N4GN6Q3V.cjs.map +1 -0
- package/dist/{chunk-FSKONGCX.cjs → chunk-OJ2AM75W.cjs} +2 -2
- package/dist/chunk-OJ2AM75W.cjs.map +1 -0
- package/dist/{chunk-QX3WNQ7V.js → chunk-OX6GOIPH.js} +4 -4
- package/dist/{chunk-QX3WNQ7V.js.map → chunk-OX6GOIPH.js.map} +1 -1
- package/dist/{chunk-OZ3CCTTA.cjs → chunk-OXYSOU6Z.cjs} +18 -5
- package/dist/chunk-OXYSOU6Z.cjs.map +1 -0
- package/dist/{chunk-CMXVTUYV.js → chunk-OYCICW4B.js} +38 -63
- package/dist/chunk-OYCICW4B.js.map +1 -0
- package/dist/{chunk-HVCUIII2.cjs → chunk-TQG7G7YI.cjs} +13 -13
- package/dist/{chunk-HVCUIII2.cjs.map → chunk-TQG7G7YI.cjs.map} +1 -1
- package/dist/{chunk-3UK5XBVJ.js → chunk-WDTTHKDS.js} +117 -10
- package/dist/chunk-WDTTHKDS.js.map +1 -0
- package/dist/cli/index.cjs +148 -14
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +148 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/client.cjs +3 -3
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1 -1
- package/dist/drizzle/index.d.cts +3 -3
- package/dist/drizzle/index.d.ts +3 -3
- package/dist/fields/index.cjs +21 -21
- package/dist/fields/index.d.cts +1 -1
- package/dist/fields/index.d.ts +1 -1
- package/dist/fields/index.js +1 -1
- package/dist/graphql/index.cjs +13 -5
- package/dist/graphql/index.d.cts +37 -7
- package/dist/graphql/index.d.ts +37 -7
- package/dist/graphql/index.js +2 -2
- package/dist/{index-BKta3cBH.d.cts → index-DHbywDs-.d.cts} +2 -2
- package/dist/{index-ClOqnkTO.d.ts → index-jLs0zlft.d.ts} +2 -2
- package/dist/index.cjs +90 -90
- package/dist/index.d.cts +15 -14
- package/dist/index.d.ts +15 -14
- package/dist/index.js +8 -8
- package/dist/mongodb/index.d.cts +3 -3
- package/dist/mongodb/index.d.ts +3 -3
- package/dist/rest/index.cjs +5 -5
- package/dist/rest/index.d.cts +4 -4
- package/dist/rest/index.d.ts +4 -4
- package/dist/rest/index.js +3 -3
- package/dist/templates/index.d.cts +2 -2
- package/dist/templates/index.d.ts +2 -2
- package/dist/trpc/index.cjs +12 -12
- package/dist/trpc/index.d.cts +3 -3
- package/dist/trpc/index.d.ts +3 -3
- package/dist/trpc/index.js +3 -3
- package/dist/{types-Dgzlftb7.d.ts → types-BzH3_rtP.d.ts} +7 -7
- package/dist/{types-Ds0tCA3L.d.cts → types-CY_iNunL.d.cts} +7 -7
- package/dist/{types-DeSApf9T.d.ts → types-C_rVxU2T.d.cts} +4 -4
- package/dist/{types-DeSApf9T.d.cts → types-C_rVxU2T.d.ts} +4 -4
- package/package.json +2 -1
- package/dist/chunk-3UK5XBVJ.js.map +0 -1
- package/dist/chunk-AX2TZRQJ.js.map +0 -1
- package/dist/chunk-CMXVTUYV.js.map +0 -1
- package/dist/chunk-DRVOUQMT.cjs.map +0 -1
- package/dist/chunk-E5UJBLQ7.js.map +0 -1
- package/dist/chunk-FKKQUMXR.cjs.map +0 -1
- package/dist/chunk-FSKONGCX.cjs.map +0 -1
- package/dist/chunk-NZEUU7QB.js.map +0 -1
- package/dist/chunk-OZ3CCTTA.cjs.map +0 -1
- package/dist/chunk-PONTBXR5.js +0 -842
- package/dist/chunk-PONTBXR5.js.map +0 -1
- package/dist/chunk-QFLB4EIJ.cjs.map +0 -1
- package/dist/chunk-QVJNSAQL.cjs.map +0 -1
- package/dist/chunk-RRKCIAPU.cjs +0 -848
- package/dist/chunk-RRKCIAPU.cjs.map +0 -1
- 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
|
|
8
|
-
var
|
|
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 =
|
|
394
|
+
const apiKeyRaw = chunk4OCMVGEY_cjs.extractApiKeyFromRequest(req);
|
|
395
395
|
if (apiKeyRaw && db) {
|
|
396
|
-
const result = await
|
|
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:
|
|
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
|
|
1690
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
3500
|
-
update:
|
|
3501
|
-
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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:
|
|
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 =
|
|
4822
|
+
const rawKey = chunk4OCMVGEY_cjs.generateApiKey();
|
|
4822
4823
|
const doc = await db.create({
|
|
4823
|
-
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 =
|
|
4908
|
+
const rawKey = chunk4OCMVGEY_cjs.generateApiKey();
|
|
4908
4909
|
const updated = await db.update({
|
|
4909
|
-
collection:
|
|
4910
|
+
collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION,
|
|
4910
4911
|
id,
|
|
4911
4912
|
data: {
|
|
4912
4913
|
key: rawKey,
|
|
4913
|
-
keyPrefix:
|
|
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
|
|
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
|
|
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-
|
|
6417
|
-
//# sourceMappingURL=chunk-
|
|
6503
|
+
//# sourceMappingURL=chunk-IEIHABVR.cjs.map
|
|
6504
|
+
//# sourceMappingURL=chunk-IEIHABVR.cjs.map
|