@sonicjs-cms/core 2.0.3 → 2.0.4

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.
@@ -4,7 +4,7 @@ var chunk3NVJ6W27_cjs = require('./chunk-3NVJ6W27.cjs');
4
4
  var chunk4BJGEGX5_cjs = require('./chunk-4BJGEGX5.cjs');
5
5
  var chunkLEG4KNFP_cjs = require('./chunk-LEG4KNFP.cjs');
6
6
  var chunk3SPQ3J4N_cjs = require('./chunk-3SPQ3J4N.cjs');
7
- var chunkUL32L2KV_cjs = require('./chunk-UL32L2KV.cjs');
7
+ var chunkBRPONFW6_cjs = require('./chunk-BRPONFW6.cjs');
8
8
  var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
9
9
  var hono = require('hono');
10
10
  var cors = require('hono/cors');
@@ -334,12 +334,12 @@ apiRoutes.get("/content", async (c) => {
334
334
  });
335
335
  }
336
336
  }
337
- const filter = chunkUL32L2KV_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
337
+ const filter = chunkBRPONFW6_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
338
338
  if (!filter.limit) {
339
339
  filter.limit = 50;
340
340
  }
341
341
  filter.limit = Math.min(filter.limit, 1e3);
342
- const builder = new chunkUL32L2KV_cjs.QueryFilterBuilder();
342
+ const builder = new chunkBRPONFW6_cjs.QueryFilterBuilder();
343
343
  const queryResult = builder.build("content", filter);
