emdash 1.0.1-rc.1 → 1.0.1

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 (102) hide show
  1. package/dist/api/schemas/index.d.mts +1 -1
  2. package/dist/astro/index.d.mts +2 -2
  3. package/dist/astro/index.mjs +3 -3
  4. package/dist/astro/middleware/auth.d.mts +2 -2
  5. package/dist/astro/middleware.d.mts +2 -2
  6. package/dist/astro/middleware.mjs +3 -3
  7. package/dist/astro/routes/api/admin/core-update.mjs +1 -1
  8. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +1 -1
  9. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +1 -1
  10. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +1 -1
  11. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +1 -1
  12. package/dist/astro/routes/api/admin/plugins/index.mjs +1 -1
  13. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +1 -1
  14. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +1 -1
  15. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +1 -1
  16. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +1 -1
  17. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +2 -2
  18. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +2 -2
  19. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +2 -2
  20. package/dist/astro/routes/api/admin/plugins/updates.mjs +1 -1
  21. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +1 -1
  22. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +1 -1
  23. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +1 -1
  24. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +1 -1
  25. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +1 -1
  26. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +1 -1
  27. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +1 -1
  28. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +1 -1
  29. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +1 -1
  30. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +1 -1
  31. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +1 -1
  32. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +1 -1
  33. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +1 -1
  34. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +1 -1
  35. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +1 -1
  36. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +1 -1
  37. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +1 -1
  38. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +1 -1
  39. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +1 -1
  40. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +1 -1
  41. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +1 -1
  42. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +1 -1
  43. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +1 -1
  44. package/dist/astro/routes/api/health.mjs +1 -1
  45. package/dist/astro/routes/api/import/wordpress/execute.d.mts +2 -2
  46. package/dist/astro/routes/api/import/wordpress/media.d.mts +2 -2
  47. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +2 -2
  48. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +2 -2
  49. package/dist/astro/routes/api/manifest.mjs +1 -1
  50. package/dist/astro/routes/api/mcp.mjs +1 -1
  51. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +1 -1
  52. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +1 -1
  53. package/dist/astro/routes/api/schema/block-types/index.mjs +1 -1
  54. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +1 -1
  55. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +1 -1
  56. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +1 -1
  57. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +1 -1
  58. package/dist/astro/routes/api/schema/collections/index.mjs +1 -1
  59. package/dist/astro/routes/api/schema/collections/reorder.mjs +1 -1
  60. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +1 -1
  61. package/dist/astro/routes/api/schema/orphans/index.mjs +1 -1
  62. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +1 -1
  63. package/dist/astro/routes/api/settings/backups/archives/index.mjs +1 -1
  64. package/dist/astro/routes/api/settings/backups/export.mjs +1 -1
  65. package/dist/astro/routes/api/settings/backups/index.mjs +1 -1
  66. package/dist/astro/types.d.mts +2 -2
  67. package/dist/{backup-Dq5C3lUw.mjs → backup-CDrPP8fI.mjs} +2 -2
  68. package/dist/{backup-Dq5C3lUw.mjs.map → backup-CDrPP8fI.mjs.map} +1 -1
  69. package/dist/cli/index.mjs +2 -2
  70. package/dist/client/index.d.mts +58 -58
  71. package/dist/{config-BM44cJDH.d.mts → config-BCM5sQP7.d.mts} +5 -5
  72. package/dist/{config-BM44cJDH.d.mts.map → config-BCM5sQP7.d.mts.map} +1 -1
  73. package/dist/db/libsql-migrations.mjs +2 -2
  74. package/dist/db/postgres-migrations.mjs +2 -2
  75. package/dist/db/sqlite-migrations.mjs +2 -2
  76. package/dist/{direct-executor-OpBeN2SS.mjs → direct-executor-Db8xA3zg.mjs} +2 -2
  77. package/dist/{direct-executor-OpBeN2SS.mjs.map → direct-executor-Db8xA3zg.mjs.map} +1 -1
  78. package/dist/{emdash-runtime-MowqLftM.mjs → emdash-runtime-BakQ6io7.mjs} +3 -3
  79. package/dist/{emdash-runtime-MowqLftM.mjs.map → emdash-runtime-BakQ6io7.mjs.map} +1 -1
  80. package/dist/{entry-lock-ZhtMQ206.d.mts → entry-lock-DY8B-xcr.d.mts} +117 -117
  81. package/dist/{entry-lock-ZhtMQ206.d.mts.map → entry-lock-DY8B-xcr.d.mts.map} +1 -1
  82. package/dist/{identity-D7b8NcWO.mjs → identity-DJ-5AcdG.mjs} +2 -2
  83. package/dist/{identity-D7b8NcWO.mjs.map → identity-DJ-5AcdG.mjs.map} +1 -1
  84. package/dist/index.d.mts +2 -2
  85. package/dist/index.mjs +1 -1
  86. package/dist/{manifest-builder-dOBOOa47.mjs → manifest-builder-8jsSLR7s.mjs} +2 -2
  87. package/dist/{manifest-builder-dOBOOa47.mjs.map → manifest-builder-8jsSLR7s.mjs.map} +1 -1
  88. package/dist/media/local-runtime.d.mts +2 -2
  89. package/dist/migrations/index.mjs +2 -2
  90. package/dist/plugin-test-runtime.d.mts +2 -2
  91. package/dist/plugin-test-runtime.mjs +3 -3
  92. package/dist/plugin-utils.d.mts +2 -2
  93. package/dist/plugins/adapt-sandbox-entry.d.mts +2 -2
  94. package/dist/runtime.d.mts +2 -2
  95. package/dist/{transfer-B6ZFzdtp.mjs → transfer-B7LUTaYD.mjs} +2 -2
  96. package/dist/{transfer-B6ZFzdtp.mjs.map → transfer-B7LUTaYD.mjs.map} +1 -1
  97. package/dist/{update-check-C-8Iy__7.mjs → update-check-D8No-E5s.mjs} +2 -2
  98. package/dist/{update-check-C-8Iy__7.mjs.map → update-check-D8No-E5s.mjs.map} +1 -1
  99. package/dist/version-BbygH8CT.mjs +7 -0
  100. package/dist/{version-BMOuGGLR.mjs.map → version-BbygH8CT.mjs.map} +1 -1
  101. package/package.json +6 -6
  102. package/dist/version-BMOuGGLR.mjs +0 -7
@@ -2,9 +2,9 @@ import "../../../../../parse-BPblgoa-.mjs";
2
2
  import "../../../../../types-ibtP7GEA.mjs";
3
3
  import "../../../../../types-BYVIYOlD.mjs";
4
4
  import "../../../../../options-DRF6dlXY.mjs";
5
- import "../../../../../entry-lock-ZhtMQ206.mjs";
5
+ import "../../../../../entry-lock-DY8B-xcr.mjs";
6
6
  import { f as MediaProvider } from "../../../../../placeholder-Bez2282x.mjs";
