Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions my-sonicjs-app/src/collections/page-blocks.collection.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,74 @@
import type { CollectionConfig } from '@sonicjs-cms/core'

const heroBlock = {
label: 'Hero',
properties: {
heading: { type: 'string', title: 'Heading', required: true },
subheading: { type: 'textarea', title: 'Subheading', maxLength: 600 },
image: { type: 'media', title: 'Background/Image' },
imageAlt: { type: 'string', title: 'Image Alt' },

ctaPrimary: {
title: 'Primary CTA',
type: 'object',
properties: {
label: { type: 'string', title: 'Label', required: true },
link: {
title: 'Link',
type: 'object',
properties: {
mode: {
type: 'select',
title: 'Link type',
enum: ['none', 'internal', 'external'],
enumLabels: ['None', 'Internal', 'External'],
default: 'none',
},
reference: { type: 'reference', title: 'Internal reference', collection: 'pages' },
url: { type: 'url', title: 'External URL' },
},
},
style: {
type: 'select',
title: 'Button style',
enum: ['primary', 'secondary'],
enumLabels: ['Primary', 'Secondary'],
default: 'primary',
},
},
},
ctaSecondary: {
title: 'Secondary CTA',
type: 'object',
properties: {
label: { type: 'string', title: 'Label' },
link: {
title: 'Link',
type: 'object',
properties: {
mode: {
type: 'select',
title: 'Type',
enum: ['none', 'internal', 'external'],
enumLabels: ['None', 'Internal', 'External'],
default: 'none',
},
reference: { type: 'reference', title: 'Internal reference', collection: 'pages' },
url: { type: 'url', title: 'External URL' },
},
},
style: {
type: 'select',
title: 'Button style',
enum: ['primary', 'secondary'],
enumLabels: ['Primary', 'Secondary'],
default: 'primary',
},
},
},
},
}