344
344
  if (queryResult.errors.length > 0) {
345
345
  return c.json({
@@ -426,7 +426,7 @@ apiRoutes.get("/collections/:collection/content", async (c) => {
426
426
  if (!collectionResult) {
427
427
  return c.json({ error: "Collection not found" }, 404);
428
428
  }
429
- const filter = chunkUL32L2KV_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
429
+ const filter = chunkBRPONFW6_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
430
430
  if (!filter.where) {
431
431
  filter.where = { and: [] };
432
432
  }
@@ -442,7 +442,7 @@ apiRoutes.get("/collections/:collection/content", async (c) => {
442
442
  filter.limit = 50;
443
443
  }
444
444
  filter.limit = Math.min(filter.limit, 1e3);
445
- const builder = new chunkUL32L2KV_cjs.QueryFilterBuilder();
445
+ const builder = new chunkBRPONFW6_cjs.QueryFilterBuilder();
446
446
  const queryResult = builder.build("content", filter);
447
447
  if (queryResult.errors.length > 0) {
448
448
  return c.json({
@@ -918,10 +918,17 @@ apiMediaRoutes.post("/create-folder", async (c) => {
918
918
  }
919
919
  const checkStmt = c.env.DB.prepare("SELECT COUNT(*) as count FROM media WHERE folder = ? AND deleted_at IS NULL");
920
920
  const existingFolder = await checkStmt.bind(folderName).first();
921
+ if (existingFolder && existingFolder.count > 0) {
922
+ return c.json({
923
+ success: false,
924
+ error: `Folder "${folderName}" already exists`
925
+ }, 400);
926
+ }
921
927
  return c.json({
922
928
  success: true,
923
- message: `Folder "${folderName}" created successfully`,
924
- folder: folderName
929
+ message: `Folder "${folderName}" is ready. Upload files to this folder to make it appear in the media library.`,
930
+ folder: folderName,
931
+ note: "Folders appear automatically when you upload files to them"
925
932
  });
926
933
  } catch (error) {
927
934
  console.error("Create folder error:", error);
@@ -2346,7 +2353,7 @@ authRoutes.post("/register/form", async (c) => {
2346
2353
  Account created successfully! Redirecting to admin dashboard...
2347
2354
  <script>
2348
2355
  setTimeout(() => {
2349
- window.location.href = '/admin/content';
2356
+ window.location.href = '/admin/dashboard';
2350
2357
  }, 2000);
2351
2358
  </script>
2352
2359
  </div>
@@ -2414,7 +2421,7 @@ authRoutes.post("/login/form", async (c) => {
2414
2421
  </div>
2415
2422
  <script>
2416
2423
  setTimeout(() => {
2417
- window.location.href = '/admin/content';
2424
+ window.location.href = '/admin/dashboard';
2418
2425
  }, 2000);
2419
2426
  </script>
2420
2427
  </div>
@@ -2707,7 +2714,7 @@ authRoutes.post("/accept-invitation", async (c) => {
2707
2714
  maxAge: 60 * 60 * 24
2708
2715
  // 24 hours
2709
2716
  });
2710
- return c.redirect("/admin/content?welcome=true");
2717
+ return c.redirect("/admin/dashboard?welcome=true");
2711
2718
  } catch (error) {
2712
2719
  console.error("Accept invitation error:", error);
2713
2720
  return c.json({ error: "Failed to accept invitation" }, 500);
@@ -6716,7 +6723,7 @@ function renderUserEditPage(data) {
6716
6723
  <input
6717
6724
  type="text"
6718
6725
  name="first_name"
6719
- value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.firstName || "")}"
6726
+ value="${chunkBRPONFW6_cjs.escapeHtml(data.userToEdit.firstName || "")}"
6720
6727
  required
6721
6728
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6722
6729
  />
@@ -6727,7 +6734,7 @@ function renderUserEditPage(data) {
6727
6734
  <input
6728
6735
  type="text"
6729
6736
  name="last_name"
6730
- value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.lastName || "")}"
6737
+ value="${chunkBRPONFW6_cjs.escapeHtml(data.userToEdit.lastName || "")}"
6731
6738
  required
6732
6739
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6733
6740
  />
@@ -6738,7 +6745,7 @@ function renderUserEditPage(data) {
6738
6745
  <input
6739
6746
  type="text"
6740
6747
  name="username"
6741
- value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.username || "")}"
6748
+ value="${chunkBRPONFW6_cjs.escapeHtml(data.userToEdit.username || "")}"
6742
6749
  required
6743
6750
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6744
6751
  />
@@ -6749,7 +6756,7 @@ function renderUserEditPage(data) {
6749
6756
  <input
6750
6757
  type="email"
6751
6758
  name="email"
6752
- value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.email || "")}"
6759
+ value="${chunkBRPONFW6_cjs.escapeHtml(data.userToEdit.email || "")}"
6753
6760
  required
6754
6761
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6755
6762
  />
@@ -6760,7 +6767,7 @@ function renderUserEditPage(data) {
6760
6767
  <input
6761
6768
  type="tel"
6762
6769
  name="phone"
6763
- value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.phone || "")}"
6770
+ value="${chunkBRPONFW6_cjs.escapeHtml(data.userToEdit.phone || "")}"
6764
6771
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6765
6772
  />
6766
6773
  </div>
@@ -6774,7 +6781,7 @@ function renderUserEditPage(data) {
6774
6781
  class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-zinc-500/30 dark:outline-zinc-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-zinc-500 dark:focus-visible:outline-zinc-400 sm:text-sm/6"
6775
6782
  >
6776
6783
  ${data.roles.map((role) => `
6777
- <option value="${chunkUL32L2KV_cjs.escapeHtml(role.value)}" ${data.userToEdit.role === role.value ? "selected" : ""}>${chunkUL32L2KV_cjs.escapeHtml(role.label)}</option>
6784
+ <option value="${chunkBRPONFW6_cjs.escapeHtml(role.value)}" ${data.userToEdit.role === role.value ? "selected" : ""}>${chunkBRPONFW6_cjs.escapeHtml(role.label)}</option>
6778
6785
  `).join("")}
6779
6786
  </select>
6780
6787
  <svg viewBox="0 0 16 16" fill="currentColor" data-slot="icon" aria-hidden="true" class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-600 dark:text-zinc-400 sm:size-4">
@@ -6790,7 +6797,7 @@ function renderUserEditPage(data) {
6790
6797
  name="bio"
6791
6798
  rows="3"
6792
6799
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6793
- >${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.bio || "")}</textarea>
6800
+ >${chunkBRPONFW6_cjs.escapeHtml(data.userToEdit.bio || "")}</textarea>
6794
6801
  </div>
6795
6802
  </div>
6796
6803
 
@@ -7789,12 +7796,12 @@ userRoutes.put("/profile", async (c) => {
7789
7796
  const db = c.env.DB;
7790
7797
  try {
7791
7798
  const formData = await c.req.formData();
7792
- const firstName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("first_name")?.toString());
7793
- const lastName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("last_name")?.toString());
7794
- const username = chunkUL32L2KV_cjs.sanitizeInput(formData.get("username")?.toString());
7799
+ const firstName = chunkBRPONFW6_cjs.sanitizeInput(formData.get("first_name")?.toString());
7800
+ const lastName = chunkBRPONFW6_cjs.sanitizeInput(formData.get("last_name")?.toString());
7801
+ const username = chunkBRPONFW6_cjs.sanitizeInput(formData.get("username")?.toString());
7795
7802
  const email = formData.get("email")?.toString()?.trim().toLowerCase() || "";
7796
- const phone = chunkUL32L2KV_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
7797
- const bio = chunkUL32L2KV_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
7803
+ const phone = chunkBRPONFW6_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
7804
+ const bio = chunkBRPONFW6_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
7798
7805
  const timezone = formData.get("timezone")?.toString() || "UTC";
7799
7806
  const language = formData.get("language")?.toString() || "en";
7800
7807
  const emailNotifications = formData.get("email_notifications") === "1";
@@ -8161,12 +8168,12 @@ userRoutes.post("/users/new", async (c) => {
8161
8168
  const user = c.get("user");
8162
8169
  try {
8163
8170
  const formData = await c.req.formData();
8164
- const firstName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("first_name")?.toString());
8165
- const lastName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("last_name")?.toString());
8166
- const username = chunkUL32L2KV_cjs.sanitizeInput(formData.get("username")?.toString());
8171
+ const firstName = chunkBRPONFW6_cjs.sanitizeInput(formData.get("first_name")?.toString());
8172
+ const lastName = chunkBRPONFW6_cjs.sanitizeInput(formData.get("last_name")?.toString());
8173
+ const username = chunkBRPONFW6_cjs.sanitizeInput(formData.get("username")?.toString());
8167
8174
  const email = formData.get("email")?.toString()?.trim().toLowerCase() || "";
8168
- const phone = chunkUL32L2KV_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
8169
- const bio = chunkUL32L2KV_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
8175
+ const phone = chunkBRPONFW6_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
8176
+ const bio = chunkBRPONFW6_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
8170
8177
  const role = formData.get("role")?.toString() || "viewer";
8171
8178
  const password = formData.get("password")?.toString() || "";
8172
8179
  const confirmPassword = formData.get("confirm_password")?.toString() || "";
@@ -8367,12 +8374,12 @@ userRoutes.put("/users/:id", async (c) => {
8367
8374
  const userId = c.req.param("id");
8368
8375
  try {
8369
8376
  const formData = await c.req.formData();
8370
- const firstName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("first_name")?.toString());
8371
- const lastName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("last_name")?.toString());
8372
- const username = chunkUL32L2KV_cjs.sanitizeInput(formData.get("username")?.toString());
8377
+ const firstName = chunkBRPONFW6_cjs.sanitizeInput(formData.get("first_name")?.toString());
8378
+ const lastName = chunkBRPONFW6_cjs.sanitizeInput(formData.get("last_name")?.toString());
8379
+ const username = chunkBRPONFW6_cjs.sanitizeInput(formData.get("username")?.toString());
8373
8380
  const email = formData.get("email")?.toString()?.trim().toLowerCase() || "";
8374
- const phone = chunkUL32L2KV_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
8375
- const bio = chunkUL32L2KV_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
8381
+ const phone = chunkBRPONFW6_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
8382
+ const bio = chunkBRPONFW6_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
8376
8383
  const role = formData.get("role")?.toString() || "viewer";
8377
8384
  const isActive = formData.get("is_active") === "1";
8378
8385
  const emailVerified = formData.get("email_verified") === "1";
@@ -8515,8 +8522,8 @@ userRoutes.post("/invite-user", async (c) => {
8515
8522
  const formData = await c.req.formData();
8516
8523
  const email = formData.get("email")?.toString()?.trim().toLowerCase() || "";
8517
8524
  const role = formData.get("role")?.toString()?.trim() || "viewer";
8518
- const firstName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("first_name")?.toString());
8519
- const lastName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("last_name")?.toString());
8525
+ const firstName = chunkBRPONFW6_cjs.sanitizeInput(formData.get("first_name")?.toString());
8526
+ const lastName = chunkBRPONFW6_cjs.sanitizeInput(formData.get("last_name")?.toString());
8520
8527
  if (!email || !firstName || !lastName) {
8521
8528
  return c.json({ error: "Email, first name, and last name are required" }, 400);
8522
8529
  }
@@ -9331,11 +9338,12 @@ function renderMediaLibraryPage(data) {
9331
9338
  </div>
9332
9339
 
9333
9340
  <!-- Upload Form -->
9334
- <form
9341
+ <form
9335
9342
  id="upload-form"
9336
9343
  hx-post="/admin/media/upload"
9337
9344
  hx-encoding="multipart/form-data"
9338
9345
  hx-target="#upload-results"
9346
+ hx-on::after-request="if(event.detail.successful) { setTimeout(() => { window.location.href = '/admin/media?t=' + Date.now(); }, 1500); }"
9339
9347
  class="space-y-4"
9340
9348
  >
9341
9349
  <!-- Drag and Drop Zone -->
@@ -10218,21 +10226,23 @@ adminMediaRoutes.get("/", async (c) => {
10218
10226
  const { results } = await stmt.bind(...params).all();
10219
10227
  const foldersStmt = db.prepare(`
10220
10228
  SELECT folder, COUNT(*) as count, SUM(size) as totalSize
10221
- FROM media
10222
- GROUP BY folder
10229
+ FROM media
10230
+ WHERE deleted_at IS NULL
10231
+ GROUP BY folder
10223
10232
  ORDER BY folder
10224
10233
  `);
10225
10234
  const { results: folders } = await foldersStmt.all();
10226
10235
  const typesStmt = db.prepare(`
10227
- SELECT
10228
- CASE
10236
+ SELECT
10237
+ CASE
10229
10238
  WHEN mime_type LIKE 'image/%' THEN 'images'
10230
10239
  WHEN mime_type LIKE 'video/%' THEN 'videos'
10231
10240
  WHEN mime_type IN ('application/pdf', 'text/plain') THEN 'documents'
10232
10241
  ELSE 'other'
10233
10242
  END as type,
10234
10243
  COUNT(*) as count
10235
- FROM media
10244
+ FROM media
10245
+ WHERE deleted_at IS NULL
10236
10246
  GROUP BY type
10237
10247
  `);
10238
10248
  const { results: types } = await typesStmt.all();
@@ -10508,6 +10518,18 @@ adminMediaRoutes.post("/upload", async (c) => {
10508
10518
  }
10509
10519
  const uploadResults = [];
10510
10520
  const errors = [];
10521
+ console.log("[MEDIA UPLOAD] c.env keys:", Object.keys(c.env));
10522
+ console.log("[MEDIA UPLOAD] MEDIA_BUCKET defined?", !!c.env.MEDIA_BUCKET);
10523
+ console.log("[MEDIA UPLOAD] MEDIA_BUCKET type:", typeof c.env.MEDIA_BUCKET);
10524
+ if (!c.env.MEDIA_BUCKET) {
10525
+ console.error("[MEDIA UPLOAD] MEDIA_BUCKET is not available! Available env keys:", Object.keys(c.env));
10526
+ return c.html(html.html`
10527
+ <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
10528
+ Media storage (R2) is not configured. Please check your wrangler.toml configuration.
10529
+ <br><small>Debug: Available bindings: ${Object.keys(c.env).join(", ")}</small>
10530
+ </div>
10531
+ `);
10532
+ }
10511
10533
  for (const file of files) {
10512
10534
  try {
10513
10535
  const validation = fileValidationSchema2.safeParse({
@@ -16237,7 +16259,7 @@ function renderStorageUsage(databaseSizeBytes, mediaSizeBytes) {
16237
16259
  }
16238
16260
 
16239
16261
  // src/routes/admin-dashboard.ts
16240
- var VERSION = chunkUL32L2KV_cjs.getCoreVersion();
16262
+ var VERSION = chunkBRPONFW6_cjs.getCoreVersion();
16241
16263
  var router = new hono.Hono();
16242
16264
  router.use("*", chunk4BJGEGX5_cjs.requireAuth());
16243
16265
  router.get("/", async (c) => {
@@ -16278,7 +16300,7 @@ router.get("/stats", async (c) => {
16278
16300
  }
16279
16301
  let contentCount = 0;
16280
16302
  try {
16281
- const contentStmt = db.prepare("SELECT COUNT(*) as count FROM content WHERE deleted_at IS NULL");
16303
+ const contentStmt = db.prepare("SELECT COUNT(*) as count FROM content");
16282
16304
  const contentResult = await contentStmt.first();
16283
16305
  contentCount = contentResult?.count || 0;
16284
16306
  } catch (error) {
@@ -17874,11 +17896,13 @@ adminCollectionsRoutes.post("/", async (c) => {
17874
17896
  now,
17875
17897
  now
17876
17898
  ).run();
17877
- try {
17878
- await c.env.CACHE_KV.delete("cache:collections:all");
17879
- await c.env.CACHE_KV.delete(`cache:collection:${name}`);
17880
- } catch (e) {
17881
- console.error("Error clearing cache:", e);
17899
+ if (c.env.CACHE_KV) {
17900
+ try {
17901
+ await c.env.CACHE_KV.delete("cache:collections:all");
17902
+ await c.env.CACHE_KV.delete(`cache:collection:${name}`);
17903
+ } catch (e) {
17904
+ console.error("Error clearing cache:", e);
17905
+ }
17882
17906
  }
17883
17907
  if (isHtmx) {
17884
17908
  return c.html(html.html`
@@ -19999,5 +20023,5 @@ exports.api_system_default = api_system_default;
19999
20023
  exports.auth_default = auth_default;
20000
20024
  exports.router = router;
20001
20025
  exports.userRoutes = userRoutes;
20002
- //# sourceMappingURL=chunk-5B3VMVEX.cjs.map
20003
- //# sourceMappingURL=chunk-5B3VMVEX.cjs.map
20026
+ //# sourceMappingURL=chunk-RZW752PE.cjs.map
20027
+ //# sourceMappingURL=chunk-RZW752PE.cjs.map