@kyro-cms/core 0.9.0 → 0.9.1
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/README.md +57 -589
- package/dist/{WebhookService-118ZTFis.d.ts → WebhookService-CUTb9XOy.d.ts} +1 -1
- package/dist/{WebhookService-AefJfqX0.d.cts → WebhookService-Yg2UEOB4.d.cts} +1 -1
- package/dist/api-handler-graphql.cjs +44 -0
- package/dist/api-handler-graphql.cjs.map +1 -0
- package/dist/api-handler-graphql.d.cts +6 -0
- package/dist/api-handler-graphql.d.ts +6 -0
- package/dist/api-handler-graphql.js +41 -0
- package/dist/api-handler-graphql.js.map +1 -0
- package/dist/api-handler-trpc.cjs +38 -0
- package/dist/api-handler-trpc.cjs.map +1 -0
- package/dist/api-handler-trpc.d.cts +5 -0
- package/dist/api-handler-trpc.d.ts +5 -0
- package/dist/api-handler-trpc.js +36 -0
- package/dist/api-handler-trpc.js.map +1 -0
- package/dist/api-handler.cjs +31 -97
- package/dist/api-handler.cjs.map +1 -1
- package/dist/api-handler.d.cts +2 -1
- package/dist/api-handler.d.ts +2 -1
- package/dist/api-handler.js +19 -95
- package/dist/api-handler.js.map +1 -1
- package/dist/{tenant-B1YB0Jy8.d.ts → base-B71y_EAF.d.cts} +6 -12
- package/dist/{tenant-Cpeveji6.d.cts → base-DaqY2GhA.d.ts} +6 -12
- package/dist/bootstrap-5NLASFOG.cjs +32 -0
- package/dist/{bootstrap-AKAUP6F6.cjs.map → bootstrap-5NLASFOG.cjs.map} +1 -1
- package/dist/bootstrap-T5BK77LD.js +7 -0
- package/dist/{bootstrap-JCML6NFO.js.map → bootstrap-T5BK77LD.js.map} +1 -1
- package/dist/{chunk-35U3FROB.js → chunk-22M4O4ZJ.js} +607 -63
- package/dist/chunk-22M4O4ZJ.js.map +1 -0
- package/dist/chunk-2HZRBATX.cjs +253 -0
- package/dist/chunk-2HZRBATX.cjs.map +1 -0
- package/dist/{chunk-VJT6P4N6.cjs → chunk-3HR772HI.cjs} +199 -32
- package/dist/chunk-3HR772HI.cjs.map +1 -0
- package/dist/chunk-3KTWGODI.cjs +178 -0
- package/dist/chunk-3KTWGODI.cjs.map +1 -0
- package/dist/{chunk-QXIQWPAP.js → chunk-3UK5XBVJ.js} +4 -134
- package/dist/chunk-3UK5XBVJ.js.map +1 -0
- package/dist/{chunk-FXYP2HA6.js → chunk-4AO3A3JM.js} +48 -4
- package/dist/chunk-4AO3A3JM.js.map +1 -0
- package/dist/chunk-4M7X5HAB.cjs +173 -0
- package/dist/chunk-4M7X5HAB.cjs.map +1 -0
- package/dist/chunk-5EPFQUQD.js +3243 -0
- package/dist/chunk-5EPFQUQD.js.map +1 -0
- package/dist/{chunk-Y3N7UUDO.js → chunk-7OGPN7MP.js} +5 -2
- package/dist/chunk-7OGPN7MP.js.map +1 -0
- package/dist/{chunk-WOWUL7ZY.js → chunk-AL5KX63J.js} +4 -3
- package/dist/chunk-AL5KX63J.js.map +1 -0
- package/dist/{chunk-2OL4O2TH.cjs → chunk-C36TMDTY.cjs} +66 -61
- package/dist/chunk-C36TMDTY.cjs.map +1 -0
- package/dist/{chunk-ES5HNFFT.js → chunk-CF7OL6HR.js} +4 -2
- package/dist/chunk-CF7OL6HR.js.map +1 -0
- package/dist/chunk-CJONKRHJ.js +162 -0
- package/dist/chunk-CJONKRHJ.js.map +1 -0
- package/dist/{chunk-2KVHZE6O.cjs → chunk-COIASRDK.cjs} +202 -46
- package/dist/chunk-COIASRDK.cjs.map +1 -0
- package/dist/chunk-DEVFAKCQ.cjs +3291 -0
- package/dist/chunk-DEVFAKCQ.cjs.map +1 -0
- package/dist/{chunk-3ZFYL34R.js → chunk-DYTZ6FQ7.js} +12 -185
- package/dist/chunk-DYTZ6FQ7.js.map +1 -0
- package/dist/{chunk-QPPDLRNR.js → chunk-EJN2PAOE.js} +197 -41
- package/dist/chunk-EJN2PAOE.js.map +1 -0
- package/dist/chunk-FAXU7BMP.js +220 -0
- package/dist/chunk-FAXU7BMP.js.map +1 -0
- package/dist/{chunk-OHVB4AJ7.js → chunk-FOPGUM27.js} +22 -17
- package/dist/chunk-FOPGUM27.js.map +1 -0
- package/dist/chunk-GAOXD3XT.js +175 -0
- package/dist/chunk-GAOXD3XT.js.map +1 -0
- package/dist/{chunk-4DA7QPLA.cjs → chunk-GXFOGU7N.cjs} +5 -2
- package/dist/chunk-GXFOGU7N.cjs.map +1 -0
- package/dist/{chunk-I7HHI6QV.cjs → chunk-IDVRRRAK.cjs} +17 -9
- package/dist/chunk-IDVRRRAK.cjs.map +1 -0
- package/dist/{chunk-WQBRWOQT.cjs → chunk-JOPVMWTM.cjs} +3 -2
- package/dist/chunk-JOPVMWTM.cjs.map +1 -0
- package/dist/chunk-KC2GDBLS.cjs +84 -0
- package/dist/chunk-KC2GDBLS.cjs.map +1 -0
- package/dist/{chunk-K7JPTH3G.cjs → chunk-KNRSROWB.cjs} +132 -74
- package/dist/chunk-KNRSROWB.cjs.map +1 -0
- package/dist/{chunk-3AJE4SEG.js → chunk-KPA4AN4R.js} +125 -67
- package/dist/chunk-KPA4AN4R.js.map +1 -0
- package/dist/{chunk-QUW2RZTM.cjs → chunk-L46ROHUS.cjs} +51 -7
- package/dist/chunk-L46ROHUS.cjs.map +1 -0
- package/dist/chunk-L4EZKIEX.js +185 -0
- package/dist/chunk-L4EZKIEX.js.map +1 -0
- package/dist/{chunk-REK7AYOC.js → chunk-L5UKKZQN.js} +199 -32
- package/dist/chunk-L5UKKZQN.js.map +1 -0
- package/dist/chunk-NKPKR5BW.cjs +188 -0
- package/dist/chunk-NKPKR5BW.cjs.map +1 -0
- package/dist/{chunk-Y3QQN7PN.js → chunk-P2HKJ7P5.js} +13 -4
- package/dist/chunk-P2HKJ7P5.js.map +1 -0
- package/dist/{chunk-SA7NSSIQ.cjs → chunk-PI73NNOK.cjs} +13 -187
- package/dist/chunk-PI73NNOK.cjs.map +1 -0
- package/dist/{chunk-HXRD4B37.js → chunk-PU2Z5VWF.js} +1279 -556
- package/dist/chunk-PU2Z5VWF.js.map +1 -0
- package/dist/{chunk-H727JIG7.js → chunk-Q72BOAPK.js} +16 -8
- package/dist/chunk-Q72BOAPK.js.map +1 -0
- package/dist/{chunk-IBG6V56E.cjs → chunk-QFLB4EIJ.cjs} +2 -139
- package/dist/chunk-QFLB4EIJ.cjs.map +1 -0
- package/dist/{chunk-YVUJBEXE.cjs → chunk-RAMGUDJN.cjs} +16 -7
- package/dist/chunk-RAMGUDJN.cjs.map +1 -0
- package/dist/{chunk-LINKCEG4.cjs → chunk-ROJHKAQ4.cjs} +617 -73
- package/dist/chunk-ROJHKAQ4.cjs.map +1 -0
- package/dist/{chunk-5KVM3WEY.cjs → chunk-RSF3UU7H.cjs} +1330 -602
- package/dist/chunk-RSF3UU7H.cjs.map +1 -0
- package/dist/{chunk-V3LKPM3O.cjs → chunk-SHTTJMLT.cjs} +4 -2
- package/dist/chunk-SHTTJMLT.cjs.map +1 -0
- package/dist/chunk-SPBTLUN6.js +92 -0
- package/dist/chunk-SPBTLUN6.js.map +1 -0
- package/dist/{chunk-57P6MJKC.js → chunk-TXSZFA4G.js} +3 -3
- package/dist/chunk-TXSZFA4G.js.map +1 -0
- package/dist/chunk-UERVXYVK.cjs +99 -0
- package/dist/chunk-UERVXYVK.cjs.map +1 -0
- package/dist/{chunk-PDYFVNUX.cjs → chunk-V2TVSCV5.cjs} +16 -23
- package/dist/chunk-V2TVSCV5.cjs.map +1 -0
- package/dist/{chunk-DXHRBMGB.js → chunk-VO35MNPH.js} +12 -19
- package/dist/chunk-VO35MNPH.js.map +1 -0
- package/dist/{chunk-IA6AU5PI.cjs → chunk-WNCYAKF3.cjs} +3 -3
- package/dist/chunk-WNCYAKF3.cjs.map +1 -0
- package/dist/chunk-XEB7PH2E.js +81 -0
- package/dist/chunk-XEB7PH2E.js.map +1 -0
- package/dist/cli/index.cjs +5 -5
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +5 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/client.cjs +3 -3
- package/dist/client.d.cts +3 -3
- package/dist/client.d.ts +3 -3
- package/dist/client.js +1 -1
- package/dist/drizzle/index.cjs +14 -13
- package/dist/drizzle/index.d.cts +9 -7
- package/dist/drizzle/index.d.ts +9 -7
- package/dist/drizzle/index.js +5 -4
- package/dist/fields/index.cjs +21 -37
- package/dist/fields/index.d.cts +2 -22
- package/dist/fields/index.d.ts +2 -22
- package/dist/fields/index.js +1 -1
- package/dist/graphql/index.cjs +5 -4
- package/dist/graphql/index.d.cts +5 -3
- package/dist/graphql/index.d.ts +5 -3
- package/dist/graphql/index.js +3 -2
- package/dist/index-CJXPB_ot.d.ts +276 -0
- package/dist/index-CaTNnLGd.d.cts +276 -0
- package/dist/index.cjs +304 -162
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +129 -205
- package/dist/index.d.ts +129 -205
- package/dist/index.js +172 -33
- package/dist/index.js.map +1 -1
- package/dist/integration.cjs +2 -2
- package/dist/integration.js +1 -1
- package/dist/mongo-auth-adapter-ISOM7FSS.cjs +17 -0
- package/dist/{mongo-auth-adapter-NHHUJHVH.cjs.map → mongo-auth-adapter-ISOM7FSS.cjs.map} +1 -1
- package/dist/mongo-auth-adapter-MO6STCV3.js +4 -0
- package/dist/{mongo-auth-adapter-NJQUUCTP.js.map → mongo-auth-adapter-MO6STCV3.js.map} +1 -1
- package/dist/mongodb/index.cjs +8 -7
- package/dist/mongodb/index.d.cts +5 -7
- package/dist/mongodb/index.d.ts +5 -7
- package/dist/mongodb/index.js +4 -3
- package/dist/postgres-auth-adapter-DWDR7P5G.js +5 -0
- package/dist/{postgres-auth-adapter-3T2NKTSE.js.map → postgres-auth-adapter-DWDR7P5G.js.map} +1 -1
- package/dist/postgres-auth-adapter-WRWSJD4E.cjs +14 -0
- package/dist/{postgres-auth-adapter-7IEENCKQ.cjs.map → postgres-auth-adapter-WRWSJD4E.cjs.map} +1 -1
- package/dist/redis-adapter-HGTPWIGV.js +4 -0
- package/dist/{redis-adapter-VQXD7ESY.js.map → redis-adapter-HGTPWIGV.js.map} +1 -1
- package/dist/redis-adapter-KJ3YOOT6.cjs +13 -0
- package/dist/{redis-adapter-D2E2S3GB.cjs.map → redis-adapter-KJ3YOOT6.cjs.map} +1 -1
- package/dist/rest/index.cjs +15 -14
- package/dist/rest/index.d.cts +4 -4
- package/dist/rest/index.d.ts +4 -4
- package/dist/rest/index.js +13 -12
- package/dist/{schema-5PHL5IVB.js → schema-6I5OFR4Z.js} +3 -3
- package/dist/{schema-5PHL5IVB.js.map → schema-6I5OFR4Z.js.map} +1 -1
- package/dist/{schema-37SE2F4B.cjs → schema-TTFE4467.cjs} +14 -14
- package/dist/{schema-37SE2F4B.cjs.map → schema-TTFE4467.cjs.map} +1 -1
- package/dist/sqlite-adapter-6GEUSVXQ.js +4 -0
- package/dist/{sqlite-adapter-TR3U3W6Q.js.map → sqlite-adapter-6GEUSVXQ.js.map} +1 -1
- package/dist/sqlite-adapter-CSIZE5SX.cjs +13 -0
- package/dist/{sqlite-adapter-LVK5PS4T.cjs.map → sqlite-adapter-CSIZE5SX.cjs.map} +1 -1
- package/dist/templates/index.cjs +133 -31
- package/dist/templates/index.d.cts +52 -9
- package/dist/templates/index.d.ts +52 -9
- package/dist/templates/index.js +3 -1
- package/dist/trpc/index.cjs +13 -12
- package/dist/trpc/index.d.cts +55 -49
- package/dist/trpc/index.d.ts +55 -49
- package/dist/trpc/index.js +4 -3
- package/dist/{types-D6ZLRGbH.d.cts → types-CpjuXbe7.d.cts} +2 -0
- package/dist/{types-D6ZLRGbH.d.ts → types-CpjuXbe7.d.ts} +2 -0
- package/dist/{types-Bs1up4yP.d.ts → types-CyCQ6SAI.d.ts} +28 -2
- package/dist/{types-J3R9nVsZ.d.cts → types-DJxD9394.d.cts} +28 -2
- package/dist/{types-VtjUxIMp.d.cts → types-Z6FBiqa2.d.cts} +35 -14
- package/dist/{types-VtjUxIMp.d.ts → types-Z6FBiqa2.d.ts} +35 -14
- package/package.json +22 -4
- package/dist/bootstrap-AKAUP6F6.cjs +0 -32
- package/dist/bootstrap-JCML6NFO.js +0 -7
- package/dist/chunk-2KVHZE6O.cjs.map +0 -1
- package/dist/chunk-2OL4O2TH.cjs.map +0 -1
- package/dist/chunk-35U3FROB.js.map +0 -1
- package/dist/chunk-3AJE4SEG.js.map +0 -1
- package/dist/chunk-3J4MFTI3.js +0 -3872
- package/dist/chunk-3J4MFTI3.js.map +0 -1
- package/dist/chunk-3ZFYL34R.js.map +0 -1
- package/dist/chunk-4DA7QPLA.cjs.map +0 -1
- package/dist/chunk-57P6MJKC.js.map +0 -1
- package/dist/chunk-5KVM3WEY.cjs.map +0 -1
- package/dist/chunk-6IMPH6WV.cjs +0 -3897
- package/dist/chunk-6IMPH6WV.cjs.map +0 -1
- package/dist/chunk-ATBOUGQP.cjs +0 -513
- package/dist/chunk-ATBOUGQP.cjs.map +0 -1
- package/dist/chunk-DXHRBMGB.js.map +0 -1
- package/dist/chunk-ES5HNFFT.js.map +0 -1
- package/dist/chunk-FXYP2HA6.js.map +0 -1
- package/dist/chunk-H727JIG7.js.map +0 -1
- package/dist/chunk-HXRD4B37.js.map +0 -1
- package/dist/chunk-I7HHI6QV.cjs.map +0 -1
- package/dist/chunk-IA6AU5PI.cjs.map +0 -1
- package/dist/chunk-IBG6V56E.cjs.map +0 -1
- package/dist/chunk-K7JPTH3G.cjs.map +0 -1
- package/dist/chunk-LINKCEG4.cjs.map +0 -1
- package/dist/chunk-OHVB4AJ7.js.map +0 -1
- package/dist/chunk-PDYFVNUX.cjs.map +0 -1
- package/dist/chunk-Q23JB3KL.js +0 -488
- package/dist/chunk-Q23JB3KL.js.map +0 -1
- package/dist/chunk-QPPDLRNR.js.map +0 -1
- package/dist/chunk-QUW2RZTM.cjs.map +0 -1
- package/dist/chunk-QXIQWPAP.js.map +0 -1
- package/dist/chunk-R3XIBBAW.cjs +0 -34
- package/dist/chunk-R3XIBBAW.cjs.map +0 -1
- package/dist/chunk-REK7AYOC.js.map +0 -1
- package/dist/chunk-SA7NSSIQ.cjs.map +0 -1
- package/dist/chunk-SDMNUYVU.js +0 -30
- package/dist/chunk-SDMNUYVU.js.map +0 -1
- package/dist/chunk-V3LKPM3O.cjs.map +0 -1
- package/dist/chunk-VJT6P4N6.cjs.map +0 -1
- package/dist/chunk-WOWUL7ZY.js.map +0 -1
- package/dist/chunk-WQBRWOQT.cjs.map +0 -1
- package/dist/chunk-Y3N7UUDO.js.map +0 -1
- package/dist/chunk-Y3QQN7PN.js.map +0 -1
- package/dist/chunk-YVUJBEXE.cjs.map +0 -1
- package/dist/index-CLp-DRKA.d.ts +0 -64
- package/dist/index-DfO7G4kN.d.cts +0 -64
- package/dist/mongo-auth-adapter-NHHUJHVH.cjs +0 -17
- package/dist/mongo-auth-adapter-NJQUUCTP.js +0 -4
- package/dist/postgres-auth-adapter-3T2NKTSE.js +0 -5
- package/dist/postgres-auth-adapter-7IEENCKQ.cjs +0 -14
- package/dist/redis-adapter-D2E2S3GB.cjs +0 -13
- package/dist/redis-adapter-VQXD7ESY.js +0 -4
- package/dist/sqlite-adapter-LVK5PS4T.cjs +0 -13
- package/dist/sqlite-adapter-TR3U3W6Q.js +0 -4
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
3
|
+
var chunk3KTWGODI_cjs = require('./chunk-3KTWGODI.cjs');
|
|
4
|
+
var chunkKNRSROWB_cjs = require('./chunk-KNRSROWB.cjs');
|
|
5
|
+
var chunk3HR772HI_cjs = require('./chunk-3HR772HI.cjs');
|
|
6
|
+
var chunkRSF3UU7H_cjs = require('./chunk-RSF3UU7H.cjs');
|
|
7
|
+
var chunkQFLB4EIJ_cjs = require('./chunk-QFLB4EIJ.cjs');
|
|
8
|
+
var chunk4M7X5HAB_cjs = require('./chunk-4M7X5HAB.cjs');
|
|
7
9
|
var chunkDVD5P72E_cjs = require('./chunk-DVD5P72E.cjs');
|
|
8
|
-
var
|
|
10
|
+
var chunkPI73NNOK_cjs = require('./chunk-PI73NNOK.cjs');
|
|
9
11
|
var zod = require('zod');
|
|
12
|
+
var graphql = require('graphql');
|
|
10
13
|
var module$1 = require('module');
|
|
11
14
|
var crypto = require('crypto');
|
|
12
15
|
|
|
@@ -177,9 +180,9 @@ function validateFields(fields, context) {
|
|
|
177
180
|
break;
|
|
178
181
|
case "select":
|
|
179
182
|
case "radio":
|
|
180
|
-
if (!field.options || field.options.length === 0) {
|
|
183
|
+
if ((!field.options || field.options.length === 0) && !field.dynamicOptions) {
|
|
181
184
|
errors.push(`${context}: ${field.type} field "${fieldName}" has no options defined`);
|
|
182
|
-
} else {
|
|
185
|
+
} else if (field.options) {
|
|
183
186
|
const values = field.options.map((o) => o.value);
|
|
184
187
|
const uniqueValues = new Set(values);
|
|
185
188
|
if (values.length !== uniqueValues.size) {
|
|
@@ -268,7 +271,7 @@ function validateRelationships(fields, collections) {
|
|
|
268
271
|
const targets = Array.isArray(field.relationTo) ? field.relationTo : [field.relationTo];
|
|
269
272
|
for (const target of targets) {
|
|
270
273
|
if (!collectionSlugs.has(target)) {
|
|
271
|
-
|
|
274
|
+
console.warn(`[Kyro Config Warning]: Relationship field "${field.name}" references unknown collection "${target}". Select options will not be available until this collection is registered.`);
|
|
272
275
|
}
|
|
273
276
|
}
|
|
274
277
|
}
|
|
@@ -368,7 +371,7 @@ function textToZod(field) {
|
|
|
368
371
|
return schema;
|
|
369
372
|
}
|
|
370
373
|
function numberToZod(field) {
|
|
371
|
-
let schema = field.integer ? zod.z.number().int() : zod.z.number();
|
|
374
|
+
let schema = field.integer ? zod.z.coerce.number().int() : zod.z.coerce.number();
|
|
372
375
|
if (field.min !== void 0) schema = schema.min(field.min);
|
|
373
376
|
if (field.max !== void 0) schema = schema.max(field.max);
|
|
374
377
|
if (field.step) {
|
|
@@ -427,12 +430,16 @@ function textareaToZod(field) {
|
|
|
427
430
|
return schema;
|
|
428
431
|
}
|
|
429
432
|
function selectToZod(field) {
|
|
430
|
-
const values = field.options.map((opt) => opt.value);
|
|
431
433
|
let schema;
|
|
432
|
-
if (field.
|
|
433
|
-
|
|
434
|
+
if (field.options && field.options.length > 0) {
|
|
435
|
+
const values = field.options.map((opt) => opt.value);
|
|
436
|
+
if (field.hasMany) {
|
|
437
|
+
schema = zod.z.array(zod.z.enum(values));
|
|
438
|
+
} else {
|
|
439
|
+
schema = zod.z.enum(values);
|
|
440
|
+
}
|
|
434
441
|
} else {
|
|
435
|
-
schema = zod.z.
|
|
442
|
+
schema = field.hasMany ? zod.z.array(zod.z.string()) : zod.z.string();
|
|
436
443
|
}
|
|
437
444
|
if (!field.required) schema = schema.optional().nullable();
|
|
438
445
|
if (field.validate) schema = addCustomValidation(schema, field.validate);
|
|
@@ -462,10 +469,7 @@ function colorToZod(field) {
|
|
|
462
469
|
return schema;
|
|
463
470
|
}
|
|
464
471
|
function richTextToZod(field) {
|
|
465
|
-
let schema = zod.z.
|
|
466
|
-
zod.z.array(zod.z.record(zod.z.any())),
|
|
467
|
-
zod.z.string()
|
|
468
|
-
]);
|
|
472
|
+
let schema = zod.z.array(zod.z.record(zod.z.any()));
|
|
469
473
|
if (!field.required) schema = schema.optional().nullable();
|
|
470
474
|
if (field.validate) schema = addCustomValidation(schema, field.validate);
|
|
471
475
|
return schema;
|
|
@@ -576,9 +580,9 @@ function blocksToZod(field) {
|
|
|
576
580
|
const unknownSchema = zod.z.object({
|
|
577
581
|
blockType: zod.z.string()
|
|
578
582
|
}).catchall(zod.z.any());
|
|
579
|
-
schema = zod.z.array(zod.z.union([knownSchema, unknownSchema]));
|
|
583
|
+
schema = zod.z.array(zod.z.union([knownSchema, unknownSchema, zod.z.record(zod.z.any())]));
|
|
580
584
|
} else {
|
|
581
|
-
schema = zod.z.array(zod.z.object({ blockType: zod.z.string() }).catchall(zod.z.any()));
|
|
585
|
+
schema = zod.z.array(zod.z.union([zod.z.object({ blockType: zod.z.string() }).catchall(zod.z.any()), zod.z.record(zod.z.any())]));
|
|
582
586
|
}
|
|
583
587
|
if (field.minRows) schema = schema.min(field.minRows);
|
|
584
588
|
if (field.maxRows) schema = schema.max(field.maxRows);
|
|
@@ -724,6 +728,7 @@ function globalToZod(global) {
|
|
|
724
728
|
|
|
725
729
|
// src/registry/index.ts
|
|
726
730
|
var Registry = class {
|
|
731
|
+
storageProviders = chunkRSF3UU7H_cjs.getDefaultRegistry();
|
|
727
732
|
collections = /* @__PURE__ */ new Map();
|
|
728
733
|
globals = /* @__PURE__ */ new Map();
|
|
729
734
|
plugins = [];
|
|
@@ -791,6 +796,19 @@ var Registry = class {
|
|
|
791
796
|
if (this.initialized) {
|
|
792
797
|
throw new Error("Cannot add globals after Registry has been initialized");
|
|
793
798
|
}
|
|
799
|
+
this._addGlobalUnsafe(config);
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Add a global after the registry is already initialized.
|
|
803
|
+
* Only for internal use (e.g. storage settings form built at startup).
|
|
804
|
+
*/
|
|
805
|
+
addGlobalPostInit(config) {
|
|
806
|
+
if (this.globals.has(config.slug)) {
|
|
807
|
+
this.globals.delete(config.slug);
|
|
808
|
+
}
|
|
809
|
+
this._addGlobalUnsafe(config);
|
|
810
|
+
}
|
|
811
|
+
_addGlobalUnsafe(config) {
|
|
794
812
|
if (this.globals.has(config.slug)) {
|
|
795
813
|
console.warn(
|
|
796
814
|
`[Registry] Duplicate global slug "${config.slug}" \u2014 skipping`
|
|
@@ -945,6 +963,17 @@ var Registry = class {
|
|
|
945
963
|
admin: { readOnly: true, hidden: true }
|
|
946
964
|
});
|
|
947
965
|
}
|
|
966
|
+
if (config.versions?.drafts && !fields.some((f) => f.name === "publishStatus")) {
|
|
967
|
+
fields.push({
|
|
968
|
+
name: "publishStatus",
|
|
969
|
+
type: "select",
|
|
970
|
+
options: [
|
|
971
|
+
{ value: "draft", label: "Draft" },
|
|
972
|
+
{ value: "published", label: "Published" }
|
|
973
|
+
],
|
|
974
|
+
admin: { readOnly: true, hidden: true }
|
|
975
|
+
});
|
|
976
|
+
}
|
|
948
977
|
if (config.auth && !fields.some((f) => f.name === "password")) {
|
|
949
978
|
fields.push({
|
|
950
979
|
name: "password",
|
|
@@ -1089,6 +1118,296 @@ function createRegistry() {
|
|
|
1089
1118
|
instance = new Registry();
|
|
1090
1119
|
return instance;
|
|
1091
1120
|
}
|
|
1121
|
+
|
|
1122
|
+
// src/plugins/storage-s3.ts
|
|
1123
|
+
var s3Variants = {
|
|
1124
|
+
aws: {
|
|
1125
|
+
type: "aws",
|
|
1126
|
+
configKey: "s3",
|
|
1127
|
+
displayName: "S3 Compatible (AWS, Backblaze, Wasabi, etc.)",
|
|
1128
|
+
configFields: [
|
|
1129
|
+
{ name: "bucket", type: "text", label: "Bucket Name", required: true },
|
|
1130
|
+
{ name: "region", type: "text", label: "Region", defaultValue: "us-east-1", admin: { placeholder: "us-east-1" } },
|
|
1131
|
+
{ name: "accessKeyId", type: "text", label: "Access Key ID", required: true },
|
|
1132
|
+
{ name: "secretAccessKey", type: "password", label: "Secret Access Key", required: true },
|
|
1133
|
+
{ name: "endpoint", type: "text", label: "Endpoint URL", admin: { placeholder: "https://s3.custom.com" } },
|
|
1134
|
+
{ name: "cdnUrl", type: "text", label: "CDN URL", admin: { placeholder: "https://cdn.example.com" } },
|
|
1135
|
+
{ name: "prefix", type: "text", label: "Path Prefix", admin: { placeholder: "uploads" } }
|
|
1136
|
+
]
|
|
1137
|
+
},
|
|
1138
|
+
r2: {
|
|
1139
|
+
type: "r2",
|
|
1140
|
+
configKey: "r2",
|
|
1141
|
+
displayName: "Cloudflare R2",
|
|
1142
|
+
configFields: [
|
|
1143
|
+
{ name: "accountId", type: "text", label: "Account ID", required: true, admin: { placeholder: "Your Cloudflare Account ID" } },
|
|
1144
|
+
{ name: "accessKeyId", type: "text", label: "Access Key ID", required: true },
|
|
1145
|
+
{ name: "secretAccessKey", type: "password", label: "Secret Access Key", required: true },
|
|
1146
|
+
{ name: "bucket", type: "text", label: "Bucket Name", required: true },
|
|
1147
|
+
{
|
|
1148
|
+
name: "publicDevUrl",
|
|
1149
|
+
type: "text",
|
|
1150
|
+
label: "Public Dev URL ID",
|
|
1151
|
+
admin: {
|
|
1152
|
+
placeholder: "pub-xxxxxxxxxxxxxxxx",
|
|
1153
|
+
description: "Enter ONLY the ID (e.g., pub-b8d8c4cc8bcf4d868ddd95efc1b305aa). Do NOT include https:// or the full URL. Found in R2 Dashboard \u2192 Public Dev URL."
|
|
1154
|
+
}
|
|
1155
|
+
},
|
|
1156
|
+
{ name: "cdnUrl", type: "text", label: "Custom CDN URL", admin: { placeholder: "https://assets.example.com (optional)" } },
|
|
1157
|
+
{ name: "prefix", type: "text", label: "Path Prefix", admin: { placeholder: "uploads (optional)", description: "Optional prefix for all object keys. Do not use '/' as prefix." } }
|
|
1158
|
+
]
|
|
1159
|
+
},
|
|
1160
|
+
gcs: {
|
|
1161
|
+
type: "gcs",
|
|
1162
|
+
configKey: "gcs",
|
|
1163
|
+
displayName: "Google Cloud Storage",
|
|
1164
|
+
configFields: [
|
|
1165
|
+
{ name: "bucket", type: "text", label: "Bucket Name", required: true },
|
|
1166
|
+
{ name: "projectId", type: "text", label: "Project ID" },
|
|
1167
|
+
{ name: "clientEmail", type: "text", label: "Client Email" },
|
|
1168
|
+
{ name: "privateKey", type: "password", label: "Private Key" },
|
|
1169
|
+
{ name: "cdnUrl", type: "text", label: "CDN URL" },
|
|
1170
|
+
{ name: "prefix", type: "text", label: "Path Prefix" }
|
|
1171
|
+
]
|
|
1172
|
+
},
|
|
1173
|
+
digitalocean: {
|
|
1174
|
+
type: "digitalocean",
|
|
1175
|
+
configKey: "digitalocean",
|
|
1176
|
+
displayName: "DigitalOcean Spaces",
|
|
1177
|
+
configFields: [
|
|
1178
|
+
{ name: "bucket", type: "text", label: "Bucket Name", required: true },
|
|
1179
|
+
{ name: "region", type: "text", label: "Region", defaultValue: "nyc3" },
|
|
1180
|
+
{ name: "accessKeyId", type: "text", label: "Access Key ID", required: true },
|
|
1181
|
+
{ name: "secretAccessKey", type: "password", label: "Secret Access Key", required: true },
|
|
1182
|
+
{ name: "cdnUrl", type: "text", label: "CDN URL" },
|
|
1183
|
+
{ name: "prefix", type: "text", label: "Path Prefix" }
|
|
1184
|
+
]
|
|
1185
|
+
},
|
|
1186
|
+
backblaze: {
|
|
1187
|
+
type: "backblaze",
|
|
1188
|
+
configKey: "backblaze",
|
|
1189
|
+
displayName: "Backblaze B2",
|
|
1190
|
+
configFields: [
|
|
1191
|
+
{ name: "bucket", type: "text", label: "Bucket Name", required: true },
|
|
1192
|
+
{ name: "accountId", type: "text", label: "Account ID" },
|
|
1193
|
+
{ name: "applicationKeyId", type: "text", label: "Application Key ID", required: true },
|
|
1194
|
+
{ name: "applicationKey", type: "password", label: "Application Key", required: true },
|
|
1195
|
+
{ name: "cdnUrl", type: "text", label: "CDN URL" },
|
|
1196
|
+
{ name: "prefix", type: "text", label: "Path Prefix" }
|
|
1197
|
+
]
|
|
1198
|
+
},
|
|
1199
|
+
wasabi: {
|
|
1200
|
+
type: "wasabi",
|
|
1201
|
+
configKey: "wasabi",
|
|
1202
|
+
displayName: "Wasabi",
|
|
1203
|
+
configFields: [
|
|
1204
|
+
{ name: "bucket", type: "text", label: "Bucket Name", required: true },
|
|
1205
|
+
{ name: "region", type: "text", label: "Region", defaultValue: "us-east-1" },
|
|
1206
|
+
{ name: "accessKeyId", type: "text", label: "Access Key ID", required: true },
|
|
1207
|
+
{ name: "secretAccessKey", type: "password", label: "Secret Access Key", required: true },
|
|
1208
|
+
{ name: "cdnUrl", type: "text", label: "CDN URL" },
|
|
1209
|
+
{ name: "prefix", type: "text", label: "Path Prefix" }
|
|
1210
|
+
]
|
|
1211
|
+
}
|
|
1212
|
+
};
|
|
1213
|
+
function getEndpoint(type, config) {
|
|
1214
|
+
switch (type) {
|
|
1215
|
+
case "r2":
|
|
1216
|
+
return config?.endpoint || `https://${config?.accountId || ""}.r2.cloudflarestorage.com`;
|
|
1217
|
+
case "digitalocean":
|
|
1218
|
+
return config?.endpoint || `https://${config?.region || "nyc3"}.digitaloceanspaces.com`;
|
|
1219
|
+
case "backblaze":
|
|
1220
|
+
return config?.endpoint || `https://s3.backblazeb2.com`;
|
|
1221
|
+
case "wasabi":
|
|
1222
|
+
return config?.endpoint || `https://s3.${config?.region || "us-east-1"}.wasabisys.com`;
|
|
1223
|
+
default:
|
|
1224
|
+
return config?.endpoint;
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
function buildS3Config(type, c) {
|
|
1228
|
+
return {
|
|
1229
|
+
provider: type,
|
|
1230
|
+
bucket: c?.bucket || "",
|
|
1231
|
+
region: c?.region || "us-east-1",
|
|
1232
|
+
accessKeyId: c?.accessKeyId || c?.clientEmail || c?.applicationKeyId || "",
|
|
1233
|
+
secretAccessKey: c?.secretAccessKey || c?.privateKey || c?.applicationKey || "",
|
|
1234
|
+
endpoint: getEndpoint(type, c),
|
|
1235
|
+
cdnUrl: c?.cdnUrl,
|
|
1236
|
+
prefix: c?.prefix,
|
|
1237
|
+
accountId: c?.accountId,
|
|
1238
|
+
publicDevUrl: c?.publicDevUrl
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1241
|
+
function buildS3ConfigFromStorageConfig(type, def, sc) {
|
|
1242
|
+
const c = sc[def.configKey] || {};
|
|
1243
|
+
return buildS3Config(type, c);
|
|
1244
|
+
}
|
|
1245
|
+
function buildS3ConfigFromRaw(type, def, raw) {
|
|
1246
|
+
const c = raw?.[def.configKey] || raw;
|
|
1247
|
+
return buildS3Config(type, c);
|
|
1248
|
+
}
|
|
1249
|
+
var s3StoragePlugin = {
|
|
1250
|
+
name: "@kyro-cms/storage-s3",
|
|
1251
|
+
version: "1.0.0",
|
|
1252
|
+
description: "S3-compatible storage (AWS R2 GCS DigitalOcean Backblaze Wasabi)",
|
|
1253
|
+
init: (kyro) => {
|
|
1254
|
+
const registry = kyro.storageProviders;
|
|
1255
|
+
if (!registry) return;
|
|
1256
|
+
const pluginName = "@kyro-cms/storage-s3";
|
|
1257
|
+
for (const v of Object.values(s3Variants)) {
|
|
1258
|
+
registry.register({
|
|
1259
|
+
type: v.type,
|
|
1260
|
+
displayName: v.displayName,
|
|
1261
|
+
pluginName,
|
|
1262
|
+
configKey: v.configKey,
|
|
1263
|
+
configFields: v.configFields,
|
|
1264
|
+
extractConfig: (sc) => buildS3ConfigFromStorageConfig(v.type, v, sc),
|
|
1265
|
+
extractRawConfig: (raw) => buildS3ConfigFromRaw(v.type, v, raw),
|
|
1266
|
+
factory: (c) => chunkRSF3UU7H_cjs.createS3Storage(c)
|
|
1267
|
+
});
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
|
|
1272
|
+
// src/plugins/storage-cloudinary.ts
|
|
1273
|
+
var cloudinaryStoragePlugin = {
|
|
1274
|
+
name: "@kyro-cms/storage-cloudinary",
|
|
1275
|
+
version: "1.0.0",
|
|
1276
|
+
description: "Cloudinary image and video storage",
|
|
1277
|
+
init: (kyro) => {
|
|
1278
|
+
const registry = kyro.storageProviders;
|
|
1279
|
+
if (!registry) return;
|
|
1280
|
+
registry.register({
|
|
1281
|
+
type: "cloudinary",
|
|
1282
|
+
displayName: "Cloudinary",
|
|
1283
|
+
pluginName: "@kyro-cms/storage-cloudinary",
|
|
1284
|
+
configKey: "cloudinary",
|
|
1285
|
+
configFields: [
|
|
1286
|
+
{ name: "cloudName", type: "text", label: "Cloud Name", required: true },
|
|
1287
|
+
{ name: "apiKey", type: "text", label: "API Key", required: true },
|
|
1288
|
+
{ name: "apiSecret", type: "password", label: "API Secret", required: true },
|
|
1289
|
+
{ name: "folder", type: "text", label: "Folder", admin: { placeholder: "Optional folder path" } },
|
|
1290
|
+
{
|
|
1291
|
+
name: "uploadPreset",
|
|
1292
|
+
type: "text",
|
|
1293
|
+
label: "Upload Preset (optional)",
|
|
1294
|
+
admin: { placeholder: "Leave empty for signed uploads", description: "If not set, uploads will be signed with API Secret" }
|
|
1295
|
+
}
|
|
1296
|
+
],
|
|
1297
|
+
extractConfig: (sc) => ({
|
|
1298
|
+
cloudName: sc.cloudinary?.cloudName || "",
|
|
1299
|
+
apiKey: sc.cloudinary?.apiKey || "",
|
|
1300
|
+
apiSecret: sc.cloudinary?.apiSecret || "",
|
|
1301
|
+
folder: sc.cloudinary?.folder,
|
|
1302
|
+
uploadPreset: sc.cloudinary?.uploadPreset
|
|
1303
|
+
}),
|
|
1304
|
+
extractRawConfig: (c) => {
|
|
1305
|
+
const cl = c?.cloudinary || c;
|
|
1306
|
+
return {
|
|
1307
|
+
cloudName: cl?.cloudName || "",
|
|
1308
|
+
apiKey: cl?.apiKey || "",
|
|
1309
|
+
apiSecret: cl?.apiSecret || "",
|
|
1310
|
+
folder: cl?.folder,
|
|
1311
|
+
uploadPreset: cl?.uploadPreset
|
|
1312
|
+
};
|
|
1313
|
+
},
|
|
1314
|
+
factory: (c) => chunkRSF3UU7H_cjs.createCloudinaryStorage(c)
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
|
|
1319
|
+
// src/plugins/storage-ftp.ts
|
|
1320
|
+
var ftpStoragePlugin = {
|
|
1321
|
+
name: "@kyro-cms/storage-ftp",
|
|
1322
|
+
version: "1.0.0",
|
|
1323
|
+
description: "FTP/SFTP storage provider",
|
|
1324
|
+
init: (kyro) => {
|
|
1325
|
+
const registry = kyro.storageProviders;
|
|
1326
|
+
if (!registry) return;
|
|
1327
|
+
registry.register({
|
|
1328
|
+
type: "ftp",
|
|
1329
|
+
displayName: "FTP",
|
|
1330
|
+
pluginName: "@kyro-cms/storage-ftp",
|
|
1331
|
+
configKey: "ftp",
|
|
1332
|
+
configFields: [
|
|
1333
|
+
{ name: "host", type: "text", label: "Host", required: true, admin: { placeholder: "ftp.example.com" } },
|
|
1334
|
+
{ name: "port", type: "number", label: "Port", defaultValue: 21, admin: { placeholder: "21 for FTP" } },
|
|
1335
|
+
{ name: "user", type: "text", label: "Username", required: true },
|
|
1336
|
+
{ name: "password", type: "password", label: "Password", required: true },
|
|
1337
|
+
{ name: "secure", type: "checkbox", label: "Use TLS/SSL", defaultValue: false, admin: { description: "Enable TLS/SSL for secure connections (FTP only)" } },
|
|
1338
|
+
{ name: "baseUrl", type: "text", label: "Base URL", required: true, admin: { placeholder: "https://files.example.com" } },
|
|
1339
|
+
{ name: "prefix", type: "text", label: "Path Prefix", admin: { placeholder: "uploads" } }
|
|
1340
|
+
],
|
|
1341
|
+
extractConfig: (sc) => ({
|
|
1342
|
+
host: sc.ftp?.host || "",
|
|
1343
|
+
port: sc.ftp?.port || 21,
|
|
1344
|
+
user: sc.ftp?.user || "",
|
|
1345
|
+
password: sc.ftp?.password || "",
|
|
1346
|
+
secure: sc.ftp?.secure || false,
|
|
1347
|
+
baseUrl: sc.ftp?.baseUrl || "",
|
|
1348
|
+
prefix: sc.ftp?.prefix,
|
|
1349
|
+
type: "ftp"
|
|
1350
|
+
}),
|
|
1351
|
+
extractRawConfig: (c) => {
|
|
1352
|
+
const ftp = c?.ftp || c;
|
|
1353
|
+
return {
|
|
1354
|
+
host: ftp?.host || "",
|
|
1355
|
+
port: ftp?.port || 21,
|
|
1356
|
+
user: ftp?.user || "",
|
|
1357
|
+
password: ftp?.password || "",
|
|
1358
|
+
secure: ftp?.secure || false,
|
|
1359
|
+
baseUrl: ftp?.baseUrl || "",
|
|
1360
|
+
prefix: ftp?.prefix,
|
|
1361
|
+
type: "ftp"
|
|
1362
|
+
};
|
|
1363
|
+
},
|
|
1364
|
+
factory: (c) => chunkRSF3UU7H_cjs.createFtpStorage(c)
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1367
|
+
};
|
|
1368
|
+
var builtinStoragePlugins = [
|
|
1369
|
+
s3StoragePlugin,
|
|
1370
|
+
cloudinaryStoragePlugin,
|
|
1371
|
+
ftpStoragePlugin
|
|
1372
|
+
];
|
|
1373
|
+
function updateFieldByPath(fields, path, updates) {
|
|
1374
|
+
const parts = path.split(".");
|
|
1375
|
+
if (parts.length === 0) return false;
|
|
1376
|
+
const currentPart = parts[0];
|
|
1377
|
+
const remainingPath = parts.slice(1).join(".");
|
|
1378
|
+
for (const field of fields) {
|
|
1379
|
+
if (field.name === currentPart) {
|
|
1380
|
+
if (remainingPath) {
|
|
1381
|
+
if (field.fields && Array.isArray(field.fields)) {
|
|
1382
|
+
return updateFieldByPath(field.fields, remainingPath, updates);
|
|
1383
|
+
}
|
|
1384
|
+
if (field.type === "array" && field.fields && Array.isArray(field.fields)) {
|
|
1385
|
+
return updateFieldByPath(field.fields, remainingPath, updates);
|
|
1386
|
+
}
|
|
1387
|
+
return false;
|
|
1388
|
+
} else {
|
|
1389
|
+
Object.assign(field, updates);
|
|
1390
|
+
return true;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
return false;
|
|
1395
|
+
}
|
|
1396
|
+
function applyCollectionOverrides(collections, overrides) {
|
|
1397
|
+
if (!overrides) return;
|
|
1398
|
+
for (const col of collections) {
|
|
1399
|
+
const override = overrides[col.slug];
|
|
1400
|
+
if (override) {
|
|
1401
|
+
const { fields: fieldOverrides, ...adminOverrides } = override;
|
|
1402
|
+
col.admin = { ...col.admin, ...adminOverrides };
|
|
1403
|
+
if (fieldOverrides && col.fields && Array.isArray(col.fields)) {
|
|
1404
|
+
for (const [fieldPath, fieldUpdates] of Object.entries(fieldOverrides)) {
|
|
1405
|
+
updateFieldByPath(col.fields, fieldPath, fieldUpdates);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1092
1411
|
var Kyro = class {
|
|
1093
1412
|
registry;
|
|
1094
1413
|
db;
|
|
@@ -1102,13 +1421,19 @@ var Kyro = class {
|
|
|
1102
1421
|
this.registry = createRegistry();
|
|
1103
1422
|
this.db = config.adapter;
|
|
1104
1423
|
this.pubsub = new chunkDVD5P72E_cjs.KyroPubSub(this.registry);
|
|
1105
|
-
this.webhookService =
|
|
1424
|
+
this.webhookService = chunkQFLB4EIJ_cjs.createWebhookService(this.db);
|
|
1425
|
+
if (config.collections && config.admin?.collectionOverrides) {
|
|
1426
|
+
applyCollectionOverrides(config.collections, config.admin.collectionOverrides);
|
|
1427
|
+
}
|
|
1106
1428
|
if (config.collections) {
|
|
1107
1429
|
this.registry.addCollections(config.collections);
|
|
1108
1430
|
}
|
|
1109
1431
|
if (config.globals) {
|
|
1110
1432
|
this.registry.addGlobals(config.globals);
|
|
1111
1433
|
}
|
|
1434
|
+
for (const plugin of builtinStoragePlugins) {
|
|
1435
|
+
this.registry.addPlugin(plugin);
|
|
1436
|
+
}
|
|
1112
1437
|
if (config.plugins) {
|
|
1113
1438
|
for (const plugin of config.plugins) {
|
|
1114
1439
|
this.registry.addPlugin(plugin);
|
|
@@ -1117,13 +1442,24 @@ var Kyro = class {
|
|
|
1117
1442
|
}
|
|
1118
1443
|
async init() {
|
|
1119
1444
|
await this.registry.init();
|
|
1445
|
+
const storageGlobal = chunk3KTWGODI_cjs.createStorageSettingsGlobal(
|
|
1446
|
+
this.registry.storageProviders,
|
|
1447
|
+
(name) => this.registry.storageProviders.isPluginEnabled(name)
|
|
1448
|
+
);
|
|
1449
|
+
this.registry.addGlobalPostInit(storageGlobal);
|
|
1450
|
+
const pluginSettingsGlobal = {
|
|
1451
|
+
slug: "plugin-settings",
|
|
1452
|
+
admin: { hidden: true },
|
|
1453
|
+
fields: [{ name: "states", type: "json" }]
|
|
1454
|
+
};
|
|
1455
|
+
this.registry.addGlobalPostInit(pluginSettingsGlobal);
|
|
1120
1456
|
if (!this.db) {
|
|
1121
1457
|
throw new Error(
|
|
1122
1458
|
`Database adapter is null \u2014 failed to load at startup. Check the server console for the exact error.`
|
|
1123
1459
|
);
|
|
1124
1460
|
}
|
|
1125
1461
|
const systemCollection = {
|
|
1126
|
-
slug:
|
|
1462
|
+
slug: chunk4M7X5HAB_cjs.API_KEY_COLLECTION,
|
|
1127
1463
|
fields: [
|
|
1128
1464
|
{ name: "userId", type: "text", required: true },
|
|
1129
1465
|
{ name: "name", type: "text", required: true },
|
|
@@ -1135,7 +1471,7 @@ var Kyro = class {
|
|
|
1135
1471
|
]
|
|
1136
1472
|
};
|
|
1137
1473
|
const webhookCollection = {
|
|
1138
|
-
slug:
|
|
1474
|
+
slug: chunkQFLB4EIJ_cjs.WEBHOOK_COLLECTION,
|
|
1139
1475
|
fields: [
|
|
1140
1476
|
{ name: "name", type: "text", required: true },
|
|
1141
1477
|
{ name: "url", type: "text", required: true },
|
|
@@ -1148,7 +1484,7 @@ var Kyro = class {
|
|
|
1148
1484
|
]
|
|
1149
1485
|
};
|
|
1150
1486
|
const webhookDeliveryCollection = {
|
|
1151
|
-
slug:
|
|
1487
|
+
slug: chunkQFLB4EIJ_cjs.WEBHOOK_DELIVERY_COLLECTION,
|
|
1152
1488
|
fields: [
|
|
1153
1489
|
{ name: "webhookId", type: "text", required: true },
|
|
1154
1490
|
{ name: "event", type: "text", required: true },
|
|
@@ -1163,6 +1499,7 @@ var Kyro = class {
|
|
|
1163
1499
|
{ name: "nextRetryAt", type: "date" }
|
|
1164
1500
|
]
|
|
1165
1501
|
};
|
|
1502
|
+
const allGlobals = this.registry.getGlobals();
|
|
1166
1503
|
await this.db.init(
|
|
1167
1504
|
[
|
|
1168
1505
|
...this.registry.getCollections(),
|
|
@@ -1170,12 +1507,13 @@ var Kyro = class {
|
|
|
1170
1507
|
webhookCollection,
|
|
1171
1508
|
webhookDeliveryCollection
|
|
1172
1509
|
],
|
|
1173
|
-
|
|
1510
|
+
allGlobals
|
|
1174
1511
|
);
|
|
1512
|
+
await this.loadPluginState();
|
|
1175
1513
|
this.pubsub.autoRegisterHooks();
|
|
1176
1514
|
console.log("\u2705 Kyro CMS initialized");
|
|
1177
1515
|
console.log(` Collections: ${this.registry.getCollections().length}`);
|
|
1178
|
-
console.log(` Globals: ${
|
|
1516
|
+
console.log(` Globals: ${allGlobals.length}`);
|
|
1179
1517
|
}
|
|
1180
1518
|
// ============================================================================
|
|
1181
1519
|
// API Methods
|
|
@@ -1184,23 +1522,43 @@ var Kyro = class {
|
|
|
1184
1522
|
async loadSettings() {
|
|
1185
1523
|
if (this.settings) return this.settings;
|
|
1186
1524
|
try {
|
|
1187
|
-
const
|
|
1188
|
-
collection: "
|
|
1189
|
-
where: {
|
|
1525
|
+
const doc = await this.db.findOne({
|
|
1526
|
+
collection: "_globals_access-settings",
|
|
1527
|
+
where: {}
|
|
1190
1528
|
});
|
|
1191
|
-
if (
|
|
1192
|
-
this.settings =
|
|
1529
|
+
if (doc) {
|
|
1530
|
+
this.settings = { access: doc };
|
|
1193
1531
|
}
|
|
1194
1532
|
} catch (e) {
|
|
1195
1533
|
console.log("\u26A0\uFE0F No access-settings found, using defaults");
|
|
1196
1534
|
}
|
|
1197
1535
|
return this.settings || {};
|
|
1198
1536
|
}
|
|
1537
|
+
async loadPluginState() {
|
|
1538
|
+
const storageRegistry = this.registry.storageProviders;
|
|
1539
|
+
const pluginNames = storageRegistry.getAllPluginNames();
|
|
1540
|
+
let pluginStates = {};
|
|
1541
|
+
try {
|
|
1542
|
+
const doc = await this.db.findOne({
|
|
1543
|
+
collection: "_globals_plugin-settings",
|
|
1544
|
+
where: {}
|
|
1545
|
+
});
|
|
1546
|
+
if (doc && doc.states) {
|
|
1547
|
+
pluginStates = doc.states;
|
|
1548
|
+
}
|
|
1549
|
+
} catch (e) {
|
|
1550
|
+
}
|
|
1551
|
+
for (const name of pluginNames) {
|
|
1552
|
+
if (pluginStates[name] !== void 0) {
|
|
1553
|
+
storageRegistry.setPluginEnabled(name, pluginStates[name]);
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1199
1557
|
getREST(options) {
|
|
1200
1558
|
const authObj = typeof this.config.auth === "object" ? this.config.auth : null;
|
|
1201
1559
|
const authSecret = authObj?.secret;
|
|
1202
1560
|
const checkSession = authObj?.checkSession !== false;
|
|
1203
|
-
return
|
|
1561
|
+
return chunkRSF3UU7H_cjs.createHonoApp({
|
|
1204
1562
|
registry: this.registry,
|
|
1205
1563
|
db: this.db,
|
|
1206
1564
|
authSecret,
|
|
@@ -1213,33 +1571,196 @@ var Kyro = class {
|
|
|
1213
1571
|
});
|
|
1214
1572
|
}
|
|
1215
1573
|
getGraphQL(options) {
|
|
1216
|
-
|
|
1574
|
+
const defaultSchema = chunk3HR772HI_cjs.buildGraphQLSchema({
|
|
1217
1575
|
registry: this.registry,
|
|
1218
1576
|
db: this.db,
|
|
1219
|
-
|
|
1220
|
-
|
|
1577
|
+
settings: this.settings,
|
|
1578
|
+
user: options?.user,
|
|
1579
|
+
req: options?.req,
|
|
1580
|
+
tenantID: options?.tenantID
|
|
1221
1581
|
});
|
|
1582
|
+
return {
|
|
1583
|
+
fetch: async (request, _locals) => {
|
|
1584
|
+
const apiKeyRaw = chunk4M7X5HAB_cjs.extractApiKeyFromRequest(request);
|
|
1585
|
+
let gqlUser;
|
|
1586
|
+
let apiKeyCtx;
|
|
1587
|
+
if (apiKeyRaw && this.db) {
|
|
1588
|
+
const apiKeyResult = await chunk4M7X5HAB_cjs.validateApiKey(apiKeyRaw, this.db);
|
|
1589
|
+
if (!apiKeyResult.valid) {
|
|
1590
|
+
return new Response(
|
|
1591
|
+
JSON.stringify({ errors: [{ message: apiKeyResult.error || "Invalid API key" }] }),
|
|
1592
|
+
{ status: 401, headers: { "Content-Type": "application/json" } }
|
|
1593
|
+
);
|
|
1594
|
+
}
|
|
1595
|
+
if (apiKeyResult.user) {
|
|
1596
|
+
gqlUser = apiKeyResult.user;
|
|
1597
|
+
apiKeyCtx = chunk4M7X5HAB_cjs.createApiKeyContext(apiKeyResult);
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
const mustRebuild = gqlUser !== options?.user || apiKeyCtx !== void 0;
|
|
1601
|
+
const schema = mustRebuild ? chunk3HR772HI_cjs.buildGraphQLSchema({
|
|
1602
|
+
registry: this.registry,
|
|
1603
|
+
db: this.db,
|
|
1604
|
+
settings: this.settings,
|
|
1605
|
+
user: gqlUser,
|
|
1606
|
+
req: request,
|
|
1607
|
+
tenantID: options?.tenantID,
|
|
1608
|
+
apiKey: apiKeyCtx
|
|
1609
|
+
}) : defaultSchema;
|
|
1610
|
+
const body = request.method === "POST" ? await request.json().catch(() => ({})) : {};
|
|
1611
|
+
const query = body.query || "";
|
|
1612
|
+
const variables = body.variables || {};
|
|
1613
|
+
if (!query) {
|
|
1614
|
+
return new Response(
|
|
1615
|
+
JSON.stringify({ error: "No GraphQL query provided" }),
|
|
1616
|
+
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
1617
|
+
);
|
|
1618
|
+
}
|
|
1619
|
+
try {
|
|
1620
|
+
const document = graphql.parse(query);
|
|
1621
|
+
const result = await graphql.execute({
|
|
1622
|
+
schema,
|
|
1623
|
+
document,
|
|
1624
|
+
variableValues: variables,
|
|
1625
|
+
contextValue: {
|
|
1626
|
+
db: this.db,
|
|
1627
|
+
registry: this.registry,
|
|
1628
|
+
settings: this.settings,
|
|
1629
|
+
user: gqlUser,
|
|
1630
|
+
req: request,
|
|
1631
|
+
tenantID: options?.tenantID
|
|
1632
|
+
}
|
|
1633
|
+
});
|
|
1634
|
+
return new Response(JSON.stringify(result), {
|
|
1635
|
+
status: 200,
|
|
1636
|
+
headers: { "Content-Type": "application/json" }
|
|
1637
|
+
});
|
|
1638
|
+
} catch (err) {
|
|
1639
|
+
return new Response(
|
|
1640
|
+
JSON.stringify({ errors: [{ message: err.message }] }),
|
|
1641
|
+
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
},
|
|
1645
|
+
schema: defaultSchema
|
|
1646
|
+
};
|
|
1222
1647
|
}
|
|
1223
1648
|
getTRPC(options) {
|
|
1224
|
-
return
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1649
|
+
return {
|
|
1650
|
+
fetch: async (request, locals) => {
|
|
1651
|
+
const url = new URL(request.url);
|
|
1652
|
+
const path = url.pathname.replace(/^\/api\/trpc\//, "");
|
|
1653
|
+
const [slug, ...rest] = path.split(".");
|
|
1654
|
+
let procedureName = rest.join(".");
|
|
1655
|
+
procedureName = procedureName.replace(/\.(query|mutate|subscribe)$/, "");
|
|
1656
|
+
if (!slug || !procedureName) {
|
|
1657
|
+
return new Response(
|
|
1658
|
+
JSON.stringify({
|
|
1659
|
+
error: {
|
|
1660
|
+
message: "Invalid tRPC path",
|
|
1661
|
+
code: -32600,
|
|
1662
|
+
data: { code: "BAD_REQUEST", httpStatus: 400 }
|
|
1663
|
+
}
|
|
1664
|
+
}),
|
|
1665
|
+
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
1666
|
+
);
|
|
1667
|
+
}
|
|
1668
|
+
const ctx = await chunkKNRSROWB_cjs.createContext({
|
|
1669
|
+
db: this.db,
|
|
1670
|
+
registry: this.registry,
|
|
1671
|
+
req: request,
|
|
1672
|
+
user: options?.user,
|
|
1673
|
+
tenantID: options?.tenantID,
|
|
1674
|
+
settings: this.settings
|
|
1675
|
+
});
|
|
1676
|
+
const kyroRouter = chunkKNRSROWB_cjs.createKyroServer(ctx);
|
|
1677
|
+
const collectionRouter = kyroRouter[slug];
|
|
1678
|
+
if (!collectionRouter) {
|
|
1679
|
+
return new Response(
|
|
1680
|
+
JSON.stringify({
|
|
1681
|
+
error: {
|
|
1682
|
+
message: `Collection '${slug}' not found`,
|
|
1683
|
+
code: -32601,
|
|
1684
|
+
data: { code: "NOT_FOUND", httpStatus: 404 }
|
|
1685
|
+
}
|
|
1686
|
+
}),
|
|
1687
|
+
{ status: 404, headers: { "Content-Type": "application/json" } }
|
|
1688
|
+
);
|
|
1689
|
+
}
|
|
1690
|
+
const procedure = collectionRouter[procedureName];
|
|
1691
|
+
if (typeof procedure !== "function") {
|
|
1692
|
+
return new Response(
|
|
1693
|
+
JSON.stringify({
|
|
1694
|
+
error: {
|
|
1695
|
+
message: `Procedure '${procedureName}' not found`,
|
|
1696
|
+
code: -32601,
|
|
1697
|
+
data: { code: "NOT_FOUND", httpStatus: 404 }
|
|
1698
|
+
}
|
|
1699
|
+
}),
|
|
1700
|
+
{ status: 404, headers: { "Content-Type": "application/json" } }
|
|
1701
|
+
);
|
|
1702
|
+
}
|
|
1703
|
+
try {
|
|
1704
|
+
let raw = {};
|
|
1705
|
+
if (request.method === "POST" || request.method === "PATCH") {
|
|
1706
|
+
raw = await request.json().catch(() => ({}));
|
|
1707
|
+
} else {
|
|
1708
|
+
const qs = new URL(request.url).searchParams.get("input");
|
|
1709
|
+
if (qs) {
|
|
1710
|
+
try {
|
|
1711
|
+
raw = JSON.parse(decodeURIComponent(qs));
|
|
1712
|
+
} catch {
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
const input = raw?.["0"] ?? raw;
|
|
1717
|
+
const result = await procedure({ ...input, collection: slug });
|
|
1718
|
+
return new Response(JSON.stringify({ result: { data: result } }), {
|
|
1719
|
+
status: 200,
|
|
1720
|
+
headers: { "Content-Type": "application/json" }
|
|
1721
|
+
});
|
|
1722
|
+
} catch (err) {
|
|
1723
|
+
const msg = err.message || "Internal error";
|
|
1724
|
+
const httpStatus = msg.includes("not found") ? 404 : msg.includes("denied") || msg.includes("authentication required") ? 403 : msg.includes("conflict") ? 409 : 500;
|
|
1725
|
+
const code = httpStatus === 404 ? -32601 : httpStatus === 403 ? -32001 : httpStatus === 409 ? -32002 : -32603;
|
|
1726
|
+
return new Response(
|
|
1727
|
+
JSON.stringify({
|
|
1728
|
+
error: {
|
|
1729
|
+
message: msg,
|
|
1730
|
+
code,
|
|
1731
|
+
data: {
|
|
1732
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
1733
|
+
httpStatus
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
}),
|
|
1737
|
+
{ status: httpStatus, headers: { "Content-Type": "application/json" } }
|
|
1738
|
+
);
|
|
1739
|
+
}
|
|
1740
|
+
},
|
|
1741
|
+
router: null
|
|
1742
|
+
};
|
|
1743
|
+
}
|
|
1744
|
+
getWS() {
|
|
1745
|
+
return this.wsServer;
|
|
1231
1746
|
}
|
|
1232
1747
|
async startWebSocket(options) {
|
|
1233
1748
|
const apiAccess = this.settings?.access?.apiAccess;
|
|
1234
|
-
if (apiAccess?.
|
|
1749
|
+
if (apiAccess?.wsEnabled === false) {
|
|
1235
1750
|
console.log("\u26A0\uFE0F WebSocket is disabled in settings");
|
|
1236
1751
|
return null;
|
|
1237
1752
|
}
|
|
1753
|
+
const defaultVerifyToken = async (token) => {
|
|
1754
|
+
const result = await chunk4M7X5HAB_cjs.validateApiKey(token, this.db);
|
|
1755
|
+
if (!result.valid) throw new Error(result.error || "Invalid API key");
|
|
1756
|
+
if (!result.user) throw new Error("API key has no associated user");
|
|
1757
|
+
return result.user;
|
|
1758
|
+
};
|
|
1238
1759
|
this.wsServer = chunkDVD5P72E_cjs.createWSServer({
|
|
1239
1760
|
pubsub: this.pubsub,
|
|
1240
1761
|
port: options?.port || 8080,
|
|
1241
1762
|
requireAuth: options?.requireAuth ?? apiAccess?.requireAuth,
|
|
1242
|
-
verifyToken: options?.verifyToken
|
|
1763
|
+
verifyToken: options?.verifyToken || defaultVerifyToken
|
|
1243
1764
|
});
|
|
1244
1765
|
console.log(`\u{1F50C} WebSocket server started on port ${options?.port || 8080}`);
|
|
1245
1766
|
return this.wsServer;
|
|
@@ -1258,7 +1779,7 @@ var Kyro = class {
|
|
|
1258
1779
|
function createKyro(config) {
|
|
1259
1780
|
return new Kyro(config);
|
|
1260
1781
|
}
|
|
1261
|
-
var _require = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
1782
|
+
var _require = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-ROJHKAQ4.cjs', document.baseURI).href)));
|
|
1262
1783
|
var modPath = "node:sqlite";
|
|
1263
1784
|
var { DatabaseSync } = _require(modPath);
|
|
1264
1785
|
function flattenFields(fields) {
|
|
@@ -1358,19 +1879,12 @@ function getTableColumns(db, tableName) {
|
|
|
1358
1879
|
return [];
|
|
1359
1880
|
}
|
|
1360
1881
|
}
|
|
1361
|
-
var LocalAdapter = class extends
|
|
1882
|
+
var LocalAdapter = class extends chunkPI73NNOK_cjs.AbstractBaseAdapter {
|
|
1362
1883
|
db;
|
|
1363
1884
|
path;
|
|
1364
1885
|
migrations = /* @__PURE__ */ new Map();
|
|
1365
1886
|
draftsTableName = "kyro_drafts";
|
|
1366
1887
|
versionsTableName = "kyro_versions";
|
|
1367
|
-
tenantContext;
|
|
1368
|
-
setTenantContext(context) {
|
|
1369
|
-
this.tenantContext = context;
|
|
1370
|
-
}
|
|
1371
|
-
getTenantContext() {
|
|
1372
|
-
return this.tenantContext;
|
|
1373
|
-
}
|
|
1374
1888
|
constructor(options) {
|
|
1375
1889
|
super();
|
|
1376
1890
|
this.path = options.path;
|
|
@@ -1384,6 +1898,34 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1384
1898
|
if (!this.db) {
|
|
1385
1899
|
this.db = new DatabaseSync(this.path || ":memory:");
|
|
1386
1900
|
}
|
|
1901
|
+
if (this.db && typeof this.db.prepare === "function" && !this.db.prepare.__wrapped) {
|
|
1902
|
+
const originalPrepare = this.db.prepare.bind(this.db);
|
|
1903
|
+
const wrappedPrepare = (sql) => {
|
|
1904
|
+
const stmt = originalPrepare(sql);
|
|
1905
|
+
const serialize = (val) => {
|
|
1906
|
+
if (typeof val === "boolean") return val ? 1 : 0;
|
|
1907
|
+
if (val === void 0) return null;
|
|
1908
|
+
return val;
|
|
1909
|
+
};
|
|
1910
|
+
return new Proxy(stmt, {
|
|
1911
|
+
get(target, prop, receiver) {
|
|
1912
|
+
if (prop === "all") {
|
|
1913
|
+
return (...params) => target.all(...params.map(serialize));
|
|
1914
|
+
}
|
|
1915
|
+
if (prop === "get") {
|
|
1916
|
+
return (...params) => target.get(...params.map(serialize));
|
|
1917
|
+
}
|
|
1918
|
+
if (prop === "run") {
|
|
1919
|
+
return (...params) => target.run(...params.map(serialize));
|
|
1920
|
+
}
|
|
1921
|
+
const val = Reflect.get(target, prop, receiver);
|
|
1922
|
+
return typeof val === "function" ? val.bind(target) : val;
|
|
1923
|
+
}
|
|
1924
|
+
});
|
|
1925
|
+
};
|
|
1926
|
+
wrappedPrepare.__wrapped = true;
|
|
1927
|
+
this.db.prepare = wrappedPrepare;
|
|
1928
|
+
}
|
|
1387
1929
|
this.db.exec("PRAGMA journal_mode = WAL");
|
|
1388
1930
|
this.db.exec("PRAGMA foreign_keys = ON");
|
|
1389
1931
|
this.connected = true;
|
|
@@ -1411,8 +1953,8 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1411
1953
|
}
|
|
1412
1954
|
columns.push(`${this.col("createdAt")} TEXT DEFAULT (datetime('now'))`);
|
|
1413
1955
|
columns.push(`${this.col("updatedAt")} TEXT DEFAULT (datetime('now'))`);
|
|
1414
|
-
columns.push(`
|
|
1415
|
-
columns.push(`
|
|
1956
|
+
columns.push(`publishStatus TEXT DEFAULT 'draft'`);
|
|
1957
|
+
columns.push(`hasDraft INTEGER DEFAULT 0`);
|
|
1416
1958
|
if (config.tenantScoped) {
|
|
1417
1959
|
columns.push(`tenant_id TEXT NOT NULL`);
|
|
1418
1960
|
}
|
|
@@ -1420,7 +1962,7 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1420
1962
|
if (existingColumns.length === 0) {
|
|
1421
1963
|
const createSQL = `CREATE TABLE IF NOT EXISTS ${name} (${columns.join(", ")})`;
|
|
1422
1964
|
this.db.exec(createSQL);
|
|
1423
|
-
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${name}
|
|
1965
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${name}_publishStatus ON ${name}(publishStatus)`);
|
|
1424
1966
|
for (const field of flattenFields(config.fields)) {
|
|
1425
1967
|
if (field.name && field.indexed) {
|
|
1426
1968
|
this.db.exec(
|
|
@@ -1439,9 +1981,9 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1439
1981
|
const colName = colDef.split(" ")[0].replace(/^"/, "").replace(/"$/, "");
|
|
1440
1982
|
if (!existingSet.has(colName) && colName !== "id") {
|
|
1441
1983
|
try {
|
|
1442
|
-
if (colName === "
|
|
1984
|
+
if (colName === "publishStatus") {
|
|
1443
1985
|
this.db.exec(`ALTER TABLE ${name} ADD COLUMN ${this.col(colName)} TEXT DEFAULT 'published'`);
|
|
1444
|
-
} else if (colName === "
|
|
1986
|
+
} else if (colName === "hasDraft") {
|
|
1445
1987
|
this.db.exec(`ALTER TABLE ${name} ADD COLUMN ${this.col(colName)} INTEGER DEFAULT 0`);
|
|
1446
1988
|
} else {
|
|
1447
1989
|
this.db.exec(`ALTER TABLE ${name} ADD COLUMN ${this.col(colName)} TEXT`);
|
|
@@ -1474,7 +2016,7 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1474
2016
|
`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_doc ON ${this.versionsTableName}(collection_slug, document_id)`
|
|
1475
2017
|
);
|
|
1476
2018
|
this.db.exec(
|
|
1477
|
-
`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}
|
|
2019
|
+
`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}publishStatus ON ${this.versionsTableName}(status)`
|
|
1478
2020
|
);
|
|
1479
2021
|
}
|
|
1480
2022
|
ensureDraftsTable() {
|
|
@@ -1571,11 +2113,11 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1571
2113
|
const conditions = [];
|
|
1572
2114
|
let effectiveWhere = { ...where };
|
|
1573
2115
|
if (this.tenantContext && config.tenantScoped) {
|
|
1574
|
-
const rlsQuery =
|
|
2116
|
+
const rlsQuery = chunkPI73NNOK_cjs.applyRLS({ where: effectiveWhere }, slug, this.tenantContext, chunkPI73NNOK_cjs.DEFAULT_RLS_CONFIG);
|
|
1575
2117
|
effectiveWhere = rlsQuery.where || {};
|
|
1576
2118
|
}
|
|
1577
2119
|
if (!draft && config.versions?.drafts) {
|
|
1578
|
-
conditions.push(`
|
|
2120
|
+
conditions.push(`publishStatus = ?`);
|
|
1579
2121
|
params.push("published");
|
|
1580
2122
|
}
|
|
1581
2123
|
if (tenantID && config.tenantScoped) {
|
|
@@ -1616,11 +2158,11 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1616
2158
|
const rows = this.db.prepare(sql).all(...params);
|
|
1617
2159
|
let docs = rows.map((row) => this.rowToDoc(row, config));
|
|
1618
2160
|
if (this.tenantContext && !this.tenantContext.isSuperAdmin) {
|
|
1619
|
-
docs = docs.filter((doc) =>
|
|
2161
|
+
docs = docs.filter((doc) => chunkPI73NNOK_cjs.canAccessDocument(doc, slug, this.tenantContext, chunkPI73NNOK_cjs.DEFAULT_RLS_CONFIG));
|
|
1620
2162
|
}
|
|
1621
2163
|
if (draft) {
|
|
1622
2164
|
docs = await Promise.all(docs.map(async (doc) => {
|
|
1623
|
-
if (doc.
|
|
2165
|
+
if (doc.hasDraft) {
|
|
1624
2166
|
const versions = await this.findVersions({
|
|
1625
2167
|
collection: slug,
|
|
1626
2168
|
documentId: doc.id,
|
|
@@ -1628,7 +2170,7 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1628
2170
|
sort: "-createdAt"
|
|
1629
2171
|
});
|
|
1630
2172
|
if (versions.docs.length > 0 && versions.docs[0].status === "draft") {
|
|
1631
|
-
return { ...doc, ...versions.docs[0].data,
|
|
2173
|
+
return { ...doc, ...versions.docs[0].data, hasDraft: true, publishStatus: doc.publishStatus };
|
|
1632
2174
|
}
|
|
1633
2175
|
}
|
|
1634
2176
|
return doc;
|
|
@@ -1657,12 +2199,12 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1657
2199
|
const params = [id];
|
|
1658
2200
|
if (this.tenantContext && config.tenantScoped) {
|
|
1659
2201
|
const tempDoc = { id, tenant_id: this.tenantContext.tenantId };
|
|
1660
|
-
if (!
|
|
2202
|
+
if (!chunkPI73NNOK_cjs.canAccessDocument(tempDoc, slug, this.tenantContext, chunkPI73NNOK_cjs.DEFAULT_RLS_CONFIG)) {
|
|
1661
2203
|
return null;
|
|
1662
2204
|
}
|
|
1663
2205
|
}
|
|
1664
2206
|
if (!draft && config.versions?.drafts) {
|
|
1665
|
-
sql += ` AND
|
|
2207
|
+
sql += ` AND publishStatus = ?`;
|
|
1666
2208
|
params.push("published");
|
|
1667
2209
|
}
|
|
1668
2210
|
if (tenantID && config.tenantScoped) {
|
|
@@ -1672,7 +2214,7 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1672
2214
|
const row = this.db.prepare(sql).get(...params);
|
|
1673
2215
|
if (!row) return null;
|
|
1674
2216
|
let doc = this.rowToDoc(row, config);
|
|
1675
|
-
if (draft && doc.
|
|
2217
|
+
if (draft && doc.hasDraft) {
|
|
1676
2218
|
const versions = await this.findVersions({
|
|
1677
2219
|
collection: slug,
|
|
1678
2220
|
documentId: doc.id,
|
|
@@ -1680,7 +2222,7 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1680
2222
|
sort: "-createdAt"
|
|
1681
2223
|
});
|
|
1682
2224
|
if (versions.docs.length > 0 && versions.docs[0].status === "draft") {
|
|
1683
|
-
doc = { ...doc, ...versions.docs[0].data,
|
|
2225
|
+
doc = { ...doc, ...versions.docs[0].data, hasDraft: true, publishStatus: doc.publishStatus };
|
|
1684
2226
|
}
|
|
1685
2227
|
}
|
|
1686
2228
|
return doc;
|
|
@@ -1711,7 +2253,7 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1711
2253
|
const quotedColumns = filteredColumns.map((c) => this.col(c));
|
|
1712
2254
|
const placeholders = filteredColumns.map(() => "?").join(", ");
|
|
1713
2255
|
const values = Object.values(filteredData).map(
|
|
1714
|
-
(v) => typeof v === "object" ? JSON.stringify(v) : v
|
|
2256
|
+
(v) => v !== null && typeof v === "object" ? JSON.stringify(v) : v
|
|
1715
2257
|
);
|
|
1716
2258
|
this.db.prepare(
|
|
1717
2259
|
`INSERT OR REPLACE INTO ${tableName} (${quotedColumns.join(", ")}) VALUES (${placeholders})`
|
|
@@ -1791,7 +2333,7 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1791
2333
|
const conditions = [];
|
|
1792
2334
|
const params = [];
|
|
1793
2335
|
if (!args.draft && globalConfig.versions) {
|
|
1794
|
-
conditions.push("
|
|
2336
|
+
conditions.push("publishStatus = 'published'");
|
|
1795
2337
|
}
|
|
1796
2338
|
if (conditions.length > 0) {
|
|
1797
2339
|
sql += ` WHERE ${conditions.join(" AND ")}`;
|
|
@@ -1800,7 +2342,7 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1800
2342
|
const result2 = this.db.prepare(sql).get(...params);
|
|
1801
2343
|
if (result2) {
|
|
1802
2344
|
let doc = this.rowToDoc(result2, globalConfig);
|
|
1803
|
-
if (args.draft && doc.
|
|
2345
|
+
if (args.draft && doc.hasDraft) {
|
|
1804
2346
|
const versions = await this.findVersions({
|
|
1805
2347
|
collection: args.collection,
|
|
1806
2348
|
documentId: parsed.globalSlug,
|
|
@@ -1808,7 +2350,7 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
1808
2350
|
sort: "-createdAt"
|
|
1809
2351
|
});
|
|
1810
2352
|
if (versions.docs.length > 0 && versions.docs[0].status === "draft") {
|
|
1811
|
-
doc = { ...doc, ...versions.docs[0].data,
|
|
2353
|
+
doc = { ...doc, ...versions.docs[0].data, hasDraft: true, publishStatus: doc.publishStatus };
|
|
1812
2354
|
}
|
|
1813
2355
|
}
|
|
1814
2356
|
return doc;
|
|
@@ -2150,6 +2692,8 @@ var LocalAdapter = class extends chunkSA7NSSIQ_cjs.AbstractBaseAdapter {
|
|
|
2150
2692
|
if (config.tenantScoped) {
|
|
2151
2693
|
doc.tenantID = row.tenant_id;
|
|
2152
2694
|
}
|
|
2695
|
+
doc.publishStatus = row.publishStatus ?? "published";
|
|
2696
|
+
doc.hasDraft = row.hasDraft ? Boolean(row.hasDraft) : false;
|
|
2153
2697
|
return doc;
|
|
2154
2698
|
}
|
|
2155
2699
|
generateId() {
|
|
@@ -2253,5 +2797,5 @@ exports.validateCollection = validateCollection;
|
|
|
2253
2797
|
exports.validateConfig = validateConfig;
|
|
2254
2798
|
exports.validateFields = validateFields;
|
|
2255
2799
|
exports.validateGlobal = validateGlobal;
|
|
2256
|
-
//# sourceMappingURL=chunk-
|
|
2257
|
-
//# sourceMappingURL=chunk-
|
|
2800
|
+
//# sourceMappingURL=chunk-ROJHKAQ4.cjs.map
|
|
2801
|
+
//# sourceMappingURL=chunk-ROJHKAQ4.cjs.map
|