@sonicjs-cms/core 2.7.0 → 2.8.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 (96) hide show
  1. package/dist/{app-DV27cjPy.d.cts → app-CYEm1ytG.d.cts} +1 -0
  2. package/dist/{app-DV27cjPy.d.ts → app-CYEm1ytG.d.ts} +1 -0
  3. package/dist/{chunk-DNHJS6RN.js → chunk-34QIAULP.js} +4 -4
  4. package/dist/{chunk-DNHJS6RN.js.map → chunk-34QIAULP.js.map} +1 -1
  5. package/dist/{chunk-Y3EWJQ4D.js → chunk-3E76TKR5.js} +3 -3
  6. package/dist/{chunk-Y3EWJQ4D.js.map → chunk-3E76TKR5.js.map} +1 -1
  7. package/dist/{chunk-YRFAQ6MI.cjs → chunk-5CENPGR2.cjs} +219 -14
  8. package/dist/chunk-5CENPGR2.cjs.map +1 -0
  9. package/dist/{chunk-MYB5RY7H.cjs → chunk-5HMR2SJW.cjs} +4 -4
  10. package/dist/{chunk-MYB5RY7H.cjs.map → chunk-5HMR2SJW.cjs.map} +1 -1
  11. package/dist/{chunk-YHW27CBV.cjs → chunk-6FHNRRJ3.cjs} +190 -2
  12. package/dist/chunk-6FHNRRJ3.cjs.map +1 -0
  13. package/dist/{chunk-UISZ2MBW.js → chunk-BAWMAS5S.js} +5438 -1443
  14. package/dist/chunk-BAWMAS5S.js.map +1 -0
  15. package/dist/{chunk-F332TENF.js → chunk-CJYFSKH7.js} +4 -190
  16. package/dist/chunk-CJYFSKH7.js.map +1 -0
  17. package/dist/{chunk-3YNNVSMC.js → chunk-G44QUVNM.js} +90 -2
  18. package/dist/chunk-G44QUVNM.js.map +1 -0
  19. package/dist/{chunk-E2BXLXPW.cjs → chunk-GPTMGUFN.cjs} +4 -4
  20. package/dist/{chunk-E2BXLXPW.cjs.map → chunk-GPTMGUFN.cjs.map} +1 -1
  21. package/dist/chunk-H7AMQWVI.js +2466 -0
  22. package/dist/chunk-H7AMQWVI.js.map +1 -0
  23. package/dist/{chunk-CLIH2T74.js → chunk-J5WGMRSU.js} +189 -3
  24. package/dist/chunk-J5WGMRSU.js.map +1 -0
  25. package/dist/{chunk-L2IDZI7F.js → chunk-JDFPB6UW.js} +219 -14
  26. package/dist/chunk-JDFPB6UW.js.map +1 -0
  27. package/dist/{chunk-Y72M3MVX.cjs → chunk-MNFY6DWY.cjs} +13 -200
  28. package/dist/chunk-MNFY6DWY.cjs.map +1 -0
  29. package/dist/chunk-S6K2H2TS.cjs +2470 -0
  30. package/dist/chunk-S6K2H2TS.cjs.map +1 -0
  31. package/dist/{chunk-EHSZ6TAN.cjs → chunk-SHCYIZAN.cjs} +9 -2
  32. package/dist/chunk-SHCYIZAN.cjs.map +1 -0
  33. package/dist/{chunk-GRN3GHUG.js → chunk-VCH6HXVP.js} +9 -2
  34. package/dist/chunk-VCH6HXVP.js.map +1 -0
  35. package/dist/{chunk-7FOAMNTI.cjs → chunk-VNLR35GO.cjs} +90 -2
  36. package/dist/chunk-VNLR35GO.cjs.map +1 -0
  37. package/dist/{chunk-J7F3NPAP.cjs → chunk-YE2MU7CN.cjs} +5192 -1194
  38. package/dist/chunk-YE2MU7CN.cjs.map +1 -0
  39. package/dist/index.cjs +201 -607
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +3 -3
  42. package/dist/index.d.ts +3 -3
  43. package/dist/index.js +67 -473
  44. package/dist/index.js.map +1 -1
  45. package/dist/middleware.cjs +23 -23
  46. package/dist/middleware.d.cts +1 -1
  47. package/dist/middleware.d.ts +1 -1
  48. package/dist/middleware.js +2 -2
  49. package/dist/migrations-7JGSFOCM.cjs +13 -0
  50. package/dist/{migrations-LEMFV2ND.cjs.map → migrations-7JGSFOCM.cjs.map} +1 -1
  51. package/dist/migrations-YB77VTVF.js +4 -0
  52. package/dist/{migrations-RKQES6XY.js.map → migrations-YB77VTVF.js.map} +1 -1
  53. package/dist/{plugin-bootstrap-CB-xaBfK.d.ts → plugin-bootstrap-C7Mj00Ud.d.ts} +2455 -1
  54. package/dist/{plugin-bootstrap-U-cw9jn3.d.cts → plugin-bootstrap-DKB5f8-E.d.cts} +2455 -1
  55. package/dist/plugins.cjs +14 -14
  56. package/dist/plugins.js +2 -2
  57. package/dist/routes.cjs +39 -27
  58. package/dist/routes.d.cts +126 -53
  59. package/dist/routes.d.ts +126 -53
  60. package/dist/routes.js +7 -7
  61. package/dist/services.cjs +14 -14
  62. package/dist/services.d.cts +1 -1
  63. package/dist/services.d.ts +1 -1
  64. package/dist/services.js +2 -2
  65. package/dist/templates.cjs +25 -17
  66. package/dist/templates.d.cts +21 -1
  67. package/dist/templates.d.ts +21 -1
  68. package/dist/templates.js +2 -2
  69. package/dist/utils.cjs +14 -14
  70. package/dist/utils.js +1 -1
  71. package/migrations/014_fix_plugin_registry.sql +1 -1
  72. package/migrations/020_add_email_plugin.sql +1 -1
  73. package/migrations/026_add_otp_login.sql +1 -1
  74. package/migrations/029_add_forms_system.sql +184 -0
  75. package/migrations/030_add_turnstile_to_forms.sql +14 -0
  76. package/package.json +2 -2
  77. package/dist/chunk-3YNNVSMC.js.map +0 -1
  78. package/dist/chunk-7FOAMNTI.cjs.map +0 -1
  79. package/dist/chunk-AYPF6C4D.cjs +0 -76
  80. package/dist/chunk-AYPF6C4D.cjs.map +0 -1
  81. package/dist/chunk-CLIH2T74.js.map +0 -1
  82. package/dist/chunk-EHSZ6TAN.cjs.map +0 -1
  83. package/dist/chunk-F332TENF.js.map +0 -1
  84. package/dist/chunk-GRN3GHUG.js.map +0 -1
  85. package/dist/chunk-J7F3NPAP.cjs.map +0 -1
  86. package/dist/chunk-L2IDZI7F.js.map +0 -1
  87. package/dist/chunk-UISZ2MBW.js.map +0 -1
  88. package/dist/chunk-V3KVSEG6.js +0 -74
  89. package/dist/chunk-V3KVSEG6.js.map +0 -1
  90. package/dist/chunk-Y72M3MVX.cjs.map +0 -1
  91. package/dist/chunk-YHW27CBV.cjs.map +0 -1
  92. package/dist/chunk-YRFAQ6MI.cjs.map +0 -1
  93. package/dist/migrations-LEMFV2ND.cjs +0 -13
  94. package/dist/migrations-RKQES6XY.js +0 -4
  95. package/migrations/025_rename_mdxeditor_to_easy_mdx.sql +0 -22
  96. /package/migrations/{029_ai_search_plugin.sql → 031_ai_search_plugin.sql} +0 -0
