@sonicjs-cms/core 2.3.17 → 2.5.0

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 (73) hide show
  1. package/dist/{chunk-CPXAVWCU.js → chunk-3YUHXWSG.js} +278 -3
  2. package/dist/chunk-3YUHXWSG.js.map +1 -0
  3. package/dist/chunk-AI2JJIJX.cjs +211 -0
  4. package/dist/chunk-AI2JJIJX.cjs.map +1 -0
  5. package/dist/{chunk-TMQOLXLY.js → chunk-BHNDALCA.js} +56 -4
  6. package/dist/chunk-BHNDALCA.js.map +1 -0
  7. package/dist/{chunk-IEWLOVP3.cjs → chunk-I4V3VZWF.cjs} +46 -2
  8. package/dist/chunk-I4V3VZWF.cjs.map +1 -0
  9. package/dist/{chunk-DTLB6UIH.cjs → chunk-LWG2MWDA.cjs} +280 -2
  10. package/dist/chunk-LWG2MWDA.cjs.map +1 -0
  11. package/dist/{chunk-QBWD6FKH.js → chunk-OJZ45OJD.js} +559 -281
  12. package/dist/chunk-OJZ45OJD.js.map +1 -0
  13. package/dist/chunk-QDBNW7KQ.js +209 -0
  14. package/dist/chunk-QDBNW7KQ.js.map +1 -0
  15. package/dist/{chunk-VYL6RIV6.js → chunk-TJTWRO4G.js} +5 -5
  16. package/dist/chunk-TJTWRO4G.js.map +1 -0
  17. package/dist/{chunk-74DP754U.cjs → chunk-UAQL2VWX.cjs} +644 -366
  18. package/dist/chunk-UAQL2VWX.cjs.map +1 -0
  19. package/dist/{chunk-B6YJRVFQ.js → chunk-VEL7QRYI.js} +46 -2
  20. package/dist/chunk-VEL7QRYI.js.map +1 -0
  21. package/dist/{chunk-YHJB26RJ.cjs → chunk-YYV3XQOQ.cjs} +6 -6
  22. package/dist/chunk-YYV3XQOQ.cjs.map +1 -0
  23. package/dist/{chunk-2XCJ3HT5.cjs → chunk-ZWV3EBZ7.cjs} +58 -3
  24. package/dist/chunk-ZWV3EBZ7.cjs.map +1 -0
  25. package/dist/{collection-config-FLlGtsh9.d.cts → collection-config-B6gMPunn.d.cts} +9 -1
  26. package/dist/{collection-config-FLlGtsh9.d.ts → collection-config-B6gMPunn.d.ts} +9 -1
  27. package/dist/index.cjs +114 -85
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +4 -4
  30. package/dist/index.d.ts +4 -4
  31. package/dist/index.js +37 -8
  32. package/dist/index.js.map +1 -1
  33. package/dist/middleware.cjs +23 -23
  34. package/dist/middleware.js +2 -2
  35. package/dist/migrations-NIEUFG44.cjs +13 -0
  36. package/dist/{migrations-EOV7NJZ7.cjs.map → migrations-NIEUFG44.cjs.map} +1 -1
  37. package/dist/migrations-TGZKJKV4.js +4 -0
  38. package/dist/{migrations-6HKPNPTK.js.map → migrations-TGZKJKV4.js.map} +1 -1
  39. package/dist/{plugin-bootstrap-C0E3jdz-.d.cts → plugin-bootstrap-SHsdjE6X.d.cts} +1 -1
  40. package/dist/{plugin-bootstrap-CDh0JHtW.d.ts → plugin-bootstrap-dYhD9fQR.d.ts} +1 -1
  41. package/dist/plugin-manager-Baa6xXqB.d.ts +328 -0
  42. package/dist/plugin-manager-vBal9Zip.d.cts +328 -0
  43. package/dist/plugins.cjs +20 -7
  44. package/dist/plugins.d.cts +53 -310
  45. package/dist/plugins.d.ts +53 -310
  46. package/dist/plugins.js +2 -1
  47. package/dist/routes.cjs +25 -24
  48. package/dist/routes.js +5 -4
  49. package/dist/services.cjs +2 -2
  50. package/dist/services.d.cts +2 -2
  51. package/dist/services.d.ts +2 -2
  52. package/dist/services.js +1 -1
  53. package/dist/types.d.cts +1 -1
  54. package/dist/types.d.ts +1 -1
  55. package/dist/utils.cjs +23 -11
  56. package/dist/utils.d.cts +38 -1
  57. package/dist/utils.d.ts +38 -1
  58. package/dist/utils.js +1 -1
  59. package/migrations/027_fix_slug_field_type.sql +18 -0
  60. package/migrations/028_fix_slug_field_type_in_schemas.sql +30 -0
  61. package/package.json +2 -1
  62. package/dist/chunk-2XCJ3HT5.cjs.map +0 -1
  63. package/dist/chunk-74DP754U.cjs.map +0 -1
  64. package/dist/chunk-B6YJRVFQ.js.map +0 -1
  65. package/dist/chunk-CPXAVWCU.js.map +0 -1
  66. package/dist/chunk-DTLB6UIH.cjs.map +0 -1
  67. package/dist/chunk-IEWLOVP3.cjs.map +0 -1
  68. package/dist/chunk-QBWD6FKH.js.map +0 -1
  69. package/dist/chunk-TMQOLXLY.js.map +0 -1
  70. package/dist/chunk-VYL6RIV6.js.map +0 -1
  71. package/dist/chunk-YHJB26RJ.cjs.map +0 -1
  72. package/dist/migrations-6HKPNPTK.js +0 -4
  73. package/dist/migrations-EOV7NJZ7.cjs +0 -13
