Skip to content

Commit 1a46493

Browse files
committed
chore: release v2.8.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 89a3747 commit 1a46493

50 files changed

Lines changed: 988 additions & 570 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package-lock.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sonicjs",
3-
"version": "2.7.0",
3+
"version": "2.8.0",
44
"private": true,
55
"type": "module",
66
"workspaces": [
Lines changed: 216 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,13 +1389,6 @@ INSERT OR IGNORE INTO plugins (
13891389
);
13901390
`
13911391
},
1392-
{
1393-
id: "025",
1394-
name: "Rename Mdxeditor To Easy Mdx",
1395-
filename: "025_rename_mdxeditor_to_easy_mdx.sql",
1396-
description: "Migration 025: Rename Mdxeditor To Easy Mdx",
1397-
sql: "-- Rename mdxeditor-plugin to easy-mdx\n-- Migration: 025_rename_mdxeditor_to_easy_mdx\n-- Description: Update plugin ID from mdxeditor-plugin to easy-mdx to reflect the change to EasyMDE editor\n\n-- Update the plugin record if it exists with the old ID\nUPDATE plugins\nSET\n id = 'easy-mdx',\n name = 'easy-mdx',\n display_name = 'EasyMDE Markdown Editor',\n description = 'Lightweight markdown editor with live preview. Provides a simple and efficient editor with markdown support for richtext fields.'\nWHERE id = 'mdxeditor-plugin';\n\n-- Update any plugin_hooks references\nUPDATE plugin_hooks\nSET plugin_id = 'easy-mdx'\nWHERE plugin_id = 'mdxeditor-plugin';\n\n-- Update any plugin_activity_log references\nUPDATE plugin_activity_log\nSET plugin_id = 'easy-mdx'\nWHERE plugin_id = 'mdxeditor-plugin';\n"
1398-
},
13991392
{
14001393
id: "026",
14011394
name: "Add Otp Login",
@@ -1491,9 +1484,221 @@ WHERE id = 'news-collection' AND schema LIKE '%"slug":{"type":"string"%';
14911484
},
14921485
{
14931486
id: "029",
1487+
name: "Add Forms System",
1488+
filename: "029_add_forms_system.sql",
1489+
description: "Migration 029: Add Forms System",
1490+
sql: `-- Migration: 029_add_forms_system.sql
1491+
-- Description: Add Form.io integration for advanced form building
1492+
-- Date: January 23, 2026
1493+
-- Phase: 1 - Database Schema
1494+
1495+
-- =====================================================
1496+
-- Table: forms
1497+
-- Description: Stores form definitions and configuration
1498+
-- =====================================================
1499+
1500+
CREATE TABLE IF NOT EXISTS forms (
1501+
id TEXT PRIMARY KEY,
1502+
name TEXT NOT NULL UNIQUE, -- Machine name (e.g., "contact-form")
1503+
display_name TEXT NOT NULL, -- Human name (e.g., "Contact Form")
1504+
description TEXT, -- Optional description
1505+
category TEXT DEFAULT 'general', -- Form category (contact, survey, registration, etc.)
1506+
1507+
-- Form.io schema (JSON)
1508+
formio_schema TEXT NOT NULL, -- Complete Form.io JSON schema
1509+
1510+
-- Settings
1511+
settings TEXT, -- JSON: {
1512+
-- emailNotifications: true,
1513+
-- notifyEmail: "admin@example.com",
1514+
-- successMessage: "Thank you!",
1515+
-- redirectUrl: "/thank-you",
1516+
-- allowAnonymous: true,
1517+
-- requireAuth: false,
1518+
-- maxSubmissions: null,
1519+
-- submitButtonText: "Submit",
1520+
-- saveProgress: true,
1521+
-- webhookUrl: null
1522+
-- }
1523+
1524+
-- Status & Management
1525+
is_active INTEGER DEFAULT 1, -- Active/inactive flag
1526+
is_public INTEGER DEFAULT 1, -- Public (anyone) vs private (auth required)
1527+
managed INTEGER DEFAULT 0, -- Code-managed (like collections)
1528+
1529+
-- Metadata
1530+
icon TEXT, -- Optional icon for admin UI
1531+
color TEXT, -- Optional color (hex) for admin UI
1532+
tags TEXT, -- JSON array of tags
1533+
1534+
-- Stats
1535+
submission_count INTEGER DEFAULT 0, -- Total submissions received
1536+
view_count INTEGER DEFAULT 0, -- Form views (optional tracking)
1537+
1538+
-- Ownership
1539+
created_by TEXT REFERENCES users(id), -- User who created the form
1540+
updated_by TEXT REFERENCES users(id), -- User who last updated
1541+
1542+
-- Timestamps
1543+
created_at INTEGER NOT NULL,
1544+
updated_at INTEGER NOT NULL
1545+
);
1546+
1547+
-- Indexes for forms
1548+
CREATE INDEX IF NOT EXISTS idx_forms_name ON forms(name);
1549+
CREATE INDEX IF NOT EXISTS idx_forms_category ON forms(category);
1550+
CREATE INDEX IF NOT EXISTS idx_forms_active ON forms(is_active);
1551+
CREATE INDEX IF NOT EXISTS idx_forms_public ON forms(is_public);
1552+
CREATE INDEX IF NOT EXISTS idx_forms_created_by ON forms(created_by);
1553+
1554+
-- =====================================================
1555+
-- Table: form_submissions
1556+
-- Description: Stores submitted form data
1557+
-- =====================================================
1558+
1559+
CREATE TABLE IF NOT EXISTS form_submissions (
1560+
id TEXT PRIMARY KEY,
1561+
form_id TEXT NOT NULL REFERENCES forms(id) ON DELETE CASCADE,
1562+
1563+
-- Submission data
1564+
submission_data TEXT NOT NULL, -- JSON: The actual form data submitted
1565+
1566+
-- Submission metadata
1567+
status TEXT DEFAULT 'pending', -- pending, reviewed, approved, rejected, spam
1568+
submission_number INTEGER, -- Sequential number per form
1569+
1570+
-- User information (if authenticated)
1571+
user_id TEXT REFERENCES users(id), -- Submitter user ID (if logged in)
1572+
user_email TEXT, -- Email from form (or user account)
1573+
1574+
-- Tracking information
1575+
ip_address TEXT, -- IP address of submitter
1576+
user_agent TEXT, -- Browser user agent
1577+
referrer TEXT, -- Page that referred to form
1578+
utm_source TEXT, -- UTM tracking params
1579+
utm_medium TEXT,
1580+
utm_campaign TEXT,
1581+
1582+
-- Review/Processing
1583+
reviewed_by TEXT REFERENCES users(id), -- Admin who reviewed
1584+
reviewed_at INTEGER, -- Review timestamp
1585+
review_notes TEXT, -- Admin notes
1586+
1587+
-- Flags
1588+
is_spam INTEGER DEFAULT 0, -- Spam flag
1589+
is_archived INTEGER DEFAULT 0, -- Archived flag
1590+
1591+
-- Timestamps
1592+
submitted_at INTEGER NOT NULL,
1593+
updated_at INTEGER NOT NULL
1594+
);
1595+
1596+
-- Indexes for submissions
1597+
CREATE INDEX IF NOT EXISTS idx_form_submissions_form_id ON form_submissions(form_id);
1598+
CREATE INDEX IF NOT EXISTS idx_form_submissions_status ON form_submissions(status);
1599+
CREATE INDEX IF NOT EXISTS idx_form_submissions_user_id ON form_submissions(user_id);
1600+
CREATE INDEX IF NOT EXISTS idx_form_submissions_email ON form_submissions(user_email);
1601+
CREATE INDEX IF NOT EXISTS idx_form_submissions_submitted_at ON form_submissions(submitted_at);
1602+
CREATE INDEX IF NOT EXISTS idx_form_submissions_spam ON form_submissions(is_spam);
1603+
1604+
-- Trigger to auto-increment submission_number per form
1605+
CREATE TRIGGER IF NOT EXISTS set_submission_number
1606+
AFTER INSERT ON form_submissions
1607+
BEGIN
1608+
UPDATE form_submissions
1609+
SET submission_number = (
1610+
SELECT COUNT(*)
1611+
FROM form_submissions
1612+
WHERE form_id = NEW.form_id
1613+
AND id <= NEW.id
1614+
)
1615+
WHERE id = NEW.id;
1616+
END;
1617+
1618+
-- Trigger to update form submission_count
1619+
CREATE TRIGGER IF NOT EXISTS increment_form_submission_count
1620+
AFTER INSERT ON form_submissions
1621+
BEGIN
1622+
UPDATE forms
1623+
SET submission_count = submission_count + 1,
1624+
updated_at = unixepoch() * 1000
1625+
WHERE id = NEW.form_id;
1626+
END;
1627+
1628+
-- =====================================================
1629+
-- Table: form_files (Optional)
1630+
-- Description: Link form submissions to uploaded files
1631+
-- =====================================================
1632+
1633+
CREATE TABLE IF NOT EXISTS form_files (
1634+
id TEXT PRIMARY KEY,
1635+
submission_id TEXT NOT NULL REFERENCES form_submissions(id) ON DELETE CASCADE,
1636+
media_id TEXT NOT NULL REFERENCES media(id) ON DELETE CASCADE,
1637+
field_name TEXT NOT NULL, -- Form field that uploaded this file
1638+
uploaded_at INTEGER NOT NULL
1639+
);
1640+
1641+
-- Indexes for form files
1642+
CREATE INDEX IF NOT EXISTS idx_form_files_submission ON form_files(submission_id);
1643+
CREATE INDEX IF NOT EXISTS idx_form_files_media ON form_files(media_id);
1644+
1645+
-- =====================================================
1646+
-- Sample Data: Create a default contact form
1647+
-- =====================================================
1648+
1649+
INSERT OR IGNORE INTO forms (
1650+
id,
1651+
name,
1652+
display_name,
1653+
description,
1654+
category,
1655+
formio_schema,
1656+
settings,
1657+
is_active,
1658+
is_public,
1659+
created_at,
1660+
updated_at
1661+
) VALUES (
1662+
'default-contact-form',
1663+
'contact',
1664+
'Contact Form',
1665+
'A simple contact form for getting in touch',
1666+
'contact',
1667+
'{"components":[]}',
1668+
'{"emailNotifications":false,"successMessage":"Thank you for your submission!","submitButtonText":"Submit","requireAuth":false}',
1669+
1,
1670+
1,
1671+
unixepoch() * 1000,
1672+
unixepoch() * 1000
1673+
);
1674+
`
1675+
},
1676+
{
1677+
id: "030",
1678+
name: "Add Turnstile To Forms",
1679+
filename: "030_add_turnstile_to_forms.sql",
1680+
description: "Migration 030: Add Turnstile To Forms",
1681+
sql: `-- Add Turnstile configuration to forms table
1682+
-- This allows per-form Turnstile settings with global fallback
1683+
1684+
-- Add columns (D1 may not support CHECK constraints in ALTER TABLE)
1685+
ALTER TABLE forms ADD COLUMN turnstile_enabled INTEGER DEFAULT 0;
1686+
ALTER TABLE forms ADD COLUMN turnstile_settings TEXT;
1687+
1688+
-- Set default to inherit global settings for existing forms
1689+
UPDATE forms
1690+
SET turnstile_settings = '{"inherit":true}'
1691+
WHERE turnstile_settings IS NULL;
1692+
1693+
-- Add index for faster lookups
1694+
CREATE INDEX IF NOT EXISTS idx_forms_turnstile ON forms(turnstile_enabled);
1695+
`
1696+
},
1697+
{
1698+
id: "031",
14941699
name: "Ai Search Plugin",
1495-
filename: "029_ai_search_plugin.sql",
1496-
description: "Migration 029: Ai Search Plugin",
1700+
filename: "031_ai_search_plugin.sql",
1701+
description: "Migration 031: Ai Search Plugin",
14971702
sql: "-- AI Search plugin settings\nCREATE TABLE IF NOT EXISTS ai_search_settings (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n enabled BOOLEAN DEFAULT 0,\n ai_mode_enabled BOOLEAN DEFAULT 1,\n selected_collections TEXT, -- JSON array of collection IDs to index\n dismissed_collections TEXT, -- JSON array of collection IDs user chose not to index\n autocomplete_enabled BOOLEAN DEFAULT 1,\n cache_duration INTEGER DEFAULT 1, -- hours\n results_limit INTEGER DEFAULT 20,\n index_media BOOLEAN DEFAULT 0,\n index_status TEXT, -- JSON object with status per collection\n last_indexed_at INTEGER,\n created_at INTEGER DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER DEFAULT (strftime('%s', 'now') * 1000)\n);\n\n-- Search history/analytics\nCREATE TABLE IF NOT EXISTS ai_search_history (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n query TEXT NOT NULL,\n mode TEXT, -- 'ai' or 'keyword'\n results_count INTEGER,\n user_id INTEGER,\n created_at INTEGER DEFAULT (strftime('%s', 'now') * 1000)\n);\n\n-- Index metadata tracking (per collection)\nCREATE TABLE IF NOT EXISTS ai_search_index_meta (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n collection_id INTEGER NOT NULL,\n collection_name TEXT NOT NULL, -- Cache collection name for display\n total_items INTEGER DEFAULT 0,\n indexed_items INTEGER DEFAULT 0,\n last_sync_at INTEGER,\n status TEXT DEFAULT 'pending', -- 'pending', 'indexing', 'completed', 'error'\n error_message TEXT,\n UNIQUE(collection_id)\n);\n\n-- Indexes for performance\nCREATE INDEX IF NOT EXISTS idx_ai_search_history_created_at ON ai_search_history(created_at);\nCREATE INDEX IF NOT EXISTS idx_ai_search_history_mode ON ai_search_history(mode);\nCREATE INDEX IF NOT EXISTS idx_ai_search_index_meta_collection_id ON ai_search_index_meta(collection_id);\nCREATE INDEX IF NOT EXISTS idx_ai_search_index_meta_status ON ai_search_index_meta(status);\n"
14981703
}
14991704
];
@@ -1903,5 +2108,5 @@ var MigrationService = class {
19032108
};
19042109

19052110
exports.MigrationService = MigrationService;
1906-
//# sourceMappingURL=chunk-336E3KOO.cjs.map
1907-
//# sourceMappingURL=chunk-336E3KOO.cjs.map
2111+
//# sourceMappingURL=chunk-2YRNPIU4.cjs.map
2112+
//# sourceMappingURL=chunk-2YRNPIU4.cjs.map

packages/core/dist/chunk-2YRNPIU4.cjs.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/dist/chunk-336E3KOO.cjs.map

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/dist/chunk-5PH7K7YR.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,5 +1506,5 @@ exports.selectWorkflowHistorySchema = selectWorkflowHistorySchema;
15061506
exports.systemLogs = systemLogs;
15071507
exports.users = users;
15081508
exports.workflowHistory = workflowHistory;
1509-
//# sourceMappingURL=chunk-VNLR35GO.cjs.map
1510-
//# sourceMappingURL=chunk-VNLR35GO.cjs.map
1509+
//# sourceMappingURL=chunk-5TO3OUFT.cjs.map
1510+
//# sourceMappingURL=chunk-5TO3OUFT.cjs.map

packages/core/dist/chunk-5TO3OUFT.cjs.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
var chunkMPT5PA6U_cjs = require('./chunk-MPT5PA6U.cjs');
4-
var chunk336E3KOO_cjs = require('./chunk-336E3KOO.cjs');
4+
var chunk2YRNPIU4_cjs = require('./chunk-2YRNPIU4.cjs');
55
var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
66
var jwt = require('hono/jwt');
77
var cookie = require('hono/cookie');
@@ -20,7 +20,7 @@ function bootstrapMiddleware(config = {}) {
2020
try {
2121
console.log("[Bootstrap] Starting system initialization...");
2222
console.log("[Bootstrap] Running database migrations...");
23-
const migrationService = new chunk336E3KOO_cjs.MigrationService(c.env.DB);
23+
const migrationService = new chunk2YRNPIU4_cjs.MigrationService(c.env.DB);
2424
await migrationService.runPendingMigrations();
2525
console.log("[Bootstrap] Syncing collection configurations...");
2626
try {
@@ -239,5 +239,5 @@ exports.requirePermission = requirePermission;
239239
exports.requireRole = requireRole;
240240
exports.securityHeaders = securityHeaders;
241241
exports.securityLoggingMiddleware = securityLoggingMiddleware;
242-
//# sourceMappingURL=chunk-E6KXFMWT.cjs.map
243-
//# sourceMappingURL=chunk-E6KXFMWT.cjs.map
242+
//# sourceMappingURL=chunk-6RABGLOO.cjs.map
243+
//# sourceMappingURL=chunk-6RABGLOO.cjs.map

0 commit comments

Comments
 (0)