@sonicjs-cms/core 2.0.0-beta.3 → 2.0.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.
Files changed (55) hide show
  1. package/dist/{chunk-4MZPFGLT.cjs → chunk-5FDDDD4J.cjs} +4385 -352
  2. package/dist/chunk-5FDDDD4J.cjs.map +1 -0
  3. package/dist/chunk-5XTB4FE5.js +1030 -0
  4. package/dist/chunk-5XTB4FE5.js.map +1 -0
  5. package/dist/{chunk-ET5I4GBD.cjs → chunk-ALOS2CBJ.cjs} +194 -4
  6. package/dist/chunk-ALOS2CBJ.cjs.map +1 -0
  7. package/dist/{chunk-7N3HK7ZK.js → chunk-CDBVZEWR.js} +7 -904
  8. package/dist/chunk-CDBVZEWR.js.map +1 -0
  9. package/dist/chunk-EGFHFM4N.cjs +76 -0
  10. package/dist/chunk-EGFHFM4N.cjs.map +1 -0
  11. package/dist/chunk-KM4AJFXI.cjs +101 -0
  12. package/dist/chunk-KM4AJFXI.cjs.map +1 -0
  13. package/dist/{chunk-RNR4HA23.cjs → chunk-LEG4KNFP.cjs} +6 -945
  14. package/dist/chunk-LEG4KNFP.cjs.map +1 -0
  15. package/dist/{chunk-P3VS4DV3.js → chunk-O46XKBFM.js} +193 -5
  16. package/dist/chunk-O46XKBFM.js.map +1 -0
  17. package/dist/chunk-P2PTTBO5.js +74 -0
  18. package/dist/chunk-P2PTTBO5.js.map +1 -0
  19. package/dist/{chunk-Q3KCKPHE.js → chunk-QSF34IYQ.js} +4244 -214
  20. package/dist/chunk-QSF34IYQ.js.map +1 -0
  21. package/dist/chunk-SRCY43RN.cjs +1076 -0
  22. package/dist/chunk-SRCY43RN.cjs.map +1 -0
  23. package/dist/chunk-TY3NHEBN.js +80 -0
  24. package/dist/chunk-TY3NHEBN.js.map +1 -0
  25. package/dist/index.cjs +196 -196
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.js +9 -9
  28. package/dist/index.js.map +1 -1
  29. package/dist/middleware.cjs +22 -22
  30. package/dist/middleware.js +2 -2
  31. package/dist/routes.cjs +34 -22
  32. package/dist/routes.js +5 -5
  33. package/dist/services.cjs +28 -28
  34. package/dist/services.js +2 -2
  35. package/dist/templates.cjs +24 -24
  36. package/dist/templates.js +2 -2
  37. package/package.json +2 -16
  38. package/dist/chunk-3MNMOLSA.js +0 -133
  39. package/dist/chunk-3MNMOLSA.js.map +0 -1
  40. package/dist/chunk-4MZPFGLT.cjs.map +0 -1
  41. package/dist/chunk-4XI3YBKU.cjs +0 -266
  42. package/dist/chunk-4XI3YBKU.cjs.map +0 -1
  43. package/dist/chunk-7N3HK7ZK.js.map +0 -1
  44. package/dist/chunk-AGOE25LF.cjs +0 -137
  45. package/dist/chunk-AGOE25LF.cjs.map +0 -1
  46. package/dist/chunk-BUKT6HP5.cjs +0 -776
  47. package/dist/chunk-BUKT6HP5.cjs.map +0 -1
  48. package/dist/chunk-ET5I4GBD.cjs.map +0 -1
  49. package/dist/chunk-LU6J53IX.js +0 -262
  50. package/dist/chunk-LU6J53IX.js.map +0 -1
  51. package/dist/chunk-P3VS4DV3.js.map +0 -1
  52. package/dist/chunk-Q3KCKPHE.js.map +0 -1
  53. package/dist/chunk-RNR4HA23.cjs.map +0 -1
  54. package/dist/chunk-WESS2U3K.js +0 -755
  55. package/dist/chunk-WESS2U3K.js.map +0 -1
@@ -1,12 +1,6 @@
1
- import { __export } from './chunk-V4OQ3NZ2.js';
2
- import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
3
- import { z } from 'zod/v4';
4
- import { getTableColumns, getViewSelectedFields, isTable, is, Column, SQL, isView, inArray, eq, like, gte, lte, and, count, asc, desc } from 'drizzle-orm';
5
- import { drizzle } from 'drizzle-orm/d1';
6
-
7
1
  // src/services/collection-loader.ts
8
2
  async function loadCollectionConfigs() {
9
- const collections2 = [];
3
+ const collections = [];
10
4
  try {
11
5
  const modules = import.meta.glob?.("../collections/*.collection.ts", { eager: true }) || {};
12
6
  for (const [path, module] of Object.entries(modules)) {
@@ -26,14 +20,14 @@ async function loadCollectionConfigs() {
26
20
  managed: config.managed !== void 0 ? config.managed : true,
27
21
  isActive: config.isActive !== void 0 ? config.isActive : true
28
22
  };
29
- collections2.push(normalizedConfig);
23
+ collections.push(normalizedConfig);
30
24
  console.log(`\u2713 Loaded collection config: ${config.name}`);
31
25
  } catch (error) {
32
26
  console.error(`Error loading collection from ${path}:`, error);
33
27
  }
34
28
  }
35
- console.log(`Loaded ${collections2.length} collection configuration(s)`);
36
- return collections2;
29
+ console.log(`Loaded ${collections.length} collection configuration(s)`);
30
+ return collections;
37
31
  } catch (error) {
38
32
  console.error("Error loading collection configurations:", error);
39
33
  return [];
@@ -981,897 +975,6 @@ INSERT OR IGNORE INTO content (
981
975
  }
982
976
  };
983
977
 