const pageBlocksCollection: CollectionConfig = {
name: 'page_blocks',
displayName: 'Page Blocks',
Expand Down Expand Up @@ -60,6 +129,7 @@ const pageBlocksCollection: CollectionConfig = {
type: 'object',
discriminator: 'blockType',
blocks: {
hero: heroBlock,
text: {
label: 'Text',
properties: {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ function buildQuery(table, filter) {
// package.json
var package_default = {
name: "@sonicjs-cms/core",
version: "2.7.0",
version: "2.8.0",
description: "Core framework for SonicJS headless CMS - Edge-first, TypeScript-native CMS built for Cloudflare Workers",
type: "module",
main: "./dist/index.cjs",
Expand Down Expand Up @@ -617,5 +617,5 @@ exports.renderTemplate = renderTemplate;
exports.sanitizeInput = sanitizeInput;
exports.sanitizeObject = sanitizeObject;
exports.templateRenderer = templateRenderer;
//# sourceMappingURL=chunk-DMZI7OU3.cjs.map
//# sourceMappingURL=chunk-DMZI7OU3.cjs.map
//# sourceMappingURL=chunk-5HMR2SJW.cjs.map
//# sourceMappingURL=chunk-5HMR2SJW.cjs.map

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion packages/core/dist/chunk-5PH7K7YR.js.map

This file was deleted.

1 change: 0 additions & 1 deletion packages/core/dist/chunk-5TO3OUFT.cjs.map

This file was deleted.

1 change: 0 additions & 1 deletion packages/core/dist/chunk-6STHJAKU.cjs.map

This file was deleted.

1 change: 0 additions & 1 deletion packages/core/dist/chunk-7DU5PUKL.js.map

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { getCacheService, CACHE_CONFIGS, getLogger, SettingsService } from './chunk-5PH7K7YR.js';
import { requireAuth, isPluginActive, requireRole, AuthManager, logActivity } from './chunk-FQAOOSEB.js';
import { getCacheService, CACHE_CONFIGS, getLogger, SettingsService } from './chunk-G44QUVNM.js';
import { requireAuth, isPluginActive, requireRole, AuthManager, logActivity } from './chunk-YGWKSR7I.js';
import { PluginService } from './chunk-YFJJU26H.js';
import { MigrationService } from './chunk-DADFCDML.js';
import { MigrationService } from './chunk-PM35AAL5.js';
import { init_admin_layout_catalyst_template, renderDesignPage, renderCheckboxPage, renderTestimonialsList, renderCodeExamplesList, renderAlert, renderTable, renderPagination, renderConfirmationDialog, getConfirmationDialogScript, renderAdminLayoutCatalyst, renderAdminLayout, adminLayoutV2, renderForm } from './chunk-VCH6HXVP.js';
import { PluginBuilder, TurnstileService } from './chunk-J5WGMRSU.js';
import { QueryFilterBuilder, sanitizeInput, getCoreVersion, escapeHtml, getBlocksFieldConfig, parseBlocksValue } from './chunk-PSRPBW3W.js';
import { QueryFilterBuilder, sanitizeInput, getCoreVersion, escapeHtml, getBlocksFieldConfig, parseBlocksValue } from './chunk-34QIAULP.js';
import { metricsTracker } from './chunk-FICTAGD4.js';
import { Hono } from 'hono';
import { cors } from 'hono/cors';
Expand Down Expand Up @@ -2231,7 +2231,7 @@ adminApiRoutes.delete("/collections/:id", async (c) => {
});
adminApiRoutes.get("/migrations/status", async (c) => {
try {
const { MigrationService: MigrationService2 } = await import('./migrations-WJVCIKQO.js');
const { MigrationService: MigrationService2 } = await import('./migrations-AIIAB6XI.js');
const db = c.env.DB;
const migrationService = new MigrationService2(db);
const status = await migrationService.getMigrationStatus();
Expand All @@ -2256,7 +2256,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
error: "Unauthorized. Admin access required."
}, 403);
}
const { MigrationService: MigrationService2 } = await import('./migrations-WJVCIKQO.js');
const { MigrationService: MigrationService2 } = await import('./migrations-AIIAB6XI.js');
const db = c.env.DB;
const migrationService = new MigrationService2(db);
const result = await migrationService.runPendingMigrations();
Expand All @@ -2275,7 +2275,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
});
adminApiRoutes.get("/migrations/validate", async (c) => {
try {
const { MigrationService: MigrationService2 } = await import('./migrations-WJVCIKQO.js');
const { MigrationService: MigrationService2 } = await import('./migrations-AIIAB6XI.js');
const db = c.env.DB;
const migrationService = new MigrationService2(db);
const validation = await migrationService.validateSchema();
Expand Down Expand Up @@ -3959,7 +3959,50 @@ function getReadFieldValueScript() {
const nonHiddenInput = inputs.find((input) => input.type !== 'hidden' && input.type !== 'checkbox');
const hiddenInput = inputs.find((input) => input.type === 'hidden');

const readStructuredFieldsHost = (host) => {
const fields = Array.from(host.querySelectorAll(':scope > .structured-subfield'));
if (fields.length === 1 && fields[0].dataset.structuredField === '__value') {
return window.sonicReadFieldValue(fields[0]);
}
return fields.reduce((acc, subfield) => {
const fieldName = subfield.dataset.structuredField;
if (!fieldName || fieldName === '__value') return acc;
acc[fieldName] = window.sonicReadFieldValue(subfield);
return acc;
}, {});
};

const readStructuredObject = () => {
const objectContainer = fieldWrapper.querySelector('[data-structured-object]');
if (!objectContainer) return null;
const host =
objectContainer.querySelector(':scope > [data-structured-object-fields]') ||
objectContainer.querySelector('[data-structured-object-fields]') ||
objectContainer;
return readStructuredFieldsHost(host);
};

const readStructuredArray = () => {
const arrayContainer = fieldWrapper.querySelector('[data-structured-array]');
if (!arrayContainer) return null;
const list = arrayContainer.querySelector('[data-structured-array-list]');
if (!list) return [];
const items = Array.from(list.querySelectorAll(':scope > .structured-array-item'));
return items.map((item) => {
const host =
item.querySelector(':scope > [data-array-item-fields]') ||
item.querySelector('[data-array-item-fields]') ||
item;
return readStructuredFieldsHost(host);
});
};

if (fieldType === 'object' || fieldType === 'array') {
const liveValue = fieldType === 'array' ? readStructuredArray() : readStructuredObject();
if (liveValue !== null) {
return liveValue;
}

if (!hiddenInput) {
return fieldType === 'array' ? [] : {};
}
Expand Down Expand Up @@ -5023,7 +5066,15 @@ function getStructuredFieldScript() {
const readFieldValue = window.sonicReadFieldValue;

const readStructuredValue = (container) => {
const fields = Array.from(container.querySelectorAll('.structured-subfield'));
// Read only the current level's direct subfields from the closest
// structured host. This avoids flattening nested object/array values
// while still working if wrappers are introduced around the host.
const fieldHost = container.querySelector(
'[data-structured-object-fields], [data-array-item-fields]'
) || container;
const fields = Array.from(
fieldHost.querySelectorAll(':scope > .structured-subfield')
);
if (fields.length === 1 && fields[0].dataset.structuredField === '__value') {
return readFieldValue(fields[0]);
}
Expand Down Expand Up @@ -27758,5 +27809,5 @@ var ROUTES_INFO = {
};

export { ROUTES_INFO, adminCheckboxRoutes, adminCollectionsRoutes, adminDesignRoutes, adminFormsRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, admin_api_default, admin_code_examples_default, admin_content_default, admin_testimonials_default, api_content_crud_default, api_default, api_media_default, api_system_default, auth_default, getConfirmationDialogScript2 as getConfirmationDialogScript, public_forms_default, renderConfirmationDialog2 as renderConfirmationDialog, router, router2, test_cleanup_default, userRoutes };
//# sourceMappingURL=chunk-7DU5PUKL.js.map
//# sourceMappingURL=chunk-7DU5PUKL.js.map
//# sourceMappingURL=chunk-CC4JXOXD.js.map
//# sourceMappingURL=chunk-CC4JXOXD.js.map
1 change: 1 addition & 0 deletions packages/core/dist/chunk-CC4JXOXD.js.map

Large diffs are not rendered by default.

Loading