@sonicjs-cms/core 2.4.0 → 2.6.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.
- package/dist/{app-Db0AfT5F.d.cts → app-DV27cjPy.d.cts} +1 -1
- package/dist/{app-Db0AfT5F.d.ts → app-DV27cjPy.d.ts} +1 -1
- package/dist/{chunk-YIXSSJWD.cjs → chunk-63K7XXRX.cjs} +5 -5
- package/dist/{chunk-YIXSSJWD.cjs.map → chunk-63K7XXRX.cjs.map} +1 -1
- package/dist/{chunk-VNCYCH3H.js → chunk-7DL5SPPX.js} +59 -5
- package/dist/chunk-7DL5SPPX.js.map +1 -0
- package/dist/{chunk-AZLU3ROK.cjs → chunk-BZC4FYW7.cjs} +4 -4
- package/dist/chunk-BZC4FYW7.cjs.map +1 -0
- package/dist/chunk-CLIH2T74.js +403 -0
- package/dist/chunk-CLIH2T74.js.map +1 -0
- package/dist/{chunk-D2NLCPO2.js → chunk-EVZOVYLO.js} +53 -2
- package/dist/chunk-EVZOVYLO.js.map +1 -0
- package/dist/{chunk-DXM575E2.js → chunk-EYWR6UA2.js} +6 -6
- package/dist/chunk-EYWR6UA2.js.map +1 -0
- package/dist/{chunk-CPXAVWCU.js → chunk-F332TENF.js} +278 -3
- package/dist/chunk-F332TENF.js.map +1 -0
- package/dist/{chunk-FT6NBHNX.js → chunk-F6GZURXJ.js} +2536 -600
- package/dist/chunk-F6GZURXJ.js.map +1 -0
- package/dist/{chunk-2MI3LZFH.cjs → chunk-IIRVZSP2.cjs} +53 -2
- package/dist/chunk-IIRVZSP2.cjs.map +1 -0
- package/dist/{chunk-V5LBQN3I.js → chunk-KA2PDJNB.js} +4 -4
- package/dist/chunk-KA2PDJNB.js.map +1 -0
- package/dist/{chunk-AVPUX57O.js → chunk-KAOWRIFD.js} +3 -3
- package/dist/{chunk-AVPUX57O.js.map → chunk-KAOWRIFD.js.map} +1 -1
- package/dist/{chunk-ILZ3DP4I.cjs → chunk-MPT5PA6U.cjs} +24 -2
- package/dist/chunk-MPT5PA6U.cjs.map +1 -0
- package/dist/{chunk-A4SVOGG6.cjs → chunk-N7TDLOUE.cjs} +2696 -762
- package/dist/chunk-N7TDLOUE.cjs.map +1 -0
- package/dist/{chunk-7I5INVNR.cjs → chunk-T3YIKW2A.cjs} +9 -9
- package/dist/chunk-T3YIKW2A.cjs.map +1 -0
- package/dist/{chunk-DTLB6UIH.cjs → chunk-Y72M3MVX.cjs} +280 -2
- package/dist/chunk-Y72M3MVX.cjs.map +1 -0
- package/dist/{chunk-SGAG6FD3.js → chunk-YFJJU26H.js} +24 -2
- package/dist/chunk-YFJJU26H.js.map +1 -0
- package/dist/chunk-YHW27CBV.cjs +406 -0
- package/dist/chunk-YHW27CBV.cjs.map +1 -0
- package/dist/{chunk-FYEDK7K7.cjs → chunk-YMTTGHEK.cjs} +61 -4
- package/dist/chunk-YMTTGHEK.cjs.map +1 -0
- package/dist/{collection-config-FLlGtsh9.d.cts → collection-config-BF95LgQb.d.cts} +10 -2
- package/dist/{collection-config-FLlGtsh9.d.ts → collection-config-BF95LgQb.d.ts} +10 -2
- package/dist/index.cjs +2001 -142
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +504 -9
- package/dist/index.d.ts +504 -9
- package/dist/index.js +1893 -41
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +24 -24
- package/dist/middleware.d.cts +1 -1
- package/dist/middleware.d.ts +1 -1
- package/dist/middleware.js +3 -3
- package/dist/migrations-QNYAWQLB.cjs +13 -0
- package/dist/{migrations-32QAYLWJ.cjs.map → migrations-QNYAWQLB.cjs.map} +1 -1
- package/dist/migrations-R6NQBKQV.js +4 -0
- package/dist/{migrations-57ZHBQ4X.js.map → migrations-R6NQBKQV.js.map} +1 -1
- package/dist/{plugin-bootstrap-CDh0JHtW.d.ts → plugin-bootstrap-CB-xaBfK.d.ts} +2 -2
- package/dist/{plugin-bootstrap-C0E3jdz-.d.cts → plugin-bootstrap-U-cw9jn3.d.cts} +2 -2
- package/dist/plugin-manager-Baa6xXqB.d.ts +328 -0
- package/dist/plugin-manager-vBal9Zip.d.cts +328 -0
- package/dist/plugins.cjs +20 -7
- package/dist/plugins.d.cts +53 -310
- package/dist/plugins.d.ts +53 -310
- package/dist/plugins.js +2 -1
- package/dist/routes.cjs +27 -26
- package/dist/routes.d.cts +1 -1
- package/dist/routes.d.ts +1 -1
- package/dist/routes.js +7 -6
- package/dist/services.cjs +16 -16
- package/dist/services.d.cts +2 -2
- package/dist/services.d.ts +2 -2
- package/dist/services.js +2 -2
- package/dist/templates.cjs +17 -17
- package/dist/templates.js +2 -2
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utils.cjs +23 -11
- package/dist/utils.d.cts +38 -1
- package/dist/utils.d.ts +38 -1
- package/dist/utils.js +1 -1
- package/migrations/027_fix_slug_field_type.sql +18 -0
- package/migrations/028_fix_slug_field_type_in_schemas.sql +30 -0
- package/migrations/029_ai_search_plugin.sql +45 -0
- package/package.json +5 -2
- package/dist/chunk-2MI3LZFH.cjs.map +0 -1
- package/dist/chunk-7I5INVNR.cjs.map +0 -1
- package/dist/chunk-A4SVOGG6.cjs.map +0 -1
- package/dist/chunk-AZLU3ROK.cjs.map +0 -1
- package/dist/chunk-CPXAVWCU.js.map +0 -1
- package/dist/chunk-D2NLCPO2.js.map +0 -1
- package/dist/chunk-DTLB6UIH.cjs.map +0 -1
- package/dist/chunk-DXM575E2.js.map +0 -1
- package/dist/chunk-FT6NBHNX.js.map +0 -1
- package/dist/chunk-FYEDK7K7.cjs.map +0 -1
- package/dist/chunk-ILZ3DP4I.cjs.map +0 -1
- package/dist/chunk-SGAG6FD3.js.map +0 -1
- package/dist/chunk-V5LBQN3I.js.map +0 -1
- package/dist/chunk-VNCYCH3H.js.map +0 -1
- package/dist/migrations-32QAYLWJ.cjs +0 -13
- package/dist/migrations-57ZHBQ4X.js +0 -4
|
@@ -30,6 +30,12 @@ function sanitizeObject(obj, fields) {
|
|
|
30
30
|
return sanitized;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// src/utils/slug-utils.ts
|
|
34
|
+
function generateSlug(text) {
|
|
35
|
+
if (!text) return "";
|
|
36
|
+
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);
|
|
37
|
+
}
|
|
38
|
+
|
|
33
39
|
// src/utils/template-renderer.ts
|
|
34
40
|
var TemplateRenderer = class {
|
|
35
41
|
templateCache = /* @__PURE__ */ new Map();
|
|
@@ -415,7 +421,7 @@ function buildQuery(table, filter) {
|
|
|
415
421
|
// package.json
|
|
416
422
|
var package_default = {
|
|
417
423
|
name: "@sonicjs-cms/core",
|
|
418
|
-
version: "2.
|
|
424
|
+
version: "2.6.0",
|
|
419
425
|
description: "Core framework for SonicJS headless CMS - Edge-first, TypeScript-native CMS built for Cloudflare Workers",
|
|
420
426
|
type: "module",
|
|
421
427
|
main: "./dist/index.cjs",
|
|
@@ -483,6 +489,7 @@ var package_default = {
|
|
|
483
489
|
lint: "eslint src/",
|
|
484
490
|
"lint:fix": "eslint src/ --fix",
|
|
485
491
|
test: "vitest --run",
|
|
492
|
+
"test:cov": "vitest --run --coverage",
|
|
486
493
|
"test:watch": "vitest",
|
|
487
494
|
prepublishOnly: "npm run build"
|
|
488
495
|
},
|
|
@@ -522,13 +529,15 @@ var package_default = {
|
|
|
522
529
|
semver: "^7.7.3"
|
|
523
530
|
},
|
|
524
531
|
devDependencies: {
|
|
532
|
+
"@vitest/coverage-v8": "^4.0.5",
|
|
525
533
|
"@cloudflare/workers-types": "^4.20251014.0",
|
|
526
534
|
"@types/node": "^24.9.2",
|
|
527
535
|
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
528
536
|
"@typescript-eslint/parser": "^8.50.0",
|
|
529
537
|
"drizzle-orm": "^0.44.7",
|
|
530
538
|
eslint: "^9.39.2",
|
|
531
|
-
|
|
539
|
+
glob: "^10.5.0",
|
|
540
|
+
hono: "^4.11.4",
|
|
532
541
|
tsup: "^8.5.0",
|
|
533
542
|
typescript: "^5.9.3",
|
|
534
543
|
vitest: "^4.0.5",
|
|
@@ -549,16 +558,64 @@ function getCoreVersion() {
|
|
|
549
558
|
return SONICJS_VERSION;
|
|
550
559
|
}
|
|
551
560
|
|
|
561
|
+
// src/utils/blocks.ts
|
|
562
|
+
function getBlocksFieldConfig(fieldOptions) {
|
|
563
|
+
if (!fieldOptions || typeof fieldOptions !== "object") return null;
|
|
564
|
+
const itemsConfig = fieldOptions.items && typeof fieldOptions.items === "object" ? fieldOptions.items : null;
|
|
565
|
+
if (!itemsConfig || !itemsConfig.blocks || typeof itemsConfig.blocks !== "object") {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
const discriminator = typeof itemsConfig.discriminator === "string" && itemsConfig.discriminator ? itemsConfig.discriminator : "blockType";
|
|
569
|
+
return {
|
|
570
|
+
blocks: itemsConfig.blocks,
|
|
571
|
+
discriminator
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
function parseBlocksValue(value, config) {
|
|
575
|
+
const errors = [];
|
|
576
|
+
let rawValue = value;
|
|
577
|
+
if (rawValue === null || rawValue === void 0 || rawValue === "") {
|
|
578
|
+
return { value: [], errors };
|
|
579
|
+
}
|
|
580
|
+
if (typeof rawValue === "string") {
|
|
581
|
+
try {
|
|
582
|
+
rawValue = JSON.parse(rawValue);
|
|
583
|
+
} catch {
|
|
584
|
+
return { value: [], errors: ["Blocks value must be valid JSON"] };
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
if (!Array.isArray(rawValue)) {
|
|
588
|
+
return { value: [], errors: ["Blocks value must be an array"] };
|
|
589
|
+
}
|
|
590
|
+
const normalized = rawValue.map((item, index) => {
|
|
591
|
+
if (!item || typeof item !== "object") {
|
|
592
|
+
errors.push(`Block #${index + 1} must be an object`);
|
|
593
|
+
return null;
|
|
594
|
+
}
|
|
595
|
+
if (item.blockType && item.data && typeof item.data === "object") {
|
|
596
|
+
return { [config.discriminator]: item.blockType, ...item.data };
|
|
597
|
+
}
|
|
598
|
+
if (!(config.discriminator in item)) {
|
|
599
|
+
errors.push(`Block #${index + 1} is missing "${config.discriminator}"`);
|
|
600
|
+
}
|
|
601
|
+
return item;
|
|
602
|
+
}).filter((item) => item !== null);
|
|
603
|
+
return { value: normalized, errors };
|
|
604
|
+
}
|
|
605
|
+
|
|
552
606
|
exports.QueryFilterBuilder = QueryFilterBuilder;
|
|
553
607
|
exports.SONICJS_VERSION = SONICJS_VERSION;
|
|
554
608
|
exports.TemplateRenderer = TemplateRenderer;
|
|
555
609
|
exports.buildQuery = buildQuery;
|
|
556
610
|
exports.escapeHtml = escapeHtml;
|
|
611
|
+
exports.generateSlug = generateSlug;
|
|
612
|
+
exports.getBlocksFieldConfig = getBlocksFieldConfig;
|
|
557
613
|
exports.getCoreVersion = getCoreVersion;
|
|
558
614
|
exports.package_default = package_default;
|
|
615
|
+
exports.parseBlocksValue = parseBlocksValue;
|
|
559
616
|
exports.renderTemplate = renderTemplate;
|
|
560
617
|
exports.sanitizeInput = sanitizeInput;
|
|
561
618
|
exports.sanitizeObject = sanitizeObject;
|
|
562
619
|
exports.templateRenderer = templateRenderer;
|
|
563
|
-
//# sourceMappingURL=chunk-
|
|
564
|
-
//# sourceMappingURL=chunk-
|
|
620
|
+
//# sourceMappingURL=chunk-YMTTGHEK.cjs.map
|
|
621
|
+
//# sourceMappingURL=chunk-YMTTGHEK.cjs.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-YMTTGHEK.cjs","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 '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\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.6.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:cov\": \"vitest --run --coverage\",\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 \"@vitest/coverage-v8\": \"^4.0.5\",\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.11.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"]}
|
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
* Collections can be defined in TypeScript/JSON files and synced to the database.
|
|
6
6
|
*/
|
|
7
7
|
type FieldType = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'email' | 'url' | 'richtext' | 'markdown' | 'json' | 'array' | 'object' | 'reference' | 'media' | 'select' | 'multiselect' | 'checkbox' | 'radio' | 'textarea' | 'slug' | 'color' | 'file';
|
|
8
|
+
interface BlockDefinition {
|
|
9
|
+
label?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
properties: Record<string, FieldConfig>;
|
|
12
|
+
}
|
|
13
|
+
type BlockDefinitions = Record<string, BlockDefinition>;
|
|
8
14
|
interface FieldConfig {
|
|
9
15
|
type: FieldType;
|
|
10
16
|
title?: string;
|
|
@@ -20,9 +26,11 @@ interface FieldConfig {
|
|
|
20
26
|
pattern?: string;
|
|
21
27
|
enum?: string[];
|
|
22
28
|
enumLabels?: string[];
|
|
23
|
-
collection?: string;
|
|
29
|
+
collection?: string | string[];
|
|
24
30
|
items?: FieldConfig;
|
|
25
31
|
properties?: Record<string, FieldConfig>;
|
|
32
|
+
blocks?: BlockDefinitions;
|
|
33
|
+
discriminator?: string;
|
|
26
34
|
format?: string;
|
|
27
35
|
widget?: string;
|
|
28
36
|
dependsOn?: string;
|
|
@@ -104,4 +112,4 @@ interface CollectionSyncResult {
|
|
|
104
112
|
error?: string;
|
|
105
113
|
}
|
|
106
114
|
|
|
107
|
-
export type { CollectionSchema as C, FieldType as F, FieldConfig as a,
|
|
115
|
+
export type { BlockDefinition as B, CollectionSchema as C, FieldType as F, FieldConfig as a, BlockDefinitions as b, CollectionConfig as c, CollectionConfigModule as d, CollectionSyncResult as e };
|
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
* Collections can be defined in TypeScript/JSON files and synced to the database.
|
|
6
6
|
*/
|
|
7
7
|
type FieldType = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'email' | 'url' | 'richtext' | 'markdown' | 'json' | 'array' | 'object' | 'reference' | 'media' | 'select' | 'multiselect' | 'checkbox' | 'radio' | 'textarea' | 'slug' | 'color' | 'file';
|
|
8
|
+
interface BlockDefinition {
|
|
9
|
+
label?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
properties: Record<string, FieldConfig>;
|
|
12
|
+
}
|
|
13
|
+
type BlockDefinitions = Record<string, BlockDefinition>;
|
|
8
14
|
interface FieldConfig {
|
|
9
15
|
type: FieldType;
|
|
10
16
|
title?: string;
|
|
@@ -20,9 +26,11 @@ interface FieldConfig {
|
|
|
20
26
|
pattern?: string;
|
|
21
27
|
enum?: string[];
|
|
22
28
|
enumLabels?: string[];
|
|
23
|
-
collection?: string;
|
|
29
|
+
collection?: string | string[];
|
|
24
30
|
items?: FieldConfig;
|
|
25
31
|
properties?: Record<string, FieldConfig>;
|
|
32
|
+
blocks?: BlockDefinitions;
|
|
33
|
+
discriminator?: string;
|
|
26
34
|
format?: string;
|
|
27
35
|
widget?: string;
|
|
28
36
|
dependsOn?: string;
|
|
@@ -104,4 +112,4 @@ interface CollectionSyncResult {
|
|
|
104
112
|
error?: string;
|
|
105
113
|
}
|
|
106
114
|
|
|
107
|
-
export type { CollectionSchema as C, FieldType as F, FieldConfig as a,
|
|
115
|
+
export type { BlockDefinition as B, CollectionSchema as C, FieldType as F, FieldConfig as a, BlockDefinitions as b, CollectionConfig as c, CollectionConfigModule as d, CollectionSyncResult as e };
|