7
- import { Yr as markContentMediaUsageCollectionStaleSafely } from "../../../../../config-BM44cJDH.mjs";
7
+ import { Yr as markContentMediaUsageCollectionStaleSafely } from "../../../../../config-BCM5sQP7.mjs";
8
8
  import "../../../../../runner-CWl76CH3.mjs";
9
9
  import "../../../../../storage-query-CdVF2bng.mjs";
10
10
  import "../../../../../index-xCy3j0f6.mjs";
@@ -2,8 +2,8 @@ import "../../../../../parse-BPblgoa-.mjs";
2
2
  import "../../../../../types-ibtP7GEA.mjs";
3
3
  import "../../../../../types-BYVIYOlD.mjs";
4
4
  import "../../../../../options-DRF6dlXY.mjs";
5
- import "../../../../../entry-lock-ZhtMQ206.mjs";
6
- import "../../../../../config-BM44cJDH.mjs";
5
+ import "../../../../../entry-lock-DY8B-xcr.mjs";
6
+ import "../../../../../config-BCM5sQP7.mjs";
7
7
  import "../../../../../runner-CWl76CH3.mjs";
8
8
  import "../../../../../storage-query-CdVF2bng.mjs";
9
9
  import { t as fetchPluginTaxonomies } from "../../../../../index-xCy3j0f6.mjs";
@@ -2,7 +2,7 @@ import { t as OptionsRepository } from "../../../options-DhrI7eMv.mjs";
2
2
  import "../../../base64-DvnNgP7e.mjs";
3
3
  import "../../../types-j6MBDjlZ.mjs";
4
4
  import "../../../errors-CjXd1LgH.mjs";
5
- import { n as VERSION, t as COMMIT } from "../../../version-BMOuGGLR.mjs";
5
+ import { n as VERSION, t as COMMIT } from "../../../version-BbygH8CT.mjs";
6
6
  import "../../../errors-CNvATh_7.mjs";
7
7
  import { n as apiSuccess, r as handleError } from "../../../error-DIYXAVk4.mjs";
8
8
  import { t as getAuthMode } from "../../../mode-B9-gMXL9.mjs";
@@ -53,7 +53,7 @@ import { t as claimEntryLockForWrite } from "../../../entry-lock-DrUAdTzf.mjs";
53
53
  import { S as TRANSFER_SCOPES, n as TransferApprovalRepository } from "../../../approvals-CVvJSEBF.mjs";
54
54
  import { a as siteImportDecisionsInputSchema, t as isPlanExecutable } from "../../../plan-Lw7iGnGD.mjs";
55
55
  import { i as TransferOperationRepository } from "../../../stage-DA0NrTRZ.mjs";
56
- import { C as requestTransferApproval, E as analysisTargetContext, S as handleTransferCapabilities, T as loadImportPlan, _ as handleImportGet, c as handleExportGet, d as handleImportAdvance, f as handleImportAnalyze, h as handleImportExecute, i as handleExportAdvance, o as handleExportCreate, t as exportParamsDigest, w as openExportPackage, x as handleImportReceipt } from "../../../transfer-B6ZFzdtp.mjs";
56
+ import { C as requestTransferApproval, E as analysisTargetContext, S as handleTransferCapabilities, T as loadImportPlan, _ as handleImportGet, c as handleExportGet, d as handleImportAdvance, f as handleImportAnalyze, h as handleImportExecute, i as handleExportAdvance, o as handleExportCreate, t as exportParamsDigest, w as openExportPackage, x as handleImportReceipt } from "../../../transfer-B7LUTaYD.mjs";
57
57
  import "../../../keys-DWwMxdZh.mjs";
58
58
  import { z } from "zod";
59
59
  import { Permissions, Role, canActOnOwn, hasPermission } from "@emdash-cms/auth";
@@ -47,7 +47,7 @@ import "../../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../content-repair-BDVsYXWK.mjs";
@@ -47,7 +47,7 @@ import "../../../../../relations-C8JpSkU6.mjs";
47
47
  import "../../../../../dashboard-BoV4pwPP.mjs";
48
48
  import "../../../../../config-CXPcy2iY.mjs";
49
49
  import "../../../../../errors-CNvATh_7.mjs";
50
- import "../../../../../update-check-C-8Iy__7.mjs";
50
+ import "../../../../../update-check-D8No-E5s.mjs";
51
51
  import "../../../../../media-3v7mqAVX.mjs";
52
52
  import "../../../../../media-folders-D2VdVBf6.mjs";
53
53
  import "../../../../../content-repair-BDVsYXWK.mjs";
@@ -6,7 +6,7 @@ import "../../../../../../errors-CjXd1LgH.mjs";
6
6
  import { t as ErrorCode } from "../../../../../../errors-CNvATh_7.mjs";
7
7
  import { a as unwrapResult, r as handleError, t as apiError } from "../../../../../../error-DIYXAVk4.mjs";
8
8
  import "../../../../../../snapshot-W36KbLmc.mjs";
9
- import { a as deleteBackupArchive, c as isValidArchiveName, r as BACKUP_STORAGE_PREFIX } from "../../../../../../backup-Dq5C3lUw.mjs";
9
+ import { a as deleteBackupArchive, c as isValidArchiveName, r as BACKUP_STORAGE_PREFIX } from "../../../../../../backup-CDrPP8fI.mjs";
10
10
  import { i as requirePerm } from "../../../../../../authorize-CTGywswM.mjs";
11
11
 
12
12
  //#region src/astro/routes/api/settings/backups/archives/[name].ts
@@ -6,7 +6,7 @@ import "../../../../../../errors-CjXd1LgH.mjs";
6
6
  import "../../../../../../errors-CNvATh_7.mjs";
7
7
  import { a as unwrapResult, t as apiError } from "../../../../../../error-DIYXAVk4.mjs";
8
8
  import "../../../../../../snapshot-W36KbLmc.mjs";
9
- import { d as runBackupToStorage, s as getBackupSettings } from "../../../../../../backup-Dq5C3lUw.mjs";
9
+ import { d as runBackupToStorage, s as getBackupSettings } from "../../../../../../backup-CDrPP8fI.mjs";
10
10
  import { i as requirePerm } from "../../../../../../authorize-CTGywswM.mjs";
11
11
 
12
12
  //#region src/astro/routes/api/settings/backups/archives/index.ts
@@ -6,7 +6,7 @@ import "../../../../../errors-CjXd1LgH.mjs";
6
6
  import { t as ErrorCode } from "../../../../../errors-CNvATh_7.mjs";
7
7
  import { r as handleError, t as apiError } from "../../../../../error-DIYXAVk4.mjs";
8
8
  import "../../../../../snapshot-W36KbLmc.mjs";
9
- import { i as archiveNameForDate, o as generateBackupJson } from "../../../../../backup-Dq5C3lUw.mjs";
9
+ import { i as archiveNameForDate, o as generateBackupJson } from "../../../../../backup-CDrPP8fI.mjs";
10
10
  import { i as requirePerm } from "../../../../../authorize-CTGywswM.mjs";