@@ -917,7 +917,7 @@ INSERT OR IGNORE INTO plugins (
917
917
  'Core analytics tracking and reporting plugin with page views and event tracking',
918
918
  '1.0.0',
919
919
  'SonicJS Team',
920
- 'analytics',
920
+ 'seo',
921
921
  '\u{1F4CA}',
922
922
  'active',
923
923
  TRUE,
@@ -1202,7 +1202,7 @@ INSERT OR IGNORE INTO plugins (
1202
1202
  'Send transactional emails using Resend',
1203
1203
  '1.0.0-beta.1',
1204
1204
  'SonicJS Team',
1205
- 'communication',
1205
+ 'utilities',
1206
1206
  '\u{1F4E7}',
1207
1207
  'inactive',
1208
1208
  TRUE,
@@ -1389,13 +1389,6 @@ INSERT OR IGNORE INTO plugins (
1389
1389
  );
1390
1390
  `
1391
1391
  },
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
- },
1399
1392
  {
1400
1393
  id: "026",
1401
1394
  name: "Add Otp Login",
@@ -1435,7 +1428,7 @@ INSERT OR IGNORE INTO plugins (
1435
1428
  'Passwordless authentication via email one-time codes',
1436
1429
  '1.0.0-beta.1',
1437
1430
  'SonicJS Team',
1438
- 'authentication',
1431
+ 'security',
1439
1432
  '\u{1F522}',
1440
1433
  'inactive',
1441
1434
  TRUE,
@@ -1491,9 +1484,221 @@ WHERE id = 'news-collection' AND schema LIKE '%"slug":{"type":"string"%';
1491
1484
  },
1492
1485
  {
1493
1486
  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",
1494
1699
  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",
1497
1702
  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"
1498
1703
  }
1499
1704
  ];
@@ -1903,5 +2108,5 @@ var MigrationService = class {
1903
2108
  };
1904
2109
 
1905
2110
  exports.MigrationService = MigrationService;
1906
- //# sourceMappingURL=chunk-YRFAQ6MI.cjs.map
1907
- //# sourceMappingURL=chunk-YRFAQ6MI.cjs.map
2111
+ //# sourceMappingURL=chunk-5CENPGR2.cjs.map
2112
+ //# sourceMappingURL=chunk-5CENPGR2.cjs.map