@kyro-cms/core 0.9.1 → 0.9.2
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 +0 -6
- package/dist/{WebhookService-Yg2UEOB4.d.cts → WebhookService-BKszZlG0.d.cts} +1 -1
- package/dist/{WebhookService-CUTb9XOy.d.ts → WebhookService-Ccf1j-IN.d.ts} +1 -1
- package/dist/api-handler-graphql.cjs +17 -17
- package/dist/api-handler-graphql.js +13 -13
- package/dist/api-handler-trpc.cjs +15 -15
- package/dist/api-handler-trpc.js +13 -13
- package/dist/api-handler.cjs +16 -16
- package/dist/api-handler.js +13 -13
- package/dist/{base-DaqY2GhA.d.ts → base-CIuXkrH4.d.cts} +3 -5
- package/dist/{base-B71y_EAF.d.cts → base-fFo4lqER.d.ts} +3 -5
- package/dist/bootstrap-3PV3GJ3S.js +7 -0
- package/dist/{bootstrap-T5BK77LD.js.map → bootstrap-3PV3GJ3S.js.map} +1 -1
- package/dist/bootstrap-4CELFLJO.cjs +32 -0
- package/dist/{bootstrap-5NLASFOG.cjs.map → bootstrap-4CELFLJO.cjs.map} +1 -1
- package/dist/{chunk-Z6ZWNWWR.js → chunk-4CV4JOE5.js} +3 -9
- package/dist/{chunk-Z6ZWNWWR.js.map → chunk-4CV4JOE5.js.map} +1 -1
- package/dist/{chunk-5EPFQUQD.js → chunk-53NYVYVX.js} +6 -6
- package/dist/chunk-53NYVYVX.js.map +1 -0
- package/dist/{chunk-22M4O4ZJ.js → chunk-5H3MWQJS.js} +129 -143
- package/dist/chunk-5H3MWQJS.js.map +1 -0
- package/dist/{chunk-RAMGUDJN.cjs → chunk-5PMQQFRE.cjs} +5 -5
- package/dist/{chunk-RAMGUDJN.cjs.map → chunk-5PMQQFRE.cjs.map} +1 -1
- package/dist/{chunk-TXSZFA4G.js → chunk-6UNONDW7.js} +93 -9
- package/dist/chunk-6UNONDW7.js.map +1 -0
- package/dist/{chunk-C36TMDTY.cjs → chunk-7OS7TX2Q.cjs} +49 -48
- package/dist/chunk-7OS7TX2Q.cjs.map +1 -0
- package/dist/{chunk-3TPQ2BU6.js → chunk-BYBMTIMT.js} +2 -6
- package/dist/chunk-BYBMTIMT.js.map +1 -0
- package/dist/{chunk-FOPGUM27.js → chunk-CJX74IYK.js} +5 -4
- package/dist/chunk-CJX74IYK.js.map +1 -0
- package/dist/{chunk-RSF3UU7H.cjs → chunk-CNKT4PME.cjs} +196 -200
- package/dist/chunk-CNKT4PME.cjs.map +1 -0
- package/dist/{chunk-G7VZBCD6.cjs → chunk-CZLDE2OZ.cjs} +2 -9
- package/dist/{chunk-G7VZBCD6.cjs.map → chunk-CZLDE2OZ.cjs.map} +1 -1
- package/dist/{chunk-JOPVMWTM.cjs → chunk-DPA3KWPY.cjs} +3 -3
- package/dist/chunk-DPA3KWPY.cjs.map +1 -0
- package/dist/{chunk-ROJHKAQ4.cjs → chunk-E2763JUP.cjs} +143 -157
- package/dist/chunk-E2763JUP.cjs.map +1 -0
- package/dist/{chunk-FAXU7BMP.js → chunk-E5UJBLQ7.js} +2 -2
- package/dist/chunk-E5UJBLQ7.js.map +1 -0
- package/dist/{chunk-DVD5P72E.cjs → chunk-EEJUFDMF.cjs} +2 -6
- package/dist/chunk-EEJUFDMF.cjs.map +1 -0
- package/dist/{chunk-2HZRBATX.cjs → chunk-FSKONGCX.cjs} +2 -2
- package/dist/chunk-FSKONGCX.cjs.map +1 -0
- package/dist/{chunk-P2HKJ7P5.js → chunk-GAAHG2Z4.js} +3 -3
- package/dist/{chunk-P2HKJ7P5.js.map → chunk-GAAHG2Z4.js.map} +1 -1
- package/dist/{chunk-PI73NNOK.cjs → chunk-GUUB5EAG.cjs} +2 -2
- package/dist/chunk-GUUB5EAG.cjs.map +1 -0
- package/dist/{chunk-PU2Z5VWF.js → chunk-IPTZM3VE.js} +183 -187
- package/dist/chunk-IPTZM3VE.js.map +1 -0
- package/dist/{chunk-UERVXYVK.cjs → chunk-NWUEVLQT.cjs} +13 -13
- package/dist/{chunk-UERVXYVK.cjs.map → chunk-NWUEVLQT.cjs.map} +1 -1
- package/dist/{chunk-KPA4AN4R.js → chunk-OHC6UHFY.js} +86 -12
- package/dist/chunk-OHC6UHFY.js.map +1 -0
- package/dist/{chunk-DEVFAKCQ.cjs → chunk-PHJRNPHY.cjs} +6 -6
- package/dist/chunk-PHJRNPHY.cjs.map +1 -0
- package/dist/{chunk-VO35MNPH.js → chunk-PQ72Z6WC.js} +67 -105
- package/dist/chunk-PQ72Z6WC.js.map +1 -0
- package/dist/{chunk-KNRSROWB.cjs → chunk-PV2I2KMI.cjs} +86 -12
- package/dist/chunk-PV2I2KMI.cjs.map +1 -0
- package/dist/{chunk-V2TVSCV5.cjs → chunk-Q23GAMLE.cjs} +71 -109
- package/dist/chunk-Q23GAMLE.cjs.map +1 -0
- package/dist/{chunk-COIASRDK.cjs → chunk-RFFSZSCL.cjs} +107 -171
- package/dist/chunk-RFFSZSCL.cjs.map +1 -0
- package/dist/{chunk-AL5KX63J.js → chunk-UUDTPZX6.js} +3 -3
- package/dist/chunk-UUDTPZX6.js.map +1 -0
- package/dist/{chunk-EJN2PAOE.js → chunk-V7KZQIZ6.js} +102 -166
- package/dist/chunk-V7KZQIZ6.js.map +1 -0
- package/dist/{chunk-DYTZ6FQ7.js → chunk-WXVB364T.js} +2 -2
- package/dist/chunk-WXVB364T.js.map +1 -0
- package/dist/{chunk-WNCYAKF3.cjs → chunk-Y7AQK4R4.cjs} +93 -9
- package/dist/chunk-Y7AQK4R4.cjs.map +1 -0
- package/dist/{chunk-SPBTLUN6.js → chunk-YFAVQQTU.js} +7 -7
- package/dist/{chunk-SPBTLUN6.js.map → chunk-YFAVQQTU.js.map} +1 -1
- package/dist/cli/index.cjs +5 -5
- package/dist/cli/index.js +5 -5
- package/dist/client.cjs +4 -4
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +2 -2
- package/dist/drizzle/index.cjs +14 -14
- package/dist/drizzle/index.d.cts +4 -10
- package/dist/drizzle/index.d.ts +4 -10
- package/dist/drizzle/index.js +5 -5
- package/dist/fields/index.cjs +22 -22
- package/dist/fields/index.d.cts +1 -1
- package/dist/fields/index.d.ts +1 -1
- package/dist/fields/index.js +2 -2
- package/dist/graphql/index.cjs +1 -1
- package/dist/graphql/index.d.cts +3 -3
- package/dist/graphql/index.d.ts +3 -3
- package/dist/graphql/index.js +1 -1
- package/dist/{index-CaTNnLGd.d.cts → index-BKta3cBH.d.cts} +3 -2
- package/dist/{index-CJXPB_ot.d.ts → index-ClOqnkTO.d.ts} +3 -2
- package/dist/index.cjs +117 -117
- package/dist/index.d.cts +10 -15
- package/dist/index.d.ts +10 -15
- package/dist/index.js +18 -18
- package/dist/integration.cjs +1 -1
- package/dist/integration.js +1 -1
- package/dist/media-7WDX4BDJ.js +4 -0
- package/dist/{media-GPPTZ43E.js.map → media-7WDX4BDJ.js.map} +1 -1
- package/dist/{media-XNTUFJZR.cjs → media-TUSLVRQ6.cjs} +3 -3
- package/dist/{media-XNTUFJZR.cjs.map → media-TUSLVRQ6.cjs.map} +1 -1
- package/dist/{mongo-auth-adapter-ISOM7FSS.cjs → mongo-auth-adapter-GT4S7SCU.cjs} +3 -3
- package/dist/{mongo-auth-adapter-ISOM7FSS.cjs.map → mongo-auth-adapter-GT4S7SCU.cjs.map} +1 -1
- package/dist/mongo-auth-adapter-M7VV4LNB.js +4 -0
- package/dist/{mongo-auth-adapter-MO6STCV3.js.map → mongo-auth-adapter-M7VV4LNB.js.map} +1 -1
- package/dist/mongodb/index.cjs +5 -5
- package/dist/mongodb/index.d.cts +4 -9
- package/dist/mongodb/index.d.ts +4 -9
- package/dist/mongodb/index.js +3 -3
- package/dist/postgres-auth-adapter-AFAPISH7.js +5 -0
- package/dist/{postgres-auth-adapter-DWDR7P5G.js.map → postgres-auth-adapter-AFAPISH7.js.map} +1 -1
- package/dist/postgres-auth-adapter-SFDTLONT.cjs +14 -0
- package/dist/{postgres-auth-adapter-WRWSJD4E.cjs.map → postgres-auth-adapter-SFDTLONT.cjs.map} +1 -1
- package/dist/{redis-adapter-KJ3YOOT6.cjs → redis-adapter-UQX4EE3B.cjs} +3 -3
- package/dist/{redis-adapter-KJ3YOOT6.cjs.map → redis-adapter-UQX4EE3B.cjs.map} +1 -1
- package/dist/redis-adapter-XALOGWY3.js +4 -0
- package/dist/{redis-adapter-HGTPWIGV.js.map → redis-adapter-XALOGWY3.js.map} +1 -1
- package/dist/rest/index.cjs +10 -10
- package/dist/rest/index.d.cts +4 -4
- package/dist/rest/index.d.ts +4 -4
- package/dist/rest/index.js +8 -8
- package/dist/{schema-TTFE4467.cjs → schema-6QL3USNB.cjs} +15 -15
- package/dist/{schema-TTFE4467.cjs.map → schema-6QL3USNB.cjs.map} +1 -1
- package/dist/{schema-6I5OFR4Z.js → schema-FNNWEAAW.js} +4 -4
- package/dist/{schema-6I5OFR4Z.js.map → schema-FNNWEAAW.js.map} +1 -1
- package/dist/{sqlite-adapter-CSIZE5SX.cjs → sqlite-adapter-AQB5TCGV.cjs} +3 -3
- package/dist/{sqlite-adapter-CSIZE5SX.cjs.map → sqlite-adapter-AQB5TCGV.cjs.map} +1 -1
- package/dist/sqlite-adapter-N5H6IM2X.js +4 -0
- package/dist/{sqlite-adapter-6GEUSVXQ.js.map → sqlite-adapter-N5H6IM2X.js.map} +1 -1
- package/dist/templates/index.cjs +49 -49
- package/dist/templates/index.d.cts +2 -2
- package/dist/templates/index.d.ts +2 -2
- package/dist/templates/index.js +2 -2
- package/dist/trpc/index.cjs +11 -11
- package/dist/trpc/index.d.cts +3 -3
- package/dist/trpc/index.d.ts +3 -3
- package/dist/trpc/index.js +2 -2
- package/dist/{types-Z6FBiqa2.d.cts → types-DeSApf9T.d.cts} +1 -0
- package/dist/{types-Z6FBiqa2.d.ts → types-DeSApf9T.d.ts} +1 -0
- package/dist/{types-CyCQ6SAI.d.ts → types-Dgzlftb7.d.ts} +6 -28
- package/dist/{types-DJxD9394.d.cts → types-Ds0tCA3L.d.cts} +6 -28
- package/dist/ws/index.cjs +6 -6
- package/dist/ws/index.js +2 -2
- package/package.json +1 -1
- package/dist/bootstrap-5NLASFOG.cjs +0 -32
- package/dist/bootstrap-T5BK77LD.js +0 -7
- package/dist/chunk-22M4O4ZJ.js.map +0 -1
- package/dist/chunk-2HZRBATX.cjs.map +0 -1
- package/dist/chunk-3TPQ2BU6.js.map +0 -1
- package/dist/chunk-5EPFQUQD.js.map +0 -1
- package/dist/chunk-AL5KX63J.js.map +0 -1
- package/dist/chunk-C36TMDTY.cjs.map +0 -1
- package/dist/chunk-COIASRDK.cjs.map +0 -1
- package/dist/chunk-DEVFAKCQ.cjs.map +0 -1
- package/dist/chunk-DVD5P72E.cjs.map +0 -1
- package/dist/chunk-DYTZ6FQ7.js.map +0 -1
- package/dist/chunk-EJN2PAOE.js.map +0 -1
- package/dist/chunk-FAXU7BMP.js.map +0 -1
- package/dist/chunk-FOPGUM27.js.map +0 -1
- package/dist/chunk-JOPVMWTM.cjs.map +0 -1
- package/dist/chunk-KNRSROWB.cjs.map +0 -1
- package/dist/chunk-KPA4AN4R.js.map +0 -1
- package/dist/chunk-PI73NNOK.cjs.map +0 -1
- package/dist/chunk-PU2Z5VWF.js.map +0 -1
- package/dist/chunk-ROJHKAQ4.cjs.map +0 -1
- package/dist/chunk-RSF3UU7H.cjs.map +0 -1
- package/dist/chunk-TXSZFA4G.js.map +0 -1
- package/dist/chunk-V2TVSCV5.cjs.map +0 -1
- package/dist/chunk-VO35MNPH.js.map +0 -1
- package/dist/chunk-WNCYAKF3.cjs.map +0 -1
- package/dist/media-GPPTZ43E.js +0 -4
- package/dist/mongo-auth-adapter-MO6STCV3.js +0 -4
- package/dist/postgres-auth-adapter-DWDR7P5G.js +0 -5
- package/dist/postgres-auth-adapter-WRWSJD4E.cjs +0 -14
- package/dist/redis-adapter-HGTPWIGV.js +0 -4
- package/dist/sqlite-adapter-6GEUSVXQ.js +0 -4
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { PasswordPolicy, ConfigService, EmailTransport } from './chunk-
|
|
1
|
+
import { PasswordPolicy, ConfigService, EmailTransport } from './chunk-6UNONDW7.js';
|
|
2
2
|
import { usersCollection } from './chunk-XEB7PH2E.js';
|
|
3
3
|
import { SQLiteAuthAdapter } from './chunk-Q72BOAPK.js';
|
|
4
4
|
import { createAuditContext } from './chunk-P2YW545G.js';
|
|
5
5
|
import { WEBHOOK_EVENTS } from './chunk-3UK5XBVJ.js';
|
|
6
6
|
import { API_KEY_COLLECTION, generateApiKey, generateApiKeyPrefix, evaluateAccess, hasApiKeyPermission, extractApiKeyFromRequest, validateApiKey, createApiKeyContext } from './chunk-CJONKRHJ.js';
|
|
7
|
-
import { genId, DrizzleAdapter } from './chunk-
|
|
8
|
-
import { PostgresAuthAdapter } from './chunk-
|
|
9
|
-
import { MongoDBAdapter } from './chunk-
|
|
7
|
+
import { genId, DrizzleAdapter } from './chunk-V7KZQIZ6.js';
|
|
8
|
+
import { PostgresAuthAdapter } from './chunk-CJX74IYK.js';
|
|
9
|
+
import { MongoDBAdapter } from './chunk-PQ72Z6WC.js';
|
|
10
10
|
import { MongoDBAuthAdapter } from './chunk-7OGPN7MP.js';
|
|
11
11
|
import { hasPermission } from './chunk-L4EZKIEX.js';
|
|
12
|
-
import { __esm, __export, __toCommonJS
|
|
12
|
+
import { __esm, __export, __toCommonJS } from './chunk-4CV4JOE5.js';
|
|
13
13
|
import crypto, { randomBytes, createHash } from 'crypto';
|
|
14
14
|
import { createStorage } from 'unstorage';
|
|
15
15
|
import fsDriver from 'unstorage/drivers/fs';
|
|
@@ -20,6 +20,7 @@ import sharp from 'sharp';
|
|
|
20
20
|
import { mkdir, readdir, stat, rename, unlink, writeFile } from 'fs/promises';
|
|
21
21
|
import process2 from 'process';
|
|
22
22
|
import { S3Client, ListObjectsV2Command, DeleteObjectsCommand, DeleteObjectCommand, PutObjectCommand, HeadObjectCommand, CopyObjectCommand } from '@aws-sdk/client-s3';
|
|
23
|
+
import { NodeHttpHandler } from '@smithy/node-http-handler';
|
|
23
24
|
import { Readable } from 'stream';
|
|
24
25
|
import { Client } from 'basic-ftp';
|
|
25
26
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
@@ -31,8 +32,8 @@ async function loadSecrets() {
|
|
|
31
32
|
if (dbAdapter) {
|
|
32
33
|
try {
|
|
33
34
|
const result = await dbAdapter.findOne({
|
|
34
|
-
collection: "
|
|
35
|
-
where: {
|
|
35
|
+
collection: "_globals_system",
|
|
36
|
+
where: {}
|
|
36
37
|
});
|
|
37
38
|
if (result) {
|
|
38
39
|
cachedSecrets = {
|
|
@@ -442,6 +443,9 @@ function createTenantContextFromUser(user) {
|
|
|
442
443
|
};
|
|
443
444
|
}
|
|
444
445
|
|
|
446
|
+
// src/api/rest/hono-app.ts
|
|
447
|
+
init_secret();
|
|
448
|
+
|
|
445
449
|
// src/auth/security/in-memory-rate-limit.ts
|
|
446
450
|
var InMemoryRateLimiter = class {
|
|
447
451
|
storage = /* @__PURE__ */ new Map();
|
|
@@ -2223,7 +2227,7 @@ function createS3Storage(config) {
|
|
|
2223
2227
|
tls: true,
|
|
2224
2228
|
// R2 requires specific SSL configuration
|
|
2225
2229
|
...config.provider === "r2" && {
|
|
2226
|
-
requestHandler: new
|
|
2230
|
+
requestHandler: new NodeHttpHandler({
|
|
2227
2231
|
connectionTimeout: 1e4,
|
|
2228
2232
|
socketTimeout: 1e4
|
|
2229
2233
|
})
|
|
@@ -2846,9 +2850,7 @@ var MediaService = class _MediaService {
|
|
|
2846
2850
|
storage2 = await resolveProviderWithConfig(options.storageConfig);
|
|
2847
2851
|
} else {
|
|
2848
2852
|
const configService = new ConfigService(db);
|
|
2849
|
-
|
|
2850
|
-
await configService.load();
|
|
2851
|
-
}
|
|
2853
|
+
await configService.load();
|
|
2852
2854
|
storage2 = await resolveProvider(configService);
|
|
2853
2855
|
}
|
|
2854
2856
|
const service = new _MediaService(db, storage2, options);
|
|
@@ -3050,7 +3052,7 @@ var MediaService = class _MediaService {
|
|
|
3050
3052
|
]
|
|
3051
3053
|
);
|
|
3052
3054
|
} else {
|
|
3053
|
-
const { media: mediaSchema } = await import('./media-
|
|
3055
|
+
const { media: mediaSchema } = await import('./media-7WDX4BDJ.js');
|
|
3054
3056
|
const mime = storageResult.mimeType;
|
|
3055
3057
|
const mediaType = mime.startsWith("image/") ? "image" : mime.startsWith("video/") ? "video" : mime.startsWith("audio/") ? "audio" : mime.startsWith("application/pdf") ? "document" : ["application/zip", "application/x-zip", "application/x-tar", "application/gzip", "application/x-7z"].includes(mime) ? "archive" : "other";
|
|
3056
3058
|
await this.db.insert(mediaSchema).values({
|
|
@@ -3112,7 +3114,7 @@ var MediaService = class _MediaService {
|
|
|
3112
3114
|
id
|
|
3113
3115
|
]);
|
|
3114
3116
|
} else {
|
|
3115
|
-
const { media: mediaSchema } = await import('./media-
|
|
3117
|
+
const { media: mediaSchema } = await import('./media-7WDX4BDJ.js');
|
|
3116
3118
|
const { eq } = await import('drizzle-orm');
|
|
3117
3119
|
const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
|
|
3118
3120
|
if (row) item = this.rowToMedia(row);
|
|
@@ -3128,7 +3130,7 @@ var MediaService = class _MediaService {
|
|
|
3128
3130
|
if (this.dialect === "sqlite") {
|
|
3129
3131
|
await this.sqliteRun(`DELETE FROM ${this.mediaTable} WHERE id = ?`, [id]);
|
|
3130
3132
|
} else {
|
|
3131
|
-
const { media: mediaSchema } = await import('./media-
|
|
3133
|
+
const { media: mediaSchema } = await import('./media-7WDX4BDJ.js');
|
|
3132
3134
|
const { eq } = await import('drizzle-orm');
|
|
3133
3135
|
await this.db.delete(mediaSchema).where(eq(mediaSchema.id, id));
|
|
3134
3136
|
}
|
|
@@ -3143,7 +3145,7 @@ var MediaService = class _MediaService {
|
|
|
3143
3145
|
id
|
|
3144
3146
|
]);
|
|
3145
3147
|
} else {
|
|
3146
|
-
const { media: mediaSchema } = await import('./media-
|
|
3148
|
+
const { media: mediaSchema } = await import('./media-7WDX4BDJ.js');
|
|
3147
3149
|
const { eq } = await import('drizzle-orm');
|
|
3148
3150
|
const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
|
|
3149
3151
|
if (row) item = this.rowToMedia(row);
|
|
@@ -3178,7 +3180,7 @@ var MediaService = class _MediaService {
|
|
|
3178
3180
|
[...vals, this.now(), id]
|
|
3179
3181
|
);
|
|
3180
3182
|
} else {
|
|
3181
|
-
const { media: mediaSchema } = await import('./media-
|
|
3183
|
+
const { media: mediaSchema } = await import('./media-7WDX4BDJ.js');
|
|
3182
3184
|
const { eq } = await import('drizzle-orm');
|
|
3183
3185
|
await this.db.update(mediaSchema).set({ ...updateData, updatedAt: this.now() }).where(eq(mediaSchema.id, id));
|
|
3184
3186
|
}
|
|
@@ -3197,7 +3199,7 @@ var MediaService = class _MediaService {
|
|
|
3197
3199
|
);
|
|
3198
3200
|
return row2 ? this.rowToMedia(row2) : null;
|
|
3199
3201
|
}
|
|
3200
|
-
const { media: mediaSchema } = await import('./media-
|
|
3202
|
+
const { media: mediaSchema } = await import('./media-7WDX4BDJ.js');
|
|
3201
3203
|
const { eq } = await import('drizzle-orm');
|
|
3202
3204
|
const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
|
|
3203
3205
|
return row ? this.rowToMedia(row) : null;
|
|
@@ -3245,7 +3247,7 @@ var MediaService = class _MediaService {
|
|
|
3245
3247
|
totalPages: Math.ceil(totalDocs2 / limit)
|
|
3246
3248
|
};
|
|
3247
3249
|
}
|
|
3248
|
-
const { media: mediaSchema } = await import('./media-
|
|
3250
|
+
const { media: mediaSchema } = await import('./media-7WDX4BDJ.js');
|
|
3249
3251
|
const { like, or, and, asc, desc, eq, sql } = await import('drizzle-orm');
|
|
3250
3252
|
const conditions = [];
|
|
3251
3253
|
if (search) {
|
|
@@ -3324,7 +3326,7 @@ var MediaService = class _MediaService {
|
|
|
3324
3326
|
);
|
|
3325
3327
|
return row ? this.rowToMedia(row) : null;
|
|
3326
3328
|
}
|
|
3327
|
-
const { media: mediaSchema } = await import('./media-
|
|
3329
|
+
const { media: mediaSchema } = await import('./media-7WDX4BDJ.js');
|
|
3328
3330
|
const { eq } = await import('drizzle-orm');
|
|
3329
3331
|
const [updated] = await this.db.update(mediaSchema).set({ ...data, updatedAt: /* @__PURE__ */ new Date() }).where(eq(mediaSchema.id, id)).returning();
|
|
3330
3332
|
return updated ? this.rowToMedia(updated) : null;
|
|
@@ -3346,7 +3348,7 @@ var MediaService = class _MediaService {
|
|
|
3346
3348
|
);
|
|
3347
3349
|
}
|
|
3348
3350
|
} else {
|
|
3349
|
-
const { media: mediaSchema } = await import('./media-
|
|
3351
|
+
const { media: mediaSchema } = await import('./media-7WDX4BDJ.js');
|
|
3350
3352
|
const { eq } = await import('drizzle-orm');
|
|
3351
3353
|
for (const id of ids) {
|
|
3352
3354
|
await this.db.update(mediaSchema).set({ ...data, updatedAt: /* @__PURE__ */ new Date() }).where(eq(mediaSchema.id, id));
|
|
@@ -3361,7 +3363,7 @@ var MediaService = class _MediaService {
|
|
|
3361
3363
|
);
|
|
3362
3364
|
return rows.map((r) => r.path).filter((f) => f && f !== "").sort();
|
|
3363
3365
|
}
|
|
3364
|
-
const { media: mediaSchema, mediaFolders: folderSchema } = await import('./media-
|
|
3366
|
+
const { media: mediaSchema, mediaFolders: folderSchema } = await import('./media-7WDX4BDJ.js');
|
|
3365
3367
|
const { eq, sql } = await import('drizzle-orm');
|
|
3366
3368
|
const fromMedia = await this.db.select({ folder: mediaSchema.folder }).from(mediaSchema).groupBy(mediaSchema.folder);
|
|
3367
3369
|
const fromFolders = await this.db.select({ path: folderSchema.path }).from(folderSchema);
|
|
@@ -3381,7 +3383,7 @@ var MediaService = class _MediaService {
|
|
|
3381
3383
|
[fullPath, name, parentPath || null, now]
|
|
3382
3384
|
);
|
|
3383
3385
|
} else {
|
|
3384
|
-
const { mediaFolders: folderSchema } = await import('./media-
|
|
3386
|
+
const { mediaFolders: folderSchema } = await import('./media-7WDX4BDJ.js');
|
|
3385
3387
|
await this.db.insert(folderSchema).values({
|
|
3386
3388
|
path: fullPath,
|
|
3387
3389
|
name,
|
|
@@ -3402,7 +3404,7 @@ var MediaService = class _MediaService {
|
|
|
3402
3404
|
[folder, `${folder}/%`]
|
|
3403
3405
|
);
|
|
3404
3406
|
} else {
|
|
3405
|
-
const { mediaFolders: folderSchema } = await import('./media-
|
|
3407
|
+
const { mediaFolders: folderSchema } = await import('./media-7WDX4BDJ.js');
|
|
3406
3408
|
const { like, or, eq } = await import('drizzle-orm');
|
|
3407
3409
|
await this.db.delete(folderSchema).where(
|
|
3408
3410
|
or(
|
|
@@ -3416,6 +3418,38 @@ var MediaService = class _MediaService {
|
|
|
3416
3418
|
function formatZodErrors(errors) {
|
|
3417
3419
|
return errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
|
|
3418
3420
|
}
|
|
3421
|
+
function normalizeEmptyStrings(data, fields) {
|
|
3422
|
+
if (!data || typeof data !== "object") return;
|
|
3423
|
+
for (const field of fields) {
|
|
3424
|
+
if (!field.name || !(field.name in data)) continue;
|
|
3425
|
+
const val = data[field.name];
|
|
3426
|
+
if (val === "") {
|
|
3427
|
+
const isTextual = field.type === "text" || field.type === "textarea" || field.type === "code" || field.type === "markdown" || field.type === "email" || field.type === "password" || field.type === "color";
|
|
3428
|
+
if (!isTextual) data[field.name] = null;
|
|
3429
|
+
}
|
|
3430
|
+
if (field.type === "tabs" && field.name && Array.isArray(field.tabs) && data[field.name] && typeof data[field.name] === "object") {
|
|
3431
|
+
for (const tab of field.tabs) {
|
|
3432
|
+
if (Array.isArray(tab.fields)) normalizeEmptyStrings(data[field.name], tab.fields);
|
|
3433
|
+
}
|
|
3434
|
+
} else if ((field.type === "group" || field.type === "collapsible") && field.name && Array.isArray(field.fields) && data[field.name] && typeof data[field.name] === "object") {
|
|
3435
|
+
normalizeEmptyStrings(data[field.name], field.fields);
|
|
3436
|
+
} else if (field.type === "array" && field.name && Array.isArray(field.fields) && Array.isArray(data[field.name])) {
|
|
3437
|
+
for (const item of data[field.name]) {
|
|
3438
|
+
if (item && typeof item === "object") normalizeEmptyStrings(item, field.fields);
|
|
3439
|
+
}
|
|
3440
|
+
} else if (field.type === "blocks" && field.name && Array.isArray(field.blocks) && Array.isArray(data[field.name])) {
|
|
3441
|
+
for (const item of data[field.name]) {
|
|
3442
|
+
if (!item || typeof item !== "object") continue;
|
|
3443
|
+
const blockTypeStr = item.type || item.blockType;
|
|
3444
|
+
if (!blockTypeStr) continue;
|
|
3445
|
+
const blockDef = field.blocks.find((b) => b.slug === blockTypeStr);
|
|
3446
|
+
if (!blockDef || !Array.isArray(blockDef.fields)) continue;
|
|
3447
|
+
const target = item.data && typeof item.data === "object" ? item.data : item;
|
|
3448
|
+
normalizeEmptyStrings(target, blockDef.fields);
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3419
3453
|
function convertRichtextFields(fields, data) {
|
|
3420
3454
|
if (!data || typeof data !== "object") return;
|
|
3421
3455
|
for (const field of fields) {
|
|
@@ -3437,6 +3471,16 @@ function convertRichtextFields(fields, data) {
|
|
|
3437
3471
|
for (const item of data[field.name]) {
|
|
3438
3472
|
if (item && typeof item === "object") convertRichtextFields(field.fields, item);
|
|
3439
3473
|
}
|
|
3474
|
+
} else if (field.type === "blocks" && field.name && Array.isArray(field.blocks) && Array.isArray(data[field.name])) {
|
|
3475
|
+
for (const item of data[field.name]) {
|
|
3476
|
+
if (!item || typeof item !== "object") continue;
|
|
3477
|
+
const blockTypeStr = item.type || item.blockType;
|
|
3478
|
+
if (!blockTypeStr) continue;
|
|
3479
|
+
const blockDef = field.blocks.find((b) => b.slug === blockTypeStr);
|
|
3480
|
+
if (!blockDef || !Array.isArray(blockDef.fields)) continue;
|
|
3481
|
+
const target = item.data && typeof item.data === "object" ? item.data : item;
|
|
3482
|
+
convertRichtextFields(blockDef.fields, target);
|
|
3483
|
+
}
|
|
3440
3484
|
}
|
|
3441
3485
|
}
|
|
3442
3486
|
}
|
|
@@ -3533,7 +3577,7 @@ async function checkCollectionAccess(collection, operation, req, ctxUser, ctxTen
|
|
|
3533
3577
|
};
|
|
3534
3578
|
}
|
|
3535
3579
|
}
|
|
3536
|
-
if (ctxUser) {
|
|
3580
|
+
if (ctxUser && !(apiKeyContext?.permissions?.length > 0)) {
|
|
3537
3581
|
const resource = collection.slug;
|
|
3538
3582
|
const action = operation === "read" ? "read" : operation === "create" ? "create" : operation === "update" ? "update" : "delete";
|
|
3539
3583
|
const permission = `${resource}:${action}`;
|
|
@@ -3729,6 +3773,13 @@ function createHonoApp(options) {
|
|
|
3729
3773
|
baseUrl: process.env.KYRO_BASE_URL || "http://localhost:4321",
|
|
3730
3774
|
rateLimiter
|
|
3731
3775
|
});
|
|
3776
|
+
EmailTransport.fromConfig(db).then((transport) => {
|
|
3777
|
+
if (transport) {
|
|
3778
|
+
authRoutes.email = transport;
|
|
3779
|
+
}
|
|
3780
|
+
}).catch((err) => {
|
|
3781
|
+
console.error("[Email] Failed to initialize transport from config:", err);
|
|
3782
|
+
});
|
|
3732
3783
|
app.post("/api/auth/login", async (c) => authRoutes.login(c.req.raw));
|
|
3733
3784
|
app.post("/api/auth/register", async (c) => authRoutes.register(c.req.raw));
|
|
3734
3785
|
app.post("/api/auth/logout", async (c) => authRoutes.logout(c.req.raw));
|
|
@@ -4804,15 +4855,13 @@ function createHonoApp(options) {
|
|
|
4804
4855
|
});
|
|
4805
4856
|
app.get("/api/keys", async (c) => {
|
|
4806
4857
|
try {
|
|
4807
|
-
const { user: ctxUser } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
|
|
4858
|
+
const { user: ctxUser, tenantID: ctxTenantID } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
|
|
4808
4859
|
if (!ctxUser || !hasPermission(ctxUser, "users:read")) {
|
|
4809
4860
|
return c.json({ error: "Forbidden" }, 403);
|
|
4810
4861
|
}
|
|
4811
4862
|
const page = parseInt(c.req.query("page") || "1");
|
|
4812
4863
|
const limit = Math.min(parseInt(c.req.query("limit") || "50"), 100);
|
|
4813
|
-
|
|
4814
|
-
const result = await db.find({ collection: API_KEY_COLLECTION, where: {}, page, limit });
|
|
4815
|
-
console.log("[ApiKeys] Result:", result);
|
|
4864
|
+
const result = await db.find({ collection: API_KEY_COLLECTION, where: {}, page, limit, tenantID: ctxTenantID });
|
|
4816
4865
|
const docs = (result.docs || []).map((doc) => ({
|
|
4817
4866
|
id: doc.id,
|
|
4818
4867
|
name: doc.name,
|
|
@@ -5205,36 +5254,6 @@ function createHonoApp(options) {
|
|
|
5205
5254
|
return c.json({ error: error.message }, 500);
|
|
5206
5255
|
}
|
|
5207
5256
|
});
|
|
5208
|
-
app.get(`${basePath}/:id/draft`, async (c) => {
|
|
5209
|
-
try {
|
|
5210
|
-
const {
|
|
5211
|
-
user: ctxUser,
|
|
5212
|
-
tenantID: ctxTenantID,
|
|
5213
|
-
apiKeyContext
|
|
5214
|
-
} = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
|
|
5215
|
-
const access = await checkCollectionAccess(
|
|
5216
|
-
collection,
|
|
5217
|
-
"read",
|
|
5218
|
-
c.req.raw,
|
|
5219
|
-
ctxUser,
|
|
5220
|
-
ctxTenantID,
|
|
5221
|
-
apiKeyContext,
|
|
5222
|
-
enablePublicAccess,
|
|
5223
|
-
defaultCollectionAccess
|
|
5224
|
-
);
|
|
5225
|
-
if (!access.allowed) {
|
|
5226
|
-
return c.json({ error: access.error }, access.status || 403);
|
|
5227
|
-
}
|
|
5228
|
-
const draft = await db.findDraft({
|
|
5229
|
-
collection: slug,
|
|
5230
|
-
documentId: c.req.param("id"),
|
|
5231
|
-
tenantID: ctxTenantID
|
|
5232
|
-
});
|
|
5233
|
-
return c.json({ data: draft });
|
|
5234
|
-
} catch (error) {
|
|
5235
|
-
return c.json({ error: error.message }, 500);
|
|
5236
|
-
}
|
|
5237
|
-
});
|
|
5238
5257
|
app.put(`${basePath}/:id/draft`, async (c) => {
|
|
5239
5258
|
try {
|
|
5240
5259
|
const {
|
|
@@ -5273,13 +5292,12 @@ function createHonoApp(options) {
|
|
|
5273
5292
|
} else {
|
|
5274
5293
|
finalData = body.data ?? omitRevisionFields(body);
|
|
5275
5294
|
}
|
|
5276
|
-
const
|
|
5295
|
+
const version = await db.updateLatestVersion({
|
|
5277
5296
|
collection: slug,
|
|
5278
5297
|
documentId: id,
|
|
5279
|
-
tenantID: ctxTenantID,
|
|
5280
5298
|
data: finalData,
|
|
5281
|
-
|
|
5282
|
-
|
|
5299
|
+
status: "draft",
|
|
5300
|
+
tenantID: ctxTenantID
|
|
5283
5301
|
});
|
|
5284
5302
|
if (ctxUser) {
|
|
5285
5303
|
sessionAuthAdapter?.createAuditLog({
|
|
@@ -5291,7 +5309,7 @@ function createHonoApp(options) {
|
|
|
5291
5309
|
metadata: { type: "draft_save" }
|
|
5292
5310
|
});
|
|
5293
5311
|
}
|
|
5294
|
-
return c.json({ data:
|
|
5312
|
+
return c.json({ data: version, message: "Draft saved successfully" });
|
|
5295
5313
|
} catch (error) {
|
|
5296
5314
|
return c.json({ error: error.message }, 500);
|
|
5297
5315
|
}
|
|
@@ -5316,11 +5334,6 @@ function createHonoApp(options) {
|
|
|
5316
5334
|
if (!access.allowed) {
|
|
5317
5335
|
return c.json({ error: access.error }, access.status || 403);
|
|
5318
5336
|
}
|
|
5319
|
-
await db.deleteDraft({
|
|
5320
|
-
collection: slug,
|
|
5321
|
-
documentId: c.req.param("id"),
|
|
5322
|
-
tenantID: ctxTenantID
|
|
5323
|
-
});
|
|
5324
5337
|
if (ctxUser) {
|
|
5325
5338
|
sessionAuthAdapter?.createAuditLog({
|
|
5326
5339
|
action: "document_update",
|
|
@@ -5412,14 +5425,7 @@ function createHonoApp(options) {
|
|
|
5412
5425
|
auditApiKeyUsage(sessionAuthAdapter, apiKeyContext, basePath, "POST", c.req.raw);
|
|
5413
5426
|
const body = await c.req.json();
|
|
5414
5427
|
let validated = body;
|
|
5415
|
-
|
|
5416
|
-
if (field.name && validated[field.name] === "") {
|
|
5417
|
-
const isTextual = field.type === "text" || field.type === "textarea" || field.type === "code" || field.type === "markdown" || field.type === "email" || field.type === "password" || field.type === "color";
|
|
5418
|
-
if (!isTextual) {
|
|
5419
|
-
validated[field.name] = null;
|
|
5420
|
-
}
|
|
5421
|
-
}
|
|
5422
|
-
}
|
|
5428
|
+
normalizeEmptyStrings(validated, collection.fields);
|
|
5423
5429
|
convertRichtextFields(collection.fields, validated);
|
|
5424
5430
|
const hookReq = c.req.raw;
|
|
5425
5431
|
if (collection.hooks?.beforeValidate) {
|
|
@@ -5445,10 +5451,7 @@ function createHonoApp(options) {
|
|
|
5445
5451
|
validated.tenantID = ctxTenantID;
|
|
5446
5452
|
}
|
|
5447
5453
|
const isDraftEnabled = collection.versions?.drafts === true;
|
|
5448
|
-
|
|
5449
|
-
validated.publishStatus = "draft";
|
|
5450
|
-
validated.hasDraft = false;
|
|
5451
|
-
}
|
|
5454
|
+
validated.status = isDraftEnabled ? "draft" : "published";
|
|
5452
5455
|
if (collection.hooks?.beforeChange) {
|
|
5453
5456
|
for (const hook of collection.hooks.beforeChange) {
|
|
5454
5457
|
const hookResult = await hook({
|
|
@@ -5467,6 +5470,17 @@ function createHonoApp(options) {
|
|
|
5467
5470
|
data: validated,
|
|
5468
5471
|
tenantID: ctxTenantID
|
|
5469
5472
|
});
|
|
5473
|
+
if (isDraftEnabled) {
|
|
5474
|
+
await db.createVersion({
|
|
5475
|
+
collection: slug,
|
|
5476
|
+
documentId: doc.id,
|
|
5477
|
+
data: validated,
|
|
5478
|
+
status: "draft",
|
|
5479
|
+
createdBy: ctxUser?.id,
|
|
5480
|
+
changeDescription: "Created",
|
|
5481
|
+
tenantID: ctxTenantID
|
|
5482
|
+
});
|
|
5483
|
+
}
|
|
5470
5484
|
if (collection.hooks?.afterChange) {
|
|
5471
5485
|
for (const hook of collection.hooks.afterChange) {
|
|
5472
5486
|
await hook({
|
|
@@ -5532,11 +5546,6 @@ function createHonoApp(options) {
|
|
|
5532
5546
|
const id = c.req.param("id");
|
|
5533
5547
|
const body = await c.req.json();
|
|
5534
5548
|
const baseUpdatedAt = readBaseUpdatedAt(body);
|
|
5535
|
-
console.log(`[PATCH] ${slug}/${id}`, {
|
|
5536
|
-
baseUpdatedAt,
|
|
5537
|
-
bodyKeys: Object.keys(body),
|
|
5538
|
-
tenantID: ctxTenantID
|
|
5539
|
-
});
|
|
5540
5549
|
const originalDoc = await db.findByID({
|
|
5541
5550
|
collection: slug,
|
|
5542
5551
|
id,
|
|
@@ -5554,14 +5563,7 @@ function createHonoApp(options) {
|
|
|
5554
5563
|
([_, v]) => v !== "null" && v !== void 0
|
|
5555
5564
|
)
|
|
5556
5565
|
);
|
|
5557
|
-
|
|
5558
|
-
if (field.name && validated[field.name] === "") {
|
|
5559
|
-
const isTextual = field.type === "text" || field.type === "textarea" || field.type === "code" || field.type === "markdown" || field.type === "email" || field.type === "password" || field.type === "color";
|
|
5560
|
-
if (!isTextual) {
|
|
5561
|
-
validated[field.name] = null;
|
|
5562
|
-
}
|
|
5563
|
-
}
|
|
5564
|
-
}
|
|
5566
|
+
normalizeEmptyStrings(validated, collection.fields);
|
|
5565
5567
|
convertRichtextFields(collection.fields, validated);
|
|
5566
5568
|
const hookReq = c.req.raw;
|
|
5567
5569
|
if (collection.hooks?.beforeValidate) {
|
|
@@ -5594,37 +5596,44 @@ function createHonoApp(options) {
|
|
|
5594
5596
|
if (hookResult) Object.assign(validated, hookResult);
|
|
5595
5597
|
}
|
|
5596
5598
|
}
|
|
5597
|
-
|
|
5599
|
+
const isDraft = c.req.header("X-Draft") === "true";
|
|
5598
5600
|
const isDraftEnabled = collection.versions?.drafts === true;
|
|
5599
|
-
const
|
|
5601
|
+
const isAutosave = c.req.query("autosave") === "true";
|
|
5600
5602
|
let doc;
|
|
5601
|
-
if (isDraftEnabled &&
|
|
5603
|
+
if (isDraftEnabled && isDraft) {
|
|
5602
5604
|
await db.createVersion({
|
|
5603
5605
|
collection: slug,
|
|
5604
5606
|
documentId: id,
|
|
5605
5607
|
data: validated,
|
|
5606
5608
|
status: "draft",
|
|
5609
|
+
autosave: isAutosave,
|
|
5607
5610
|
createdBy: ctxUser?.id,
|
|
5608
|
-
changeDescription: "
|
|
5611
|
+
changeDescription: isAutosave ? "Autosave" : "Draft saved",
|
|
5609
5612
|
tenantID: ctxTenantID
|
|
5610
5613
|
});
|
|
5614
|
+
} else if (isDraftEnabled) {
|
|
5611
5615
|
await db.update({
|
|
5612
5616
|
collection: slug,
|
|
5613
5617
|
id,
|
|
5614
|
-
data: {
|
|
5615
|
-
|
|
5618
|
+
data: { ...validated, status: "published" },
|
|
5619
|
+
tenantID: ctxTenantID
|
|
5620
|
+
});
|
|
5621
|
+
await db.createVersion({
|
|
5622
|
+
collection: slug,
|
|
5623
|
+
documentId: id,
|
|
5624
|
+
data: validated,
|
|
5625
|
+
status: "published",
|
|
5626
|
+
createdBy: ctxUser?.id,
|
|
5627
|
+
changeDescription: "Published",
|
|
5616
5628
|
tenantID: ctxTenantID
|
|
5617
5629
|
});
|
|
5618
5630
|
} else {
|
|
5619
|
-
const saveData = isDraftEnabled ? { ...validated, publishStatus: "draft", hasDraft: false } : validated;
|
|
5620
|
-
console.log(`[PATCH] About to call db.update for ${slug}/${id} with keys:`, Object.keys(saveData));
|
|
5621
5631
|
await db.update({
|
|
5622
5632
|
collection: slug,
|
|
5623
5633
|
id,
|
|
5624
|
-
data:
|
|
5634
|
+
data: validated,
|
|
5625
5635
|
tenantID: ctxTenantID
|
|
5626
5636
|
});
|
|
5627
|
-
console.log(`[PATCH] db.update SUCCEEDED for ${slug}/${id}`);
|
|
5628
5637
|
}
|
|
5629
5638
|
doc = await db.findByID({
|
|
5630
5639
|
collection: slug,
|
|
@@ -5632,25 +5641,6 @@ function createHonoApp(options) {
|
|
|
5632
5641
|
tenantID: ctxTenantID,
|
|
5633
5642
|
draft: true
|
|
5634
5643
|
});
|
|
5635
|
-
if (isDraftEnabled) {
|
|
5636
|
-
if (!isAlreadyPublished) {
|
|
5637
|
-
await db.createVersion({
|
|
5638
|
-
collection: slug,
|
|
5639
|
-
documentId: id,
|
|
5640
|
-
data: validated,
|
|
5641
|
-
status: "draft",
|
|
5642
|
-
createdBy: ctxUser?.id,
|
|
5643
|
-
changeDescription: "Manual save",
|
|
5644
|
-
tenantID: ctxTenantID
|
|
5645
|
-
});
|
|
5646
|
-
}
|
|
5647
|
-
} else {
|
|
5648
|
-
await db.deleteDraft({
|
|
5649
|
-
collection: slug,
|
|
5650
|
-
documentId: id,
|
|
5651
|
-
tenantID: ctxTenantID
|
|
5652
|
-
});
|
|
5653
|
-
}
|
|
5654
5644
|
if (collection.hooks?.afterChange) {
|
|
5655
5645
|
for (const hook of collection.hooks.afterChange) {
|
|
5656
5646
|
await hook({
|
|
@@ -5722,7 +5712,6 @@ function createHonoApp(options) {
|
|
|
5722
5712
|
db.setTenantContext({ tenantId: ctxTenantID, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
|
|
5723
5713
|
}
|
|
5724
5714
|
const id = c.req.param("id");
|
|
5725
|
-
console.log(`[DELETE] Deleting ${slug}/${id}`);
|
|
5726
5715
|
const hookReq = c.req.raw;
|
|
5727
5716
|
const originalDoc = await db.findByID({
|
|
5728
5717
|
collection: slug,
|
|
@@ -5750,11 +5739,6 @@ function createHonoApp(options) {
|
|
|
5750
5739
|
id,
|
|
5751
5740
|
tenantID: ctxTenantID
|
|
5752
5741
|
});
|
|
5753
|
-
await db.deleteDraft({
|
|
5754
|
-
collection: slug,
|
|
5755
|
-
documentId: id,
|
|
5756
|
-
tenantID: ctxTenantID
|
|
5757
|
-
});
|
|
5758
5742
|
if (collection.hooks?.afterDelete) {
|
|
5759
5743
|
for (const hook of collection.hooks.afterDelete) {
|
|
5760
5744
|
await hook({
|
|
@@ -5796,7 +5780,6 @@ function createHonoApp(options) {
|
|
|
5796
5780
|
});
|
|
5797
5781
|
app.post(`${basePath}/:id/duplicate`, async (c) => {
|
|
5798
5782
|
try {
|
|
5799
|
-
console.log(`[Duplicate] Request for ${slug}`);
|
|
5800
5783
|
const {
|
|
5801
5784
|
user: ctxUser,
|
|
5802
5785
|
tenantID: ctxTenantID,
|
|
@@ -5813,11 +5796,9 @@ function createHonoApp(options) {
|
|
|
5813
5796
|
defaultCollectionAccess
|
|
5814
5797
|
);
|
|
5815
5798
|
if (!access.allowed) {
|
|
5816
|
-
console.log("[Duplicate] Access denied:", access.error);
|
|
5817
5799
|
return c.json({ error: access.error }, access.status || 403);
|
|
5818
5800
|
}
|
|
5819
5801
|
const id = c.req.param("id");
|
|
5820
|
-
console.log(`[Duplicate] ID: ${id}`);
|
|
5821
5802
|
const originalDoc = await db.findByID({
|
|
5822
5803
|
collection: slug,
|
|
5823
5804
|
id,
|
|
@@ -5825,14 +5806,11 @@ function createHonoApp(options) {
|
|
|
5825
5806
|
draft: true
|
|
5826
5807
|
});
|
|
5827
5808
|
if (!originalDoc) {
|
|
5828
|
-
console.log("[Duplicate] Document not found");
|
|
5829
5809
|
return c.json({ error: "Document not found" }, 404);
|
|
5830
5810
|
}
|
|
5831
|
-
console.log(`[Duplicate] Original doc:`, originalDoc);
|
|
5832
5811
|
const { id: _oldId, createdAt: _oldCreated, updatedAt: _oldUpdated, ...docData } = originalDoc;
|
|
5833
5812
|
const timestamp = Date.now().toString(36);
|
|
5834
5813
|
const newSlug = `${originalDoc.slug || "document"}-copy-${timestamp}`;
|
|
5835
|
-
console.log(`[Duplicate] New slug: ${newSlug}`);
|
|
5836
5814
|
const newDoc = await db.create({
|
|
5837
5815
|
collection: slug,
|
|
5838
5816
|
data: {
|
|
@@ -5842,7 +5820,6 @@ function createHonoApp(options) {
|
|
|
5842
5820
|
},
|
|
5843
5821
|
tenantID: ctxTenantID
|
|
5844
5822
|
});
|
|
5845
|
-
console.log(`[Duplicate] Created successfully:`, newDoc.id);
|
|
5846
5823
|
return c.json({ data: newDoc, message: "Document duplicated successfully" });
|
|
5847
5824
|
} catch (error) {
|
|
5848
5825
|
console.error("[Duplicate] Error:", error);
|
|
@@ -5882,7 +5859,7 @@ function createHonoApp(options) {
|
|
|
5882
5859
|
const doc = await db.update({
|
|
5883
5860
|
collection: slug,
|
|
5884
5861
|
id,
|
|
5885
|
-
data: { ...version.data,
|
|
5862
|
+
data: { ...version.data, status: "draft" },
|
|
5886
5863
|
tenantID: ctxTenantID
|
|
5887
5864
|
});
|
|
5888
5865
|
return c.json({
|
|
@@ -5927,7 +5904,7 @@ function createHonoApp(options) {
|
|
|
5927
5904
|
const doc = await db.update({
|
|
5928
5905
|
collection: slug,
|
|
5929
5906
|
id: c.req.param("id"),
|
|
5930
|
-
data: { ...version.data,
|
|
5907
|
+
data: { ...version.data, status: "draft" },
|
|
5931
5908
|
tenantID: ctxTenantID
|
|
5932
5909
|
});
|
|
5933
5910
|
return c.json({
|
|
@@ -5978,9 +5955,9 @@ function createHonoApp(options) {
|
|
|
5978
5955
|
if (baseUpdatedAt && originalDoc.updatedAt && baseUpdatedAt !== originalDoc.updatedAt) {
|
|
5979
5956
|
return c.json(buildConflictResponse(baseUpdatedAt, originalDoc), 409);
|
|
5980
5957
|
}
|
|
5981
|
-
let publishData = {
|
|
5958
|
+
let publishData = { status: "published" };
|
|
5982
5959
|
let finalContent = originalDoc;
|
|
5983
|
-
if (
|
|
5960
|
+
if (collection.versions?.drafts) {
|
|
5984
5961
|
const versions = await db.findVersions({
|
|
5985
5962
|
collection: slug,
|
|
5986
5963
|
documentId: id,
|
|
@@ -5988,9 +5965,10 @@ function createHonoApp(options) {
|
|
|
5988
5965
|
sort: "-createdAt",
|
|
5989
5966
|
tenantID: ctxTenantID
|
|
5990
5967
|
});
|
|
5991
|
-
if (versions.docs.length > 0
|
|
5992
|
-
|
|
5993
|
-
|
|
5968
|
+
if (versions.docs.length > 0) {
|
|
5969
|
+
const latestVersion = versions.docs[0];
|
|
5970
|
+
finalContent = { ...originalDoc, ...latestVersion.data };
|
|
5971
|
+
publishData = { ...latestVersion.data, ...publishData };
|
|
5994
5972
|
}
|
|
5995
5973
|
}
|
|
5996
5974
|
const doc = await db.update({
|
|
@@ -6003,18 +5981,13 @@ function createHonoApp(options) {
|
|
|
6003
5981
|
await db.createVersion({
|
|
6004
5982
|
collection: slug,
|
|
6005
5983
|
documentId: id,
|
|
6006
|
-
data: { ...finalContent,
|
|
5984
|
+
data: { ...finalContent, status: "published" },
|
|
6007
5985
|
status: "published",
|
|
6008
5986
|
createdBy: ctxUser?.id,
|
|
6009
5987
|
changeDescription: "Published",
|
|
6010
5988
|
tenantID: ctxTenantID
|
|
6011
5989
|
});
|
|
6012
5990
|
}
|
|
6013
|
-
await db.deleteDraft({
|
|
6014
|
-
collection: slug,
|
|
6015
|
-
documentId: id,
|
|
6016
|
-
tenantID: ctxTenantID
|
|
6017
|
-
});
|
|
6018
5991
|
if (webhookService) {
|
|
6019
5992
|
webhookService.trigger(getWebhookEvent(slug, "update"), {
|
|
6020
5993
|
collection: slug,
|
|
@@ -6062,7 +6035,7 @@ function createHonoApp(options) {
|
|
|
6062
6035
|
const doc = await db.update({
|
|
6063
6036
|
collection: slug,
|
|
6064
6037
|
id,
|
|
6065
|
-
data: {
|
|
6038
|
+
data: { status: "draft" },
|
|
6066
6039
|
tenantID: ctxTenantID
|
|
6067
6040
|
});
|
|
6068
6041
|
if (webhookService) {
|
|
@@ -6097,7 +6070,7 @@ function createHonoApp(options) {
|
|
|
6097
6070
|
if (!access.allowed) {
|
|
6098
6071
|
return c.json({ error: access.error }, access.status || 403);
|
|
6099
6072
|
}
|
|
6100
|
-
const isDraftRequest =
|
|
6073
|
+
const isDraftRequest = !!ctxUser;
|
|
6101
6074
|
let doc = await db.findOne({
|
|
6102
6075
|
collection: `_globals_${slug}`,
|
|
6103
6076
|
where: {},
|
|
@@ -6145,23 +6118,16 @@ function createHonoApp(options) {
|
|
|
6145
6118
|
const cleaned = Object.fromEntries(
|
|
6146
6119
|
Object.entries(body).filter(([_, v]) => v !== null && v !== "null" && v !== void 0)
|
|
6147
6120
|
);
|
|
6148
|
-
|
|
6149
|
-
if (field.name && cleaned[field.name] === "") {
|
|
6150
|
-
const isTextual = field.type === "text" || field.type === "textarea" || field.type === "code" || field.type === "markdown" || field.type === "email" || field.type === "password" || field.type === "color";
|
|
6151
|
-
if (!isTextual) {
|
|
6152
|
-
cleaned[field.name] = null;
|
|
6153
|
-
}
|
|
6154
|
-
}
|
|
6155
|
-
}
|
|
6121
|
+
normalizeEmptyStrings(cleaned, globalConfig.fields);
|
|
6156
6122
|
convertRichtextFields(globalConfig.fields, cleaned);
|
|
6157
|
-
const schema = registry.
|
|
6123
|
+
const schema = registry.getUpdateZodSchema(slug);
|
|
6158
6124
|
let validated;
|
|
6159
6125
|
try {
|
|
6160
6126
|
validated = schema.parse(cleaned);
|
|
6161
6127
|
} catch (zodErr) {
|
|
6162
6128
|
return c.json({ error: `Validation failed: ${formatZodErrors(zodErr.errors)}`, details: zodErr.errors }, 400);
|
|
6163
6129
|
}
|
|
6164
|
-
const SYSTEM_FIELDS = /* @__PURE__ */ new Set(["id", "createdAt", "updatedAt", "
|
|
6130
|
+
const SYSTEM_FIELDS = /* @__PURE__ */ new Set(["id", "createdAt", "updatedAt", "status", "baseUpdatedAt", "_baseUpdatedAt"]);
|
|
6165
6131
|
const userData = Object.fromEntries(
|
|
6166
6132
|
Object.entries(validated).filter(([k]) => !SYSTEM_FIELDS.has(k))
|
|
6167
6133
|
);
|
|
@@ -6172,49 +6138,68 @@ function createHonoApp(options) {
|
|
|
6172
6138
|
tenantID: ctxTenantID,
|
|
6173
6139
|
draft: true
|
|
6174
6140
|
});
|
|
6141
|
+
const isDraft = c.req.header("X-Draft") === "true";
|
|
6175
6142
|
const isDraftEnabled = globalConfig.versions?.drafts === true;
|
|
6176
|
-
const
|
|
6143
|
+
const isAutosave = c.req.query("autosave") === "true";
|
|
6177
6144
|
let doc;
|
|
6178
|
-
if (isDraftEnabled &&
|
|
6145
|
+
if (isDraftEnabled && isDraft) {
|
|
6179
6146
|
await db.createVersion({
|
|
6180
6147
|
collection: collectionSlug,
|
|
6181
6148
|
documentId: slug,
|
|
6182
6149
|
data: userData,
|
|
6183
6150
|
status: "draft",
|
|
6151
|
+
autosave: isAutosave,
|
|
6184
6152
|
createdBy: ctxUser?.id,
|
|
6185
|
-
changeDescription: "Manual save
|
|
6153
|
+
changeDescription: isAutosave ? "Autosave" : "Manual save",
|
|
6186
6154
|
tenantID: ctxTenantID
|
|
6187
6155
|
});
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6156
|
+
if (!originalDoc) {
|
|
6157
|
+
doc = await db.create({
|
|
6158
|
+
collection: collectionSlug,
|
|
6159
|
+
data: { ...userData, id: slug, status: "draft" },
|
|
6160
|
+
tenantID: ctxTenantID
|
|
6161
|
+
});
|
|
6162
|
+
} else {
|
|
6163
|
+
doc = originalDoc;
|
|
6164
|
+
}
|
|
6165
|
+
} else if (isDraftEnabled && !isDraft) {
|
|
6166
|
+
const publishStatus = "published";
|
|
6196
6167
|
if (originalDoc) {
|
|
6197
6168
|
doc = await db.update({
|
|
6198
6169
|
collection: collectionSlug,
|
|
6199
6170
|
id: slug,
|
|
6200
|
-
data:
|
|
6171
|
+
data: { ...userData, status: publishStatus },
|
|
6201
6172
|
tenantID: ctxTenantID
|
|
6202
6173
|
});
|
|
6203
6174
|
} else {
|
|
6204
6175
|
doc = await db.create({
|
|
6205
6176
|
collection: collectionSlug,
|
|
6206
|
-
data: { ...
|
|
6177
|
+
data: { ...userData, id: slug, status: publishStatus },
|
|
6207
6178
|
tenantID: ctxTenantID
|
|
6208
6179
|
});
|
|
6209
6180
|
}
|
|
6210
|
-
|
|
6211
|
-
|
|
6181
|
+
await db.createVersion({
|
|
6182
|
+
collection: collectionSlug,
|
|
6183
|
+
documentId: slug,
|
|
6184
|
+
data: userData,
|
|
6185
|
+
status: publishStatus,
|
|
6186
|
+
autosave: false,
|
|
6187
|
+
createdBy: ctxUser?.id,
|
|
6188
|
+
changeDescription: "Published",
|
|
6189
|
+
tenantID: ctxTenantID
|
|
6190
|
+
});
|
|
6191
|
+
} else {
|
|
6192
|
+
if (originalDoc) {
|
|
6193
|
+
doc = await db.update({
|
|
6212
6194
|
collection: collectionSlug,
|
|
6213
|
-
|
|
6195
|
+
id: slug,
|
|
6214
6196
|
data: userData,
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6197
|
+
tenantID: ctxTenantID
|
|
6198
|
+
});
|
|
6199
|
+
} else {
|
|
6200
|
+
doc = await db.create({
|
|
6201
|
+
collection: collectionSlug,
|
|
6202
|
+
data: { ...userData, id: slug },
|
|
6218
6203
|
tenantID: ctxTenantID
|
|
6219
6204
|
});
|
|
6220
6205
|
}
|
|
@@ -6223,6 +6208,13 @@ function createHonoApp(options) {
|
|
|
6223
6208
|
mediaService = null;
|
|
6224
6209
|
mediaServiceInitError = null;
|
|
6225
6210
|
}
|
|
6211
|
+
if (slug === "email-settings") {
|
|
6212
|
+
const newEmailTransport = await EmailTransport.fromConfig(db);
|
|
6213
|
+
authRoutes.email = newEmailTransport || void 0;
|
|
6214
|
+
}
|
|
6215
|
+
if (slug === "system") {
|
|
6216
|
+
await loadSecrets();
|
|
6217
|
+
}
|
|
6226
6218
|
if (ctxUser) {
|
|
6227
6219
|
sessionAuthAdapter?.createAuditLog({
|
|
6228
6220
|
action: "settings_change",
|
|
@@ -6256,9 +6248,9 @@ function createHonoApp(options) {
|
|
|
6256
6248
|
draft: true
|
|
6257
6249
|
});
|
|
6258
6250
|
if (!originalDoc) return c.json({ error: "Global not found" }, 404);
|
|
6259
|
-
let publishData = {
|
|
6251
|
+
let publishData = { status: "published" };
|
|
6260
6252
|
let finalContent = originalDoc;
|
|
6261
|
-
if (
|
|
6253
|
+
if (globalConfig.versions?.drafts) {
|
|
6262
6254
|
const versions = await db.findVersions({
|
|
6263
6255
|
collection: collectionSlug,
|
|
6264
6256
|
documentId: slug,
|
|
@@ -6266,7 +6258,7 @@ function createHonoApp(options) {
|
|
|
6266
6258
|
sort: "-createdAt",
|
|
6267
6259
|
tenantID: ctxTenantID
|
|
6268
6260
|
});
|
|
6269
|
-
if (versions.docs.length > 0
|
|
6261
|
+
if (versions.docs.length > 0) {
|
|
6270
6262
|
finalContent = { ...originalDoc, ...versions.docs[0].data };
|
|
6271
6263
|
publishData = { ...versions.docs[0].data, ...publishData };
|
|
6272
6264
|
}
|
|
@@ -6281,7 +6273,7 @@ function createHonoApp(options) {
|
|
|
6281
6273
|
await db.createVersion({
|
|
6282
6274
|
collection: collectionSlug,
|
|
6283
6275
|
documentId: slug,
|
|
6284
|
-
data: { ...finalContent,
|
|
6276
|
+
data: { ...finalContent, status: "published" },
|
|
6285
6277
|
status: "published",
|
|
6286
6278
|
createdBy: ctxUser?.id,
|
|
6287
6279
|
changeDescription: "Published",
|
|
@@ -6301,7 +6293,7 @@ function createHonoApp(options) {
|
|
|
6301
6293
|
const doc = await db.update({
|
|
6302
6294
|
collection: `_globals_${slug}`,
|
|
6303
6295
|
id: slug,
|
|
6304
|
-
data: {
|
|
6296
|
+
data: { status: "draft" },
|
|
6305
6297
|
tenantID: ctxTenantID
|
|
6306
6298
|
});
|
|
6307
6299
|
return c.json({ data: doc, message: "Unpublished successfully" });
|
|
@@ -6361,9 +6353,13 @@ function createHonoApp(options) {
|
|
|
6361
6353
|
const doc = await db.update({
|
|
6362
6354
|
collection: collectionSlug,
|
|
6363
6355
|
id: slug,
|
|
6364
|
-
data: { ...version.data,
|
|
6356
|
+
data: { ...version.data, status: "draft" },
|
|
6365
6357
|
tenantID: ctxTenantID
|
|
6366
6358
|
});
|
|
6359
|
+
return c.json({
|
|
6360
|
+
data: doc,
|
|
6361
|
+
message: "Version restored successfully"
|
|
6362
|
+
});
|
|
6367
6363
|
return c.json({ data: doc, message: "Restored successfully" });
|
|
6368
6364
|
} catch (error) {
|
|
6369
6365
|
return c.json({ error: error.message }, 500);
|
|
@@ -6466,5 +6462,5 @@ function createRESTAPI(registry, db, options) {
|
|
|
6466
6462
|
}
|
|
6467
6463
|
|
|
6468
6464
|
export { AuditLogger, AuthRoutes, InMemoryAuditLogger, InMemoryRateLimiter, MediaService, createAuditContext2 as createAuditContext, createCloudinaryStorage, createFtpStorage, createHonoApp, createLocalStorage, createRESTAPI, createS3Storage, getAppSecret, getDefaultRegistry, getEncryptionKey, getSessionConfig, init_secret, loadSecrets, resolveProvider, setDbAdapter };
|
|
6469
|
-
//# sourceMappingURL=chunk-
|
|
6470
|
-
//# sourceMappingURL=chunk-
|
|
6465
|
+
//# sourceMappingURL=chunk-IPTZM3VE.js.map
|
|
6466
|
+
//# sourceMappingURL=chunk-IPTZM3VE.js.map
|