@sonicjs-cms/core 2.18.1 → 3.0.0-beta.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 +4 -3
- package/dist/admin-documents-form.template-KN7JF66Q.cjs +19 -0
- package/dist/{admin-layout-catalyst.template-UMTIN66R.js.map → admin-documents-form.template-KN7JF66Q.cjs.map} +1 -1
- package/dist/admin-documents-form.template-NLSI6Z42.js +6 -0
- package/dist/{admin-layout-catalyst.template-HFD37TY5.cjs.map → admin-documents-form.template-NLSI6Z42.js.map} +1 -1
- package/dist/admin-layout-catalyst.template-WHJGSWWD.js +7 -0
- package/dist/admin-layout-catalyst.template-WHJGSWWD.js.map +1 -0
- package/dist/admin-layout-catalyst.template-ZK5HD545.cjs +17 -0
- package/dist/admin-layout-catalyst.template-ZK5HD545.cjs.map +1 -0
- package/dist/app-Bo0X1OWX.d.ts +1268 -0
- package/dist/app-Do66yCcV.d.cts +1268 -0
- package/dist/cache-DDARE4QE.js +4 -0
- package/dist/cache-DDARE4QE.js.map +1 -0
- package/dist/cache-LVYS4BPL.cjs +33 -0
- package/dist/cache-LVYS4BPL.cjs.map +1 -0
- package/dist/chunk-2CB4KY7I.cjs +771 -0
- package/dist/chunk-2CB4KY7I.cjs.map +1 -0
- package/dist/{chunk-55RDMDOP.js → chunk-3TB6AT6X.js} +148 -55
- package/dist/chunk-3TB6AT6X.js.map +1 -0
- package/dist/{chunk-ON5ZMSU4.js → chunk-6JQOUUOB.js} +3 -3
- package/dist/chunk-6JQOUUOB.js.map +1 -0
- package/dist/chunk-6OUHGKFD.js +387 -0
- package/dist/chunk-6OUHGKFD.js.map +1 -0
- package/dist/{chunk-DSUJ5YQH.cjs → chunk-AAWNRBRB.cjs} +537 -92
- package/dist/chunk-AAWNRBRB.cjs.map +1 -0
- package/dist/chunk-AI663NBO.js +821 -0
- package/dist/chunk-AI663NBO.js.map +1 -0
- package/dist/chunk-BDDABDAB.cjs +1149 -0
- package/dist/chunk-BDDABDAB.cjs.map +1 -0
- package/dist/chunk-BLMTL57B.js +767 -0
- package/dist/chunk-BLMTL57B.js.map +1 -0
- package/dist/chunk-DNQCEKUK.cjs +327 -0
- package/dist/chunk-DNQCEKUK.cjs.map +1 -0
- package/dist/chunk-DSA4UX5B.cjs +276 -0
- package/dist/chunk-DSA4UX5B.cjs.map +1 -0
- package/dist/chunk-EF2NQUIQ.js +323 -0
- package/dist/chunk-EF2NQUIQ.js.map +1 -0
- package/dist/chunk-GCDZZNIN.js +192 -0
- package/dist/chunk-GCDZZNIN.js.map +1 -0
- package/dist/{chunk-ABB34XUS.cjs → chunk-H2AXVCLS.cjs} +667 -19
- package/dist/chunk-H2AXVCLS.cjs.map +1 -0
- package/dist/{chunk-XWIA3HVX.js → chunk-HDWE5FRJ.js} +6 -1249
- package/dist/chunk-HDWE5FRJ.js.map +1 -0
- package/dist/chunk-HIKBY7MS.cjs +70 -0
- package/dist/chunk-HIKBY7MS.cjs.map +1 -0
- package/dist/chunk-IESEVHXL.js +66 -0
- package/dist/chunk-IESEVHXL.js.map +1 -0
- package/dist/chunk-IVPRUGTY.js +242 -0
- package/dist/chunk-IVPRUGTY.js.map +1 -0
- package/dist/{chunk-SQ6FNXU2.cjs → chunk-IXUHXTHW.cjs} +2 -151
- package/dist/chunk-IXUHXTHW.cjs.map +1 -0
- package/dist/chunk-J6JTWD2A.cjs +100 -0
- package/dist/chunk-J6JTWD2A.cjs.map +1 -0
- package/dist/chunk-JEQ7FLOD.cjs +199 -0
- package/dist/chunk-JEQ7FLOD.cjs.map +1 -0
- package/dist/chunk-K25XHMM3.js +566 -0
- package/dist/chunk-K25XHMM3.js.map +1 -0
- package/dist/chunk-LRZIAW7U.cjs +158 -0
- package/dist/chunk-LRZIAW7U.cjs.map +1 -0
- package/dist/{chunk-OHYBNCVL.cjs → chunk-MVIZJOO5.cjs} +10 -1256
- package/dist/chunk-MVIZJOO5.cjs.map +1 -0
- package/dist/{chunk-UYJ6TJHX.cjs → chunk-NAVPFIG5.cjs} +148 -55
- package/dist/chunk-NAVPFIG5.cjs.map +1 -0
- package/dist/chunk-NLJVSER2.js +273 -0
- package/dist/chunk-NLJVSER2.js.map +1 -0
- package/dist/chunk-NMPEMSU4.js +154 -0
- package/dist/chunk-NMPEMSU4.js.map +1 -0
- package/dist/chunk-NUKJ54GA.cjs +245 -0
- package/dist/chunk-NUKJ54GA.cjs.map +1 -0
- package/dist/{chunk-T3Q5V33G.cjs → chunk-QAYFOER6.cjs} +621 -829
- package/dist/chunk-QAYFOER6.cjs.map +1 -0
- package/dist/{chunk-MGFRZO24.js → chunk-QZGABF2M.js} +3 -149
- package/dist/chunk-QZGABF2M.js.map +1 -0
- package/dist/chunk-RNZFGN4R.js +88 -0
- package/dist/chunk-RNZFGN4R.js.map +1 -0
- package/dist/chunk-RZ6H7OZK.js +1134 -0
- package/dist/chunk-RZ6H7OZK.js.map +1 -0
- package/dist/{chunk-XXDFQERJ.js → chunk-VD2EA3WT.js} +7192 -9806
- package/dist/chunk-VD2EA3WT.js.map +1 -0
- package/dist/{chunk-SXXTQETM.cjs → chunk-VXE42MYF.cjs} +8722 -11323
- package/dist/chunk-VXE42MYF.cjs.map +1 -0
- package/dist/{chunk-4ZSNJDLS.cjs → chunk-WULONYGB.cjs} +9 -9
- package/dist/chunk-WULONYGB.cjs.map +1 -0
- package/dist/chunk-XW56B23A.cjs +408 -0
- package/dist/chunk-XW56B23A.cjs.map +1 -0
- package/dist/chunk-YA3TJ65D.cjs +575 -0
- package/dist/chunk-YA3TJ65D.cjs.map +1 -0
- package/dist/{chunk-TFNTM3OA.js → chunk-YHSQVQXX.js} +645 -15
- package/dist/chunk-YHSQVQXX.js.map +1 -0
- package/dist/chunk-YP7GW2G5.cjs +866 -0
- package/dist/chunk-YP7GW2G5.cjs.map +1 -0
- package/dist/{chunk-QFWHAFEO.js → chunk-ZEZ245PW.js} +148 -858
- package/dist/chunk-ZEZ245PW.js.map +1 -0
- package/dist/{chunk-EW5NOBVU.js → chunk-ZGGXCFR6.js} +611 -817
- package/dist/chunk-ZGGXCFR6.js.map +1 -0
- package/dist/{collection-config-B4PG-AaF.d.cts → collection-config-JgHOpFCG.d.cts} +30 -2
- package/dist/{collection-config-B4PG-AaF.d.ts → collection-config-JgHOpFCG.d.ts} +30 -2
- package/dist/config-HFXANXCC.js +6 -0
- package/dist/config-HFXANXCC.js.map +1 -0
- package/dist/config-ON6FNMYX.cjs +19 -0
- package/dist/config-ON6FNMYX.cjs.map +1 -0
- package/dist/define-plugin-BzNHc1ZI.d.ts +1321 -0
- package/dist/define-plugin-IWDKYaVm.d.cts +1321 -0
- package/dist/document-projection-TDWRJX3Z.cjs +13 -0
- package/dist/document-projection-TDWRJX3Z.cjs.map +1 -0
- package/dist/document-projection-YYMC6I4U.js +4 -0
- package/dist/document-projection-YYMC6I4U.js.map +1 -0
- package/dist/index.cjs +13735 -4329
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +329 -492
- package/dist/index.d.ts +329 -492
- package/dist/index.js +13386 -3999
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +36 -32
- package/dist/middleware.d.cts +69 -7
- package/dist/middleware.d.ts +69 -7
- package/dist/middleware.js +7 -3
- package/dist/migrations-NJJWQUKK.cjs +13 -0
- package/dist/{migrations-IYNTWDC6.cjs.map → migrations-NJJWQUKK.cjs.map} +1 -1
- package/dist/migrations-WCAVBD7C.js +4 -0
- package/dist/{migrations-R337UD46.js.map → migrations-WCAVBD7C.js.map} +1 -1
- package/dist/{plugin-bootstrap-DfVerYV4.d.cts → plugin-bootstrap-B8ThJU21.d.cts} +4315 -1661
- package/dist/{plugin-bootstrap-P_ciLp_C.d.ts → plugin-bootstrap-qu8hJgUt.d.ts} +4315 -1661
- package/dist/plugins.cjs +171 -12
- package/dist/plugins.d.cts +36 -2
- package/dist/plugins.d.ts +36 -2
- package/dist/plugins.js +5 -2
- package/dist/rbac-O73MFKDA.js +5 -0
- package/dist/rbac-O73MFKDA.js.map +1 -0
- package/dist/rbac-VONLJJKB.cjs +14 -0
- package/dist/rbac-VONLJJKB.cjs.map +1 -0
- package/dist/routes.cjs +41 -45
- package/dist/routes.d.cts +56 -146
- package/dist/routes.d.ts +56 -146
- package/dist/routes.js +17 -9
- package/dist/services.cjs +39 -72
- package/dist/services.d.cts +79 -54
- package/dist/services.d.ts +79 -54
- package/dist/services.js +6 -3
- package/dist/templates.cjs +17 -29
- package/dist/templates.d.cts +1 -66
- package/dist/templates.d.ts +1 -66
- package/dist/templates.js +3 -3
- package/dist/types-Dea1eNxU.d.cts +286 -0
- package/dist/types-Dea1eNxU.d.ts +286 -0
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utils.cjs +18 -17
- package/dist/utils.d.cts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +2 -1
- package/migrations/0001_core.sql +184 -0
- package/migrations/0002_documents.sql +163 -0
- package/package.json +12 -7
- package/dist/admin-layout-catalyst.template-HFD37TY5.cjs +0 -17
- package/dist/admin-layout-catalyst.template-UMTIN66R.js +0 -7
- package/dist/app-C9esKLmh.d.cts +0 -112
- package/dist/app-C9esKLmh.d.ts +0 -112
- package/dist/chunk-4R3NOOL3.js +0 -2217
- package/dist/chunk-4R3NOOL3.js.map +0 -1
- package/dist/chunk-4ZSNJDLS.cjs.map +0 -1
- package/dist/chunk-55RDMDOP.js.map +0 -1
- package/dist/chunk-635JAMSE.cjs +0 -653
- package/dist/chunk-635JAMSE.cjs.map +0 -1
- package/dist/chunk-ABB34XUS.cjs.map +0 -1
- package/dist/chunk-C54YUA23.cjs +0 -2219
- package/dist/chunk-C54YUA23.cjs.map +0 -1
- package/dist/chunk-DSUJ5YQH.cjs.map +0 -1
- package/dist/chunk-EW5NOBVU.js.map +0 -1
- package/dist/chunk-EXNEW5US.js +0 -648
- package/dist/chunk-EXNEW5US.js.map +0 -1
- package/dist/chunk-I2H5NGJQ.js +0 -692
- package/dist/chunk-I2H5NGJQ.js.map +0 -1
- package/dist/chunk-MGFRZO24.js.map +0 -1
- package/dist/chunk-OHYBNCVL.cjs.map +0 -1
- package/dist/chunk-ON5ZMSU4.js.map +0 -1
- package/dist/chunk-QFWHAFEO.js.map +0 -1
- package/dist/chunk-SQ6FNXU2.cjs.map +0 -1
- package/dist/chunk-SXXTQETM.cjs.map +0 -1
- package/dist/chunk-T3Q5V33G.cjs.map +0 -1
- package/dist/chunk-TFNTM3OA.js.map +0 -1
- package/dist/chunk-UYJ6TJHX.cjs.map +0 -1
- package/dist/chunk-WAEQXGCX.cjs +0 -1898
- package/dist/chunk-WAEQXGCX.cjs.map +0 -1
- package/dist/chunk-XWIA3HVX.js.map +0 -1
- package/dist/chunk-XXDFQERJ.js.map +0 -1
- package/dist/migrations-IYNTWDC6.cjs +0 -13
- package/dist/migrations-R337UD46.js +0 -4
- package/dist/plugin-manager-BoM3Q7o7.d.cts +0 -328
- package/dist/plugin-manager-Efx9RyDX.d.ts +0 -328
- package/migrations/001_initial_schema.sql +0 -170
- package/migrations/002_faq_plugin.sql +0 -86
- package/migrations/003_stage5_enhancements.sql +0 -121
- package/migrations/004_stage6_user_management.sql +0 -183
- package/migrations/005_stage7_workflow_automation.sql +0 -294
- package/migrations/006_plugin_system.sql +0 -155
- package/migrations/007_demo_login_plugin.sql +0 -23
- package/migrations/008_fix_slug_validation.sql +0 -22
- package/migrations/009_system_logging.sql +0 -57
- package/migrations/011_config_managed_collections.sql +0 -15
- package/migrations/012_testimonials_plugin.sql +0 -80
- package/migrations/013_code_examples_plugin.sql +0 -177
- package/migrations/014_fix_plugin_registry.sql +0 -88
- package/migrations/015_add_remaining_plugins.sql +0 -89
- package/migrations/016_remove_duplicate_cache_plugin.sql +0 -17
- package/migrations/017_auth_configurable_fields.sql +0 -49
- package/migrations/018_settings_table.sql +0 -23
- package/migrations/019_remove_blog_posts_collection.sql +0 -15
- package/migrations/020_add_email_plugin.sql +0 -22
- package/migrations/021_add_magic_link_auth_plugin.sql +0 -42
- package/migrations/022_add_tinymce_plugin.sql +0 -25
- package/migrations/023_add_easy_mdx_plugin.sql +0 -25
- package/migrations/024_add_quill_editor_plugin.sql +0 -25
- package/migrations/025_add_easymde_plugin.sql +0 -25
- package/migrations/026_add_otp_login.sql +0 -42
- package/migrations/027_fix_slug_field_type.sql +0 -18
- package/migrations/028_fix_slug_field_type_in_schemas.sql +0 -30
- package/migrations/029_add_forms_system.sql +0 -184
- package/migrations/030_add_turnstile_to_forms.sql +0 -14
- package/migrations/031_ai_search_plugin.sql +0 -45
- package/migrations/032_user_profiles.sql +0 -37
- package/migrations/033_form_content_integration.sql +0 -19
- package/migrations/034_security_audit_plugin.sql +0 -27
- package/migrations/035_user_profiles_data_column.sql +0 -16
- package/migrations/036_analytics_events.sql +0 -22
|
@@ -1,713 +1,10 @@
|
|
|
1
|
+
import { getCacheService } from './chunk-K25XHMM3.js';
|
|
2
|
+
import { systemLogs, logConfig } from './chunk-AI663NBO.js';
|
|
1
3
|
import { getTelemetryConfig, sanitizeErrorMessage, sanitizeRoute, generateInstallationId, generateProjectId } from './chunk-X7ZAEI5S.js';
|
|
2
|
-
import { __export } from './chunk-V4OQ3NZ2.js';
|
|
3
|
-
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
|
|
4
|
-
import { z } from 'zod/v4';
|
|
5
|
-
import { isTable, getTableColumns, getViewSelectedFields, is, Column, SQL, isView, inArray, eq, like, gte, lte, and, count, asc, desc } from 'drizzle-orm';
|
|
6
4
|
import { drizzle } from 'drizzle-orm/d1';
|
|
5
|
+
import { inArray, eq, like, gte, lte, and, count, asc, desc } from 'drizzle-orm';
|
|
7
6
|
import { inspectRoutes } from 'hono/dev';
|
|
8
7
|
|
|
9
|
-
// src/db/schema.ts
|
|
10
|
-
var schema_exports = {};
|
|
11
|
-
__export(schema_exports, {
|
|
12
|
-
apiTokens: () => apiTokens,
|
|
13
|
-
collections: () => collections,
|
|
14
|
-
content: () => content,
|
|
15
|
-
contentVersions: () => contentVersions,
|
|
16
|
-
formFiles: () => formFiles,
|
|
17
|
-
formSubmissions: () => formSubmissions,
|
|
18
|
-
forms: () => forms,
|
|
19
|
-
insertCollectionSchema: () => insertCollectionSchema,
|
|
20
|
-
insertContentSchema: () => insertContentSchema,
|
|
21
|
-
insertFormFileSchema: () => insertFormFileSchema,
|
|
22
|
-
insertFormSchema: () => insertFormSchema,
|
|
23
|
-
insertFormSubmissionSchema: () => insertFormSubmissionSchema,
|
|
24
|
-
insertLogConfigSchema: () => insertLogConfigSchema,
|
|
25
|
-
insertMediaSchema: () => insertMediaSchema,
|
|
26
|
-
insertPluginActivityLogSchema: () => insertPluginActivityLogSchema,
|
|
27
|
-
insertPluginAssetSchema: () => insertPluginAssetSchema,
|
|
28
|
-
insertPluginHookSchema: () => insertPluginHookSchema,
|
|
29
|
-
insertPluginRouteSchema: () => insertPluginRouteSchema,
|
|
30
|
-
insertPluginSchema: () => insertPluginSchema,
|
|
31
|
-
insertSecurityEventSchema: () => insertSecurityEventSchema,
|
|
32
|
-
insertSystemLogSchema: () => insertSystemLogSchema,
|
|
33
|
-
insertUserSchema: () => insertUserSchema,
|
|
34
|
-
insertWorkflowHistorySchema: () => insertWorkflowHistorySchema,
|
|
35
|
-
logConfig: () => logConfig,
|
|
36
|
-
media: () => media,
|
|
37
|
-
pluginActivityLog: () => pluginActivityLog,
|
|
38
|
-
pluginAssets: () => pluginAssets,
|
|
39
|
-
pluginHooks: () => pluginHooks,
|
|
40
|
-
pluginRoutes: () => pluginRoutes,
|
|
41
|
-
plugins: () => plugins,
|
|
42
|
-
securityEvents: () => securityEvents,
|
|
43
|
-
selectCollectionSchema: () => selectCollectionSchema,
|
|
44
|
-
selectContentSchema: () => selectContentSchema,
|
|
45
|
-
selectFormFileSchema: () => selectFormFileSchema,
|
|
46
|
-
selectFormSchema: () => selectFormSchema,
|
|
47
|
-
selectFormSubmissionSchema: () => selectFormSubmissionSchema,
|
|
48
|
-
selectLogConfigSchema: () => selectLogConfigSchema,
|
|
49
|
-
selectMediaSchema: () => selectMediaSchema,
|
|
50
|
-
selectPluginActivityLogSchema: () => selectPluginActivityLogSchema,
|
|
51
|
-
selectPluginAssetSchema: () => selectPluginAssetSchema,
|
|
52
|
-
selectPluginHookSchema: () => selectPluginHookSchema,
|
|
53
|
-
selectPluginRouteSchema: () => selectPluginRouteSchema,
|
|
54
|
-
selectPluginSchema: () => selectPluginSchema,
|
|
55
|
-
selectSecurityEventSchema: () => selectSecurityEventSchema,
|
|
56
|
-
selectSystemLogSchema: () => selectSystemLogSchema,
|
|
57
|
-
selectUserSchema: () => selectUserSchema,
|
|
58
|
-
selectWorkflowHistorySchema: () => selectWorkflowHistorySchema,
|
|
59
|
-
systemLogs: () => systemLogs,
|
|
60
|
-
users: () => users,
|
|
61
|
-
workflowHistory: () => workflowHistory
|
|
62
|
-
});
|
|
63
|
-
var CONSTANTS = {
|
|
64
|
-
INT8_MIN: -128,
|
|
65
|
-
INT8_MAX: 127,
|
|
66
|
-
INT8_UNSIGNED_MAX: 255,
|
|
67
|
-
INT16_MIN: -32768,
|
|
68
|
-
INT16_MAX: 32767,
|
|
69
|
-
INT16_UNSIGNED_MAX: 65535,
|
|
70
|
-
INT24_MIN: -8388608,
|
|
71
|
-
INT24_MAX: 8388607,
|
|
72
|
-
INT24_UNSIGNED_MAX: 16777215,
|
|
73
|
-
INT32_MIN: -2147483648,
|
|
74
|
-
INT32_MAX: 2147483647,
|
|
75
|
-
INT32_UNSIGNED_MAX: 4294967295,
|
|
76
|
-
INT48_MIN: -140737488355328,
|
|
77
|
-
INT48_MAX: 140737488355327,
|
|
78
|
-
INT48_UNSIGNED_MAX: 281474976710655,
|
|
79
|
-
INT64_MIN: -9223372036854775808n,
|
|
80
|
-
INT64_MAX: 9223372036854775807n,
|
|
81
|
-
INT64_UNSIGNED_MAX: 18446744073709551615n
|
|
82
|
-
};
|
|
83
|
-
function isColumnType(column, columnTypes) {
|
|
84
|
-
return columnTypes.includes(column.columnType);
|
|
85
|
-
}
|
|
86
|
-
function isWithEnum(column) {
|
|
87
|
-
return "enumValues" in column && Array.isArray(column.enumValues) && column.enumValues.length > 0;
|
|
88
|
-
}
|
|
89
|
-
var isPgEnum = isWithEnum;
|
|
90
|
-
var literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
|
91
|
-
var jsonSchema = z.union([
|
|
92
|
-
literalSchema,
|
|
93
|
-
z.record(z.string(), z.any()),
|
|
94
|
-
z.array(z.any())
|
|
95
|
-
]);
|
|
96
|
-
var bufferSchema = z.custom((v) => v instanceof Buffer);
|
|
97
|
-
function columnToSchema(column, factory) {
|
|
98
|
-
const z$1 = z;
|
|
99
|
-
const coerce = {};
|
|
100
|
-
let schema;
|
|
101
|
-
if (isWithEnum(column)) {
|
|
102
|
-
schema = column.enumValues.length ? z$1.enum(column.enumValues) : z$1.string();
|
|
103
|
-
}
|
|
104
|
-
if (!schema) {
|
|
105
|
-
if (isColumnType(column, ["PgGeometry", "PgPointTuple"])) {
|
|
106
|
-
schema = z$1.tuple([z$1.number(), z$1.number()]);
|
|
107
|
-
} else if (isColumnType(column, ["PgGeometryObject", "PgPointObject"])) {
|
|
108
|
-
schema = z$1.object({ x: z$1.number(), y: z$1.number() });
|
|
109
|
-
} else if (isColumnType(column, ["PgHalfVector", "PgVector"])) {
|
|
110
|
-
schema = z$1.array(z$1.number());
|
|
111
|
-
schema = column.dimensions ? schema.length(column.dimensions) : schema;
|
|
112
|
-
} else if (isColumnType(column, ["PgLine"])) {
|
|
113
|
-
schema = z$1.tuple([z$1.number(), z$1.number(), z$1.number()]);
|
|
114
|
-
} else if (isColumnType(column, ["PgLineABC"])) {
|
|
115
|
-
schema = z$1.object({
|
|
116
|
-
a: z$1.number(),
|
|
117
|
-
b: z$1.number(),
|
|
118
|
-
c: z$1.number()
|
|
119
|
-
});
|
|
120
|
-
} else if (isColumnType(column, ["PgArray"])) {
|
|
121
|
-
schema = z$1.array(columnToSchema(column.baseColumn));
|
|
122
|
-
schema = column.size ? schema.length(column.size) : schema;
|
|
123
|
-
} else if (column.dataType === "array") {
|
|
124
|
-
schema = z$1.array(z$1.any());
|
|
125
|
-
} else if (column.dataType === "number") {
|
|
126
|
-
schema = numberColumnToSchema(column, z$1, coerce);
|
|
127
|
-
} else if (column.dataType === "bigint") {
|
|
128
|
-
schema = bigintColumnToSchema(column, z$1, coerce);
|
|
129
|
-
} else if (column.dataType === "boolean") {
|
|
130
|
-
schema = coerce === true || coerce.boolean ? z$1.coerce.boolean() : z$1.boolean();
|
|
131
|
-
} else if (column.dataType === "date") {
|
|
132
|
-
schema = coerce === true || coerce.date ? z$1.coerce.date() : z$1.date();
|
|
133
|
-
} else if (column.dataType === "string") {
|
|
134
|
-
schema = stringColumnToSchema(column, z$1, coerce);
|
|
135
|
-
} else if (column.dataType === "json") {
|
|
136
|
-
schema = jsonSchema;
|
|
137
|
-
} else if (column.dataType === "custom") {
|
|
138
|
-
schema = z$1.any();
|
|
139
|
-
} else if (column.dataType === "buffer") {
|
|
140
|
-
schema = bufferSchema;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
if (!schema) {
|
|
144
|
-
schema = z$1.any();
|
|
145
|
-
}
|
|
146
|
-
return schema;
|
|
147
|
-
}
|
|
148
|
-
function numberColumnToSchema(column, z2, coerce) {
|
|
149
|
-
let unsigned = column.getSQLType().includes("unsigned");
|
|
150
|
-
let min;
|
|
151
|
-
let max;
|
|
152
|
-
let integer2 = false;
|
|
153
|
-
if (isColumnType(column, ["MySqlTinyInt", "SingleStoreTinyInt"])) {
|
|
154
|
-
min = unsigned ? 0 : CONSTANTS.INT8_MIN;
|
|
155
|
-
max = unsigned ? CONSTANTS.INT8_UNSIGNED_MAX : CONSTANTS.INT8_MAX;
|
|
156
|
-
integer2 = true;
|
|
157
|
-
} else if (isColumnType(column, [
|
|
158
|
-
"PgSmallInt",
|
|
159
|
-
"PgSmallSerial",
|
|
160
|
-
"MySqlSmallInt",
|
|
161
|
-
"SingleStoreSmallInt"
|
|
162
|
-
])) {
|
|
163
|
-
min = unsigned ? 0 : CONSTANTS.INT16_MIN;
|
|
164
|
-
max = unsigned ? CONSTANTS.INT16_UNSIGNED_MAX : CONSTANTS.INT16_MAX;
|
|
165
|
-
integer2 = true;
|
|
166
|
-
} else if (isColumnType(column, [
|
|
167
|
-
"PgReal",
|
|
168
|
-
"MySqlFloat",
|
|
169
|
-
"MySqlMediumInt",
|
|
170
|
-
"SingleStoreMediumInt",
|
|
171
|
-
"SingleStoreFloat"
|
|
172
|
-
])) {
|
|
173
|
-
min = unsigned ? 0 : CONSTANTS.INT24_MIN;
|
|
174
|
-
max = unsigned ? CONSTANTS.INT24_UNSIGNED_MAX : CONSTANTS.INT24_MAX;
|
|
175
|
-
integer2 = isColumnType(column, ["MySqlMediumInt", "SingleStoreMediumInt"]);
|
|
176
|
-
} else if (isColumnType(column, [
|
|
177
|
-
"PgInteger",
|
|
178
|
-
"PgSerial",
|
|
179
|
-
"MySqlInt",
|
|
180
|
-
"SingleStoreInt"
|
|
181
|
-
])) {
|
|
182
|
-
min = unsigned ? 0 : CONSTANTS.INT32_MIN;
|
|
183
|
-
max = unsigned ? CONSTANTS.INT32_UNSIGNED_MAX : CONSTANTS.INT32_MAX;
|
|
184
|
-
integer2 = true;
|
|
185
|
-
} else if (isColumnType(column, [
|
|
186
|
-
"PgDoublePrecision",
|
|
187
|
-
"MySqlReal",
|
|
188
|
-
"MySqlDouble",
|
|
189
|
-
"SingleStoreReal",
|
|
190
|
-
"SingleStoreDouble",
|
|
191
|
-
"SQLiteReal"
|
|
192
|
-
])) {
|
|
193
|
-
min = unsigned ? 0 : CONSTANTS.INT48_MIN;
|
|
194
|
-
max = unsigned ? CONSTANTS.INT48_UNSIGNED_MAX : CONSTANTS.INT48_MAX;
|
|
195
|
-
} else if (isColumnType(column, [
|
|
196
|
-
"PgBigInt53",
|
|
197
|
-
"PgBigSerial53",
|
|
198
|
-
"MySqlBigInt53",
|
|
199
|
-
"MySqlSerial",
|
|
200
|
-
"SingleStoreBigInt53",
|
|
201
|
-
"SingleStoreSerial",
|
|
202
|
-
"SQLiteInteger"
|
|
203
|
-
])) {
|
|
204
|
-
unsigned = unsigned || isColumnType(column, ["MySqlSerial", "SingleStoreSerial"]);
|
|
205
|
-
min = unsigned ? 0 : Number.MIN_SAFE_INTEGER;
|
|
206
|
-
max = Number.MAX_SAFE_INTEGER;
|
|
207
|
-
integer2 = true;
|
|
208
|
-
} else if (isColumnType(column, ["MySqlYear", "SingleStoreYear"])) {
|
|
209
|
-
min = 1901;
|
|
210
|
-
max = 2155;
|
|
211
|
-
integer2 = true;
|
|
212
|
-
} else {
|
|
213
|
-
min = Number.MIN_SAFE_INTEGER;
|
|
214
|
-
max = Number.MAX_SAFE_INTEGER;
|
|
215
|
-
}
|
|
216
|
-
let schema = coerce === true || coerce?.number ? integer2 ? z2.coerce.number() : z2.coerce.number().int() : integer2 ? z2.int() : z2.number();
|
|
217
|
-
schema = schema.gte(min).lte(max);
|
|
218
|
-
return schema;
|
|
219
|
-
}
|
|
220
|
-
function bigintColumnToSchema(column, z2, coerce) {
|
|
221
|
-
const unsigned = column.getSQLType().includes("unsigned");
|
|
222
|
-
const min = unsigned ? 0n : CONSTANTS.INT64_MIN;
|
|
223
|
-
const max = unsigned ? CONSTANTS.INT64_UNSIGNED_MAX : CONSTANTS.INT64_MAX;
|
|
224
|
-
const schema = coerce === true || coerce?.bigint ? z2.coerce.bigint() : z2.bigint();
|
|
225
|
-
return schema.gte(min).lte(max);
|
|
226
|
-
}
|
|
227
|
-
function stringColumnToSchema(column, z2, coerce) {
|
|
228
|
-
if (isColumnType(column, ["PgUUID"])) {
|
|
229
|
-
return z2.uuid();
|
|
230
|
-
}
|
|
231
|
-
let max;
|
|
232
|
-
let regex;
|
|
233
|
-
let fixed = false;
|
|
234
|
-
if (isColumnType(column, ["PgVarchar", "SQLiteText"])) {
|
|
235
|
-
max = column.length;
|
|
236
|
-
} else if (isColumnType(column, ["MySqlVarChar", "SingleStoreVarChar"])) {
|
|
237
|
-
max = column.length ?? CONSTANTS.INT16_UNSIGNED_MAX;
|
|
238
|
-
} else if (isColumnType(column, ["MySqlText", "SingleStoreText"])) {
|
|
239
|
-
if (column.textType === "longtext") {
|
|
240
|
-
max = CONSTANTS.INT32_UNSIGNED_MAX;
|
|
241
|
-
} else if (column.textType === "mediumtext") {
|
|
242
|
-
max = CONSTANTS.INT24_UNSIGNED_MAX;
|
|
243
|
-
} else if (column.textType === "text") {
|
|
244
|
-
max = CONSTANTS.INT16_UNSIGNED_MAX;
|
|
245
|
-
} else {
|
|
246
|
-
max = CONSTANTS.INT8_UNSIGNED_MAX;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
if (isColumnType(column, [
|
|
250
|
-
"PgChar",
|
|
251
|
-
"MySqlChar",
|
|
252
|
-
"SingleStoreChar"
|
|
253
|
-
])) {
|
|
254
|
-
max = column.length;
|
|
255
|
-
fixed = true;
|
|
256
|
-
}
|
|
257
|
-
if (isColumnType(column, ["PgBinaryVector"])) {
|
|
258
|
-
regex = /^[01]+$/;
|
|
259
|
-
max = column.dimensions;
|
|
260
|
-
}
|
|
261
|
-
let schema = coerce === true || coerce?.string ? z2.coerce.string() : z2.string();
|
|
262
|
-
schema = regex ? schema.regex(regex) : schema;
|
|
263
|
-
return max && fixed ? schema.length(max) : max ? schema.max(max) : schema;
|
|
264
|
-
}
|
|
265
|
-
function getColumns(tableLike) {
|
|
266
|
-
return isTable(tableLike) ? getTableColumns(tableLike) : getViewSelectedFields(tableLike);
|
|
267
|
-
}
|
|
268
|
-
function handleColumns(columns, refinements, conditions, factory) {
|
|
269
|
-
const columnSchemas = {};
|
|
270
|
-
for (const [key, selected] of Object.entries(columns)) {
|
|
271
|
-
if (!is(selected, Column) && !is(selected, SQL) && !is(selected, SQL.Aliased) && typeof selected === "object") {
|
|
272
|
-
const columns2 = isTable(selected) || isView(selected) ? getColumns(selected) : selected;
|
|
273
|
-
columnSchemas[key] = handleColumns(columns2, refinements[key] ?? {}, conditions);
|
|
274
|
-
continue;
|
|
275
|
-
}
|
|
276
|
-
const refinement = refinements[key];
|
|
277
|
-
if (refinement !== void 0 && typeof refinement !== "function") {
|
|
278
|
-
columnSchemas[key] = refinement;
|
|
279
|
-
continue;
|
|
280
|
-
}
|
|
281
|
-
const column = is(selected, Column) ? selected : void 0;
|
|
282
|
-
const schema = column ? columnToSchema(column) : z.any();
|
|
283
|
-
const refined = typeof refinement === "function" ? refinement(schema) : schema;
|
|
284
|
-
if (conditions.never(column)) {
|
|
285
|
-
continue;
|
|
286
|
-
} else {
|
|
287
|
-
columnSchemas[key] = refined;
|
|
288
|
-
}
|
|
289
|
-
if (column) {
|
|
290
|
-
if (conditions.nullable(column)) {
|
|
291
|
-
columnSchemas[key] = columnSchemas[key].nullable();
|
|
292
|
-
}
|
|
293
|
-
if (conditions.optional(column)) {
|
|
294
|
-
columnSchemas[key] = columnSchemas[key].optional();
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return z.object(columnSchemas);
|
|
299
|
-
}
|
|
300
|
-
function handleEnum(enum_, factory) {
|
|
301
|
-
const zod = z;
|
|
302
|
-
return zod.enum(enum_.enumValues);
|
|
303
|
-
}
|
|
304
|
-
var selectConditions = {
|
|
305
|
-
never: () => false,
|
|
306
|
-
optional: () => false,
|
|
307
|
-
nullable: (column) => !column.notNull
|
|
308
|
-
};
|
|
309
|
-
var insertConditions = {
|
|
310
|
-
never: (column) => column?.generated?.type === "always" || column?.generatedIdentity?.type === "always",
|
|
311
|
-
optional: (column) => !column.notNull || column.notNull && column.hasDefault,
|
|
312
|
-
nullable: (column) => !column.notNull
|
|
313
|
-
};
|
|
314
|
-
var createSelectSchema = (entity, refine) => {
|
|
315
|
-
if (isPgEnum(entity)) {
|
|
316
|
-
return handleEnum(entity);
|
|
317
|
-
}
|
|
318
|
-
const columns = getColumns(entity);
|
|
319
|
-
return handleColumns(columns, {}, selectConditions);
|
|
320
|
-
};
|
|
321
|
-
var createInsertSchema = (entity, refine) => {
|
|
322
|
-
const columns = getColumns(entity);
|
|
323
|
-
return handleColumns(columns, refine ?? {}, insertConditions);
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
// src/db/schema.ts
|
|
327
|
-
var users = sqliteTable("users", {
|
|
328
|
-
id: text("id").primaryKey(),
|
|
329
|
-
email: text("email").notNull().unique(),
|
|
330
|
-
username: text("username").notNull().unique(),
|
|
331
|
-
firstName: text("first_name").notNull(),
|
|
332
|
-
lastName: text("last_name").notNull(),
|
|
333
|
-
passwordHash: text("password_hash"),
|
|
334
|
-
// Hashed password, nullable for OAuth users
|
|
335
|
-
role: text("role").notNull().default("viewer"),
|
|
336
|
-
// 'admin', 'editor', 'author', 'viewer'
|
|
337
|
-
avatar: text("avatar"),
|
|
338
|
-
isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
|
|
339
|
-
lastLoginAt: integer("last_login_at"),
|
|
340
|
-
createdAt: integer("created_at").notNull(),
|
|
341
|
-
updatedAt: integer("updated_at").notNull()
|
|
342
|
-
});
|
|
343
|
-
var collections = sqliteTable("collections", {
|
|
344
|
-
id: text("id").primaryKey(),
|
|
345
|
-
name: text("name").notNull().unique(),
|
|
346
|
-
displayName: text("display_name").notNull(),
|
|
347
|
-
description: text("description"),
|
|
348
|
-
schema: text("schema", { mode: "json" }).notNull(),
|
|
349
|
-
// JSON schema definition
|
|
350
|
-
isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
|
|
351
|
-
managed: integer("managed", { mode: "boolean" }).notNull().default(false),
|
|
352
|
-
// Config-managed collections cannot be edited in UI
|
|
353
|
-
sourceType: text("source_type").default("user"),
|
|
354
|
-
// 'user' (normal), 'form' (form-derived)
|
|
355
|
-
sourceId: text("source_id"),
|
|
356
|
-
// stores the form ID for form-derived collections
|
|
357
|
-
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
|
|
358
|
-
updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
|
|
359
|
-
});
|
|
360
|
-
var content = sqliteTable("content", {
|
|
361
|
-
id: text("id").primaryKey(),
|
|
362
|
-
collectionId: text("collection_id").notNull().references(() => collections.id),
|
|
363
|
-
slug: text("slug").notNull(),
|
|
364
|
-
title: text("title").notNull(),
|
|
365
|
-
data: text("data", { mode: "json" }).notNull(),
|
|
366
|
-
// JSON content data
|
|
367
|
-
status: text("status").notNull().default("draft"),
|
|
368
|
-
// 'draft', 'published', 'archived'
|
|
369
|
-
publishedAt: integer("published_at", { mode: "timestamp" }),
|
|
370
|
-
authorId: text("author_id").notNull().references(() => users.id),
|
|
371
|
-
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
|
|
372
|
-
updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
|
|
373
|
-
});
|
|
374
|
-
var contentVersions = sqliteTable("content_versions", {
|
|
375
|
-
id: text("id").primaryKey(),
|
|
376
|
-
contentId: text("content_id").notNull().references(() => content.id),
|
|
377
|
-
version: integer("version").notNull(),
|
|
378
|
-
data: text("data", { mode: "json" }).notNull(),
|
|
379
|
-
authorId: text("author_id").notNull().references(() => users.id),
|
|
380
|
-
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
|
|
381
|
-
});
|
|
382
|
-
var media = sqliteTable("media", {
|
|
383
|
-
id: text("id").primaryKey(),
|
|
384
|
-
filename: text("filename").notNull(),
|
|
385
|
-
originalName: text("original_name").notNull(),
|
|
386
|
-
mimeType: text("mime_type").notNull(),
|
|
387
|
-
size: integer("size").notNull(),
|
|
388
|
-
width: integer("width"),
|
|
389
|
-
height: integer("height"),
|
|
390
|
-
folder: text("folder").notNull().default("uploads"),
|
|
391
|
-
r2Key: text("r2_key").notNull(),
|
|
392
|
-
// R2 storage key
|
|
393
|
-
publicUrl: text("public_url").notNull(),
|
|
394
|
-
// CDN URL
|
|
395
|
-
thumbnailUrl: text("thumbnail_url"),
|
|
396
|
-
alt: text("alt"),
|
|
397
|
-
caption: text("caption"),
|
|
398
|
-
tags: text("tags", { mode: "json" }),
|
|
399
|
-
// JSON array of tags
|
|
400
|
-
uploadedBy: text("uploaded_by").notNull().references(() => users.id),
|
|
401
|
-
uploadedAt: integer("uploaded_at").notNull(),
|
|
402
|
-
updatedAt: integer("updated_at"),
|
|
403
|
-
publishedAt: integer("published_at"),
|
|
404
|
-
scheduledAt: integer("scheduled_at"),
|
|
405
|
-
archivedAt: integer("archived_at"),
|
|
406
|
-
deletedAt: integer("deleted_at")
|
|
407
|
-
});
|
|
408
|
-
var apiTokens = sqliteTable("api_tokens", {
|
|
409
|
-
id: text("id").primaryKey(),
|
|
410
|
-
name: text("name").notNull(),
|
|
411
|
-
token: text("token").notNull().unique(),
|
|
412
|
-
userId: text("user_id").notNull().references(() => users.id),
|
|
413
|
-
permissions: text("permissions", { mode: "json" }).notNull(),
|
|
414
|
-
// Array of permissions
|
|
415
|
-
expiresAt: integer("expires_at", { mode: "timestamp" }),
|
|
416
|
-
lastUsedAt: integer("last_used_at", { mode: "timestamp" }),
|
|
417
|
-
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
|
|
418
|
-
});
|
|
419
|
-
var workflowHistory = sqliteTable("workflow_history", {
|
|
420
|
-
id: text("id").primaryKey(),
|
|
421
|
-
contentId: text("content_id").notNull().references(() => content.id),
|
|
422
|
-
action: text("action").notNull(),
|
|
423
|
-
fromStatus: text("from_status").notNull(),
|
|
424
|
-
toStatus: text("to_status").notNull(),
|
|
425
|
-
userId: text("user_id").notNull().references(() => users.id),
|
|
426
|
-
comment: text("comment"),
|
|
427
|
-
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
|
|
428
|
-
});
|
|
429
|
-
var plugins = sqliteTable("plugins", {
|
|
430
|
-
id: text("id").primaryKey(),
|
|
431
|
-
name: text("name").notNull().unique(),
|
|
432
|
-
displayName: text("display_name").notNull(),
|
|
433
|
-
description: text("description"),
|
|
434
|
-
version: text("version").notNull(),
|
|
435
|
-
author: text("author").notNull(),
|
|
436
|
-
category: text("category").notNull(),
|
|
437
|
-
icon: text("icon"),
|
|
438
|
-
status: text("status").notNull().default("inactive"),
|
|
439
|
-
// 'active', 'inactive', 'error'
|
|
440
|
-
isCore: integer("is_core", { mode: "boolean" }).notNull().default(false),
|
|
441
|
-
settings: text("settings", { mode: "json" }),
|
|
442
|
-
permissions: text("permissions", { mode: "json" }),
|
|
443
|
-
dependencies: text("dependencies", { mode: "json" }),
|
|
444
|
-
downloadCount: integer("download_count").notNull().default(0),
|
|
445
|
-
rating: integer("rating").notNull().default(0),
|
|
446
|
-
installedAt: integer("installed_at").notNull(),
|
|
447
|
-
activatedAt: integer("activated_at"),
|
|
448
|
-
lastUpdated: integer("last_updated").notNull(),
|
|
449
|
-
errorMessage: text("error_message"),
|
|
450
|
-
createdAt: integer("created_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3)),
|
|
451
|
-
updatedAt: integer("updated_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
|
|
452
|
-
});
|
|
453
|
-
var pluginHooks = sqliteTable("plugin_hooks", {
|
|
454
|
-
id: text("id").primaryKey(),
|
|
455
|
-
pluginId: text("plugin_id").notNull().references(() => plugins.id),
|
|
456
|
-
hookName: text("hook_name").notNull(),
|
|
457
|
-
handlerName: text("handler_name").notNull(),
|
|
458
|
-
priority: integer("priority").notNull().default(10),
|
|
459
|
-
isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
|
|
460
|
-
createdAt: integer("created_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
|
|
461
|
-
});
|
|
462
|
-
var pluginRoutes = sqliteTable("plugin_routes", {
|
|
463
|
-
id: text("id").primaryKey(),
|
|
464
|
-
pluginId: text("plugin_id").notNull().references(() => plugins.id),
|
|
465
|
-
path: text("path").notNull(),
|
|
466
|
-
method: text("method").notNull(),
|
|
467
|
-
handlerName: text("handler_name").notNull(),
|
|
468
|
-
middleware: text("middleware", { mode: "json" }),
|
|
469
|
-
isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
|
|
470
|
-
createdAt: integer("created_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
|
|
471
|
-
});
|
|
472
|
-
var pluginAssets = sqliteTable("plugin_assets", {
|
|
473
|
-
id: text("id").primaryKey(),
|
|
474
|
-
pluginId: text("plugin_id").notNull().references(() => plugins.id),
|
|
475
|
-
assetType: text("asset_type").notNull(),
|
|
476
|
-
// 'css', 'js', 'image', 'font'
|
|
477
|
-
assetPath: text("asset_path").notNull(),
|
|
478
|
-
loadOrder: integer("load_order").notNull().default(100),
|
|
479
|
-
loadLocation: text("load_location").notNull().default("footer"),
|
|
480
|
-
// 'header', 'footer'
|
|
481
|
-
isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
|
|
482
|
-
createdAt: integer("created_at").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
|
|
483
|
-
});
|
|
484
|
-
var pluginActivityLog = sqliteTable("plugin_activity_log", {
|
|
485
|
-
id: text("id").primaryKey(),
|
|
486
|
-
pluginId: text("plugin_id").notNull().references(() => plugins.id),
|
|
487
|
-
action: text("action").notNull(),
|
|
488
|
-
userId: text("user_id"),
|
|
489
|
-
details: text("details", { mode: "json" }),
|
|
490
|
-
timestamp: integer("timestamp").notNull().$defaultFn(() => Math.floor(Date.now() / 1e3))
|
|
491
|
-
});
|
|
492
|
-
var insertUserSchema = createInsertSchema(users, {
|
|
493
|
-
email: (schema) => schema.email(),
|
|
494
|
-
firstName: (schema) => schema.min(1),
|
|
495
|
-
lastName: (schema) => schema.min(1),
|
|
496
|
-
username: (schema) => schema.min(3)
|
|
497
|
-
});
|
|
498
|
-
var selectUserSchema = createSelectSchema(users);
|
|
499
|
-
var insertCollectionSchema = createInsertSchema(collections, {
|
|
500
|
-
name: (schema) => schema.min(1).regex(/^[a-z0-9_]+$/, "Collection name must be lowercase with underscores"),
|
|
501
|
-
displayName: (schema) => schema.min(1)
|
|
502
|
-
});
|
|
503
|
-
var selectCollectionSchema = createSelectSchema(collections);
|
|
504
|
-
var insertContentSchema = createInsertSchema(content, {
|
|
505
|
-
slug: (schema) => schema.min(1).regex(/^[a-zA-Z0-9_-]+$/, "Slug must contain only letters, numbers, underscores, and hyphens"),
|
|
506
|
-
title: (schema) => schema.min(1),
|
|
507
|
-
status: (schema) => schema
|
|
508
|
-
});
|
|
509
|
-
var selectContentSchema = createSelectSchema(content);
|
|
510
|
-
var insertMediaSchema = createInsertSchema(media, {
|
|
511
|
-
filename: (schema) => schema.min(1),
|
|
512
|
-
originalName: (schema) => schema.min(1),
|
|
513
|
-
mimeType: (schema) => schema.min(1),
|
|
514
|
-
size: (schema) => schema.positive(),
|
|
515
|
-
r2Key: (schema) => schema.min(1),
|
|
516
|
-
publicUrl: (schema) => schema.url(),
|
|
517
|
-
folder: (schema) => schema.min(1)
|
|
518
|
-
});
|
|
519
|
-
var selectMediaSchema = createSelectSchema(media);
|
|
520
|
-
var insertWorkflowHistorySchema = createInsertSchema(workflowHistory, {
|
|
521
|
-
action: (schema) => schema.min(1),
|
|
522
|
-
fromStatus: (schema) => schema.min(1),
|
|
523
|
-
toStatus: (schema) => schema.min(1)
|
|
524
|
-
});
|
|
525
|
-
var selectWorkflowHistorySchema = createSelectSchema(workflowHistory);
|
|
526
|
-
var insertPluginSchema = createInsertSchema(plugins, {
|
|
527
|
-
name: (schema) => schema.min(1),
|
|
528
|
-
displayName: (schema) => schema.min(1),
|
|
529
|
-
version: (schema) => schema.min(1),
|
|
530
|
-
author: (schema) => schema.min(1),
|
|
531
|
-
category: (schema) => schema.min(1)
|
|
532
|
-
});
|
|
533
|
-
var selectPluginSchema = createSelectSchema(plugins);
|
|
534
|
-
var insertPluginHookSchema = createInsertSchema(pluginHooks, {
|
|
535
|
-
hookName: (schema) => schema.min(1),
|
|
536
|
-
handlerName: (schema) => schema.min(1)
|
|
537
|
-
});
|
|
538
|
-
var selectPluginHookSchema = createSelectSchema(pluginHooks);
|
|
539
|
-
var insertPluginRouteSchema = createInsertSchema(pluginRoutes, {
|
|
540
|
-
path: (schema) => schema.min(1),
|
|
541
|
-
method: (schema) => schema.min(1),
|
|
542
|
-
handlerName: (schema) => schema.min(1)
|
|
543
|
-
});
|
|
544
|
-
var selectPluginRouteSchema = createSelectSchema(pluginRoutes);
|
|
545
|
-
var insertPluginAssetSchema = createInsertSchema(pluginAssets, {
|
|
546
|
-
assetType: (schema) => schema.min(1),
|
|
547
|
-
assetPath: (schema) => schema.min(1)
|
|
548
|
-
});
|
|
549
|
-
var selectPluginAssetSchema = createSelectSchema(pluginAssets);
|
|
550
|
-
var insertPluginActivityLogSchema = createInsertSchema(pluginActivityLog, {
|
|
551
|
-
action: (schema) => schema.min(1)
|
|
552
|
-
});
|
|
553
|
-
var selectPluginActivityLogSchema = createSelectSchema(pluginActivityLog);
|
|
554
|
-
var systemLogs = sqliteTable("system_logs", {
|
|
555
|
-
id: text("id").primaryKey(),
|
|
556
|
-
level: text("level").notNull(),
|
|
557
|
-
// 'debug', 'info', 'warn', 'error', 'fatal'
|
|
558
|
-
category: text("category").notNull(),
|
|
559
|
-
// 'auth', 'api', 'workflow', 'plugin', 'media', 'system', etc.
|
|
560
|
-
message: text("message").notNull(),
|
|
561
|
-
data: text("data", { mode: "json" }),
|
|
562
|
-
// Additional structured data
|
|
563
|
-
userId: text("user_id").references(() => users.id),
|
|
564
|
-
sessionId: text("session_id"),
|
|
565
|
-
requestId: text("request_id"),
|
|
566
|
-
ipAddress: text("ip_address"),
|
|
567
|
-
userAgent: text("user_agent"),
|
|
568
|
-
method: text("method"),
|
|
569
|
-
// HTTP method for API logs
|
|
570
|
-
url: text("url"),
|
|
571
|
-
// Request URL for API logs
|
|
572
|
-
statusCode: integer("status_code"),
|
|
573
|
-
// HTTP status code for API logs
|
|
574
|
-
duration: integer("duration"),
|
|
575
|
-
// Request duration in milliseconds
|
|
576
|
-
stackTrace: text("stack_trace"),
|
|
577
|
-
// Error stack trace for error logs
|
|
578
|
-
tags: text("tags", { mode: "json" }),
|
|
579
|
-
// Array of tags for categorization
|
|
580
|
-
source: text("source"),
|
|
581
|
-
// Source component/module that generated the log
|
|
582
|
-
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
|
|
583
|
-
});
|
|
584
|
-
var logConfig = sqliteTable("log_config", {
|
|
585
|
-
id: text("id").primaryKey(),
|
|
586
|
-
category: text("category").notNull().unique(),
|
|
587
|
-
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
|
588
|
-
level: text("level").notNull().default("info"),
|
|
589
|
-
// minimum log level to store
|
|
590
|
-
retention: integer("retention").notNull().default(30),
|
|
591
|
-
// days to keep logs
|
|
592
|
-
maxSize: integer("max_size").default(1e4),
|
|
593
|
-
// max number of logs per category
|
|
594
|
-
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
|
|
595
|
-
updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
|
|
596
|
-
});
|
|
597
|
-
var insertSystemLogSchema = createInsertSchema(systemLogs, {
|
|
598
|
-
level: (schema) => schema.min(1),
|
|
599
|
-
category: (schema) => schema.min(1),
|
|
600
|
-
message: (schema) => schema.min(1)
|
|
601
|
-
});
|
|
602
|
-
var selectSystemLogSchema = createSelectSchema(systemLogs);
|
|
603
|
-
var insertLogConfigSchema = createInsertSchema(logConfig, {
|
|
604
|
-
category: (schema) => schema.min(1),
|
|
605
|
-
level: (schema) => schema.min(1)
|
|
606
|
-
});
|
|
607
|
-
var selectLogConfigSchema = createSelectSchema(logConfig);
|
|
608
|
-
var securityEvents = sqliteTable("security_events", {
|
|
609
|
-
id: text("id").primaryKey(),
|
|
610
|
-
eventType: text("event_type").notNull(),
|
|
611
|
-
severity: text("severity").notNull().default("info"),
|
|
612
|
-
userId: text("user_id"),
|
|
613
|
-
email: text("email"),
|
|
614
|
-
ipAddress: text("ip_address"),
|
|
615
|
-
userAgent: text("user_agent"),
|
|
616
|
-
countryCode: text("country_code"),
|
|
617
|
-
requestPath: text("request_path"),
|
|
618
|
-
requestMethod: text("request_method"),
|
|
619
|
-
details: text("details", { mode: "json" }),
|
|
620
|
-
fingerprint: text("fingerprint"),
|
|
621
|
-
blocked: integer("blocked").notNull().default(0),
|
|
622
|
-
createdAt: integer("created_at").notNull().$defaultFn(() => Date.now())
|
|
623
|
-
});
|
|
624
|
-
var insertSecurityEventSchema = createInsertSchema(securityEvents, {
|
|
625
|
-
eventType: (schema) => schema.min(1),
|
|
626
|
-
severity: (schema) => schema.min(1)
|
|
627
|
-
});
|
|
628
|
-
var selectSecurityEventSchema = createSelectSchema(securityEvents);
|
|
629
|
-
var forms = sqliteTable("forms", {
|
|
630
|
-
id: text("id").primaryKey(),
|
|
631
|
-
name: text("name").notNull().unique(),
|
|
632
|
-
// Machine name (e.g., "contact-form")
|
|
633
|
-
displayName: text("display_name").notNull(),
|
|
634
|
-
// Human name (e.g., "Contact Form")
|
|
635
|
-
description: text("description"),
|
|
636
|
-
category: text("category").notNull().default("general"),
|
|
637
|
-
// contact, survey, registration, etc.
|
|
638
|
-
// Form.io schema (JSON)
|
|
639
|
-
formioSchema: text("formio_schema", { mode: "json" }).notNull(),
|
|
640
|
-
// Complete Form.io JSON schema
|
|
641
|
-
// Settings (JSON)
|
|
642
|
-
settings: text("settings", { mode: "json" }),
|
|
643
|
-
// emailNotifications, successMessage, etc.
|
|
644
|
-
// Status & Management
|
|
645
|
-
isActive: integer("is_active", { mode: "boolean" }).notNull().default(true),
|
|
646
|
-
isPublic: integer("is_public", { mode: "boolean" }).notNull().default(true),
|
|
647
|
-
managed: integer("managed", { mode: "boolean" }).notNull().default(false),
|
|
648
|
-
// Metadata
|
|
649
|
-
icon: text("icon"),
|
|
650
|
-
color: text("color"),
|
|
651
|
-
tags: text("tags", { mode: "json" }),
|
|
652
|
-
// JSON array
|
|
653
|
-
// Stats
|
|
654
|
-
submissionCount: integer("submission_count").notNull().default(0),
|
|
655
|
-
viewCount: integer("view_count").notNull().default(0),
|
|
656
|
-
// Ownership
|
|
657
|
-
createdBy: text("created_by").references(() => users.id),
|
|
658
|
-
updatedBy: text("updated_by").references(() => users.id),
|
|
659
|
-
// Timestamps
|
|
660
|
-
createdAt: integer("created_at").notNull(),
|
|
661
|
-
updatedAt: integer("updated_at").notNull()
|
|
662
|
-
});
|
|
663
|
-
var formSubmissions = sqliteTable("form_submissions", {
|
|
664
|
-
id: text("id").primaryKey(),
|
|
665
|
-
formId: text("form_id").notNull().references(() => forms.id, { onDelete: "cascade" }),
|
|
666
|
-
// Submission data
|
|
667
|
-
submissionData: text("submission_data", { mode: "json" }).notNull(),
|
|
668
|
-
// The actual form data
|
|
669
|
-
// Submission metadata
|
|
670
|
-
status: text("status").notNull().default("pending"),
|
|
671
|
-
// pending, reviewed, approved, rejected, spam
|
|
672
|
-
submissionNumber: integer("submission_number"),
|
|
673
|
-
// User information
|
|
674
|
-
userId: text("user_id").references(() => users.id),
|
|
675
|
-
userEmail: text("user_email"),
|
|
676
|
-
// Tracking
|
|
677
|
-
ipAddress: text("ip_address"),
|
|
678
|
-
userAgent: text("user_agent"),
|
|
679
|
-
referrer: text("referrer"),
|
|
680
|
-
utmSource: text("utm_source"),
|
|
681
|
-
utmMedium: text("utm_medium"),
|
|
682
|
-
utmCampaign: text("utm_campaign"),
|
|
683
|
-
// Review/Processing
|
|
684
|
-
reviewedBy: text("reviewed_by").references(() => users.id),
|
|
685
|
-
reviewedAt: integer("reviewed_at"),
|
|
686
|
-
reviewNotes: text("review_notes"),
|
|
687
|
-
// Flags
|
|
688
|
-
isSpam: integer("is_spam", { mode: "boolean" }).notNull().default(false),
|
|
689
|
-
isArchived: integer("is_archived", { mode: "boolean" }).notNull().default(false),
|
|
690
|
-
// Content integration
|
|
691
|
-
contentId: text("content_id").references(() => content.id),
|
|
692
|
-
// Links submission to its content item
|
|
693
|
-
// Timestamps
|
|
694
|
-
submittedAt: integer("submitted_at").notNull(),
|
|
695
|
-
updatedAt: integer("updated_at").notNull()
|
|
696
|
-
});
|
|
697
|
-
var formFiles = sqliteTable("form_files", {
|
|
698
|
-
id: text("id").primaryKey(),
|
|
699
|
-
submissionId: text("submission_id").notNull().references(() => formSubmissions.id, { onDelete: "cascade" }),
|
|
700
|
-
mediaId: text("media_id").notNull().references(() => media.id, { onDelete: "cascade" }),
|
|
701
|
-
fieldName: text("field_name").notNull(),
|
|
702
|
-
// Form field that uploaded this file
|
|
703
|
-
uploadedAt: integer("uploaded_at").notNull()
|
|
704
|
-
});
|
|
705
|
-
var insertFormSchema = createInsertSchema(forms);
|
|
706
|
-
var selectFormSchema = createSelectSchema(forms);
|
|
707
|
-
var insertFormSubmissionSchema = createInsertSchema(formSubmissions);
|
|
708
|
-
var selectFormSubmissionSchema = createSelectSchema(formSubmissions);
|
|
709
|
-
var insertFormFileSchema = createInsertSchema(formFiles);
|
|
710
|
-
var selectFormFileSchema = createSelectSchema(formFiles);
|
|
711
8
|
var Logger = class {
|
|
712
9
|
db;
|
|
713
10
|
enabled = true;
|
|
@@ -1017,104 +314,82 @@ function initLogger(database) {
|
|
|
1017
314
|
}
|
|
1018
315
|
|
|
1019
316
|
// src/services/cache.ts
|
|
317
|
+
function toPluginConfig(config) {
|
|
318
|
+
return {
|
|
319
|
+
ttl: config.ttl,
|
|
320
|
+
namespace: config.keyPrefix,
|
|
321
|
+
// KV survives isolate evictions — required for the dashboard to show non-zero
|
|
322
|
+
// counts across requests in production. Falls back to memory-only when the
|
|
323
|
+
// CACHE_KV binding is missing (cache plugin handles the null case).
|
|
324
|
+
kvEnabled: true,
|
|
325
|
+
memoryEnabled: true,
|
|
326
|
+
invalidateOn: [],
|
|
327
|
+
version: "v1"
|
|
328
|
+
};
|
|
329
|
+
}
|
|
1020
330
|
var CacheService = class {
|
|
1021
331
|
config;
|
|
1022
|
-
|
|
332
|
+
inner;
|
|
333
|
+
// Tracks expiry times so getWithSource can distinguish 'none' vs 'expired'.
|
|
334
|
+
// The plugin returns source:'miss' for both cases; we differentiate here.
|
|
335
|
+
keyExpiry = /* @__PURE__ */ new Map();
|
|
1023
336
|
constructor(config) {
|
|
1024
337
|
this.config = config;
|
|
338
|
+
this.inner = getCacheService(toPluginConfig(config));
|
|
1025
339
|
}
|
|
1026
|
-
/**
|
|
1027
|
-
* Generate cache key with prefix
|
|
1028
|
-
*/
|
|
1029
340
|
generateKey(type, identifier) {
|
|
1030
341
|
const parts = [this.config.keyPrefix, type];
|
|
1031
|
-
if (identifier)
|
|
1032
|
-
parts.push(identifier);
|
|
1033
|
-
}
|
|
342
|
+
if (identifier !== void 0 && identifier !== "") parts.push(identifier);
|
|
1034
343
|
return parts.join(":");
|
|
1035
344
|
}
|
|
1036
|
-
/**
|
|
1037
|
-
* Get value from cache
|
|
1038
|
-
*/
|
|
1039
345
|
async get(key) {
|
|
1040
|
-
|
|
1041
|
-
if (!cached) {
|
|
1042
|
-
return null;
|
|
1043
|
-
}
|
|
1044
|
-
if (Date.now() > cached.expires) {
|
|
1045
|
-
this.memoryCache.delete(key);
|
|
1046
|
-
return null;
|
|
1047
|
-
}
|
|
1048
|
-
return cached.value;
|
|
346
|
+
return this.inner.get(key);
|
|
1049
347
|
}
|
|
1050
|
-
/**
|
|
1051
|
-
* Get value from cache with source information
|
|
1052
|
-
*/
|
|
1053
348
|
async getWithSource(key) {
|
|
1054
|
-
const
|
|
1055
|
-
if (
|
|
1056
|
-
|
|
1057
|
-
hit:
|
|
1058
|
-
data:
|
|
1059
|
-
source:
|
|
349
|
+
const result = await this.inner.getWithSource(key);
|
|
350
|
+
if (result.hit) {
|
|
351
|
+
const out = {
|
|
352
|
+
hit: true,
|
|
353
|
+
data: result.data,
|
|
354
|
+
source: result.source
|
|
1060
355
|
};
|
|
356
|
+
if (result.ttl !== void 0) out.ttl = result.ttl;
|
|
357
|
+
return out;
|
|
1061
358
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
data: null,
|
|
1067
|
-
source: "expired"
|
|
1068
|
-
};
|
|
359
|
+
const expiry = this.keyExpiry.get(key);
|
|
360
|
+
if (expiry !== void 0) {
|
|
361
|
+
this.keyExpiry.delete(key);
|
|
362
|
+
return { hit: false, data: null, source: "expired" };
|
|
1069
363
|
}
|
|
1070
|
-
return {
|
|
1071
|
-
hit: true,
|
|
1072
|
-
data: cached.value,
|
|
1073
|
-
source: "memory",
|
|
1074
|
-
ttl: (cached.expires - Date.now()) / 1e3
|
|
1075
|
-
// TTL in seconds
|
|
1076
|
-
};
|
|
364
|
+
return { hit: false, data: null, source: "none" };
|
|
1077
365
|
}
|
|
1078
|
-
/**
|
|
1079
|
-
* Set value in cache
|
|
1080
|
-
*/
|
|
1081
366
|
async set(key, value, ttl) {
|
|
1082
|
-
const
|
|
1083
|
-
this.
|
|
367
|
+
const effectiveTtl = ttl ?? this.config.ttl;
|
|
368
|
+
this.keyExpiry.set(key, Date.now() + effectiveTtl * 1e3);
|
|
369
|
+
await this.inner.set(key, value, ttl !== void 0 ? { ttl } : void 0);
|
|
1084
370
|
}
|
|
1085
|
-
/**
|
|
1086
|
-
* Delete specific key from cache
|
|
1087
|
-
*/
|
|
1088
371
|
async delete(key) {
|
|
1089
|
-
this.
|
|
372
|
+
this.keyExpiry.delete(key);
|
|
373
|
+
await this.inner.delete(key);
|
|
1090
374
|
}
|
|
1091
|
-
/**
|
|
1092
|
-
* Invalidate cache keys matching a pattern
|
|
1093
|
-
* For memory cache, we do simple string matching
|
|
1094
|
-
*/
|
|
1095
375
|
async invalidate(pattern) {
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
this.memoryCache.delete(key);
|
|
376
|
+
if (pattern.includes("*") || pattern.includes("?")) {
|
|
377
|
+
const regex = new RegExp("^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$");
|
|
378
|
+
for (const k of this.keyExpiry.keys()) {
|
|
379
|
+
if (regex.test(k)) this.keyExpiry.delete(k);
|
|
1101
380
|
}
|
|
381
|
+
} else {
|
|
382
|
+
this.keyExpiry.delete(pattern);
|
|
1102
383
|
}
|
|
384
|
+
await this.inner.invalidate(pattern);
|
|
1103
385
|
}
|
|
1104
|
-
/**
|
|
1105
|
-
* Clear all cache
|
|
1106
|
-
*/
|
|
1107
386
|
async clear() {
|
|
1108
|
-
this.
|
|
387
|
+
this.keyExpiry.clear();
|
|
388
|
+
await this.inner.clear();
|
|
1109
389
|
}
|
|
1110
|
-
/**
|
|
1111
|
-
* Get value from cache or set it using a callback
|
|
1112
|
-
*/
|
|
1113
390
|
async getOrSet(key, callback, ttl) {
|
|
1114
391
|
const cached = await this.get(key);
|
|
1115
|
-
if (cached !== null)
|
|
1116
|
-
return cached;
|
|
1117
|
-
}
|
|
392
|
+
if (cached !== null) return cached;
|
|
1118
393
|
const value = await callback();
|
|
1119
394
|
await this.set(key, value, ttl);
|
|
1120
395
|
return value;
|
|
@@ -1142,86 +417,96 @@ var CACHE_CONFIGS = {
|
|
|
1142
417
|
keyPrefix: "collection"
|
|
1143
418
|
}
|
|
1144
419
|
};
|
|
1145
|
-
function
|
|
420
|
+
function getCacheService2(config) {
|
|
1146
421
|
return new CacheService(config);
|
|
1147
422
|
}
|
|
1148
423
|
|
|
1149
424
|
// src/services/settings.ts
|
|
425
|
+
var TYPE_ID = "site_settings";
|
|
426
|
+
var TENANT = "default";
|
|
1150
427
|
var SettingsService = class {
|
|
1151
428
|
constructor(db) {
|
|
1152
429
|
this.db = db;
|
|
1153
430
|
}
|
|
1154
431
|
/**
|
|
1155
|
-
* Get
|
|
432
|
+
* Get settings document for a category (general or security)
|
|
1156
433
|
*/
|
|
1157
|
-
async
|
|
434
|
+
async getSettingsDocument(category) {
|
|
1158
435
|
try {
|
|
1159
|
-
const
|
|
1160
|
-
|
|
436
|
+
const row = await this.db.prepare(`
|
|
437
|
+
SELECT data FROM documents
|
|
438
|
+
WHERE type_id = ? AND slug = ? AND tenant_id = ? AND is_current_draft = 1 AND deleted_at IS NULL
|
|
439
|
+
`).bind(TYPE_ID, category, TENANT).first();
|
|
440
|
+
if (!row) {
|
|
1161
441
|
return null;
|
|
1162
442
|
}
|
|
1163
|
-
return JSON.parse(
|
|
443
|
+
return JSON.parse(row.data);
|
|
1164
444
|
} catch (error) {
|
|
1165
|
-
console.error(`Error getting
|
|
445
|
+
console.error(`Error getting settings document for ${category}:`, error);
|
|
1166
446
|
return null;
|
|
1167
447
|
}
|
|
1168
448
|
}
|
|
1169
449
|
/**
|
|
1170
|
-
*
|
|
450
|
+
* Save settings document for a category (general or security)
|
|
1171
451
|
*/
|
|
1172
|
-
async
|
|
452
|
+
async saveSettingsDocument(category, data) {
|
|
1173
453
|
try {
|
|
1174
|
-
const
|
|
1175
|
-
const
|
|
1176
|
-
for (const row of results || []) {
|
|
1177
|
-
const r = row;
|
|
1178
|
-
settings[r.key] = JSON.parse(r.value);
|
|
1179
|
-
}
|
|
1180
|
-
return settings;
|
|
1181
|
-
} catch (error) {
|
|
1182
|
-
console.error(`Error getting category settings for ${category}:`, error);
|
|
1183
|
-
return {};
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
/**
|
|
1187
|
-
* Set a setting value
|
|
1188
|
-
*/
|
|
1189
|
-
async setSetting(category, key, value) {
|
|
1190
|
-
try {
|
|
1191
|
-
const now = Date.now();
|
|
1192
|
-
const jsonValue = JSON.stringify(value);
|
|
454
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
455
|
+
const jsonData = JSON.stringify(data);
|
|
1193
456
|
await this.db.prepare(`
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
const jsonValue = JSON.stringify(value);
|
|
457
|
+
INSERT OR IGNORE INTO document_types (id, name, display_name, description, schema, source, is_system, is_active, created_at, updated_at)
|
|
458
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
459
|
+
`).bind(
|
|
460
|
+
TYPE_ID,
|
|
461
|
+
TYPE_ID,
|
|
462
|
+
"Site Settings",
|
|
463
|
+
"Global site configuration settings",
|
|
464
|
+
"{}",
|
|
465
|
+
"system",
|
|
466
|
+
1,
|
|
467
|
+
1,
|
|
468
|
+
now,
|
|
469
|
+
now
|
|
470
|
+
).run();
|
|
471
|
+
const existing = await this.db.prepare(`
|
|
472
|
+
SELECT id FROM documents
|
|
473
|
+
WHERE type_id = ? AND slug = ? AND tenant_id = ? AND is_current_draft = 1 AND deleted_at IS NULL
|
|
474
|
+
`).bind(TYPE_ID, category, TENANT).first();
|
|
475
|
+
if (existing) {
|
|
1214
476
|
await this.db.prepare(`
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
477
|
+
UPDATE documents
|
|
478
|
+
SET data = ?, updated_at = ?
|
|
479
|
+
WHERE id = ? AND is_current_draft = 1
|
|
480
|
+
`).bind(jsonData, now, existing.id).run();
|
|
481
|
+
} else {
|
|
482
|
+
const docId = crypto.randomUUID();
|
|
483
|
+
const rootId = docId;
|
|
484
|
+
const title = category === "general" ? "General Settings" : "Security Settings";
|
|
485
|
+
await this.db.prepare(`
|
|
486
|
+
INSERT INTO documents (
|
|
487
|
+
id, root_id, type_id, version_number, is_current_draft, is_published, status,
|
|
488
|
+
parent_root_id, slug, title, tenant_id, locale, translation_group_id,
|
|
489
|
+
data, metadata, created_at, updated_at
|
|
490
|
+
) VALUES (
|
|
491
|
+
?, ?, ?, 1, 1, 1, 'published',
|
|
492
|
+
'', ?, ?, ?, 'default', '',
|
|
493
|
+
?, '{}', ?, ?
|
|
494
|
+
)
|
|
495
|
+
`).bind(
|
|
496
|
+
docId,
|
|
497
|
+
rootId,
|
|
498
|
+
TYPE_ID,
|
|
499
|
+
category,
|
|
500
|
+
title,
|
|
501
|
+
TENANT,
|
|
502
|
+
jsonData,
|
|
503
|
+
now,
|
|
504
|
+
now
|
|
505
|
+
).run();
|
|
1221
506
|
}
|
|
1222
507
|
return true;
|
|
1223
508
|
} catch (error) {
|
|
1224
|
-
console.error(`Error
|
|
509
|
+
console.error(`Error saving settings document for ${category}:`, error);
|
|
1225
510
|
return false;
|
|
1226
511
|
}
|
|
1227
512
|
}
|
|
@@ -1229,48 +514,41 @@ var SettingsService = class {
|
|
|
1229
514
|
* Get general settings with defaults
|
|
1230
515
|
*/
|
|
1231
516
|
async getGeneralSettings(userEmail) {
|
|
1232
|
-
const settings = await this.
|
|
517
|
+
const settings = await this.getSettingsDocument("general");
|
|
1233
518
|
return {
|
|
1234
|
-
siteName: settings
|
|
1235
|
-
siteDescription: settings
|
|
1236
|
-
adminEmail: settings
|
|
1237
|
-
timezone: settings
|
|
1238
|
-
language: settings
|
|
1239
|
-
maintenanceMode: settings
|
|
519
|
+
siteName: settings?.siteName || "SonicJS AI",
|
|
520
|
+
siteDescription: settings?.siteDescription || "A modern headless CMS powered by AI",
|
|
521
|
+
adminEmail: settings?.adminEmail || userEmail || "admin@example.com",
|
|
522
|
+
timezone: settings?.timezone || "UTC",
|
|
523
|
+
language: settings?.language || "en",
|
|
524
|
+
maintenanceMode: settings?.maintenanceMode || false
|
|
1240
525
|
};
|
|
1241
526
|
}
|
|
1242
527
|
/**
|
|
1243
528
|
* Save general settings
|
|
1244
529
|
*/
|
|
1245
530
|
async saveGeneralSettings(settings) {
|
|
1246
|
-
const
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
if (settings.adminEmail !== void 0) settingsToSave.adminEmail = settings.adminEmail;
|
|
1250
|
-
if (settings.timezone !== void 0) settingsToSave.timezone = settings.timezone;
|
|
1251
|
-
if (settings.language !== void 0) settingsToSave.language = settings.language;
|
|
1252
|
-
if (settings.maintenanceMode !== void 0) settingsToSave.maintenanceMode = settings.maintenanceMode;
|
|
1253
|
-
return await this.setMultipleSettings("general", settingsToSave);
|
|
531
|
+
const existing = await this.getSettingsDocument("general");
|
|
532
|
+
const merged = { ...existing, ...settings };
|
|
533
|
+
return await this.saveSettingsDocument("general", merged);
|
|
1254
534
|
}
|
|
1255
535
|
/**
|
|
1256
536
|
* Get security settings with defaults
|
|
1257
537
|
*/
|
|
1258
538
|
async getSecuritySettings() {
|
|
1259
|
-
const settings = await this.
|
|
539
|
+
const settings = await this.getSettingsDocument("security");
|
|
1260
540
|
return {
|
|
1261
|
-
jwtExpiresIn: settings
|
|
1262
|
-
jwtRefreshGraceSeconds: typeof settings
|
|
541
|
+
jwtExpiresIn: settings?.jwtExpiresIn || "30d",
|
|
542
|
+
jwtRefreshGraceSeconds: typeof settings?.jwtRefreshGraceSeconds === "number" ? settings.jwtRefreshGraceSeconds : 60 * 60 * 24 * 7
|
|
1263
543
|
};
|
|
1264
544
|
}
|
|
1265
545
|
/**
|
|
1266
546
|
* Save security settings
|
|
1267
547
|
*/
|
|
1268
548
|
async saveSecuritySettings(settings) {
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
settingsToSave.jwtRefreshGraceSeconds = settings.jwtRefreshGraceSeconds;
|
|
1273
|
-
return await this.setMultipleSettings("security", settingsToSave);
|
|
549
|
+
const existing = await this.getSettingsDocument("security");
|
|
550
|
+
const merged = { ...existing, ...settings };
|
|
551
|
+
return await this.saveSettingsDocument("security", merged);
|
|
1274
552
|
}
|
|
1275
553
|
};
|
|
1276
554
|
|
|
@@ -1567,6 +845,11 @@ var CATEGORY_INFO = {
|
|
|
1567
845
|
title: "Files",
|
|
1568
846
|
description: "File serving from R2 storage",
|
|
1569
847
|
icon: "📁"
|
|
848
|
+
},
|
|
849
|
+
"Collections": {
|
|
850
|
+
title: "Collections",
|
|
851
|
+
description: "Per-collection REST endpoints (auto-generated from registered collections)",
|
|
852
|
+
icon: "📚"
|
|
1570
853
|
}
|
|
1571
854
|
};
|
|
1572
855
|
var ROUTE_METADATA = {
|
|
@@ -1611,7 +894,7 @@ var ROUTE_METADATA = {
|
|
|
1611
894
|
"DELETE /admin/api/collections/:id/fields/:fieldId": { description: "Remove a field from a collection", category: "Admin", authentication: true },
|
|
1612
895
|
"POST /admin/api/collections/:id/fields/reorder": { description: "Reorder fields in a collection", category: "Admin", authentication: true },
|
|
1613
896
|
"GET /admin/api/migrations/status": { description: "Get database migration status", category: "Admin", authentication: true },
|
|
1614
|
-
"POST /admin/api/migrations/run": { description: "
|
|
897
|
+
"POST /admin/api/migrations/run": { description: "Explain how to run D1 migrations with Wrangler", category: "Admin", authentication: true },
|
|
1615
898
|
"GET /admin/api/content": { description: "List content items with filtering and pagination", category: "Admin", authentication: true },
|
|
1616
899
|
"GET /admin/api/content/:id": { description: "Get a content item for admin editing", category: "Admin", authentication: true },
|
|
1617
900
|
"POST /admin/api/content": { description: "Create content via admin API", category: "Admin", authentication: true },
|
|
@@ -1699,6 +982,12 @@ var ROUTE_METADATA = {
|
|
|
1699
982
|
"GET /api": { description: "API root - returns API information and available endpoints", category: "System", authentication: false },
|
|
1700
983
|
"GET /api/system/info": { description: "Get system information and version", category: "System", authentication: false },
|
|
1701
984
|
"GET /api/system/schema": { description: "Get database schema information", category: "System", authentication: false },
|
|
985
|
+
// Collection shorthand routes
|
|
986
|
+
"GET /api/:collection": { description: "List items from a collection (shorthand route)", category: "Collections", authentication: false },
|
|
987
|
+
"GET /api/:collection/:id": { description: "Get a single item by ID from a collection", category: "Collections", authentication: false },
|
|
988
|
+
"POST /api/:collection": { description: "Create an item in a collection", category: "Collections", authentication: true },
|
|
989
|
+
"PUT /api/:collection/:id": { description: "Update an item in a collection", category: "Collections", authentication: true },
|
|
990
|
+
"DELETE /api/:collection/:id": { description: "Delete an item from a collection", category: "Collections", authentication: true },
|
|
1702
991
|
// File serving
|
|
1703
992
|
"GET /files/*": { description: "Serve files from R2 storage (public access)", category: "Files", authentication: false },
|
|
1704
993
|
// Database tools
|
|
@@ -1776,6 +1065,7 @@ function inferCategory(path) {
|
|
|
1776
1065
|
if (path.startsWith("/forms/")) return "Forms";
|
|
1777
1066
|
if (path.startsWith("/files/")) return "Files";
|
|
1778
1067
|
if (path === "/health" || path.startsWith("/api")) return "System";
|
|
1068
|
+
if (path.match(/^\/api\/[^/]+(\/:id)?$/) && !path.startsWith("/api/content") && !path.startsWith("/api/collections") && !path.startsWith("/api/media") && !path.startsWith("/api/search") && !path.startsWith("/api/system") && !path.startsWith("/api/health") && !path.startsWith("/api/documents") && !path.startsWith("/api/forms")) return "Collections";
|
|
1779
1069
|
return "Other";
|
|
1780
1070
|
}
|
|
1781
1071
|
function inferAuth(path) {
|
|
@@ -1838,6 +1128,6 @@ function buildRouteList(app) {
|
|
|
1838
1128
|
}
|
|
1839
1129
|
}
|
|
1840
1130
|
|
|
1841
|
-
export { CACHE_CONFIGS, CATEGORY_INFO, CacheService, Logger, SettingsService, TelemetryService,
|
|
1842
|
-
//# sourceMappingURL=chunk-
|
|
1843
|
-
//# sourceMappingURL=chunk-
|
|
1131
|
+
export { CACHE_CONFIGS, CATEGORY_INFO, CacheService, Logger, SettingsService, TelemetryService, buildRouteList, createInstallationIdentity, getAppInstance, getCacheService2 as getCacheService, getLogger, getTelemetryService, initLogger, initTelemetry, setAppInstance };
|
|
1132
|
+
//# sourceMappingURL=chunk-ZEZ245PW.js.map
|
|
1133
|
+
//# sourceMappingURL=chunk-ZEZ245PW.js.map
|