984
- // src/db/schema.ts
985
- var schema_exports = {};
986
- __export(schema_exports, {
987
- apiTokens: () => apiTokens,
988
- collections: () => collections,
989
- content: () => content,
990
- contentVersions: () => contentVersions,
991
- insertCollectionSchema: () => insertCollectionSchema,
992
- insertContentSchema: () => insertContentSchema,
993
- insertLogConfigSchema: () => insertLogConfigSchema,
994
- insertMediaSchema: () => insertMediaSchema,
995
- insertPluginActivityLogSchema: () => insertPluginActivityLogSchema,
996
- insertPluginAssetSchema: () => insertPluginAssetSchema,
997
- insertPluginHookSchema: () => insertPluginHookSchema,
998
- insertPluginRouteSchema: () => insertPluginRouteSchema,
999
- insertPluginSchema: () => insertPluginSchema,
1000
- insertSystemLogSchema: () => insertSystemLogSchema,
1001
- insertUserSchema: () => insertUserSchema,
1002
- insertWorkflowHistorySchema: () => insertWorkflowHistorySchema,
1003
- logConfig: () => logConfig,
1004
- media: () => media,
1005
- pluginActivityLog: () => pluginActivityLog,
1006
- pluginAssets: () => pluginAssets,
1007
- pluginHooks: () => pluginHooks,
1008
- pluginRoutes: () => pluginRoutes,
1009
- plugins: () => plugins,
1010
- selectCollectionSchema: () => selectCollectionSchema,
1011
- selectContentSchema: () => selectContentSchema,
1012
- selectLogConfigSchema: () => selectLogConfigSchema,
1013
- selectMediaSchema: () => selectMediaSchema,
1014
- selectPluginActivityLogSchema: () => selectPluginActivityLogSchema,
1015
- selectPluginAssetSchema: () => selectPluginAssetSchema,
1016
- selectPluginHookSchema: () => selectPluginHookSchema,
1017
- selectPluginRouteSchema: () => selectPluginRouteSchema,
1018
- selectPluginSchema: () => selectPluginSchema,
1019
- selectSystemLogSchema: () => selectSystemLogSchema,
1020
- selectUserSchema: () => selectUserSchema,
1021
- selectWorkflowHistorySchema: () => selectWorkflowHistorySchema,
1022
- systemLogs: () => systemLogs,
1023
- users: () => users,
1024
- workflowHistory: () => workflowHistory
1025
- });
1026
- var CONSTANTS = {
1027
- INT8_MIN: -128,
1028
- INT8_MAX: 127,
1029
- INT8_UNSIGNED_MAX: 255,
1030
- INT16_MIN: -32768,
1031
- INT16_MAX: 32767,
1032
- INT16_UNSIGNED_MAX: 65535,
1033
- INT24_MIN: -8388608,
1034
- INT24_MAX: 8388607,
1035
- INT24_UNSIGNED_MAX: 16777215,
1036
- INT32_MIN: -2147483648,
1037
- INT32_MAX: 2147483647,
1038
- INT32_UNSIGNED_MAX: 4294967295,
1039
- INT48_MIN: -140737488355328,
1040
- INT48_MAX: 140737488355327,
1041
- INT48_UNSIGNED_MAX: 281474976710655,
1042
- INT64_MIN: -9223372036854775808n,
1043
- INT64_MAX: 9223372036854775807n,
1044
- INT64_UNSIGNED_MAX: 18446744073709551615n
1045
- };
1046
- function isColumnType(column, columnTypes) {
1047
- return columnTypes.includes(column.columnType);
1048
- }
1049
- function isWithEnum(column) {
1050
- return "enumValues" in column && Array.isArray(column.enumValues) && column.enumValues.length > 0;
1051
- }
1052
- var isPgEnum = isWithEnum;
1053
- var literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
1054
- var jsonSchema = z.union([
1055
- literalSchema,
1056
- z.record(z.string(), z.any()),
1057
- z.array(z.any())
1058
- ]);
1059
- var bufferSchema = z.custom((v) => v instanceof Buffer);
1060
- function columnToSchema(column, factory) {
1061
- const z$1 = z;
1062
- const coerce = {};
1063
- let schema;
1064
- if (isWithEnum(column)) {
1065
- schema = column.enumValues.length ? z$1.enum(column.enumValues) : z$1.string();
1066
- }
1067
- if (!schema) {
1068
- if (isColumnType(column, ["PgGeometry", "PgPointTuple"])) {
1069
- schema = z$1.tuple([z$1.number(), z$1.number()]);
1070
- } else if (isColumnType(column, ["PgGeometryObject", "PgPointObject"])) {
1071
- schema = z$1.object({ x: z$1.number(), y: z$1.number() });
1072
- } else if (isColumnType(column, ["PgHalfVector", "PgVector"])) {
1073
- schema = z$1.array(z$1.number());
1074
- schema = column.dimensions ? schema.length(column.dimensions) : schema;
1075
- } else if (isColumnType(column, ["PgLine"])) {
1076
- schema = z$1.tuple([z$1.number(), z$1.number(), z$1.number()]);
1077
- } else if (isColumnType(column, ["PgLineABC"])) {
1078
- schema = z$1.object({
1079
- a: z$1.number(),
1080
- b: z$1.number(),
1081
- c: z$1.number()
1082
- });
1083
- } else if (isColumnType(column, ["PgArray"])) {
1084
- schema = z$1.array(columnToSchema(column.baseColumn));
1085
- schema = column.size ? schema.length(column.size) : schema;
1086
- } else if (column.dataType === "array") {
1087
- schema = z$1.array(z$1.any());
1088
- } else if (column.dataType === "number") {
1089
- schema = numberColumnToSchema(column, z$1, coerce);
1090
- } else if (column.dataType === "bigint") {
1091
- schema = bigintColumnToSchema(column, z$1, coerce);
1092
- } else if (column.dataType === "boolean") {
1093
- schema = coerce === true || coerce.boolean ? z$1.coerce.boolean() : z$1.boolean();
1094
- } else if (column.dataType === "date") {
1095
- schema = coerce === true || coerce.date ? z$1.coerce.date() : z$1.date();
1096
- } else if (column.dataType === "string") {
1097
- schema = stringColumnToSchema(column, z$1, coerce);
1098
- } else if (column.dataType === "json") {
1099
- schema = jsonSchema;
1100
- } else if (column.dataType === "custom") {
1101
- schema = z$1.any();
1102
- } else if (column.dataType === "buffer") {
1103
- schema = bufferSchema;
1104
- }
1105
- }
1106
- if (!schema) {
1107
- schema = z$1.any();
1108
- }
1109
- return schema;
1110
- }
1111
- function numberColumnToSchema(column, z2, coerce) {
1112
- let unsigned = column.getSQLType().includes("unsigned");
1113
- let min;
1114
- let max;
1115
- let integer2 = false;
1116
- if (isColumnType(column, ["MySqlTinyInt", "SingleStoreTinyInt"])) {
1117
- min = unsigned ? 0 : CONSTANTS.INT8_MIN;
1118
- max = unsigned ? CONSTANTS.INT8_UNSIGNED_MAX : CONSTANTS.INT8_MAX;
1119
- integer2 = true;
1120
- } else if (isColumnType(column, [
1121
- "PgSmallInt",
1122
- "PgSmallSerial",
1123
- "MySqlSmallInt",
1124
- "SingleStoreSmallInt"
1125
- ])) {
1126
- min = unsigned ? 0 : CONSTANTS.INT16_MIN;
1127
- max = unsigned ? CONSTANTS.INT16_UNSIGNED_MAX : CONSTANTS.INT16_MAX;
1128
- integer2 = true;
1129
- } else if (isColumnType(column, [
1130
- "PgReal",
1131
- "MySqlFloat",
1132
- "MySqlMediumInt",
1133
- "SingleStoreMediumInt",
1134
- "SingleStoreFloat"
1135
- ])) {
1136
- min = unsigned ? 0 : CONSTANTS.INT24_MIN;
1137
- max = unsigned ? CONSTANTS.INT24_UNSIGNED_MAX : CONSTANTS.INT24_MAX;
1138
- integer2 = isColumnType(column, ["MySqlMediumInt", "SingleStoreMediumInt"]);
1139
- } else if (isColumnType(column, [
1140
- "PgInteger",
1141
- "PgSerial",
1142
- "MySqlInt",
1143
- "SingleStoreInt"
1144
- ])) {
1145
- min = unsigned ? 0 : CONSTANTS.INT32_MIN;
1146
- max = unsigned ? CONSTANTS.INT32_UNSIGNED_MAX : CONSTANTS.INT32_MAX;
1147
- integer2 = true;
1148
- } else if (isColumnType(column, [
1149
- "PgDoublePrecision",
1150
- "MySqlReal",
1151
- "MySqlDouble",
1152
- "SingleStoreReal",
1153
- "SingleStoreDouble",
1154
- "SQLiteReal"
1155
- ])) {
1156
- min = unsigned ? 0 : CONSTANTS.INT48_MIN;
1157
- max = unsigned ? CONSTANTS.INT48_UNSIGNED_MAX : CONSTANTS.INT48_MAX;
1158
- } else if (isColumnType(column, [
1159
- "PgBigInt53",
1160
- "PgBigSerial53",
1161
- "MySqlBigInt53",
1162
- "MySqlSerial",
1163
- "SingleStoreBigInt53",
1164
- "SingleStoreSerial",
1165
- "SQLiteInteger"
1166
- ])) {
1167
- unsigned = unsigned || isColumnType(column, ["MySqlSerial", "SingleStoreSerial"]);
1168
- min = unsigned ? 0 : Number.MIN_SAFE_INTEGER;
1169
- max = Number.MAX_SAFE_INTEGER;
1170
- integer2 = true;
1171
- } else if (isColumnType(column, ["MySqlYear", "SingleStoreYear"])) {
1172
- min = 1901;
1173
- max = 2155;
1174
- integer2 = true;
1175
- } else {
1176
- min = Number.MIN_SAFE_INTEGER;
1177
- max = Number.MAX_SAFE_INTEGER;
1178
- }
1179
- let schema = coerce === true || coerce?.number ? integer2 ? z2.coerce.number() : z2.coerce.number().int() : integer2 ? z2.int() : z2.number();
1180
- schema = schema.gte(min).lte(max);
1181
- return schema;
1182
- }
1183
- function bigintColumnToSchema(column, z2, coerce) {
1184
- const unsigned = column.getSQLType().includes("unsigned");
1185
- const min = unsigned ? 0n : CONSTANTS.INT64_MIN;
1186
- const max = unsigned ? CONSTANTS.INT64_UNSIGNED_MAX : CONSTANTS.INT64_MAX;
1187
- const schema = coerce === true || coerce?.bigint ? z2.coerce.bigint() : z2.bigint();
1188
- return schema.gte(min).lte(max);
1189
- }
1190
- function stringColumnToSchema(column, z2, coerce) {
1191
- if (isColumnType(column, ["PgUUID"])) {
1192
- return z2.uuid();
1193
- }
1194
- let max;
1195
- let regex;
1196
- let fixed = false;
1197
- if (isColumnType(column, ["PgVarchar", "SQLiteText"])) {
1198
- max = column.length;
1199
- } else if (isColumnType(column, ["MySqlVarChar", "SingleStoreVarChar"])) {
1200
- max = column.length ?? CONSTANTS.INT16_UNSIGNED_MAX;
1201
- } else if (isColumnType(column, ["MySqlText", "SingleStoreText"])) {
1202
- if (column.textType === "longtext") {
1203
- max = CONSTANTS.INT32_UNSIGNED_MAX;
1204
- } else if (column.textType === "mediumtext") {
1205
- max = CONSTANTS.INT24_UNSIGNED_MAX;
1206
- } else if (column.textType === "text") {
1207
- max = CONSTANTS.INT16_UNSIGNED_MAX;
1208
- } else {
1209
- max = CONSTANTS.INT8_UNSIGNED_MAX;
1210
- }
1211
- }
1212
- if (isColumnType(column, [
1213
- "PgChar",
1214
- "MySqlChar",
1215
- "SingleStoreChar"
1216
- ])) {
1217
- max = column.length;
1218
- fixed = true;
1219
- }
1220
- if (isColumnType(column, ["PgBinaryVector"])) {
1221
- regex = /^[01]+$/;
1222
- max = column.dimensions;
1223
- }
1224
- let schema = coerce === true || coerce?.string ? z2.coerce.string() : z2.string();
1225
- schema = regex ? schema.regex(regex) : schema;
1226
- return max && fixed ? schema.length(max) : max ? schema.max(max) : schema;
1227
- }
1228
- function getColumns(tableLike) {
1229
- return isTable(tableLike) ? getTableColumns(tableLike) : getViewSelectedFields(tableLike);
1230
- }
1231
- function handleColumns(columns, refinements, conditions, factory) {
1232
- const columnSchemas = {};
1233
- for (const [key, selected] of Object.entries(columns)) {
1234
- if (!is(selected, Column) && !is(selected, SQL) && !is(selected, SQL.Aliased) && typeof selected === "object") {
1235
- const columns2 = isTable(selected) || isView(selected) ? getColumns(selected) : selected;
1236
- columnSchemas[key] = handleColumns(columns2, refinements[key] ?? {}, conditions);
1237
- continue;
1238
- }
1239
- const refinement = refinements[key];
1240
- if (refinement !== void 0 && typeof refinement !== "function") {
1241
- columnSchemas[key] = refinement;
1242
- continue;
1243
- }
1244
- const column = is(selected, Column) ? selected : void 0;
1245
- const schema = column ? columnToSchema(column) : z.any();
1246
- const refined = typeof refinement === "function" ? refinement(schema) : schema;
1247
- if (conditions.never(column)) {
1248
- continue;
1249
- } else {
1250
- columnSchemas[key] = refined;
1251
- }
1252
- if (column) {
1253
- if (conditions.nullable(column)) {
1254
- columnSchemas[key] = columnSchemas[key].nullable();
1255
- }
1256
- if (conditions.optional(column)) {
1257
- columnSchemas[key] = columnSchemas[key].optional();
1258
- }
1259
- }
1260
- }
1261
- return z.object(columnSchemas);
1262
- }
1263
- function handleEnum(enum_, factory) {
1264
- const zod = z;
1265
- return zod.enum(enum_.enumValues);
1266
- }
1267
- var selectConditions = {
1268
- never: () => false,
1269
- optional: () => false,
1270
- nullable: (column) => !column.notNull
1271
- };
1272
- var insertConditions = {
1273
- never: (column) => column?.generated?.type === "always" || column?.generatedIdentity?.type === "always",
1274
- optional: (column) => !column.notNull || column.notNull && column.hasDefault,
1275
- nullable: (column) => !column.notNull
1276
- };
1277
- var createSelectSchema = (entity, refine) => {
1278
- if (isPgEnum(entity)) {
1279
- return handleEnum(entity);
1280
- }
1281
- const columns = getColumns(entity);
1282
- return handleColumns(columns, {}, selectConditions);
1283
- };
1284
- var createInsertSchema = (entity, refine) => {
1285
- const columns = getColumns(entity);
1286
- return handleColumns(columns, refine ?? {}, insertConditions);
1287
- };
1288
-
1289
- // src/db/schema.ts
1290
- var users = sqliteTable("users", {
1291
- id: text("id").primaryKey(),
1292
- email: text("email").notNull().unique(),
1293
- username: text("username").notNull().unique(),
1294
- firstName: text("first_name").notNull(),
1295
- lastName: text("last_name").notNull(),
1296
- passwordHash: text("password_hash"),
1297
- // Hashed password, nullable for OAuth users
1298
- role: text("role").notNull().default("viewer"),
1299
- // 'admin', 'editor', 'author', 'viewer'
1300
- avatar: text("avatar"),
1301
- isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
1302
- lastLoginAt: integer("last_login_at"),
1303
- createdAt: integer("created_at").notNull(),
1304
- updatedAt: integer("updated_at").notNull()
1305
- });
1306
- var collections = sqliteTable("collections", {
1307
- id: text("id").primaryKey(),
1308
- name: text("name").notNull().unique(),
1309
- displayName: text("display_name").notNull(),
1310
- description: text("description"),
1311
- schema: text("schema", { mode: "json" }).notNull(),
1312
- // JSON schema definition
1313
- isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
1314
- managed: integer("managed", { mode: "boolean" }).notNull().default(false),
1315
- // Config-managed collections cannot be edited in UI
1316
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
1317
- updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
1318
- });
1319
- var content = sqliteTable("content", {
1320
- id: text("id").primaryKey(),
1321
- collectionId: text("collection_id").notNull().references(() => collections.id),
1322
- slug: text("slug").notNull(),
1323
- title: text("title").notNull(),
1324
- data: text("data", { mode: "json" }).notNull(),
1325
- // JSON content data
1326
- status: text("status").notNull().default("draft"),
1327
- // 'draft', 'published', 'archived'
1328
- publishedAt: integer("published_at", { mode: "timestamp" }),
1329
- authorId: text("author_id").notNull().references(() => users.id),
1330
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
1331
- updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
1332
- });
1333
- var contentVersions = sqliteTable("content_versions", {
1334
- id: text("id").primaryKey(),
1335
- contentId: text("content_id").notNull().references(() => content.id),
1336
- version: integer("version").notNull(),
1337
- data: text("data", { mode: "json" }).notNull(),
1338
- authorId: text("author_id").notNull().references(() => users.id),
1339
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
1340
- });
1341
- var media = sqliteTable("media", {
1342
- id: text("id").primaryKey(),
1343
- filename: text("filename").notNull(),
1344
- originalName: text("original_name").notNull(),
1345
- mimeType: text("mime_type").notNull(),
1346
- size: integer("size").notNull(),
1347
- width: integer("width"),
1348
- height: integer("height"),
1349
- folder: text("folder").notNull().default("uploads"),
1350
- r2Key: text("r2_key").notNull(),
1351
- // R2 storage key
1352
- publicUrl: text("public_url").notNull(),
1353
- // CDN URL
1354
- thumbnailUrl: text("thumbnail_url"),
1355
- alt: text("alt"),
1356
- caption: text("caption"),
1357
- tags: text("tags", { mode: "json" }),
1358
- // JSON array of tags
1359
- uploadedBy: text("uploaded_by").notNull().references(() => users.id),
1360
- uploadedAt: integer("uploaded_at").notNull(),
1361
- updatedAt: integer("updated_at"),
1362
- publishedAt: integer("published_at"),
1363
- scheduledAt: integer("scheduled_at"),
1364
- archivedAt: integer("archived_at"),
1365
- deletedAt: integer("deleted_at")
1366
- });
1367
- var apiTokens = sqliteTable("api_tokens", {
1368
- id: text("id").primaryKey(),
1369
- name: text("name").notNull(),
1370
- token: text("token").notNull().unique(),
1371
- userId: text("user_id").notNull().references(() => users.id),
1372
- permissions: text("permissions", { mode: "json" }).notNull(),
1373
- // Array of permissions
1374
- expiresAt: integer("expires_at", { mode: "timestamp" }),
1375
- lastUsedAt: integer("last_used_at", { mode: "timestamp" }),
1376
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
1377
- });
1378
- var workflowHistory = sqliteTable("workflow_history", {
1379
- id: text("id").primaryKey(),
1380
- contentId: text("content_id").notNull().references(() => content.id),
1381
- action: text("action").notNull(),
1382
- fromStatus: text("from_status").notNull(),
1383
- toStatus: text("to_status").notNull(),
1384
- userId: text("user_id").notNull().references(() => users.id),
1385
- comment: text("comment"),
1386
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
1387
- });
1388
- var plugins = sqliteTable("plugins", {
1389
- id: text("id").primaryKey(),
1390
- name: text("name").notNull().unique(),
1391
- displayName: text("display_name").notNull(),
1392
- description: text("description"),
1393
- version: text("version").notNull(),
1394
- author: text("author").notNull(),
1395
- category: text("category").notNull(),
1396
- icon: text("icon"),
1397
- status: text("status").notNull().default("inactive"),
1398
- // 'active', 'inactive', 'error'
1399
- isCore: integer("is_core", { mode: "boolean" }).notNull().default(false),
1400
- settings: text("settings", { mode: "json" }),
1401
- permissions: text("permissions", { mode: "json" }),
1402
- dependencies: text("dependencies", { mode: "json" }),
1403
- downloadCount: integer("download_count").notNull().default(0),
1404
- rating: integer("rating").notNull().default(0),
1405
- installedAt: integer("installed_at").notNull(),
1406
- activatedAt: integer("activated_at"),
1407
- lastUpdated: integer("last_updated").notNull(),
1408
- errorMessage: text("error_message"),
1409
- createdAt: integer("created_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3)),
1410
- updatedAt: integer("updated_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
1411
- });
1412
- var pluginHooks = sqliteTable("plugin_hooks", {
1413
- id: text("id").primaryKey(),
1414
- pluginId: text("plugin_id").notNull().references(() => plugins.id),
1415
- hookName: text("hook_name").notNull(),
1416
- handlerName: text("handler_name").notNull(),
1417
- priority: integer("priority").notNull().default(10),
1418
- isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
1419
- createdAt: integer("created_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
1420
- });
1421
- var pluginRoutes = sqliteTable("plugin_routes", {
1422
- id: text("id").primaryKey(),
1423
- pluginId: text("plugin_id").notNull().references(() => plugins.id),
1424
- path: text("path").notNull(),
1425
- method: text("method").notNull(),
1426
- handlerName: text("handler_name").notNull(),
1427
- middleware: text("middleware", { mode: "json" }),
1428
- isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
1429
- createdAt: integer("created_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
1430
- });
1431
- var pluginAssets = sqliteTable("plugin_assets", {
1432
- id: text("id").primaryKey(),
1433
- pluginId: text("plugin_id").notNull().references(() => plugins.id),
1434
- assetType: text("asset_type").notNull(),
1435
- // 'css', 'js', 'image', 'font'
1436
- assetPath: text("asset_path").notNull(),
1437
- loadOrder: integer("load_order").notNull().default(100),
1438
- loadLocation: text("load_location").notNull().default("footer"),
1439
- // 'header', 'footer'
1440
- isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
1441
- createdAt: integer("created_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
1442
- });
1443
- var pluginActivityLog = sqliteTable("plugin_activity_log", {
1444
- id: text("id").primaryKey(),
1445
- pluginId: text("plugin_id").notNull().references(() => plugins.id),
1446
- action: text("action").notNull(),
1447
- userId: text("user_id"),
1448
- details: text("details", { mode: "json" }),
1449
- timestamp: integer("timestamp").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
1450
- });
1451
- var insertUserSchema = createInsertSchema(users, {
1452
- email: (schema) => schema.email(),
1453
- firstName: (schema) => schema.min(1),
1454
- lastName: (schema) => schema.min(1),
1455
- username: (schema) => schema.min(3)
1456
- });
1457
- var selectUserSchema = createSelectSchema(users);
1458
- var insertCollectionSchema = createInsertSchema(collections, {
1459
- name: (schema) => schema.min(1).regex(/^[a-z0-9_]+$/, "Collection name must be lowercase with underscores"),
1460
- displayName: (schema) => schema.min(1)
1461
- });
1462
- var selectCollectionSchema = createSelectSchema(collections);
1463
- var insertContentSchema = createInsertSchema(content, {
1464
- slug: (schema) => schema.min(1).regex(/^[a-zA-Z0-9_-]+$/, "Slug must contain only letters, numbers, underscores, and hyphens"),
1465
- title: (schema) => schema.min(1),
1466
- status: (schema) => schema
1467
- });
1468
- var selectContentSchema = createSelectSchema(content);
1469
- var insertMediaSchema = createInsertSchema(media, {
1470
- filename: (schema) => schema.min(1),
1471
- originalName: (schema) => schema.min(1),
1472
- mimeType: (schema) => schema.min(1),
1473
- size: (schema) => schema.positive(),
1474
- r2Key: (schema) => schema.min(1),
1475
- publicUrl: (schema) => schema.url(),
1476
- folder: (schema) => schema.min(1)
1477
- });
1478
- var selectMediaSchema = createSelectSchema(media);
1479
- var insertWorkflowHistorySchema = createInsertSchema(workflowHistory, {
1480
- action: (schema) => schema.min(1),
1481
- fromStatus: (schema) => schema.min(1),
1482
- toStatus: (schema) => schema.min(1)
1483
- });
1484
- var selectWorkflowHistorySchema = createSelectSchema(workflowHistory);
1485
- var insertPluginSchema = createInsertSchema(plugins, {
1486
- name: (schema) => schema.min(1),
1487
- displayName: (schema) => schema.min(1),
1488
- version: (schema) => schema.min(1),
1489
- author: (schema) => schema.min(1),
1490
- category: (schema) => schema.min(1)
1491
- });
1492
- var selectPluginSchema = createSelectSchema(plugins);
1493
- var insertPluginHookSchema = createInsertSchema(pluginHooks, {
1494
- hookName: (schema) => schema.min(1),
1495
- handlerName: (schema) => schema.min(1)
1496
- });
1497
- var selectPluginHookSchema = createSelectSchema(pluginHooks);
1498
- var insertPluginRouteSchema = createInsertSchema(pluginRoutes, {
1499
- path: (schema) => schema.min(1),
1500
- method: (schema) => schema.min(1),
1501
- handlerName: (schema) => schema.min(1)
1502
- });
1503
- var selectPluginRouteSchema = createSelectSchema(pluginRoutes);
1504
- var insertPluginAssetSchema = createInsertSchema(pluginAssets, {
1505
- assetType: (schema) => schema.min(1),
1506
- assetPath: (schema) => schema.min(1)
1507
- });
1508
- var selectPluginAssetSchema = createSelectSchema(pluginAssets);
1509
- var insertPluginActivityLogSchema = createInsertSchema(pluginActivityLog, {
1510
- action: (schema) => schema.min(1)
1511
- });
1512
- var selectPluginActivityLogSchema = createSelectSchema(pluginActivityLog);
1513
- var systemLogs = sqliteTable("system_logs", {
1514
- id: text("id").primaryKey(),
1515
- level: text("level").notNull(),
1516
- // 'debug', 'info', 'warn', 'error', 'fatal'
1517
- category: text("category").notNull(),
1518
- // 'auth', 'api', 'workflow', 'plugin', 'media', 'system', etc.
1519
- message: text("message").notNull(),
1520
- data: text("data", { mode: "json" }),
1521
- // Additional structured data
1522
- userId: text("user_id").references(() => users.id),
1523
- sessionId: text("session_id"),
1524
- requestId: text("request_id"),
1525
- ipAddress: text("ip_address"),
1526
- userAgent: text("user_agent"),
1527
- method: text("method"),
1528
- // HTTP method for API logs
1529
- url: text("url"),
1530
- // Request URL for API logs
1531
- statusCode: integer("status_code"),
1532
- // HTTP status code for API logs
1533
- duration: integer("duration"),
1534
- // Request duration in milliseconds
1535
- stackTrace: text("stack_trace"),
1536
- // Error stack trace for error logs
1537
- tags: text("tags", { mode: "json" }),
1538
- // Array of tags for categorization
1539
- source: text("source"),
1540
- // Source component/module that generated the log
1541
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
1542
- });
1543
- var logConfig = sqliteTable("log_config", {
1544
- id: text("id").primaryKey(),
1545
- category: text("category").notNull().unique(),
1546
- enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
1547
- level: text("level").notNull().default("info"),
1548
- // minimum log level to store
1549
- retention: integer("retention").notNull().default(30),
1550
- // days to keep logs
1551
- maxSize: integer("max_size").default(1e4),
1552
- // max number of logs per category
1553
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
1554
- updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
1555
- });
1556
- var insertSystemLogSchema = createInsertSchema(systemLogs, {
1557
- level: (schema) => schema.min(1),
1558
- category: (schema) => schema.min(1),
1559
- message: (schema) => schema.min(1)
1560
- });
1561
- var selectSystemLogSchema = createSelectSchema(systemLogs);
1562
- var insertLogConfigSchema = createInsertSchema(logConfig, {
1563
- category: (schema) => schema.min(1),
1564
- level: (schema) => schema.min(1)
1565
- });
1566
- var selectLogConfigSchema = createSelectSchema(logConfig);
1567
- var Logger = class {
1568
- db;
1569
- enabled = true;
1570
- configCache = /* @__PURE__ */ new Map();
1571
- lastConfigRefresh = 0;
1572
- configRefreshInterval = 6e4;
1573
- // 1 minute
1574
- constructor(database) {
1575
- this.db = drizzle(database);
1576
- }
1577
- /**
1578
- * Log a debug message
1579
- */
1580
- async debug(category, message, data, context) {
1581
- return this.log("debug", category, message, data, context);
1582
- }
1583
- /**
1584
- * Log an info message
1585
- */
1586
- async info(category, message, data, context) {
1587
- return this.log("info", category, message, data, context);
1588
- }
1589
- /**
1590
- * Log a warning message
1591
- */
1592
- async warn(category, message, data, context) {
1593
- return this.log("warn", category, message, data, context);
1594
- }
1595
- /**
1596
- * Log an error message
1597
- */
1598
- async error(category, message, error, context) {
1599
- const errorData = error instanceof Error ? {
1600
- name: error.name,
1601
- message: error.message,
1602
- stack: error.stack
1603
- } : error;
1604
- return this.log("error", category, message, errorData, {
1605
- ...context,
1606
- stackTrace: error instanceof Error ? error.stack : void 0
1607
- });
1608
- }
1609
- /**
1610
- * Log a fatal message
1611
- */
1612
- async fatal(category, message, error, context) {
1613
- const errorData = error instanceof Error ? {
1614
- name: error.name,
1615
- message: error.message,
1616
- stack: error.stack
1617
- } : error;
1618
- return this.log("fatal", category, message, errorData, {
1619
- ...context,
1620
- stackTrace: error instanceof Error ? error.stack : void 0
1621
- });
1622
- }
1623
- /**
1624
- * Log an API request
1625
- */
1626
- async logRequest(method, url, statusCode, duration, context) {
1627
- const level = statusCode >= 500 ? "error" : statusCode >= 400 ? "warn" : "info";
1628
- return this.log(level, "api", `${method} ${url} - ${statusCode}`, {
1629
- method,
1630
- url,
1631
- statusCode,
1632
- duration
1633
- }, {
1634
- ...context,
1635
- method,
1636
- url,
1637
- statusCode,
1638
- duration
1639
- });
1640
- }
1641
- /**
1642
- * Log an authentication event
1643
- */
1644
- async logAuth(action, userId, success = true, context) {
1645
- const level = success ? "info" : "warn";
1646
- return this.log(level, "auth", `Authentication ${action}: ${success ? "success" : "failed"}`, {
1647
- action,
1648
- success,
1649
- userId
1650
- }, {
1651
- ...context,
1652
- userId,
1653
- tags: ["authentication", action]
1654
- });
1655
- }
1656
- /**
1657
- * Log a security event
1658
- */
1659
- async logSecurity(event, severity, context) {
1660
- const level = severity === "critical" ? "fatal" : severity === "high" ? "error" : "warn";
1661
- return this.log(level, "security", `Security event: ${event}`, {
1662
- event,
1663
- severity
1664
- }, {
1665
- ...context,
1666
- tags: ["security", severity]
1667
- });
1668
- }
1669
- /**
1670
- * Core logging method
1671
- */
1672
- async log(level, category, message, data, context) {
1673
- if (!this.enabled) return;
1674
- try {
1675
- const config = await this.getConfig(category);
1676
- if (!config || !config.enabled || !this.shouldLog(level, config.level)) {
1677
- return;
1678
- }
1679
- const logEntry = {
1680
- id: crypto.randomUUID(),
1681
- level,
1682
- category,
1683
- message,
1684
- data: data ? JSON.stringify(data) : null,
1685
- userId: context?.userId || null,
1686
- sessionId: context?.sessionId || null,
1687
- requestId: context?.requestId || null,
1688
- ipAddress: context?.ipAddress || null,
1689
- userAgent: context?.userAgent || null,
1690
- method: context?.method || null,
1691
- url: context?.url || null,
1692
- statusCode: context?.statusCode || null,
1693
- duration: context?.duration || null,
1694
- stackTrace: context?.stackTrace || null,
1695
- tags: context?.tags ? JSON.stringify(context.tags) : null,
1696
- source: context?.source || null,
1697
- createdAt: /* @__PURE__ */ new Date()
1698
- };
1699
- await this.db.insert(systemLogs).values(logEntry);
1700
- if (config.maxSize) {
1701
- await this.cleanupCategory(category, config.maxSize);
1702
- }
1703
- } catch (error) {
1704
- console.error("Logger error:", error);
1705
- }
1706
- }
1707
- /**
1708
- * Get logs with filtering and pagination
1709
- */
1710
- async getLogs(filter = {}) {
1711
- try {
1712
- const conditions = [];
1713
- if (filter.level && filter.level.length > 0) {
1714
- conditions.push(inArray(systemLogs.level, filter.level));
1715
- }
1716
- if (filter.category && filter.category.length > 0) {
1717
- conditions.push(inArray(systemLogs.category, filter.category));
1718
- }
1719
- if (filter.userId) {
1720
- conditions.push(eq(systemLogs.userId, filter.userId));
1721
- }
1722
- if (filter.source) {
1723
- conditions.push(eq(systemLogs.source, filter.source));
1724
- }
1725
- if (filter.search) {
1726
- conditions.push(
1727
- like(systemLogs.message, `%${filter.search}%`)
1728
- );
1729
- }
1730
- if (filter.startDate) {
1731
- conditions.push(gte(systemLogs.createdAt, filter.startDate));
1732
- }
1733
- if (filter.endDate) {
1734
- conditions.push(lte(systemLogs.createdAt, filter.endDate));
1735
- }
1736
- const whereClause = conditions.length > 0 ? and(...conditions) : void 0;
1737
- const totalResult = await this.db.select({ count: count() }).from(systemLogs).where(whereClause);
1738
- const total = totalResult[0]?.count || 0;
1739
- const sortColumn = filter.sortBy === "level" ? systemLogs.level : filter.sortBy === "category" ? systemLogs.category : systemLogs.createdAt;
1740
- const sortFn = filter.sortOrder === "asc" ? asc : desc;
1741
- const logs = await this.db.select().from(systemLogs).where(whereClause).orderBy(sortFn(sortColumn)).limit(filter.limit || 50).offset(filter.offset || 0);
1742
- return { logs, total };
1743
- } catch (error) {
1744
- console.error("Error getting logs:", error);
1745
- return { logs: [], total: 0 };
1746
- }
1747
- }
1748
- /**
1749
- * Get log configuration for a category
1750
- */
1751
- async getConfig(category) {
1752
- try {
1753
- const now = Date.now();
1754
- if (this.configCache.has(category) && now - this.lastConfigRefresh < this.configRefreshInterval) {
1755
- return this.configCache.get(category) || null;
1756
- }
1757
- const configs = await this.db.select().from(logConfig).where(eq(logConfig.category, category));
1758
- const config = configs[0] || null;
1759
- if (config) {
1760
- this.configCache.set(category, config);
1761
- this.lastConfigRefresh = now;
1762
- }
1763
- return config;
1764
- } catch (error) {
1765
- console.error("Error getting log config:", error);
1766
- return null;
1767
- }
1768
- }
1769
- /**
1770
- * Update log configuration
1771
- */
1772
- async updateConfig(category, updates) {
1773
- try {
1774
- await this.db.update(logConfig).set({
1775
- ...updates,
1776
- updatedAt: /* @__PURE__ */ new Date()
1777
- }).where(eq(logConfig.category, category));
1778
- this.configCache.delete(category);
1779
- } catch (error) {
1780
- console.error("Error updating log config:", error);
1781
- }
1782
- }
1783
- /**
1784
- * Get all log configurations
1785
- */
1786
- async getAllConfigs() {
1787
- try {
1788
- return await this.db.select().from(logConfig);
1789
- } catch (error) {
1790
- console.error("Error getting log configs:", error);
1791
- return [];
1792
- }
1793
- }
1794
- /**
1795
- * Clean up old logs for a category
1796
- */
1797
- async cleanupCategory(category, maxSize) {
1798
- try {
1799
- const countResult = await this.db.select({ count: count() }).from(systemLogs).where(eq(systemLogs.category, category));
1800
- const currentCount = countResult[0]?.count || 0;
1801
- if (currentCount > maxSize) {
1802
- const cutoffLogs = await this.db.select({ createdAt: systemLogs.createdAt }).from(systemLogs).where(eq(systemLogs.category, category)).orderBy(desc(systemLogs.createdAt)).limit(1).offset(maxSize - 1);
1803
- if (cutoffLogs[0]) {
1804
- await this.db.delete(systemLogs).where(
1805
- and(
1806
- eq(systemLogs.category, category),
1807
- lte(systemLogs.createdAt, cutoffLogs[0].createdAt)
1808
- )
1809
- );
1810
- }
1811
- }
1812
- } catch (error) {
1813
- console.error("Error cleaning up logs:", error);
1814
- }
1815
- }
1816
- /**
1817
- * Clean up logs based on retention policy
1818
- */
1819
- async cleanupByRetention() {
1820
- try {
1821
- const configs = await this.getAllConfigs();
1822
- for (const config of configs) {
1823
- if (config.retention > 0) {
1824
- const cutoffDate = /* @__PURE__ */ new Date();
1825
- cutoffDate.setDate(cutoffDate.getDate() - config.retention);
1826
- await this.db.delete(systemLogs).where(
1827
- and(
1828
- eq(systemLogs.category, config.category),
1829
- lte(systemLogs.createdAt, cutoffDate)
1830
- )
1831
- );
1832
- }
1833
- }
1834
- } catch (error) {
1835
- console.error("Error cleaning up logs by retention:", error);
1836
- }
1837
- }
1838
- /**
1839
- * Check if a log level should be recorded based on configuration
1840
- */
1841
- shouldLog(level, configLevel) {
1842
- const levels = ["debug", "info", "warn", "error", "fatal"];
1843
- const levelIndex = levels.indexOf(level);
1844
- const configLevelIndex = levels.indexOf(configLevel);
1845
- return levelIndex >= configLevelIndex;
1846
- }
1847
- /**
1848
- * Enable or disable logging
1849
- */
1850
- setEnabled(enabled) {
1851
- this.enabled = enabled;
1852
- }
1853
- /**
1854
- * Check if logging is enabled
1855
- */
1856
- isEnabled() {
1857
- return this.enabled;
1858
- }
1859
- };
1860
- var loggerInstance = null;
1861
- function getLogger(database) {
1862
- if (!loggerInstance && database) {
1863
- loggerInstance = new Logger(database);
1864
- }
1865
- if (!loggerInstance) {
1866
- throw new Error("Logger not initialized. Call getLogger with a database instance first.");
1867
- }
1868
- return loggerInstance;
1869
- }
1870
- function initLogger(database) {
1871
- loggerInstance = new Logger(database);
1872
- return loggerInstance;
1873
- }
1874
-
1875
978
  // src/services/plugin-service.ts
1876
979
  var PluginService = class {
1877
980
  constructor(db) {
@@ -2355,6 +1458,6 @@ var PluginBootstrapService = class {
2355
1458
  }
2356
1459
  };
2357
1460
 
2358
- export { Logger, MigrationService, PluginBootstrapService, PluginService, apiTokens, cleanupRemovedCollections, collections, content, contentVersions, fullCollectionSync, getAvailableCollectionNames, getLogger, getManagedCollections, initLogger, insertCollectionSchema, insertContentSchema, insertLogConfigSchema, insertMediaSchema, insertPluginActivityLogSchema, insertPluginAssetSchema, insertPluginHookSchema, insertPluginRouteSchema, insertPluginSchema, insertSystemLogSchema, insertUserSchema, insertWorkflowHistorySchema, isCollectionManaged, loadCollectionConfig, loadCollectionConfigs, logConfig, media, pluginActivityLog, pluginAssets, pluginHooks, pluginRoutes, plugins, schema_exports, selectCollectionSchema, selectContentSchema, selectLogConfigSchema, selectMediaSchema, selectPluginActivityLogSchema, selectPluginAssetSchema, selectPluginHookSchema, selectPluginRouteSchema, selectPluginSchema, selectSystemLogSchema, selectUserSchema, selectWorkflowHistorySchema, syncCollection, syncCollections, systemLogs, users, validateCollectionConfig, workflowHistory };
2359
- //# sourceMappingURL=chunk-7N3HK7ZK.js.map
2360
- //# sourceMappingURL=chunk-7N3HK7ZK.js.map
1461
+ export { MigrationService, PluginBootstrapService, PluginService, cleanupRemovedCollections, fullCollectionSync, getAvailableCollectionNames, getManagedCollections, isCollectionManaged, loadCollectionConfig, loadCollectionConfigs, syncCollection, syncCollections, validateCollectionConfig };
1462
+ //# sourceMappingURL=chunk-CDBVZEWR.js.map
1463
+ //# sourceMappingURL=chunk-CDBVZEWR.js.map