11
11
 
12
12
  //#region src/astro/routes/api/settings/backups/export.ts
@@ -7,7 +7,7 @@ import { t as ErrorCode } from "../../../../../errors-CNvATh_7.mjs";
7
7
  import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-DIYXAVk4.mjs";
8
8
  import { n as parseBody, t as isParseError } from "../../../../../parse-5Y0W39xR.mjs";
9
9
  import "../../../../../snapshot-W36KbLmc.mjs";
10
- import { f as updateBackupSettings, l as listBackupArchives, n as BACKUP_RETENTION_MIN, s as getBackupSettings, t as BACKUP_RETENTION_MAX } from "../../../../../backup-Dq5C3lUw.mjs";
10
+ import { f as updateBackupSettings, l as listBackupArchives, n as BACKUP_RETENTION_MIN, s as getBackupSettings, t as BACKUP_RETENTION_MAX } from "../../../../../backup-CDrPP8fI.mjs";
11
11
  import { i as requirePerm } from "../../../../../authorize-CTGywswM.mjs";
12
12
  import { z } from "zod";
13
13
 
@@ -5,9 +5,9 @@ import { d as ContentResponse, u as ContentListResponse } from "../parse-BPblgoa
5
5
  import { t as Database } from "../types-ibtP7GEA.mjs";
6
6
  import { It as PageFragmentContribution, Sn as ResolvedPlugin, dn as PublicPageContext, en as PluginEditorAction, k as ContentActionOrigin, nn as PluginEditorPanel, t as ActorInfo, zt as PageMetadataContribution } from "../types-BYVIYOlD.mjs";
7
7
  import "../options-DRF6dlXY.mjs";
8
- import "../entry-lock-ZhtMQ206.mjs";
8
+ import "../entry-lock-DY8B-xcr.mjs";
9
9
  import { f as MediaProvider, p as MediaProviderCapabilities } from "../placeholder-Bez2282x.mjs";
10
- import { Ar as EmDashConfig, Dr as RouteCallerInput, Er as PluginContentCacheInvalidator, Or as RouteMeta, Sr as SandboxedPluginEntry, Xr as MediaListResponse, Zr as MediaResponse, br as ResolvedPluginEditorExtension, t as ManifestRegistryConfigurationError, yr as PluginEditorExtensionDispatch } from "../config-BM44cJDH.mjs";
10
+ import { Ar as EmDashConfig, Dr as RouteCallerInput, Er as PluginContentCacheInvalidator, Or as RouteMeta, Sr as SandboxedPluginEntry, Xr as MediaListResponse, Zr as MediaResponse, br as ResolvedPluginEditorExtension, t as ManifestRegistryConfigurationError, yr as PluginEditorExtensionDispatch } from "../config-BCM5sQP7.mjs";
11
11
  import "../runner-CWl76CH3.mjs";
12
12
  import { $ as MediaItem, J as HookPipeline, q as EmailPipeline, x as SandboxRunner } from "../storage-query-CdVF2bng.mjs";
13
13
  import "../index-xCy3j0f6.mjs";
@@ -1,5 +1,5 @@
1
1
  import { t as OptionsRepository } from "./options-DhrI7eMv.mjs";
2
- import { n as VERSION } from "./version-BMOuGGLR.mjs";
2
+ import { n as VERSION } from "./version-BbygH8CT.mjs";
3
3
  import { t as ErrorCode } from "./errors-CNvATh_7.mjs";
4
4
  import { t as generateSnapshot } from "./snapshot-W36KbLmc.mjs";
5
5
 