@@ -0,0 +1,211 @@
1
+ 'use strict';
2
+
3
+ require('hono');
4
+ require('zod');
5
+
6
+ // src/plugins/sdk/plugin-builder.ts
7
+ var PluginBuilder = class _PluginBuilder {
8
+ plugin;
9
+ constructor(options) {
10
+ this.plugin = {
11
+ name: options.name,
12
+ version: options.version,
13
+ description: options.description,
14
+ author: options.author,
15
+ dependencies: options.dependencies,
16
+ routes: [],
17
+ middleware: [],
18
+ models: [],
19
+ services: [],
20
+ adminPages: [],
21
+ adminComponents: [],
22
+ menuItems: [],
23
+ hooks: []
24
+ };
25
+ }
26
+ /**
27
+ * Create a new plugin builder
28
+ */
29
+ static create(options) {
30
+ return new _PluginBuilder(options);
31
+ }
32
+ /**
33
+ * Add metadata to the plugin
34
+ */
35
+ metadata(metadata) {
36
+ Object.assign(this.plugin, metadata);
37
+ return this;
38
+ }
39
+ /**
40
+ * Add routes to plugin
41
+ */
42
+ addRoutes(routes) {
43
+ this.plugin.routes = [...this.plugin.routes || [], ...routes];
44
+ return this;
45
+ }
46
+ /**
47
+ * Add a single route to plugin
48
+ */
49
+ addRoute(path, handler, options) {
50
+ const route = {
51
+ path,
52
+ handler,
53
+ ...options
54
+ };
55
+ this.plugin.routes = [...this.plugin.routes || [], route];
56
+ return this;
57
+ }
58
+ /**
59
+ * Add middleware to plugin
60
+ */
61
+ addMiddleware(middleware) {
62
+ this.plugin.middleware = [...this.plugin.middleware || [], ...middleware];
63
+ return this;
64
+ }
65
+ /**
66
+ * Add a single middleware to plugin
67
+ */
68
+ addSingleMiddleware(name, handler, options) {
69
+ const middleware = {
70
+ name,
71
+ handler,
72
+ ...options
73
+ };
74
+ this.plugin.middleware = [...this.plugin.middleware || [], middleware];
75
+ return this;
76
+ }
77
+ /**
78
+ * Add models to plugin
79
+ */
80
+ addModels(models) {
81
+ this.plugin.models = [...this.plugin.models || [], ...models];
82
+ return this;
83
+ }
84
+ /**
85
+ * Add a single model to plugin
86
+ */
87
+ addModel(name, options) {
88
+ const model = {
89
+ name,
90
+ ...options
91
+ };
92
+ this.plugin.models = [...this.plugin.models || [], model];
93
+ return this;
94
+ }
95
+ /**
96
+ * Add services to plugin
97
+ */
98
+ addServices(services) {
99
+ this.plugin.services = [...this.plugin.services || [], ...services];
100
+ return this;
101
+ }
102
+ /**
103
+ * Add a single service to plugin
104
+ */
105
+ addService(name, implementation, options) {
106
+ const service = {
107
+ name,
108
+ implementation,
109
+ ...options
110
+ };
111
+ this.plugin.services = [...this.plugin.services || [], service];
112
+ return this;
113
+ }
114
+ /**
115
+ * Add admin pages to plugin
116
+ */
117
+ addAdminPages(pages) {
118
+ this.plugin.adminPages = [...this.plugin.adminPages || [], ...pages];
119
+ return this;
120
+ }
121
+ /**
122
+ * Add a single admin page to plugin
123
+ */
124
+ addAdminPage(path, title, component, options) {
125
+ const page = {
126
+ path,
127
+ title,
128
+ component,
129
+ ...options
130
+ };
131
+ this.plugin.adminPages = [...this.plugin.adminPages || [], page];
132
+ return this;
133
+ }
134
+ /**
135
+ * Add admin components to plugin
136
+ */
137
+ addComponents(components) {
138
+ this.plugin.adminComponents = [...this.plugin.adminComponents || [], ...components];
139
+ return this;
140
+ }
141
+ /**
142
+ * Add a single admin component to plugin
143
+ */
144
+ addComponent(name, template, options) {
145
+ const component = {
146
+ name,
147
+ template,
148
+ ...options
149
+ };
150
+ this.plugin.adminComponents = [...this.plugin.adminComponents || [], component];
151
+ return this;
152
+ }
153
+ /**
154
+ * Add menu items to plugin
155
+ */
156
+ addMenuItems(items) {
157
+ this.plugin.menuItems = [...this.plugin.menuItems || [], ...items];
158
+ return this;
159
+ }
160
+ /**
161
+ * Add a single menu item to plugin
162
+ */
163
+ addMenuItem(label, path, options) {
164
+ const menuItem = {
165
+ label,
166
+ path,
167
+ ...options
168
+ };
169
+ this.plugin.menuItems = [...this.plugin.menuItems || [], menuItem];
170
+ return this;
171
+ }
172
+ /**
173
+ * Add hooks to plugin
174
+ */
175
+ addHooks(hooks) {
176
+ this.plugin.hooks = [...this.plugin.hooks || [], ...hooks];
177
+ return this;
178
+ }
179
+ /**
180
+ * Add a single hook to plugin
181
+ */
182
+ addHook(name, handler, options) {
183
+ const hook = {
184
+ name,
185
+ handler,
186
+ ...options
187
+ };
188
+ this.plugin.hooks = [...this.plugin.hooks || [], hook];
189
+ return this;
190
+ }
191
+ /**
192
+ * Add lifecycle hooks
193
+ */
194
+ lifecycle(hooks) {
195
+ Object.assign(this.plugin, hooks);
196
+ return this;
197
+ }
198
+ /**
199
+ * Build the plugin
200
+ */
201
+ build() {
202
+ if (!this.plugin.name || !this.plugin.version) {
203
+ throw new Error("Plugin name and version are required");
204
+ }
205
+ return this.plugin;
206
+ }
207
+ };
208
+
209
+ exports.PluginBuilder = PluginBuilder;
210
+ //# sourceMappingURL=chunk-AI2JJIJX.cjs.map
211
+ //# sourceMappingURL=chunk-AI2JJIJX.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/sdk/plugin-builder.ts"],"names":[],"mappings":"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","file":"chunk-AI2JJIJX.cjs","sourcesContent":["/**\n * Plugin Builder SDK\n * \n * Provides a fluent API for building SonicJS plugins\n */\n\nimport { Hono } from 'hono'\nimport { z } from 'zod'\nimport { Plugin, PluginBuilderOptions, PluginRoutes, PluginMiddleware, PluginModel, PluginService, PluginAdminPage, PluginComponent, PluginHook, PluginMenuItem } from '../types'\n\nexport class PluginBuilder {\n private plugin: Partial<Plugin>\n\n constructor(options: PluginBuilderOptions) {\n this.plugin = {\n name: options.name,\n version: options.version,\n description: options.description,\n author: options.author,\n dependencies: options.dependencies,\n routes: [],\n middleware: [],\n models: [],\n services: [],\n adminPages: [],\n adminComponents: [],\n menuItems: [],\n hooks: []\n }\n }\n\n /**\n * Create a new plugin builder\n */\n static create(options: PluginBuilderOptions): PluginBuilder {\n return new PluginBuilder(options)\n }\n\n /**\n * Add metadata to the plugin\n */\n metadata(metadata: {\n description?: string\n author?: Plugin['author']\n license?: string\n compatibility?: string\n dependencies?: string[]\n }): PluginBuilder {\n Object.assign(this.plugin, metadata)\n return this\n }\n\n /**\n * Add routes to plugin\n */\n addRoutes(routes: PluginRoutes[]): PluginBuilder {\n this.plugin.routes = [...(this.plugin.routes || []), ...routes]\n return this\n }\n\n /**\n * Add a single route to plugin\n */\n addRoute(path: string, handler: Hono, options?: {\n description?: string\n requiresAuth?: boolean\n roles?: string[]\n priority?: number\n }): PluginBuilder {\n const route: PluginRoutes = {\n path,\n handler,\n ...options\n }\n this.plugin.routes = [...(this.plugin.routes || []), route]\n return this\n }\n\n /**\n * Add middleware to plugin\n */\n addMiddleware(middleware: PluginMiddleware[]): PluginBuilder {\n this.plugin.middleware = [...(this.plugin.middleware || []), ...middleware]\n return this\n }\n\n /**\n * Add a single middleware to plugin\n */\n addSingleMiddleware(name: string, handler: any, options?: {\n description?: string\n priority?: number\n routes?: string[]\n global?: boolean\n }): PluginBuilder {\n const middleware: PluginMiddleware = {\n name,\n handler,\n ...options\n }\n this.plugin.middleware = [...(this.plugin.middleware || []), middleware]\n return this\n }\n\n /**\n * Add models to plugin\n */\n addModels(models: PluginModel[]): PluginBuilder {\n this.plugin.models = [...(this.plugin.models || []), ...models]\n return this\n }\n\n /**\n * Add a single model to plugin\n */\n addModel(name: string, options: {\n tableName: string\n schema: z.ZodSchema\n migrations: string[]\n relationships?: PluginModel['relationships']\n extendsContent?: boolean\n }): PluginBuilder {\n const model: PluginModel = {\n name,\n ...options\n }\n this.plugin.models = [...(this.plugin.models || []), model]\n return this\n }\n\n /**\n * Add services to plugin\n */\n addServices(services: PluginService[]): PluginBuilder {\n this.plugin.services = [...(this.plugin.services || []), ...services]\n return this\n }\n\n /**\n * Add a single service to plugin\n */\n addService(name: string, implementation: any, options?: {\n description?: string\n dependencies?: string[]\n singleton?: boolean\n }): PluginBuilder {\n const service: PluginService = {\n name,\n implementation,\n ...options\n }\n this.plugin.services = [...(this.plugin.services || []), service]\n return this\n }\n\n /**\n * Add admin pages to plugin\n */\n addAdminPages(pages: PluginAdminPage[]): PluginBuilder {\n this.plugin.adminPages = [...(this.plugin.adminPages || []), ...pages]\n return this\n }\n\n /**\n * Add a single admin page to plugin\n */\n addAdminPage(path: string, title: string, component: string, options?: {\n description?: string\n permissions?: string[]\n icon?: string\n menuItem?: PluginMenuItem\n }): PluginBuilder {\n const page: PluginAdminPage = {\n path,\n title,\n component,\n ...options\n }\n this.plugin.adminPages = [...(this.plugin.adminPages || []), page]\n return this\n }\n\n /**\n * Add admin components to plugin\n */\n addComponents(components: PluginComponent[]): PluginBuilder {\n this.plugin.adminComponents = [...(this.plugin.adminComponents || []), ...components]\n return this\n }\n\n /**\n * Add a single admin component to plugin\n */\n addComponent(name: string, template: (props: any) => string, options?: {\n description?: string\n propsSchema?: z.ZodSchema\n }): PluginBuilder {\n const component: PluginComponent = {\n name,\n template,\n ...options\n }\n this.plugin.adminComponents = [...(this.plugin.adminComponents || []), component]\n return this\n }\n\n /**\n * Add menu items to plugin\n */\n addMenuItems(items: PluginMenuItem[]): PluginBuilder {\n this.plugin.menuItems = [...(this.plugin.menuItems || []), ...items]\n return this\n }\n\n /**\n * Add a single menu item to plugin\n */\n addMenuItem(label: string, path: string, options?: {\n icon?: string\n order?: number\n parent?: string\n permissions?: string[]\n }): PluginBuilder {\n const menuItem: PluginMenuItem = {\n label,\n path,\n ...options\n }\n this.plugin.menuItems = [...(this.plugin.menuItems || []), menuItem]\n return this\n }\n\n /**\n * Add hooks to plugin\n */\n addHooks(hooks: PluginHook[]): PluginBuilder {\n this.plugin.hooks = [...(this.plugin.hooks || []), ...hooks]\n return this\n }\n\n /**\n * Add a single hook to plugin\n */\n addHook(name: string, handler: any, options?: {\n priority?: number\n description?: string\n }): PluginBuilder {\n const hook: PluginHook = {\n name,\n handler,\n ...options\n }\n this.plugin.hooks = [...(this.plugin.hooks || []), hook]\n return this\n }\n\n /**\n * Add lifecycle hooks\n */\n lifecycle(hooks: {\n install?: Plugin['install']\n uninstall?: Plugin['uninstall']\n activate?: Plugin['activate']\n deactivate?: Plugin['deactivate']\n configure?: Plugin['configure']\n }): PluginBuilder {\n Object.assign(this.plugin, hooks)\n return this\n }\n\n /**\n * Build the plugin\n */\n build(): Plugin {\n // Validate required fields\n if (!this.plugin.name || !this.plugin.version) {\n throw new Error('Plugin name and version are required')\n }\n\n return this.plugin as Plugin\n }\n}\n\n/**\n * Helper functions for common plugin patterns\n */\nexport class PluginHelpers {\n /**\n * Create a REST API route for a model\n */\n static createModelAPI(modelName: string, options?: {\n basePath?: string\n permissions?: {\n read?: string[]\n write?: string[]\n delete?: string[]\n }\n }): Hono {\n const app = new Hono()\n const basePath = options?.basePath || `/${modelName.toLowerCase()}`\n\n // GET /models - List all\n app.get('/', async (c) => {\n // Implementation would depend on the model service\n return c.json({ message: `List ${modelName} items` })\n })\n\n // GET /models/:id - Get by ID\n app.get('/:id', async (c) => {\n const id = c.req.param('id')\n return c.json({ message: `Get ${modelName} with ID: ${id}` })\n })\n\n // POST /models - Create new\n app.post('/', async (c) => {\n return c.json({ message: `Create new ${modelName}` })\n })\n\n // PUT /models/:id - Update\n app.put('/:id', async (c) => {\n const id = c.req.param('id')\n return c.json({ message: `Update ${modelName} with ID: ${id}` })\n })\n\n // DELETE /models/:id - Delete\n app.delete('/:id', async (c) => {\n const id = c.req.param('id')\n return c.json({ message: `Delete ${modelName} with ID: ${id}` })\n })\n\n return app\n }\n\n /**\n * Create an admin CRUD interface for a model\n */\n static createAdminInterface(modelName: string, options?: {\n icon?: string\n permissions?: string[]\n fields?: Array<{\n name: string\n type: string\n label: string\n required?: boolean\n }>\n }): {\n pages: PluginAdminPage[]\n menuItems: PluginMenuItem[]\n } {\n const basePath = `/admin/${modelName.toLowerCase()}`\n const displayName = modelName.charAt(0).toUpperCase() + modelName.slice(1)\n\n const pages: PluginAdminPage[] = [\n {\n path: basePath,\n title: `${displayName} List`,\n component: `${modelName}List`,\n permissions: options?.permissions,\n icon: options?.icon\n },\n {\n path: `${basePath}/new`,\n title: `New ${displayName}`,\n component: `${modelName}Form`,\n permissions: options?.permissions\n },\n {\n path: `${basePath}/:id`,\n title: `Edit ${displayName}`,\n component: `${modelName}Form`,\n permissions: options?.permissions\n }\n ]\n\n const menuItems: PluginMenuItem[] = [\n {\n label: displayName,\n path: basePath,\n icon: options?.icon,\n permissions: options?.permissions\n }\n ]\n\n return { pages, menuItems }\n }\n\n /**\n * Create a database migration for a model\n */\n static createMigration(tableName: string, fields: Array<{\n name: string\n type: 'TEXT' | 'INTEGER' | 'REAL' | 'BLOB'\n nullable?: boolean\n primaryKey?: boolean\n unique?: boolean\n defaultValue?: string\n }>): string {\n const columns = fields.map(field => {\n let definition = `${field.name} ${field.type}`\n \n if (field.primaryKey) definition += ' PRIMARY KEY'\n if (field.unique) definition += ' UNIQUE'\n if (!field.nullable && !field.primaryKey) definition += ' NOT NULL'\n if (field.defaultValue) definition += ` DEFAULT ${field.defaultValue}`\n \n return definition\n }).join(',\\n ')\n\n return `\nCREATE TABLE IF NOT EXISTS ${tableName} (\n ${columns},\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))\n);\n\nCREATE TRIGGER IF NOT EXISTS ${tableName}_updated_at\n AFTER UPDATE ON ${tableName}\nBEGIN\n UPDATE ${tableName} SET updated_at = strftime('%s', 'now') WHERE id = NEW.id;\nEND;\n `.trim()\n }\n\n /**\n * Create a Zod schema for a model\n */\n static createSchema(fields: Array<{\n name: string\n type: 'string' | 'number' | 'boolean' | 'date' | 'array' | 'object'\n optional?: boolean\n required?: boolean\n validation?: any\n items?: any\n properties?: Record<string, any>\n }>): z.ZodSchema {\n const shape: Record<string, z.ZodTypeAny> = {}\n\n const applyValidation = (field: any, schema: z.ZodTypeAny) => {\n if (field.validation) {\n if (field.type === 'string' && field.validation.min) {\n schema = (schema as z.ZodString).min(field.validation.min)\n }\n if (field.type === 'string' && field.validation.max) {\n schema = (schema as z.ZodString).max(field.validation.max)\n }\n if (field.type === 'string' && field.validation.email) {\n schema = (schema as z.ZodString).email()\n }\n if (field.type === 'string' && field.validation.url) {\n schema = (schema as z.ZodString).url()\n }\n }\n return schema\n }\n\n const buildSchema = (field: any): z.ZodTypeAny => {\n let schema: z.ZodTypeAny\n\n switch (field.type) {\n case 'string':\n schema = z.string()\n break\n case 'number':\n schema = z.number()\n break\n case 'boolean':\n schema = z.boolean()\n break\n case 'date':\n schema = z.date()\n break\n case 'array':\n if (field.items?.blocks && typeof field.items.blocks === 'object') {\n const discriminator = typeof field.items.discriminator === 'string' && field.items.discriminator\n ? field.items.discriminator\n : 'blockType'\n const blockSchemas = Object.entries(field.items.blocks).map(([blockName, blockDef]: [string, any]) => {\n const properties = blockDef?.properties && typeof blockDef.properties === 'object'\n ? blockDef.properties\n : {}\n const blockShape: Record<string, z.ZodTypeAny> = {\n [discriminator]: z.literal(blockName)\n }\n\n Object.entries(properties).forEach(([propertyName, propertyConfigRaw]) => {\n const propertyConfig = propertyConfigRaw && typeof propertyConfigRaw === 'object'\n ? propertyConfigRaw as Record<string, any>\n : {}\n const propertySchema = buildSchema({\n ...propertyConfig,\n optional: propertyConfig.required === false\n })\n blockShape[propertyName] = propertySchema\n })\n\n return z.object(blockShape)\n })\n\n if (blockSchemas.length === 1 && blockSchemas[0]) {\n schema = z.array(blockSchemas[0])\n } else if (blockSchemas.length > 1) {\n schema = z.array(z.union(blockSchemas as unknown as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]))\n } else {\n schema = z.array(z.any())\n }\n break\n }\n if (field.items) {\n schema = z.array(buildSchema(field.items))\n break\n }\n schema = z.array(z.any())\n break\n case 'object':\n if (field.properties && typeof field.properties === 'object') {\n const objectShape: Record<string, z.ZodTypeAny> = {}\n Object.entries(field.properties).forEach(([propertyName, propertyConfigRaw]) => {\n const propertyConfig = propertyConfigRaw && typeof propertyConfigRaw === 'object'\n ? propertyConfigRaw as Record<string, any>\n : {}\n objectShape[propertyName] = buildSchema({\n ...propertyConfig,\n optional: propertyConfig.required === false\n })\n })\n schema = z.object(objectShape)\n break\n }\n schema = z.object({})\n break\n default:\n schema = z.any()\n }\n\n schema = applyValidation(field, schema)\n\n if (field.optional || field.required === false) {\n schema = schema.optional()\n }\n\n return schema\n }\n\n for (const field of fields) {\n shape[field.name] = buildSchema(field)\n }\n\n return z.object(shape)\n }\n}\n\n/**\n * Common plugin templates\n */\nexport class PluginTemplates {\n /**\n * Create a simple content type plugin\n */\n static contentType(name: string, fields: Array<{\n name: string\n type: string\n label: string\n required?: boolean\n }>): Plugin {\n const builder = PluginBuilder.create({\n name: `${name}-content-type`,\n version: '1.0.0',\n description: `${name} content type plugin`\n })\n\n // Create model\n const schema = PluginHelpers.createSchema(\n fields.map(f => ({\n name: f.name,\n type: f.type as any,\n optional: !f.required\n }))\n )\n\n const migration = PluginHelpers.createMigration(\n name.toLowerCase(),\n fields.map(f => ({\n name: f.name,\n type: 'TEXT',\n nullable: !f.required\n }))\n )\n\n builder.addModel(name, {\n tableName: name.toLowerCase(),\n schema,\n migrations: [migration],\n extendsContent: true\n })\n\n // Create API routes\n const apiRoutes = PluginHelpers.createModelAPI(name)\n builder.addRoute(`/api/${name.toLowerCase()}`, apiRoutes)\n\n // Create admin interface\n const { pages, menuItems } = PluginHelpers.createAdminInterface(name, {\n fields\n })\n builder.addAdminPages(pages)\n builder.addMenuItems(menuItems)\n\n return builder.build()\n }\n\n /**\n * Create an analytics plugin\n */\n static analytics(name: string, options?: {\n endpoints?: string[]\n dashboard?: boolean\n }): Plugin {\n const builder = PluginBuilder.create({\n name: `${name}-analytics`,\n version: '1.0.0',\n description: `${name} analytics plugin`\n })\n\n // Add middleware to track requests\n builder.addSingleMiddleware('analytics-tracker', async (c: any, next: any) => {\n const start = Date.now()\n await next()\n const duration = Date.now() - start\n \n // Log analytics data\n console.info(`Analytics: ${c.req.method} ${c.req.path} - ${duration}ms`)\n }, {\n global: true,\n priority: 1\n })\n\n // Add analytics API\n const analyticsAPI = new Hono()\n analyticsAPI.get('/stats', (c) => {\n return c.json({ message: 'Analytics stats' })\n })\n builder.addRoute('/api/analytics', analyticsAPI)\n\n // Add dashboard if requested\n if (options?.dashboard) {\n builder.addAdminPage(\n '/analytics',\n 'Analytics Dashboard',\n 'AnalyticsDashboard',\n {\n description: 'View analytics and statistics',\n icon: 'chart-bar'\n }\n )\n\n builder.addMenuItem('Analytics', '/admin/analytics', {\n icon: 'chart-bar',\n order: 100\n })\n }\n\n return builder.build()\n }\n}\n"]}
@@ -28,6 +28,12 @@ function sanitizeObject(obj, fields) {
28
28
  return sanitized;
29
29
  }