@@ -243,4 +243,4 @@ async function maybeRunScheduledBackup(db, storage) {
243
243
 
244
244
  //#endregion
245
245
  export { deleteBackupArchive as a, isValidArchiveName as c, runBackupToStorage as d, updateBackupSettings as f, archiveNameForDate as i, listBackupArchives as l, BACKUP_RETENTION_MIN as n, generateBackupJson as o, BACKUP_STORAGE_PREFIX as r, getBackupSettings as s, BACKUP_RETENTION_MAX as t, maybeRunScheduledBackup as u };
246
- //# sourceMappingURL=backup-Dq5C3lUw.mjs.map
246
+ //# sourceMappingURL=backup-CDrPP8fI.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"backup-Dq5C3lUw.mjs","names":[],"sources":["../src/api/handlers/backup.ts"],"sourcesContent":["/**\n * Backup handlers — portable content backups, on demand and scheduled.\n *\n * A backup is the snapshot format (see `snapshot.ts`) wrapped in a small\n * envelope: all content (including drafts, scheduled, and trashed entries),\n * schema definitions, taxonomies, menus, widgets, revisions, media metadata,\n * and site settings.\n *\n * Deliberately NOT included:\n * - Users, sessions, credentials, API/OAuth tokens (auth data is neither\n * portable nor safe in a user-downloadable file)\n * - Secrets (`emdash:preview_secret`, plugin config, passkey challenges)\n * - Media binaries (metadata only — the files live in the same bucket the\n * scheduled archives are written to)\n *\n * For full point-in-time database recovery on Cloudflare, D1 Time Travel\n * covers the last 30 days out of the box; these backups complement it with\n * user-holdable, longer-lived archives.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { OptionsRepository } from \"../../database/repositories/options.js\";\nimport type { Database } from \"../../database/types.js\";\nimport type { Storage } from \"../../storage/types.js\";\nimport { VERSION } from \"../../version.js\";\nimport { ErrorCode } from \"../errors.js\";\nimport type { ApiResult } from \"../types.js\";\nimport { generateSnapshot } from \"./snapshot.js\";\n\n// ── Constants ───────────────────────────────────────────────────\n\n/** Storage key prefix for scheduled/manual archives. */\nexport const BACKUP_STORAGE_PREFIX = \"backups/\";\n\n/**\n * Filename prefix within the backups/ folder. Included in the list() prefix\n * so LocalStorage (which matches directory + filename prefix, not flat keys\n * like S3/R2) finds the archives too.\n */\nconst BACKUP_FILE_PREFIX = \"emdash-backup-\";\n\n/** Options key holding the scheduled-backup settings. */\nexport const BACKUP_SETTINGS_KEY = \"emdash:backups\";\n\n/** Options key holding the ISO timestamp of the last scheduled run. */\nconst BACKUP_LAST_RUN_KEY = \"emdash:backups_last_run\";\n\n/** Minimum interval between scheduled backups (23h — daily with cron jitter). */\nconst SCHEDULED_BACKUP_INTERVAL_MS = 23 * 60 * 60 * 1000;\n\n/** Retention bounds for stored archives. */\nexport const BACKUP_RETENTION_MIN = 1;\nexport const BACKUP_RETENTION_MAX = 30;\nconst BACKUP_RETENTION_DEFAULT = 7;\n\n/**\n * Options-table key prefixes included in backups. Never widen this to a\n * prefix that can match secrets (`emdash:preview_secret`, `plugin:`,\n * `emdash:passkey_pending:`).\n */\nconst BACKUP_OPTION_PREFIXES = [\"site:\"];\n\n/**\n * Exact `emdash:*` keys included in backups. Do not add `emdash:site_url`: it\n * is the origin of the deployment that took the backup, not portable site data.\n */\nconst BACKUP_OPTION_KEYS = [\"emdash:site_title\", \"emdash:site_tagline\", \"emdash:locale\"];\n\n/**\n * Archive filename shape. Strict allowlist — the download/delete routes\n * interpolate this into a storage key, so it must never contain `/` or `..`.\n * The random suffix makes names unguessable (defense in depth on top of the\n * media route's backups/ deny) and avoids same-second collisions.\n */\nconst ARCHIVE_NAME_PATTERN =\n\t/^emdash-backup-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-[0-9a-f]{8}\\.json$/;\n\nexport function isValidArchiveName(name: string): boolean {\n\treturn ARCHIVE_NAME_PATTERN.test(name);\n}\n\n// ── Types ───────────────────────────────────────────────────────\n\nexport interface BackupSettings {\n\t/** Whether daily scheduled backups to storage are enabled. */\n\tenabled: boolean;\n\t/** How many archives to keep in storage (oldest pruned first). */\n\tretention: number;\n}\n\nexport interface BackupArchive {\n\t/** Filename within the backups/ prefix (no path separators). */\n\tname: string;\n\t/** Size in bytes. */\n\tsize: number;\n\t/** Last-modified timestamp (ISO). */\n\tlastModified: string;\n}\n\nconst DEFAULT_SETTINGS: BackupSettings = {\n\tenabled: false,\n\tretention: BACKUP_RETENTION_DEFAULT,\n};\n\nfunction clampRetention(value: number): number {\n\tif (!Number.isFinite(value)) return BACKUP_RETENTION_DEFAULT;\n\treturn Math.min(BACKUP_RETENTION_MAX, Math.max(BACKUP_RETENTION_MIN, Math.trunc(value)));\n}\n\n// ── Export ──────────────────────────────────────────────────────\n\n/**\n * Generate a full content backup as a JSON string.\n *\n * ponytail: the whole backup is materialized in memory. Fine for the sites\n * EmDash targets today; truly huge databases should use `wrangler d1 export`\n * (documented on the backups docs page). Upgrade path: stream table-by-table.\n */\nexport async function generateBackupJson(db: Kysely<Database>): Promise<string> {\n\tconst snapshot = await generateSnapshot(db, {\n\t\tincludeDrafts: true,\n\t\tincludeTrashed: true,\n\t\toptionPrefixes: BACKUP_OPTION_PREFIXES,\n\t\toptionKeys: BACKUP_OPTION_KEYS,\n\t});\n\n\treturn JSON.stringify({\n\t\tformat: \"emdash-backup\",\n\t\tformatVersion: 1,\n\t\temdashVersion: VERSION,\n\t\tgeneratedAt: snapshot.generatedAt,\n\t\tschema: snapshot.schema,\n\t\ttables: snapshot.tables,\n\t});\n}\n\n/** Derive the archive filename for a given date (plus a random suffix). */\nexport function archiveNameForDate(date: Date): string {\n\t// 2026-07-09T08:45:12.345Z → emdash-backup-2026-07-09T08-45-12-1a2b3c4d.json\n\tconst stamp = date.toISOString().slice(0, 19).replaceAll(\":\", \"-\");\n\tconst suffix = crypto.randomUUID().replaceAll(\"-\", \"\").slice(0, 8);\n\treturn `emdash-backup-${stamp}-${suffix}.json`;\n}\n\n// ── Settings ────────────────────────────────────────────────────\n\nexport async function getBackupSettings(db: Kysely<Database>): Promise<BackupSettings> {\n\tconst options = new OptionsRepository(db);\n\tconst stored = await options.get<Partial<BackupSettings>>(BACKUP_SETTINGS_KEY);\n\tif (!stored) return { ...DEFAULT_SETTINGS };\n\treturn {\n\t\tenabled: stored.enabled === true,\n\t\tretention: clampRetention(stored.retention ?? BACKUP_RETENTION_DEFAULT),\n\t};\n}\n\nexport async function updateBackupSettings(\n\tdb: Kysely<Database>,\n\tinput: { enabled: boolean; retention: number },\n): Promise<ApiResult<BackupSettings>> {\n\ttry {\n\t\tconst settings: BackupSettings = {\n\t\t\tenabled: input.enabled,\n\t\t\tretention: clampRetention(input.retention),\n\t\t};\n\t\tconst options = new OptionsRepository(db);\n\t\tawait options.set(BACKUP_SETTINGS_KEY, settings);\n\t\treturn { success: true, data: settings };\n\t} catch (error) {\n\t\tconsole.error(\"[backup] Failed to update settings:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.BACKUP_SETTINGS_ERROR, message: \"Failed to update backup settings\" },\n\t\t};\n\t}\n}\n\n// ── Archives in storage ─────────────────────────────────────────\n\n/**\n * List stored archives, newest first.\n *\n * ponytail: single unpaginated list. The retention cap (max 30) bounds the\n * archive count, so one page always suffices.\n */\nexport async function listBackupArchives(storage: Storage): Promise<ApiResult<BackupArchive[]>> {\n\ttry {\n\t\tconst result = await storage.list({\n\t\t\tprefix: `${BACKUP_STORAGE_PREFIX}${BACKUP_FILE_PREFIX}`,\n\t\t\tlimit: 100,\n\t\t});\n\t\tconst archives = result.files\n\t\t\t.map((file) => ({\n\t\t\t\tname: file.key.slice(BACKUP_STORAGE_PREFIX.length),\n\t\t\t\tsize: file.size,\n\t\t\t\tlastModified: file.lastModified.toISOString(),\n\t\t\t}))\n\t\t\t.filter((archive) => isValidArchiveName(archive.name))\n\t\t\t.toSorted((a, b) => (a.name < b.name ? 1 : -1));\n\t\treturn { success: true, data: archives };\n\t} catch (error) {\n\t\tconsole.error(\"[backup] Failed to list archives:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.BACKUP_LIST_ERROR, message: \"Failed to list backup archives\" },\n\t\t};\n\t}\n}\n\n/**\n * Create a backup and store it as an archive, then prune old archives\n * beyond `retention`.\n */\nexport async function runBackupToStorage(\n\tdb: Kysely<Database>,\n\tstorage: Storage,\n\tretention: number,\n): Promise<ApiResult<BackupArchive>> {\n\ttry {\n\t\tconst json = await generateBackupJson(db);\n\t\tconst name = archiveNameForDate(new Date());\n\t\tconst body = new TextEncoder().encode(json);\n\n\t\tawait storage.upload({\n\t\t\tkey: `${BACKUP_STORAGE_PREFIX}${name}`,\n\t\t\tbody,\n\t\t\tcontentType: \"application/json\",\n\t\t});\n\n\t\tawait pruneArchives(storage, clampRetention(retention));\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { name, size: body.byteLength, lastModified: new Date().toISOString() },\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[backup] Failed to create archive:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.BACKUP_CREATE_ERROR, message: \"Failed to create backup archive\" },\n\t\t};\n\t}\n}\n\n/** Delete archives beyond the newest `keep`. Failures are logged, not fatal. */\nasync function pruneArchives(storage: Storage, keep: number): Promise<void> {\n\tconst listed = await listBackupArchives(storage);\n\tif (!listed.success) return;\n\n\tfor (const archive of listed.data.slice(keep)) {\n\t\ttry {\n\t\t\tawait storage.delete(`${BACKUP_STORAGE_PREFIX}${archive.name}`);\n\t\t} catch (error) {\n\t\t\tconsole.error(`[backup] Failed to prune archive ${archive.name}:`, error);\n\t\t}\n\t}\n}\n\nexport async function deleteBackupArchive(\n\tstorage: Storage,\n\tname: string,\n): Promise<ApiResult<{ deleted: true }>> {\n\tif (!isValidArchiveName(name)) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.VALIDATION_ERROR, message: \"Invalid archive name\" },\n\t\t};\n\t}\n\ttry {\n\t\tawait storage.delete(`${BACKUP_STORAGE_PREFIX}${name}`);\n\t\treturn { success: true, data: { deleted: true } };\n\t} catch (error) {\n\t\tconsole.error(`[backup] Failed to delete archive ${name}:`, error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.BACKUP_DELETE_ERROR, message: \"Failed to delete backup archive\" },\n\t\t};\n\t}\n}\n\n// ── Scheduled runs ──────────────────────────────────────────────\n\n/**\n * Run a scheduled backup if enabled and due. Called from the maintenance\n * tick alongside scheduled publishing and system cleanup — never from a\n * request. Never throws.\n *\n * ponytail: last-run bookkeeping is a plain read-then-write, so two isolates\n * ticking simultaneously could both back up. Worst case is a duplicate\n * archive that retention prunes; not worth a lock.\n */\nexport async function maybeRunScheduledBackup(\n\tdb: Kysely<Database>,\n\tstorage: Storage | undefined,\n): Promise<void> {\n\ttry {\n\t\tif (!storage) return;\n\n\t\tconst settings = await getBackupSettings(db);\n\t\tif (!settings.enabled) return;\n\n\t\tconst options = new OptionsRepository(db);\n\t\tconst lastRun = await options.get<string>(BACKUP_LAST_RUN_KEY);\n\t\tif (lastRun) {\n\t\t\tconst elapsed = Date.now() - Date.parse(lastRun);\n\t\t\tif (Number.isFinite(elapsed) && elapsed < SCHEDULED_BACKUP_INTERVAL_MS) return;\n\t\t}\n\n\t\tconst result = await runBackupToStorage(db, storage, settings.retention);\n\t\tif (result.success) {\n\t\t\tawait options.set(BACKUP_LAST_RUN_KEY, new Date().toISOString());\n\t\t\tconsole.log(`[backup] Scheduled backup stored: ${result.data.name}`);\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(\"[backup] Scheduled backup failed:\", error);\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"backup-CDrPP8fI.mjs","names":[],"sources":["../src/api/handlers/backup.ts"],"sourcesContent":["/**\n * Backup handlers — portable content backups, on demand and scheduled.\n *\n * A backup is the snapshot format (see `snapshot.ts`) wrapped in a small\n * envelope: all content (including drafts, scheduled, and trashed entries),\n * schema definitions, taxonomies, menus, widgets, revisions, media metadata,\n * and site settings.\n *\n * Deliberately NOT included:\n * - Users, sessions, credentials, API/OAuth tokens (auth data is neither\n * portable nor safe in a user-downloadable file)\n * - Secrets (`emdash:preview_secret`, plugin config, passkey challenges)\n * - Media binaries (metadata only — the files live in the same bucket the\n * scheduled archives are written to)\n *\n * For full point-in-time database recovery on Cloudflare, D1 Time Travel\n * covers the last 30 days out of the box; these backups complement it with\n * user-holdable, longer-lived archives.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { OptionsRepository } from \"../../database/repositories/options.js\";\nimport type { Database } from \"../../database/types.js\";\nimport type { Storage } from \"../../storage/types.js\";\nimport { VERSION } from \"../../version.js\";\nimport { ErrorCode } from \"../errors.js\";\nimport type { ApiResult } from \"../types.js\";\nimport { generateSnapshot } from \"./snapshot.js\";\n\n// ── Constants ───────────────────────────────────────────────────\n\n/** Storage key prefix for scheduled/manual archives. */\nexport const BACKUP_STORAGE_PREFIX = \"backups/\";\n\n/**\n * Filename prefix within the backups/ folder. Included in the list() prefix\n * so LocalStorage (which matches directory + filename prefix, not flat keys\n * like S3/R2) finds the archives too.\n */\nconst BACKUP_FILE_PREFIX = \"emdash-backup-\";\n\n/** Options key holding the scheduled-backup settings. */\nexport const BACKUP_SETTINGS_KEY = \"emdash:backups\";\n\n/** Options key holding the ISO timestamp of the last scheduled run. */\nconst BACKUP_LAST_RUN_KEY = \"emdash:backups_last_run\";\n\n/** Minimum interval between scheduled backups (23h — daily with cron jitter). */\nconst SCHEDULED_BACKUP_INTERVAL_MS = 23 * 60 * 60 * 1000;\n\n/** Retention bounds for stored archives. */\nexport const BACKUP_RETENTION_MIN = 1;\nexport const BACKUP_RETENTION_MAX = 30;\nconst BACKUP_RETENTION_DEFAULT = 7;\n\n/**\n * Options-table key prefixes included in backups. Never widen this to a\n * prefix that can match secrets (`emdash:preview_secret`, `plugin:`,\n * `emdash:passkey_pending:`).\n */\nconst BACKUP_OPTION_PREFIXES = [\"site:\"];\n\n/**\n * Exact `emdash:*` keys included in backups. Do not add `emdash:site_url`: it\n * is the origin of the deployment that took the backup, not portable site data.\n */\nconst BACKUP_OPTION_KEYS = [\"emdash:site_title\", \"emdash:site_tagline\", \"emdash:locale\"];\n\n/**\n * Archive filename shape. Strict allowlist — the download/delete routes\n * interpolate this into a storage key, so it must never contain `/` or `..`.\n * The random suffix makes names unguessable (defense in depth on top of the\n * media route's backups/ deny) and avoids same-second collisions.\n */\nconst ARCHIVE_NAME_PATTERN =\n\t/^emdash-backup-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-[0-9a-f]{8}\\.json$/;\n\nexport function isValidArchiveName(name: string): boolean {\n\treturn ARCHIVE_NAME_PATTERN.test(name);\n}\n\n// ── Types ───────────────────────────────────────────────────────\n\nexport interface BackupSettings {\n\t/** Whether daily scheduled backups to storage are enabled. */\n\tenabled: boolean;\n\t/** How many archives to keep in storage (oldest pruned first). */\n\tretention: number;\n}\n\nexport interface BackupArchive {\n\t/** Filename within the backups/ prefix (no path separators). */\n\tname: string;\n\t/** Size in bytes. */\n\tsize: number;\n\t/** Last-modified timestamp (ISO). */\n\tlastModified: string;\n}\n\nconst DEFAULT_SETTINGS: BackupSettings = {\n\tenabled: false,\n\tretention: BACKUP_RETENTION_DEFAULT,\n};\n\nfunction clampRetention(value: number): number {\n\tif (!Number.isFinite(value)) return BACKUP_RETENTION_DEFAULT;\n\treturn Math.min(BACKUP_RETENTION_MAX, Math.max(BACKUP_RETENTION_MIN, Math.trunc(value)));\n}\n\n// ── Export ──────────────────────────────────────────────────────\n\n/**\n * Generate a full content backup as a JSON string.\n *\n * ponytail: the whole backup is materialized in memory. Fine for the sites\n * EmDash targets today; truly huge databases should use `wrangler d1 export`\n * (documented on the backups docs page). Upgrade path: stream table-by-table.\n */\nexport async function generateBackupJson(db: Kysely<Database>): Promise<string> {\n\tconst snapshot = await generateSnapshot(db, {\n\t\tincludeDrafts: true,\n\t\tincludeTrashed: true,\n\t\toptionPrefixes: BACKUP_OPTION_PREFIXES,\n\t\toptionKeys: BACKUP_OPTION_KEYS,\n\t});\n\n\treturn JSON.stringify({\n\t\tformat: \"emdash-backup\",\n\t\tformatVersion: 1,\n\t\temdashVersion: VERSION,\n\t\tgeneratedAt: snapshot.generatedAt,\n\t\tschema: snapshot.schema,\n\t\ttables: snapshot.tables,\n\t});\n}\n\n/** Derive the archive filename for a given date (plus a random suffix). */\nexport function archiveNameForDate(date: Date): string {\n\t// 2026-07-09T08:45:12.345Z → emdash-backup-2026-07-09T08-45-12-1a2b3c4d.json\n\tconst stamp = date.toISOString().slice(0, 19).replaceAll(\":\", \"-\");\n\tconst suffix = crypto.randomUUID().replaceAll(\"-\", \"\").slice(0, 8);\n\treturn `emdash-backup-${stamp}-${suffix}.json`;\n}\n\n// ── Settings ────────────────────────────────────────────────────\n\nexport async function getBackupSettings(db: Kysely<Database>): Promise<BackupSettings> {\n\tconst options = new OptionsRepository(db);\n\tconst stored = await options.get<Partial<BackupSettings>>(BACKUP_SETTINGS_KEY);\n\tif (!stored) return { ...DEFAULT_SETTINGS };\n\treturn {\n\t\tenabled: stored.enabled === true,\n\t\tretention: clampRetention(stored.retention ?? BACKUP_RETENTION_DEFAULT),\n\t};\n}\n\nexport async function updateBackupSettings(\n\tdb: Kysely<Database>,\n\tinput: { enabled: boolean; retention: number },\n): Promise<ApiResult<BackupSettings>> {\n\ttry {\n\t\tconst settings: BackupSettings = {\n\t\t\tenabled: input.enabled,\n\t\t\tretention: clampRetention(input.retention),\n\t\t};\n\t\tconst options = new OptionsRepository(db);\n\t\tawait options.set(BACKUP_SETTINGS_KEY, settings);\n\t\treturn { success: true, data: settings };\n\t} catch (error) {\n\t\tconsole.error(\"[backup] Failed to update settings:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.BACKUP_SETTINGS_ERROR, message: \"Failed to update backup settings\" },\n\t\t};\n\t}\n}\n\n// ── Archives in storage ─────────────────────────────────────────\n\n/**\n * List stored archives, newest first.\n *\n * ponytail: single unpaginated list. The retention cap (max 30) bounds the\n * archive count, so one page always suffices.\n */\nexport async function listBackupArchives(storage: Storage): Promise<ApiResult<BackupArchive[]>> {\n\ttry {\n\t\tconst result = await storage.list({\n\t\t\tprefix: `${BACKUP_STORAGE_PREFIX}${BACKUP_FILE_PREFIX}`,\n\t\t\tlimit: 100,\n\t\t});\n\t\tconst archives = result.files\n\t\t\t.map((file) => ({\n\t\t\t\tname: file.key.slice(BACKUP_STORAGE_PREFIX.length),\n\t\t\t\tsize: file.size,\n\t\t\t\tlastModified: file.lastModified.toISOString(),\n\t\t\t}))\n\t\t\t.filter((archive) => isValidArchiveName(archive.name))\n\t\t\t.toSorted((a, b) => (a.name < b.name ? 1 : -1));\n\t\treturn { success: true, data: archives };\n\t} catch (error) {\n\t\tconsole.error(\"[backup] Failed to list archives:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.BACKUP_LIST_ERROR, message: \"Failed to list backup archives\" },\n\t\t};\n\t}\n}\n\n/**\n * Create a backup and store it as an archive, then prune old archives\n * beyond `retention`.\n */\nexport async function runBackupToStorage(\n\tdb: Kysely<Database>,\n\tstorage: Storage,\n\tretention: number,\n): Promise<ApiResult<BackupArchive>> {\n\ttry {\n\t\tconst json = await generateBackupJson(db);\n\t\tconst name = archiveNameForDate(new Date());\n\t\tconst body = new TextEncoder().encode(json);\n\n\t\tawait storage.upload({\n\t\t\tkey: `${BACKUP_STORAGE_PREFIX}${name}`,\n\t\t\tbody,\n\t\t\tcontentType: \"application/json\",\n\t\t});\n\n\t\tawait pruneArchives(storage, clampRetention(retention));\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { name, size: body.byteLength, lastModified: new Date().toISOString() },\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[backup] Failed to create archive:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.BACKUP_CREATE_ERROR, message: \"Failed to create backup archive\" },\n\t\t};\n\t}\n}\n\n/** Delete archives beyond the newest `keep`. Failures are logged, not fatal. */\nasync function pruneArchives(storage: Storage, keep: number): Promise<void> {\n\tconst listed = await listBackupArchives(storage);\n\tif (!listed.success) return;\n\n\tfor (const archive of listed.data.slice(keep)) {\n\t\ttry {\n\t\t\tawait storage.delete(`${BACKUP_STORAGE_PREFIX}${archive.name}`);\n\t\t} catch (error) {\n\t\t\tconsole.error(`[backup] Failed to prune archive ${archive.name}:`, error);\n\t\t}\n\t}\n}\n\nexport async function deleteBackupArchive(\n\tstorage: Storage,\n\tname: string,\n): Promise<ApiResult<{ deleted: true }>> {\n\tif (!isValidArchiveName(name)) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.VALIDATION_ERROR, message: \"Invalid archive name\" },\n\t\t};\n\t}\n\ttry {\n\t\tawait storage.delete(`${BACKUP_STORAGE_PREFIX}${name}`);\n\t\treturn { success: true, data: { deleted: true } };\n\t} catch (error) {\n\t\tconsole.error(`[backup] Failed to delete archive ${name}:`, error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.BACKUP_DELETE_ERROR, message: \"Failed to delete backup archive\" },\n\t\t};\n\t}\n}\n\n// ── Scheduled runs ──────────────────────────────────────────────\n\n/**\n * Run a scheduled backup if enabled and due. Called from the maintenance\n * tick alongside scheduled publishing and system cleanup — never from a\n * request. Never throws.\n *\n * ponytail: last-run bookkeeping is a plain read-then-write, so two isolates\n * ticking simultaneously could both back up. Worst case is a duplicate\n * archive that retention prunes; not worth a lock.\n */\nexport async function maybeRunScheduledBackup(\n\tdb: Kysely<Database>,\n\tstorage: Storage | undefined,\n): Promise<void> {\n\ttry {\n\t\tif (!storage) return;\n\n\t\tconst settings = await getBackupSettings(db);\n\t\tif (!settings.enabled) return;\n\n\t\tconst options = new OptionsRepository(db);\n\t\tconst lastRun = await options.get<string>(BACKUP_LAST_RUN_KEY);\n\t\tif (lastRun) {\n\t\t\tconst elapsed = Date.now() - Date.parse(lastRun);\n\t\t\tif (Number.isFinite(elapsed) && elapsed < SCHEDULED_BACKUP_INTERVAL_MS) return;\n\t\t}\n\n\t\tconst result = await runBackupToStorage(db, storage, settings.retention);\n\t\tif (result.success) {\n\t\t\tawait options.set(BACKUP_LAST_RUN_KEY, new Date().toISOString());\n\t\t\tconsole.log(`[backup] Scheduled backup stored: ${result.data.name}`);\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(\"[backup] Scheduled backup failed:\", error);\n\t}\n}\n"],"mappings":"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"}
@@ -49,8 +49,8 @@ import "../ssrf-CRJ-xom5.mjs";
49
49
  import { t as applySeed } from "../apply-CDNV4JJ-.mjs";
50
50
  import "../ssrf-sC4_5rxm.mjs";
51
51
  import { n as validateSeed } from "../validate-BttYU7NK.mjs";
52
- import { a as MigrationManifestValidationError, c as normalizeAstroI18n, i as getMigrationIntegrationMetadata, n as MIGRATION_CONFIG_SYMBOL, s as validateMigrationManifest, t as buildMigrationManifest } from "../manifest-builder-dOBOOa47.mjs";
53
- import "../identity-D7b8NcWO.mjs";
52
+ import { a as MigrationManifestValidationError, c as normalizeAstroI18n, i as getMigrationIntegrationMetadata, n as MIGRATION_CONFIG_SYMBOL, s as validateMigrationManifest, t as buildMigrationManifest } from "../manifest-builder-8jsSLR7s.mjs";
53
+ import "../identity-DJ-5AcdG.mjs";
54
54
  import { n as claimExplicitSeedOwnership } from "../ownership-Bd77AmJz.mjs";
55
55
  import { LocalStorage } from "../storage/local.mjs";
56
56
  import { t as createDatabase } from "../connection-C5GIciX9.mjs";
@@ -65,15 +65,15 @@ declare const siteImportPlanSchema: z.ZodObject<{
65
65
  emdashVersion: z.ZodString;
66
66
  }, z.core.$strict>;
67
67
  counts: z.ZodRecord<z.ZodEnum<{
68
- menu: "menu";
69
- byline: "byline";
70
68
  seo: "seo";
69
+ media: "media";
70
+ byline: "byline";
71
71
  collection: "collection";
72
- relation: "relation";
73
72
  setting: "setting";
73
+ relation: "relation";
74
74
  widget: "widget";
75
75
  term: "term";
76
- media: "media";
76
+ menu: "menu";
77
77
  principal: "principal";
78
78
  block_type: "block_type";
79
79
  block_type_version: "block_type_version";
@@ -140,15 +140,15 @@ declare const siteImportPlanSchema: z.ZodObject<{
140
140
  unknown_storage_key: "unknown_storage_key";
141
141
  }>;
142
142
  kind: z.ZodEnum<{
143
- menu: "menu";
144
- byline: "byline";
145
143
  seo: "seo";
144
+ media: "media";
145
+ byline: "byline";
146
146
  collection: "collection";
147
- relation: "relation";
148
147
  setting: "setting";
148
+ relation: "relation";
149
149
  widget: "widget";
150
150
  term: "term";
151
- media: "media";
151
+ menu: "menu";
152
152
  principal: "principal";
153
153
  block_type: "block_type";
154
154
  block_type_version: "block_type_version";
@@ -212,15 +212,15 @@ declare const siteImportPlanSchema: z.ZodObject<{
212
212
  }>;
213
213
  message: z.ZodString;
214
214
  kind: z.ZodOptional<z.ZodEnum<{
215
- menu: "menu";
216
- byline: "byline";
217
215
  seo: "seo";
216
+ media: "media";
217
+ byline: "byline";
218
218
  collection: "collection";
219
- relation: "relation";
220
219
  setting: "setting";
220
+ relation: "relation";
221
221
  widget: "widget";
222
222
  term: "term";
223
- media: "media";
223
+ menu: "menu";
224
224
  principal: "principal";
225
225
  block_type: "block_type";
226
226
  block_type_version: "block_type_version";
@@ -273,15 +273,15 @@ declare const siteImportPlanSchema: z.ZodObject<{
273
273
  }>;
274
274
  message: z.ZodString;
275
275
  kind: z.ZodOptional<z.ZodEnum<{
276
- menu: "menu";
277
- byline: "byline";
278
276
  seo: "seo";
277
+ media: "media";
278
+ byline: "byline";
279
279
  collection: "collection";
280
- relation: "relation";
281
280
  setting: "setting";
281
+ relation: "relation";
282
282
  widget: "widget";
283
283
  term: "term";
284
- media: "media";
284
+ menu: "menu";
285
285
  principal: "principal";
286
286
  block_type: "block_type";
287
287
  block_type_version: "block_type_version";
@@ -361,15 +361,15 @@ declare const exportCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
361
361
  }, z.core.$strict>>;
362
362
  }, z.core.$strict>;
363
363
  kind: z.ZodEnum<{
364
- menu: "menu";
365
- byline: "byline";
366
364
  seo: "seo";
365
+ media: "media";
366
+ byline: "byline";
367
367
  collection: "collection";
368
- relation: "relation";
369
368
  setting: "setting";
369
+ relation: "relation";
370
370
  widget: "widget";
371
371
  term: "term";
372
- media: "media";
372
+ menu: "menu";
373
373
  principal: "principal";
374
374
  block_type: "block_type";
375
375
  block_type_version: "block_type_version";
@@ -431,15 +431,15 @@ declare const exportCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
431
431
  stage: z.ZodLiteral<"export_validate">;
432
432
  position: z.ZodNullable<z.ZodObject<{
433
433
  kind: z.ZodEnum<{
434
- menu: "menu";
435
- byline: "byline";
436
434
  seo: "seo";
435
+ media: "media";
436
+ byline: "byline";
437
437
  collection: "collection";
438
- relation: "relation";
439
438
  setting: "setting";
439
+ relation: "relation";
440
440
  widget: "widget";
441
441
  term: "term";
442
- media: "media";
442
+ menu: "menu";
443
443
  principal: "principal";
444
444
  block_type: "block_type";
445
445
  block_type_version: "block_type_version";
@@ -474,15 +474,15 @@ declare const analysisCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
474
474
  stage: z.ZodLiteral<"analyze_records">;
475
475
  position: z.ZodObject<{
476
476
  kind: z.ZodEnum<{
477
- menu: "menu";
478
- byline: "byline";
479
477
  seo: "seo";
478
+ media: "media";
479
+ byline: "byline";
480
480
  collection: "collection";
481
- relation: "relation";
482
481
  setting: "setting";
482
+ relation: "relation";
483
483
  widget: "widget";
484
484
  term: "term";
485
- media: "media";
485
+ menu: "menu";
486
486
  principal: "principal";
487
487
  block_type: "block_type";
488
488
  block_type_version: "block_type_version";
@@ -524,15 +524,15 @@ declare const importCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
524
524
  stage: z.ZodLiteral<"schema">;
525
525
  position: z.ZodObject<{
526
526
  kind: z.ZodEnum<{
527
- menu: "menu";
528
- byline: "byline";
529
527
  seo: "seo";
528
+ media: "media";
529
+ byline: "byline";
530
530
  collection: "collection";
531
- relation: "relation";
532
531
  setting: "setting";
532
+ relation: "relation";
533
533
  widget: "widget";
534
534
  term: "term";
535
- media: "media";
535
+ menu: "menu";
536
536
  principal: "principal";
537
537
  block_type: "block_type";
538
538
  block_type_version: "block_type_version";
@@ -561,15 +561,15 @@ declare const importCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
561
561
  stage: z.ZodLiteral<"media">;
562
562
  position: z.ZodObject<{
563
563
  kind: z.ZodEnum<{
564
- menu: "menu";
565
- byline: "byline";
566
564
  seo: "seo";
565
+ media: "media";
566
+ byline: "byline";
567
567
  collection: "collection";
568
- relation: "relation";
569
568
  setting: "setting";
569
+ relation: "relation";
570
570
  widget: "widget";
571
571
  term: "term";
572
- media: "media";
572
+ menu: "menu";
573
573
  principal: "principal";
574
574
  block_type: "block_type";
575
575
  block_type_version: "block_type_version";
@@ -598,15 +598,15 @@ declare const importCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
598
598
  stage: z.ZodLiteral<"terms_bylines">;
599
599
  position: z.ZodObject<{
600
600
  kind: z.ZodEnum<{
601
- menu: "menu";
602
- byline: "byline";
603
601
  seo: "seo";
602
+ media: "media";
603
+ byline: "byline";
604
604
  collection: "collection";
605
- relation: "relation";
606
605
  setting: "setting";
606
+ relation: "relation";
607
607
  widget: "widget";
608
608
  term: "term";
609
- media: "media";
609
+ menu: "menu";
610
610
  principal: "principal";
611
611
  block_type: "block_type";
612
612
  block_type_version: "block_type_version";
@@ -635,15 +635,15 @@ declare const importCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
635
635
  stage: z.ZodLiteral<"content">;
636
636
  position: z.ZodObject<{
637
637
  kind: z.ZodEnum<{
638
- menu: "menu";
639
- byline: "byline";
640
638
  seo: "seo";
639
+ media: "media";
640
+ byline: "byline";
641
641
  collection: "collection";
642
- relation: "relation";
643
642
  setting: "setting";
643
+ relation: "relation";
644
644
  widget: "widget";
645
645
  term: "term";
646
- media: "media";
646
+ menu: "menu";
647
647
  principal: "principal";
648
648
  block_type: "block_type";
649
649
  block_type_version: "block_type_version";
@@ -672,15 +672,15 @@ declare const importCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
672
672
  stage: z.ZodLiteral<"relations">;
673
673
  position: z.ZodObject<{
674
674
  kind: z.ZodEnum<{
675
- menu: "menu";
676
- byline: "byline";
677
675
  seo: "seo";
676
+ media: "media";
677
+ byline: "byline";
678
678
  collection: "collection";
679
- relation: "relation";
680
679
  setting: "setting";
680
+ relation: "relation";
681
681
  widget: "widget";
682
682
  term: "term";
683
- media: "media";
683
+ menu: "menu";
684
684
  principal: "principal";
685
685
  block_type: "block_type";
686
686
  block_type_version: "block_type_version";
@@ -709,15 +709,15 @@ declare const importCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
709
709
  stage: z.ZodLiteral<"presentation">;
710
710
  position: z.ZodObject<{
711
711
  kind: z.ZodEnum<{
712
- menu: "menu";
713
- byline: "byline";
714
712
  seo: "seo";
713
+ media: "media";
714
+ byline: "byline";
715
715
  collection: "collection";
716
- relation: "relation";
717
716
  setting: "setting";
717
+ relation: "relation";
718
718
  widget: "widget";
719
719
  term: "term";
720
- media: "media";
720
+ menu: "menu";
721
721
  principal: "principal";
722
722
  block_type: "block_type";
723
723
  block_type_version: "block_type_version";
@@ -745,9 +745,9 @@ declare const importCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
745
745
  }, z.core.$strict>, z.ZodObject<{
746
746
  stage: z.ZodLiteral<"rebuild">;
747
747
  step: z.ZodEnum<{
748
- search: "search";
749
- options: "options";
750
748
  taxonomies: "taxonomies";
749
+ options: "options";
750
+ search: "search";
751
751
  media_usage: "media_usage";
752
752
  caches: "caches";
753
753
  }>;
@@ -756,15 +756,15 @@ declare const importCursorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
756
756
  stage: z.ZodLiteral<"verify">;
757
757
  position: z.ZodNullable<z.ZodObject<{
758
758
  kind: z.ZodEnum<{
759
- menu: "menu";
760
- byline: "byline";
761
759
  seo: "seo";
760
+ media: "media";
761
+ byline: "byline";
762
762
  collection: "collection";
763
- relation: "relation";
764
763
  setting: "setting";
764
+ relation: "relation";
765
765
  widget: "widget";
766
766
  term: "term";
767
- media: "media";
767
+ menu: "menu";
768
768
  principal: "principal";
769
769
  block_type: "block_type";
770
770
  block_type_version: "block_type_version";