30
30
 
31
+ // src/utils/slug-utils.ts
32
+ function generateSlug(text) {
33
+ if (!text) return "";
34
+ return text.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9\s_-]/g, "").replace(/\s+/g, "-").replace(/[-_]+/g, "-").replace(/^[-_]+|[-_]+$/g, "").substring(0, 100);
35
+ }
36
+
31
37
  // src/utils/template-renderer.ts
32
38
  var TemplateRenderer = class {
33
39
  templateCache = /* @__PURE__ */ new Map();
@@ -413,7 +419,7 @@ function buildQuery(table, filter) {
413
419
  // package.json
414
420
  var package_default = {
415
421
  name: "@sonicjs-cms/core",
416
- version: "2.3.17",
422
+ version: "2.5.0",
417
423
  description: "Core framework for SonicJS headless CMS - Edge-first, TypeScript-native CMS built for Cloudflare Workers",
418
424
  type: "module",
419
425
  main: "./dist/index.cjs",
@@ -526,6 +532,7 @@ var package_default = {
526
532
  "@typescript-eslint/parser": "^8.50.0",
527
533
  "drizzle-orm": "^0.44.7",
528
534
  eslint: "^9.39.2",
535
+ glob: "^10.5.0",
529
536
  hono: "^4.10.4",
530
537
  tsup: "^8.5.0",
531
538
  typescript: "^5.9.3",
@@ -547,6 +554,51 @@ function getCoreVersion() {
547
554
  return SONICJS_VERSION;
548
555
  }
549
556
 
550
- export { QueryFilterBuilder, SONICJS_VERSION, TemplateRenderer, buildQuery, escapeHtml, getCoreVersion, package_default, renderTemplate, sanitizeInput, sanitizeObject, templateRenderer };
551
- //# sourceMappingURL=chunk-TMQOLXLY.js.map
552
- //# sourceMappingURL=chunk-TMQOLXLY.js.map
557
+ // src/utils/blocks.ts
558
+ function getBlocksFieldConfig(fieldOptions) {
559
+ if (!fieldOptions || typeof fieldOptions !== "object") return null;
560
+ const itemsConfig = fieldOptions.items && typeof fieldOptions.items === "object" ? fieldOptions.items : null;
561
+ if (!itemsConfig || !itemsConfig.blocks || typeof itemsConfig.blocks !== "object") {
562
+ return null;
563
+ }
564
+ const discriminator = typeof itemsConfig.discriminator === "string" && itemsConfig.discriminator ? itemsConfig.discriminator : "blockType";
565
+ return {
566
+ blocks: itemsConfig.blocks,
567
+ discriminator
568
+ };
569
+ }
570
+ function parseBlocksValue(value, config) {
571
+ const errors = [];
572
+ let rawValue = value;
573
+ if (rawValue === null || rawValue === void 0 || rawValue === "") {
574
+ return { value: [], errors };
575
+ }
576
+ if (typeof rawValue === "string") {
577
+ try {
578
+ rawValue = JSON.parse(rawValue);
579
+ } catch {
580
+ return { value: [], errors: ["Blocks value must be valid JSON"] };
581
+ }
582
+ }
583
+ if (!Array.isArray(rawValue)) {
584
+ return { value: [], errors: ["Blocks value must be an array"] };
585
+ }
586
+ const normalized = rawValue.map((item, index) => {
587
+ if (!item || typeof item !== "object") {
588
+ errors.push(`Block #${index + 1} must be an object`);
589
+ return null;
590
+ }
591
+ if (item.blockType && item.data && typeof item.data === "object") {
592
+ return { [config.discriminator]: item.blockType, ...item.data };
593
+ }
594
+ if (!(config.discriminator in item)) {
595
+ errors.push(`Block #${index + 1} is missing "${config.discriminator}"`);
596
+ }
597
+ return item;
598
+ }).filter((item) => item !== null);
599
+ return { value: normalized, errors };
600
+ }
601
+
602
+ export { QueryFilterBuilder, SONICJS_VERSION, TemplateRenderer, buildQuery, escapeHtml, generateSlug, getBlocksFieldConfig, getCoreVersion, package_default, parseBlocksValue, renderTemplate, sanitizeInput, sanitizeObject, templateRenderer };
603
+ //# sourceMappingURL=chunk-BHNDALCA.js.map
604
+ //# sourceMappingURL=chunk-BHNDALCA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/sanitize.ts","../src/utils/slug-utils.ts","../src/utils/template-renderer.ts","../src/utils/query-filter.ts","../package.json","../src/utils/version.ts","../src/utils/blocks.ts"],"names":[],"mappings":"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","file":"chunk-BHNDALCA.js","sourcesContent":["/**\n * HTML sanitization utilities for preventing XSS attacks\n */\n\n/**\n * Escapes HTML special characters to prevent XSS attacks\n * @param text - The text to escape\n * @returns The escaped text safe for HTML output\n */\nexport function escapeHtml(text: string): string {\n if (typeof text !== 'string') {\n return ''\n }\n\n const map: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#039;'\n }\n\n return text.replace(/[&<>\"']/g, (char) => map[char] || char)\n}\n\n/**\n * Sanitizes user input by escaping HTML special characters\n * This should be used for all user-provided text fields to prevent XSS\n * @param input - The input string to sanitize\n * @returns The sanitized string\n */\nexport function sanitizeInput(input: string | null | undefined): string {\n if (!input) {\n return ''\n }\n return escapeHtml(String(input).trim())\n}\n\n/**\n * Sanitizes an object's string properties\n * @param obj - Object with string properties to sanitize\n * @param fields - Array of field names to sanitize\n * @returns New object with sanitized fields\n */\nexport function sanitizeObject<T extends Record<string, any>>(\n obj: T,\n fields: (keyof T)[]\n): T {\n const sanitized = { ...obj }\n\n for (const field of fields) {\n if (typeof obj[field] === 'string') {\n sanitized[field] = sanitizeInput(obj[field]) as T[keyof T]\n }\n }\n\n return sanitized\n}\n","/**\n * Slug generation utilities for creating URL-friendly slugs\n */\n\n/**\n * Generate URL-friendly slug from text\n * \n * Features:\n * - Converts to lowercase\n * - Handles accented characters (NFD normalization)\n * - Removes diacritics\n * - Keeps only alphanumeric, spaces, underscores, and hyphens\n * - Replaces spaces with hyphens\n * - Collapses multiple hyphens/underscores\n * - Trims leading/trailing hyphens/underscores\n * - Limits length to 100 characters\n * \n * @param text - Text to slugify\n * @returns URL-safe slug\n * \n * @example\n * generateSlug('Hello World!') // 'hello-world'\n * generateSlug('Café París 2024') // 'cafe-paris-2024'\n * generateSlug('Multiple Spaces') // 'multiple-spaces'\n */\nexport function generateSlug(text: string): string {\n if (!text) return '';\n \n return text\n .toLowerCase()\n .normalize('NFD') // Decompose combined characters (e.g., é -> e + ́)\n .replace(/[\\u0300-\\u036f]/g, '') // Remove diacritics\n .replace(/[^a-z0-9\\s_-]/g, '') // Keep only alphanumeric, spaces, underscores, hyphens\n .replace(/\\s+/g, '-') // Replace spaces with hyphens\n .replace(/[-_]+/g, '-') // Collapse multiple hyphens/underscores\n .replace(/^[-_]+|[-_]+$/g, '') // Trim leading/trailing hyphens/underscores\n .substring(0, 100); // Limit length for URL safety\n}\n","// Template renderer compatible with Cloudflare Workers\n// No filesystem access available\n\ninterface TemplateData {\n [key: string]: any\n}\n\nexport class TemplateRenderer {\n private templateCache = new Map<string, string>()\n\n constructor() {\n // Cloudflare Workers compatible - no filesystem access\n }\n\n /**\n * Simple Handlebars-like template engine\n */\n private renderTemplate(template: string, data: TemplateData): string {\n let rendered = template\n\n // Handle each loops - process outermost loops first for proper nesting\n rendered = rendered.replace(/\\{\\{#each\\s+([^}]+)\\}\\}([\\s\\S]*?)\\{\\{\\/each\\}\\}/g, (_match, arrayName, content) => {\n const array = this.getNestedValue(data, arrayName.trim())\n if (!Array.isArray(array)) return ''\n \n return array.map((item, index) => {\n // Create context with array item and special variables\n const itemContext = {\n ...data,\n // Handle primitive items (for {{.}} syntax)\n '.': item,\n // Spread item properties if it's an object\n ...(typeof item === 'object' && item !== null ? item : {}),\n '@index': index,\n '@first': index === 0,\n '@last': index === array.length - 1\n }\n return this.renderTemplate(content, itemContext)\n }).join('')\n })\n\n // Second pass: Handle conditionals\n let ifCount = 0\n while (rendered.includes('{{#if ') && ifCount < 100) {\n const previousRendered = rendered\n rendered = rendered.replace(/\\{\\{#if\\s+([^}]+)\\}\\}([\\s\\S]*?)\\{\\{\\/if\\}\\}/g, (_match, condition, content) => {\n const value = this.getNestedValue(data, condition.trim())\n // Handle boolean values properly - @first/@last are explicitly boolean\n const isTruthy = value === true || (value && value !== 0 && value !== '' && value !== null && value !== undefined)\n return isTruthy ? this.renderTemplate(content, data) : ''\n })\n if (previousRendered === rendered) break\n ifCount++\n }\n\n // Third pass: Handle triple braces for raw HTML {{{variable}}}\n rendered = rendered.replace(/\\{\\{\\{([^}]+)\\}\\}\\}/g, (_match, variable) => {\n const value = this.getNestedValue(data, variable.trim())\n return value !== undefined && value !== null ? String(value) : ''\n })\n\n // Fourth pass: Handle helper functions like {{titleCase field}}\n rendered = rendered.replace(/\\{\\{([^}#\\/]+)\\s+([^}]+)\\}\\}/g, (match, helper, variable) => {\n const helperName = helper.trim()\n const varName = variable.trim()\n \n if (helperName === 'titleCase') {\n const value = this.getNestedValue(data, varName)\n if (value !== undefined && value !== null) {\n return this.titleCase(String(value))\n }\n }\n \n return match // Return original if helper not found\n })\n\n // Final pass: Handle simple variables {{variable}}\n rendered = rendered.replace(/\\{\\{([^}#\\/]+)\\}\\}/g, (match, variable) => {\n const trimmed = variable.trim()\n \n // Skip if it's a helper function (has spaces)\n if (trimmed.includes(' ')) {\n return match\n }\n \n const value = this.getNestedValue(data, trimmed)\n if (value === null) return ''\n if (value === undefined) return ''\n return String(value)\n })\n\n return rendered\n }\n\n /**\n * Get nested value from object using dot notation\n */\n private getNestedValue(obj: any, path: string): any {\n if (!obj || path === '') return undefined\n \n return path.split('.').reduce((current, key) => {\n if (current === null || current === undefined) return undefined\n return current[key]\n }, obj)\n }\n\n /**\n * Title case helper function\n */\n private titleCase(str: string): string {\n return str\n .replace(/_/g, ' ')\n .replace(/\\b\\w/g, l => l.toUpperCase())\n }\n\n /**\n * Render a template string with data\n */\n render(template: string, data: TemplateData = {}): string {\n return this.renderTemplate(template, data)\n }\n\n /**\n * Clear template cache (useful for development)\n */\n clearCache(): void {\n this.templateCache.clear()\n }\n}\n\n// Export singleton instance\nexport const templateRenderer = new TemplateRenderer()\n\n// Utility function to render template strings directly\nexport function renderTemplate(template: string, data: TemplateData = {}): string {\n return templateRenderer.render(template, data)\n}","/**\n * Query Filter Builder for SonicJS AI\n * Supports comprehensive filtering with AND/OR logic\n * Compatible with D1 Database (SQLite)\n */\n\nexport type FilterOperator =\n | 'equals'\n | 'not_equals'\n | 'greater_than'\n | 'greater_than_equal'\n | 'less_than'\n | 'less_than_equal'\n | 'like'\n | 'contains'\n | 'in'\n | 'not_in'\n | 'all'\n | 'exists'\n | 'near'\n | 'within'\n | 'intersects'\n\nexport interface FilterCondition {\n field: string\n operator: FilterOperator\n value: any\n}\n\nexport interface FilterGroup {\n and?: FilterCondition[]\n or?: FilterCondition[]\n}\n\nexport interface QueryFilter {\n where?: FilterGroup\n limit?: number\n offset?: number\n sort?: {\n field: string\n order: 'asc' | 'desc'\n }[]\n}\n\nexport interface QueryResult {\n sql: string\n params: any[]\n errors: string[]\n}\n\n/**\n * Query Filter Builder\n * Converts filter objects into SQL WHERE clauses with parameterized queries\n */\nexport class QueryFilterBuilder {\n private params: any[] = []\n private errors: string[] = []\n\n /**\n * Build a complete SQL query from filter object\n */\n build(baseTable: string, filter: QueryFilter): QueryResult {\n this.params = []\n this.errors = []\n\n let sql = `SELECT * FROM ${baseTable}`\n\n // Build WHERE clause\n if (filter.where) {\n const whereClause = this.buildWhereClause(filter.where)\n if (whereClause) {\n sql += ` WHERE ${whereClause}`\n }\n }\n\n // Build ORDER BY clause\n if (filter.sort && filter.sort.length > 0) {\n const orderClauses = filter.sort\n .map(s => `${this.sanitizeFieldName(s.field)} ${s.order.toUpperCase()}`)\n .join(', ')\n sql += ` ORDER BY ${orderClauses}`\n }\n\n // Build LIMIT clause\n if (filter.limit) {\n sql += ` LIMIT ?`\n this.params.push(filter.limit)\n }\n\n // Build OFFSET clause\n if (filter.offset) {\n sql += ` OFFSET ?`\n this.params.push(filter.offset)\n }\n\n return {\n sql,\n params: this.params,\n errors: this.errors\n }\n }\n\n /**\n * Build WHERE clause from filter group\n */\n private buildWhereClause(group: FilterGroup): string {\n const clauses: string[] = []\n\n // Handle AND conditions\n if (group.and && group.and.length > 0) {\n const andClauses = group.and\n .map(condition => this.buildCondition(condition))\n .filter(clause => clause !== null)\n\n if (andClauses.length > 0) {\n clauses.push(`(${andClauses.join(' AND ')})`)\n }\n }\n\n // Handle OR conditions\n if (group.or && group.or.length > 0) {\n const orClauses = group.or\n .map(condition => this.buildCondition(condition))\n .filter(clause => clause !== null)\n\n if (orClauses.length > 0) {\n clauses.push(`(${orClauses.join(' OR ')})`)\n }\n }\n\n return clauses.join(' AND ')\n }\n\n /**\n * Build a single condition\n */\n private buildCondition(condition: FilterCondition): string | null {\n const field = this.sanitizeFieldName(condition.field)\n\n switch (condition.operator) {\n case 'equals':\n return this.buildEquals(field, condition.value)\n\n case 'not_equals':\n return this.buildNotEquals(field, condition.value)\n\n case 'greater_than':\n return this.buildComparison(field, '>', condition.value)\n\n case 'greater_than_equal':\n return this.buildComparison(field, '>=', condition.value)\n\n case 'less_than':\n return this.buildComparison(field, '<', condition.value)\n\n case 'less_than_equal':\n return this.buildComparison(field, '<=', condition.value)\n\n case 'like':\n return this.buildLike(field, condition.value)\n\n case 'contains':\n return this.buildContains(field, condition.value)\n\n case 'in':\n return this.buildIn(field, condition.value)\n\n case 'not_in':\n return this.buildNotIn(field, condition.value)\n\n case 'all':\n return this.buildAll(field, condition.value)\n\n case 'exists':\n return this.buildExists(field, condition.value)\n\n case 'near':\n this.errors.push(`'near' operator not supported in SQLite. Use spatial extension or application-level filtering.`)\n return null\n\n case 'within':\n this.errors.push(`'within' operator not supported in SQLite. Use spatial extension or application-level filtering.`)\n return null\n\n case 'intersects':\n this.errors.push(`'intersects' operator not supported in SQLite. Use spatial extension or application-level filtering.`)\n return null\n\n default:\n this.errors.push(`Unknown operator: ${condition.operator}`)\n return null\n }\n }\n\n /**\n * Build equals condition\n */\n private buildEquals(field: string, value: any): string {\n if (value === null) {\n return `${field} IS NULL`\n }\n this.params.push(value)\n return `${field} = ?`\n }\n\n /**\n * Build not equals condition\n */\n private buildNotEquals(field: string, value: any): string {\n if (value === null) {\n return `${field} IS NOT NULL`\n }\n this.params.push(value)\n return `${field} != ?`\n }\n\n /**\n * Build comparison condition (>, >=, <, <=)\n */\n private buildComparison(field: string, operator: string, value: any): string {\n this.params.push(value)\n return `${field} ${operator} ?`\n }\n\n /**\n * Build LIKE condition (case-insensitive, all words must be present)\n */\n private buildLike(field: string, value: string): string {\n const words = value.split(/\\s+/).filter(w => w.length > 0)\n\n if (words.length === 0) {\n return `1=1` // No-op condition\n }\n\n const conditions = words.map(word => {\n this.params.push(`%${word}%`)\n return `${field} LIKE ?`\n })\n\n return `(${conditions.join(' AND ')})`\n }\n\n /**\n * Build CONTAINS condition (case-insensitive substring)\n */\n private buildContains(field: string, value: string): string {\n this.params.push(`%${value}%`)\n return `${field} LIKE ?`\n }\n\n /**\n * Build IN condition\n */\n private buildIn(field: string, value: any): string {\n let values: any[]\n\n if (typeof value === 'string') {\n // Parse comma-delimited string\n values = value.split(',').map(v => v.trim()).filter(v => v.length > 0)\n } else if (Array.isArray(value)) {\n values = value\n } else {\n values = [value]\n }\n\n if (values.length === 0) {\n return `1=0` // No values means no matches\n }\n\n const placeholders = values.map(v => {\n this.params.push(v)\n return '?'\n }).join(', ')\n\n return `${field} IN (${placeholders})`\n }\n\n /**\n * Build NOT IN condition\n */\n private buildNotIn(field: string, value: any): string {\n let values: any[]\n\n if (typeof value === 'string') {\n // Parse comma-delimited string\n values = value.split(',').map(v => v.trim()).filter(v => v.length > 0)\n } else if (Array.isArray(value)) {\n values = value\n } else {\n values = [value]\n }\n\n if (values.length === 0) {\n return `1=1` // No values means all match\n }\n\n const placeholders = values.map(v => {\n this.params.push(v)\n return '?'\n }).join(', ')\n\n return `${field} NOT IN (${placeholders})`\n }\n\n /**\n * Build ALL condition (value must contain all items in list)\n * For SQLite, we'll check if a JSON array contains all values\n */\n private buildAll(field: string, value: any): string {\n let values: any[]\n\n if (typeof value === 'string') {\n values = value.split(',').map(v => v.trim()).filter(v => v.length > 0)\n } else if (Array.isArray(value)) {\n values = value\n } else {\n values = [value]\n }\n\n if (values.length === 0) {\n return `1=1`\n }\n\n // For SQLite, check if field contains all values using JSON functions\n // This assumes the field is a JSON array or comma-separated string\n const conditions = values.map(val => {\n this.params.push(`%${val}%`)\n return `${field} LIKE ?`\n })\n\n return `(${conditions.join(' AND ')})`\n }\n\n /**\n * Build EXISTS condition\n */\n private buildExists(field: string, value: boolean): string {\n if (value) {\n return `${field} IS NOT NULL AND ${field} != ''`\n } else {\n return `(${field} IS NULL OR ${field} = '')`\n }\n }\n\n /**\n * Sanitize field names to prevent SQL injection\n */\n private sanitizeFieldName(field: string): string {\n // Allow alphanumeric, underscores, dots (for JSON fields)\n const sanitized = field.replace(/[^a-zA-Z0-9_$.]/g, '')\n\n // Handle JSON field access (e.g., data.title -> json_extract(data, '$.title'))\n if (sanitized.includes('.')) {\n const [table, ...path] = sanitized.split('.')\n return `json_extract(${table}, '$.${path.join('.')}')`\n }\n\n return sanitized\n }\n\n /**\n * Parse filter from query string\n */\n static parseFromQuery(query: Record<string, any>): QueryFilter {\n const filter: QueryFilter = {}\n\n // Parse where clause from 'where' parameter (JSON string)\n if (query.where) {\n try {\n filter.where = typeof query.where === 'string'\n ? JSON.parse(query.where)\n : query.where\n } catch (e) {\n console.error('Failed to parse where clause:', e)\n }\n }\n\n // Initialize where clause if not present\n if (!filter.where) {\n filter.where = { and: [] }\n }\n if (!filter.where.and) {\n filter.where.and = []\n }\n\n // Parse simple field filters (status, collection_id, etc.)\n // These are convenience parameters that get converted to WHERE conditions\n const simpleFieldMappings: Record<string, string> = {\n 'status': 'status',\n 'collection_id': 'collection_id'\n }\n\n for (const [queryParam, dbField] of Object.entries(simpleFieldMappings)) {\n if (query[queryParam]) {\n filter.where.and.push({\n field: dbField,\n operator: 'equals',\n value: query[queryParam]\n })\n }\n }\n\n // Parse limit\n if (query.limit) {\n filter.limit = Math.min(parseInt(query.limit), 1000) // Max 1000\n }\n\n // Parse offset\n if (query.offset) {\n filter.offset = parseInt(query.offset)\n }\n\n // Parse sort\n if (query.sort) {\n try {\n filter.sort = typeof query.sort === 'string'\n ? JSON.parse(query.sort)\n : query.sort\n } catch (e) {\n console.error('Failed to parse sort clause:', e)\n }\n }\n\n return filter\n }\n}\n\n/**\n * Helper function to build query from filter\n */\nexport function buildQuery(table: string, filter: QueryFilter): QueryResult {\n const builder = new QueryFilterBuilder()\n return builder.build(table, filter)\n}\n","{\n \"name\": \"@sonicjs-cms/core\",\n \"version\": \"2.5.0\",\n \"description\": \"Core framework for SonicJS headless CMS - Edge-first, TypeScript-native CMS built for Cloudflare Workers\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"sonicjs-db-reset\": \"./bin/db-reset.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./services\": {\n \"types\": \"./dist/services.d.ts\",\n \"import\": \"./dist/services.js\",\n \"require\": \"./dist/services.cjs\"\n },\n \"./middleware\": {\n \"types\": \"./dist/middleware.d.ts\",\n \"import\": \"./dist/middleware.js\",\n \"require\": \"./dist/middleware.cjs\"\n },\n \"./routes\": {\n \"types\": \"./dist/routes.d.ts\",\n \"import\": \"./dist/routes.js\",\n \"require\": \"./dist/routes.cjs\"\n },\n \"./templates\": {\n \"types\": \"./dist/templates.d.ts\",\n \"import\": \"./dist/templates.js\",\n \"require\": \"./dist/templates.cjs\"\n },\n \"./plugins\": {\n \"types\": \"./dist/plugins.d.ts\",\n \"import\": \"./dist/plugins.js\",\n \"require\": \"./dist/plugins.cjs\"\n },\n \"./utils\": {\n \"types\": \"./dist/utils.d.ts\",\n \"import\": \"./dist/utils.js\",\n \"require\": \"./dist/utils.cjs\"\n },\n \"./types\": {\n \"types\": \"./dist/types.d.ts\",\n \"import\": \"./dist/types.js\",\n \"require\": \"./dist/types.cjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"bin\",\n \"dist\",\n \"migrations\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"generate:migrations\": \"npx tsx scripts/generate-migrations.ts\",\n \"prebuild\": \"npm run generate:migrations\",\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"type-check\": \"tsc --noEmit\",\n \"lint\": \"eslint src/\",\n \"lint:fix\": \"eslint src/ --fix\",\n \"test\": \"vitest --run\",\n \"test:watch\": \"vitest\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"cms\",\n \"headless-cms\",\n \"cloudflare\",\n \"workers\",\n \"edge\",\n \"typescript\",\n \"hono\",\n \"content-management\",\n \"api\",\n \"sonicjs\"\n ],\n \"author\": \"SonicJS Team\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/sonicjs/sonicjs.git\",\n \"directory\": \"packages/core\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/sonicjs/sonicjs/issues\"\n },\n \"homepage\": \"https://sonicjs.com\",\n \"peerDependencies\": {\n \"@cloudflare/workers-types\": \"^4.0.0\",\n \"drizzle-orm\": \"^0.44.0\",\n \"hono\": \"^4.0.0\",\n \"zod\": \"^3.0.0 || ^4.0.0\"\n },\n \"dependencies\": {\n \"drizzle-zod\": \"^0.8.3\",\n \"highlight.js\": \"^11.11.1\",\n \"marked\": \"^16.4.1\",\n \"semver\": \"^7.7.3\"\n },\n \"devDependencies\": {\n \"@cloudflare/workers-types\": \"^4.20251014.0\",\n \"@types/node\": \"^24.9.2\",\n \"@typescript-eslint/eslint-plugin\": \"^8.50.0\",\n \"@typescript-eslint/parser\": \"^8.50.0\",\n \"drizzle-orm\": \"^0.44.7\",\n \"eslint\": \"^9.39.2\",\n \"glob\": \"^10.5.0\",\n \"hono\": \"^4.10.4\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.9.3\",\n \"vitest\": \"^4.0.5\",\n \"zod\": \"^4.1.12\"\n },\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n }\n}\n","/**\n * Version utility\n *\n * Provides the current version of @sonicjs-cms/core package\n */\n\nimport pkg from '../../package.json'\n\nexport const SONICJS_VERSION = pkg.version\n\n/**\n * Get the current SonicJS core version\n */\nexport function getCoreVersion(): string {\n return SONICJS_VERSION\n}\n","import type { BlockDefinitions } from '../types/collection-config'\n\nexport type BlocksFieldConfig = {\n blocks: BlockDefinitions\n discriminator: string\n}\n\nexport function getBlocksFieldConfig(fieldOptions: any): BlocksFieldConfig | null {\n if (!fieldOptions || typeof fieldOptions !== 'object') return null\n\n const itemsConfig = fieldOptions.items && typeof fieldOptions.items === 'object'\n ? fieldOptions.items\n : null\n\n if (!itemsConfig || !itemsConfig.blocks || typeof itemsConfig.blocks !== 'object') {\n return null\n }\n\n const discriminator = typeof itemsConfig.discriminator === 'string' && itemsConfig.discriminator\n ? itemsConfig.discriminator\n : 'blockType'\n\n return {\n blocks: itemsConfig.blocks as BlockDefinitions,\n discriminator\n }\n}\n\nexport function parseBlocksValue(value: unknown, config: BlocksFieldConfig) {\n const errors: string[] = []\n let rawValue = value\n\n if (rawValue === null || rawValue === undefined || rawValue === '') {\n return { value: [] as any[], errors }\n }\n\n if (typeof rawValue === 'string') {\n try {\n rawValue = JSON.parse(rawValue)\n } catch {\n return { value: [] as any[], errors: ['Blocks value must be valid JSON'] }\n }\n }\n\n if (!Array.isArray(rawValue)) {\n return { value: [] as any[], errors: ['Blocks value must be an array'] }\n }\n\n const normalized = rawValue.map((item, index) => {\n if (!item || typeof item !== 'object') {\n errors.push(`Block #${index + 1} must be an object`)\n return null\n }\n\n if ((item as any).blockType && (item as any).data && typeof (item as any).data === 'object') {\n return { [config.discriminator]: (item as any).blockType, ...(item as any).data }\n }\n\n if (!(config.discriminator in (item as any))) {\n errors.push(`Block #${index + 1} is missing \"${config.discriminator}\"`)\n }\n\n return item as any\n }).filter((item) => item !== null)\n\n return { value: normalized, errors }\n}\n"]}
@@ -1443,6 +1443,50 @@ INSERT OR IGNORE INTO plugins (
1443
1443
  unixepoch(),
1444
1444
  unixepoch()
1445
1445
  );
1446
+ `
1447
+ },
1448
+ {
1449
+ id: "027",
1450
+ name: "Fix Slug Field Type",
1451
+ filename: "027_fix_slug_field_type.sql",
1452
+ description: "Migration 027: Fix Slug Field Type",
1453
+ sql: "-- Migration: Fix slug field type\n-- Description: Update slug fields to use 'slug' field type instead of 'text' for proper auto-generation\n-- Created: 2026-01-10\n\n-- Update pages collection slug field to use 'slug' field type\nUPDATE content_fields \nSET field_type = 'slug'\nWHERE field_name = 'slug' AND collection_id = 'pages-collection';\n\n-- Update blog posts slug field if it exists\nUPDATE content_fields \nSET field_type = 'slug'\nWHERE field_name = 'slug' AND collection_id = 'blog-posts-collection';\n\n-- Update news slug field if it exists\nUPDATE content_fields \nSET field_type = 'slug'\nWHERE field_name = 'slug' AND collection_id = 'news-collection';\n"
1454
+ },
1455
+ {
1456
+ id: "028",
1457
+ name: "Fix Slug Field Type In Schemas",
1458
+ filename: "028_fix_slug_field_type_in_schemas.sql",
1459
+ description: "Migration 028: Fix Slug Field Type In Schemas",
1460
+ sql: `-- Migration: Fix slug field type in collection schemas
1461
+ -- Description: Update slug fields in collection schemas to use 'slug' type instead of 'string'
1462
+ -- Created: 2026-01-10
1463
+
1464
+ -- Update pages-collection schema
1465
+ UPDATE collections
1466
+ SET schema = REPLACE(
1467
+ schema,
1468
+ '"slug":{"type":"string"',
1469
+ '"slug":{"type":"slug"'
1470
+ )
1471
+ WHERE id = 'pages-collection' AND schema LIKE '%"slug":{"type":"string"%';
1472
+
1473
+ -- Update blog-posts-collection schema if it exists
1474
+ UPDATE collections
1475
+ SET schema = REPLACE(
1476
+ schema,
1477
+ '"slug":{"type":"string"',
1478
+ '"slug":{"type":"slug"'
1479
+ )
1480
+ WHERE id = 'blog-posts-collection' AND schema LIKE '%"slug":{"type":"string"%';
1481
+
1482
+ -- Update news-collection schema if it exists
1483
+ UPDATE collections
1484
+ SET schema = REPLACE(
1485
+ schema,
1486
+ '"slug":{"type":"string"',
1487
+ '"slug":{"type":"slug"'
1488
+ )
1489
+ WHERE id = 'news-collection' AND schema LIKE '%"slug":{"type":"string"%';
1446
1490
  `
1447
1491
  }
1448
1492
  ];
@@ -1852,5 +1896,5 @@ var MigrationService = class {
1852
1896
  };
1853
1897
 
1854
1898
  exports.MigrationService = MigrationService;
1855
- //# sourceMappingURL=chunk-IEWLOVP3.cjs.map
1856
- //# sourceMappingURL=chunk-IEWLOVP3.cjs.map
1899
+ //# sourceMappingURL=chunk-I4V3VZWF.cjs.map
1900
+ //# sourceMappingURL=chunk-I4V3VZWF.cjs.map