canopycms 0.0.61-int.75 → 0.0.62
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.
- package/dist/ai/handler.js +1 -1
- package/dist/ai/handler.js.map +1 -1
- package/dist/ai/json-to-markdown.js +1 -2
- package/dist/ai/json-to-markdown.js.map +1 -1
- package/dist/api/__test__/mock-client.d.ts +5 -1
- package/dist/api/__test__/mock-client.d.ts.map +1 -1
- package/dist/api/__test__/mock-client.js +9 -2
- package/dist/api/__test__/mock-client.js.map +1 -1
- package/dist/api/admin-branch-health.d.ts +36 -1
- package/dist/api/admin-branch-health.d.ts.map +1 -1
- package/dist/api/admin-branch-health.js +176 -2
- package/dist/api/admin-branch-health.js.map +1 -1
- package/dist/api/admin.d.ts +8 -1
- package/dist/api/admin.d.ts.map +1 -1
- package/dist/api/admin.js.map +1 -1
- package/dist/api/assets.d.ts.map +1 -1
- package/dist/api/assets.js +36 -4
- package/dist/api/assets.js.map +1 -1
- package/dist/api/branch-status.d.ts.map +1 -1
- package/dist/api/branch-status.js +56 -0
- package/dist/api/branch-status.js.map +1 -1
- package/dist/api/branch-withdraw.d.ts.map +1 -1
- package/dist/api/branch-withdraw.js +14 -3
- package/dist/api/branch-withdraw.js.map +1 -1
- package/dist/api/branch.d.ts +31 -2
- package/dist/api/branch.d.ts.map +1 -1
- package/dist/api/branch.js +268 -15
- package/dist/api/branch.js.map +1 -1
- package/dist/api/client.d.ts +5 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +6 -0
- package/dist/api/client.js.map +1 -1
- package/dist/api/comments.d.ts +2 -2
- package/dist/api/content.d.ts +11 -5
- package/dist/api/content.d.ts.map +1 -1
- package/dist/api/content.js +91 -10
- package/dist/api/content.js.map +1 -1
- package/dist/api/entries.d.ts +10 -0
- package/dist/api/entries.d.ts.map +1 -1
- package/dist/api/entries.js +51 -24
- package/dist/api/entries.js.map +1 -1
- package/dist/api/guards.d.ts.map +1 -1
- package/dist/api/guards.js +12 -5
- package/dist/api/guards.js.map +1 -1
- package/dist/api/permissions.d.ts +2 -2
- package/dist/api/permissions.d.ts.map +1 -1
- package/dist/api/permissions.js +51 -3
- package/dist/api/permissions.js.map +1 -1
- package/dist/api/reference-options.d.ts.map +1 -1
- package/dist/api/reference-options.js +10 -17
- package/dist/api/reference-options.js.map +1 -1
- package/dist/api/resolve-references.d.ts.map +1 -1
- package/dist/api/resolve-references.js +3 -1
- package/dist/api/resolve-references.js.map +1 -1
- package/dist/api/schema.d.ts +4 -4
- package/dist/api/schema.d.ts.map +1 -1
- package/dist/api/schema.js +16 -15
- package/dist/api/schema.js.map +1 -1
- package/dist/api/settings-helpers.d.ts.map +1 -1
- package/dist/api/settings-helpers.js +6 -5
- package/dist/api/settings-helpers.js.map +1 -1
- package/dist/assets/pipeline.d.ts +11 -2
- package/dist/assets/pipeline.d.ts.map +1 -1
- package/dist/assets/pipeline.js +114 -2
- package/dist/assets/pipeline.js.map +1 -1
- package/dist/assets/transform-directives.d.ts +18 -0
- package/dist/assets/transform-directives.d.ts.map +1 -1
- package/dist/assets/transform-directives.js +18 -0
- package/dist/assets/transform-directives.js.map +1 -1
- package/dist/assets/transform.d.ts.map +1 -1
- package/dist/assets/transform.js +20 -16
- package/dist/assets/transform.js.map +1 -1
- package/dist/auth/types.d.ts +29 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.d.ts.map +1 -1
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/index.js.map +1 -1
- package/dist/authorization/protected-branch.d.ts +75 -0
- package/dist/authorization/protected-branch.d.ts.map +1 -1
- package/dist/authorization/protected-branch.js +39 -0
- package/dist/authorization/protected-branch.js.map +1 -1
- package/dist/branch-health.d.ts +13 -0
- package/dist/branch-health.d.ts.map +1 -1
- package/dist/branch-health.js +23 -0
- package/dist/branch-health.js.map +1 -1
- package/dist/branch-registry.d.ts.map +1 -1
- package/dist/branch-registry.js +5 -1
- package/dist/branch-registry.js.map +1 -1
- package/dist/branch-schema-cache.d.ts.map +1 -1
- package/dist/branch-schema-cache.js +9 -0
- package/dist/branch-schema-cache.js.map +1 -1
- package/dist/build/generate-ai-content.js +1 -1
- package/dist/build/generate-ai-content.js.map +1 -1
- package/dist/cli/cli.js +2215 -1280
- package/dist/cli/generate-ai-content.js +1158 -585
- package/dist/cli/init.d.ts +8 -2
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +459 -152
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/project-detect.d.ts +89 -0
- package/dist/cli/project-detect.d.ts.map +1 -0
- package/dist/cli/project-detect.js +240 -0
- package/dist/cli/project-detect.js.map +1 -0
- package/dist/cli/template-files/Dockerfile.cms.template +30 -7
- package/dist/cli/template-files/canopycms.config.ts.template +7 -0
- package/dist/cli/template-files/cdk-app.ts.template +82 -0
- package/dist/cli/template-files/cdk.json.template +9 -0
- package/dist/cli/template-files/cms-stack.ts.template +130 -0
- package/dist/cli/template-files/deploy-cms.yml.template +125 -13
- package/dist/cli/template-files/dockerignore.template +2 -1
- package/dist/cli/templates.d.ts +26 -2
- package/dist/cli/templates.d.ts.map +1 -1
- package/dist/cli/templates.js +36 -4
- package/dist/cli/templates.js.map +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/config/schemas/config.d.ts +2 -3
- package/dist/config/schemas/config.d.ts.map +1 -1
- package/dist/config/schemas/config.js +21 -1
- package/dist/config/schemas/config.js.map +1 -1
- package/dist/config/schemas/field.d.ts +15 -15
- package/dist/config/types.d.ts +2 -2
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +0 -1
- package/dist/config/types.js.map +1 -1
- package/dist/config/validation.d.ts +18 -0
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +36 -12
- package/dist/config/validation.js.map +1 -1
- package/dist/content-id-index.d.ts +97 -5
- package/dist/content-id-index.d.ts.map +1 -1
- package/dist/content-id-index.js +170 -18
- package/dist/content-id-index.js.map +1 -1
- package/dist/content-reader.js +1 -1
- package/dist/content-reader.js.map +1 -1
- package/dist/content-store.d.ts +92 -7
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +445 -259
- package/dist/content-store.js.map +1 -1
- package/dist/dev-content-watcher.d.ts.map +1 -1
- package/dist/dev-content-watcher.js +4 -1
- package/dist/dev-content-watcher.js.map +1 -1
- package/dist/editor/BranchManager.d.ts +15 -0
- package/dist/editor/BranchManager.d.ts.map +1 -1
- package/dist/editor/BranchManager.js +61 -15
- package/dist/editor/BranchManager.js.map +1 -1
- package/dist/editor/CanopyEditor.d.ts.map +1 -1
- package/dist/editor/CanopyEditor.js +3 -3
- package/dist/editor/CanopyEditor.js.map +1 -1
- package/dist/editor/CanopyEditorPage.d.ts +9 -1
- package/dist/editor/CanopyEditorPage.d.ts.map +1 -1
- package/dist/editor/CanopyEditorPage.js +9 -2
- package/dist/editor/CanopyEditorPage.js.map +1 -1
- package/dist/editor/Editor.d.ts +9 -1
- package/dist/editor/Editor.d.ts.map +1 -1
- package/dist/editor/Editor.js +156 -60
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/FormRenderer.d.ts.map +1 -1
- package/dist/editor/FormRenderer.js +12 -0
- package/dist/editor/FormRenderer.js.map +1 -1
- package/dist/editor/admin/SystemHealthPanel.d.ts.map +1 -1
- package/dist/editor/admin/SystemHealthPanel.js +14 -9
- package/dist/editor/admin/SystemHealthPanel.js.map +1 -1
- package/dist/editor/components/EditorHeader.d.ts +6 -0
- package/dist/editor/components/EditorHeader.d.ts.map +1 -1
- package/dist/editor/components/EditorHeader.js +76 -23
- package/dist/editor/components/EditorHeader.js.map +1 -1
- package/dist/editor/components/EntryCreateModal.d.ts +9 -1
- package/dist/editor/components/EntryCreateModal.d.ts.map +1 -1
- package/dist/editor/components/EntryCreateModal.js +25 -7
- package/dist/editor/components/EntryCreateModal.js.map +1 -1
- package/dist/editor/context/SWRProvider.d.ts +31 -0
- package/dist/editor/context/SWRProvider.d.ts.map +1 -0
- package/dist/editor/context/SWRProvider.js +12 -0
- package/dist/editor/context/SWRProvider.js.map +1 -0
- package/dist/editor/context/index.d.ts +3 -0
- package/dist/editor/context/index.d.ts.map +1 -1
- package/dist/editor/context/index.js +3 -0
- package/dist/editor/context/index.js.map +1 -1
- package/dist/editor/editor-utils.d.ts.map +1 -1
- package/dist/editor/editor-utils.js +8 -2
- package/dist/editor/editor-utils.js.map +1 -1
- package/dist/editor/fields/DateTimeField.d.ts +46 -0
- package/dist/editor/fields/DateTimeField.d.ts.map +1 -0
- package/dist/editor/fields/DateTimeField.js +66 -0
- package/dist/editor/fields/DateTimeField.js.map +1 -0
- package/dist/editor/fields/ImageField.d.ts.map +1 -1
- package/dist/editor/fields/ImageField.js +27 -3
- package/dist/editor/fields/ImageField.js.map +1 -1
- package/dist/editor/fields/NumberField.d.ts +34 -0
- package/dist/editor/fields/NumberField.d.ts.map +1 -0
- package/dist/editor/fields/NumberField.js +53 -0
- package/dist/editor/fields/NumberField.js.map +1 -0
- package/dist/editor/fields/NumberListField.d.ts +25 -0
- package/dist/editor/fields/NumberListField.d.ts.map +1 -0
- package/dist/editor/fields/NumberListField.js +53 -0
- package/dist/editor/fields/NumberListField.js.map +1 -0
- package/dist/editor/fields/ReferenceField.d.ts.map +1 -1
- package/dist/editor/fields/ReferenceField.js +52 -31
- package/dist/editor/fields/ReferenceField.js.map +1 -1
- package/dist/editor/hooks/__test__/test-utils.d.ts +38 -3
- package/dist/editor/hooks/__test__/test-utils.d.ts.map +1 -1
- package/dist/editor/hooks/__test__/test-utils.js +50 -4
- package/dist/editor/hooks/__test__/test-utils.js.map +1 -1
- package/dist/editor/hooks/index.d.ts +4 -1
- package/dist/editor/hooks/index.d.ts.map +1 -1
- package/dist/editor/hooks/index.js +4 -1
- package/dist/editor/hooks/index.js.map +1 -1
- package/dist/editor/hooks/useBranchManager.d.ts +21 -1
- package/dist/editor/hooks/useBranchManager.d.ts.map +1 -1
- package/dist/editor/hooks/useBranchManager.js +183 -58
- package/dist/editor/hooks/useBranchManager.js.map +1 -1
- package/dist/editor/hooks/useBranchesData.d.ts +57 -0
- package/dist/editor/hooks/useBranchesData.d.ts.map +1 -0
- package/dist/editor/hooks/useBranchesData.js +69 -0
- package/dist/editor/hooks/useBranchesData.js.map +1 -0
- package/dist/editor/hooks/useCommentSystem.d.ts.map +1 -1
- package/dist/editor/hooks/useCommentSystem.js +24 -22
- package/dist/editor/hooks/useCommentSystem.js.map +1 -1
- package/dist/editor/hooks/useCommentsData.d.ts +29 -0
- package/dist/editor/hooks/useCommentsData.d.ts.map +1 -0
- package/dist/editor/hooks/useCommentsData.js +40 -0
- package/dist/editor/hooks/useCommentsData.js.map +1 -0
- package/dist/editor/hooks/useDraftManager.d.ts +8 -0
- package/dist/editor/hooks/useDraftManager.d.ts.map +1 -1
- package/dist/editor/hooks/useDraftManager.js +290 -36
- package/dist/editor/hooks/useDraftManager.js.map +1 -1
- package/dist/editor/hooks/useEntriesData.d.ts +35 -0
- package/dist/editor/hooks/useEntriesData.d.ts.map +1 -0
- package/dist/editor/hooks/useEntriesData.js +96 -0
- package/dist/editor/hooks/useEntriesData.js.map +1 -0
- package/dist/editor/hooks/useEntryManager.d.ts +29 -15
- package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
- package/dist/editor/hooks/useEntryManager.js +284 -119
- package/dist/editor/hooks/useEntryManager.js.map +1 -1
- package/dist/editor/hooks/usePermissionManager.d.ts +2 -2
- package/dist/editor/hooks/usePermissionManager.d.ts.map +1 -1
- package/dist/editor/hooks/usePermissionManager.js +11 -9
- package/dist/editor/hooks/usePermissionManager.js.map +1 -1
- package/dist/editor/hooks/useReferenceResolution.d.ts.map +1 -1
- package/dist/editor/hooks/useReferenceResolution.js +24 -1
- package/dist/editor/hooks/useReferenceResolution.js.map +1 -1
- package/dist/editor/media/MediaLibraryBody.d.ts.map +1 -1
- package/dist/editor/media/MediaLibraryBody.js +12 -2
- package/dist/editor/media/MediaLibraryBody.js.map +1 -1
- package/dist/editor/permission-manager/GroupSelector.d.ts.map +1 -1
- package/dist/editor/permission-manager/GroupSelector.js +7 -2
- package/dist/editor/permission-manager/GroupSelector.js.map +1 -1
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts +3 -3
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts.map +1 -1
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js +1 -0
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js.map +1 -1
- package/dist/editor/permission-manager/types.d.ts +6 -4
- package/dist/editor/permission-manager/types.d.ts.map +1 -1
- package/dist/editor/test-setup.js +8 -0
- package/dist/editor/test-setup.js.map +1 -1
- package/dist/editor/theme.d.ts +8 -8
- package/dist/git-manager.d.ts +175 -14
- package/dist/git-manager.d.ts.map +1 -1
- package/dist/git-manager.js +354 -39
- package/dist/git-manager.js.map +1 -1
- package/dist/github-service.d.ts.map +1 -1
- package/dist/github-service.js +13 -7
- package/dist/github-service.js.map +1 -1
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/handler.js +78 -29
- package/dist/http/handler.js.map +1 -1
- package/dist/http/router.d.ts.map +1 -1
- package/dist/http/router.js +40 -3
- package/dist/http/router.js.map +1 -1
- package/dist/operating-mode/client-unsafe-strategy.d.ts.map +1 -1
- package/dist/operating-mode/client-unsafe-strategy.js +7 -8
- package/dist/operating-mode/client-unsafe-strategy.js.map +1 -1
- package/dist/operating-mode/deployment-name-fixtures.d.ts +29 -0
- package/dist/operating-mode/deployment-name-fixtures.d.ts.map +1 -0
- package/dist/operating-mode/deployment-name-fixtures.js +55 -0
- package/dist/operating-mode/deployment-name-fixtures.js.map +1 -0
- package/dist/operating-mode/deployment-name.d.ts +37 -0
- package/dist/operating-mode/deployment-name.d.ts.map +1 -0
- package/dist/operating-mode/deployment-name.js +86 -0
- package/dist/operating-mode/deployment-name.js.map +1 -0
- package/dist/operating-mode/index.d.ts +6 -1
- package/dist/operating-mode/index.d.ts.map +1 -1
- package/dist/operating-mode/index.js +10 -1
- package/dist/operating-mode/index.js.map +1 -1
- package/dist/operating-mode/mode-env.d.ts +58 -0
- package/dist/operating-mode/mode-env.d.ts.map +1 -0
- package/dist/operating-mode/mode-env.js +97 -0
- package/dist/operating-mode/mode-env.js.map +1 -0
- package/dist/operating-mode/types.d.ts +13 -3
- package/dist/operating-mode/types.d.ts.map +1 -1
- package/dist/paths/branch-name.d.ts +38 -0
- package/dist/paths/branch-name.d.ts.map +1 -1
- package/dist/paths/branch-name.js +46 -0
- package/dist/paths/branch-name.js.map +1 -1
- package/dist/paths/index.d.ts +1 -1
- package/dist/paths/index.d.ts.map +1 -1
- package/dist/paths/index.js +1 -1
- package/dist/paths/index.js.map +1 -1
- package/dist/reference-resolver.d.ts +6 -2
- package/dist/reference-resolver.d.ts.map +1 -1
- package/dist/reference-resolver.js +8 -1
- package/dist/reference-resolver.js.map +1 -1
- package/dist/resolve-canopy-user.d.ts +34 -0
- package/dist/resolve-canopy-user.d.ts.map +1 -0
- package/dist/resolve-canopy-user.js +55 -0
- package/dist/resolve-canopy-user.js.map +1 -0
- package/dist/schema/meta-loader.d.ts.map +1 -1
- package/dist/schema/meta-loader.js +10 -2
- package/dist/schema/meta-loader.js.map +1 -1
- package/dist/schema/schema-store.d.ts +64 -4
- package/dist/schema/schema-store.d.ts.map +1 -1
- package/dist/schema/schema-store.js +113 -30
- package/dist/schema/schema-store.js.map +1 -1
- package/dist/server.d.ts +9 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +9 -0
- package/dist/server.js.map +1 -1
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +40 -6
- package/dist/services.js.map +1 -1
- package/dist/settings-workspace.d.ts +27 -2
- package/dist/settings-workspace.d.ts.map +1 -1
- package/dist/settings-workspace.js +142 -58
- package/dist/settings-workspace.js.map +1 -1
- package/dist/types.d.ts +73 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/content-write-lock.d.ts +127 -0
- package/dist/utils/content-write-lock.d.ts.map +1 -0
- package/dist/utils/content-write-lock.js +170 -0
- package/dist/utils/content-write-lock.js.map +1 -0
- package/dist/utils/debug.d.ts +11 -0
- package/dist/utils/debug.d.ts.map +1 -1
- package/dist/utils/debug.js +12 -1
- package/dist/utils/debug.js.map +1 -1
- package/dist/utils/error.d.ts +1 -1
- package/dist/utils/error.js +1 -1
- package/dist/utils/git.d.ts +54 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +91 -0
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/logger.d.ts +71 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +85 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/sanitize-href.d.ts +28 -3
- package/dist/utils/sanitize-href.d.ts.map +1 -1
- package/dist/utils/sanitize-href.js +64 -6
- package/dist/utils/sanitize-href.js.map +1 -1
- package/dist/validation/entry-link-validator.d.ts +1 -1
- package/dist/validation/entry-link-validator.js +3 -3
- package/dist/validation/entry-link-validator.js.map +1 -1
- package/dist/validation/entry-type-reference-validator.d.ts +33 -0
- package/dist/validation/entry-type-reference-validator.d.ts.map +1 -0
- package/dist/validation/entry-type-reference-validator.js +110 -0
- package/dist/validation/entry-type-reference-validator.js.map +1 -0
- package/dist/validation/entry-validator.js +1 -1
- package/dist/validation/entry-validator.js.map +1 -1
- package/dist/worker/cms-worker.d.ts +245 -3
- package/dist/worker/cms-worker.d.ts.map +1 -1
- package/dist/worker/cms-worker.js +1084 -253
- package/dist/worker/cms-worker.js.map +1 -1
- package/dist/worker/log.d.ts +61 -0
- package/dist/worker/log.d.ts.map +1 -0
- package/dist/worker/log.js +74 -0
- package/dist/worker/log.js.map +1 -0
- package/package.json +4 -2
package/dist/cli/init.js
CHANGED
|
@@ -9,6 +9,18 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// dist/utils/logger.js
|
|
13
|
+
function canopyLogWarn(...args) {
|
|
14
|
+
active.warn(...args);
|
|
15
|
+
}
|
|
16
|
+
var active;
|
|
17
|
+
var init_logger = __esm({
|
|
18
|
+
"dist/utils/logger.js"() {
|
|
19
|
+
"use strict";
|
|
20
|
+
active = console;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
12
24
|
// dist/config/types.js
|
|
13
25
|
var primitiveFieldTypes, fieldTypes;
|
|
14
26
|
var init_types = __esm({
|
|
@@ -19,7 +31,6 @@ var init_types = __esm({
|
|
|
19
31
|
"number",
|
|
20
32
|
"boolean",
|
|
21
33
|
"datetime",
|
|
22
|
-
"rich-text",
|
|
23
34
|
"markdown",
|
|
24
35
|
"mdx",
|
|
25
36
|
"code"
|
|
@@ -267,6 +278,16 @@ var init_config = __esm({
|
|
|
267
278
|
allowNetworkRemoteInProd: z4.boolean().optional(),
|
|
268
279
|
settingsBranch: z4.string().optional(),
|
|
269
280
|
autoCreateSettingsPR: z4.boolean().optional(),
|
|
281
|
+
// Deliberately `deploymentNameSchema.optional()`, NOT `deploymentNameSchema` alone.
|
|
282
|
+
// deploymentNameSchema.default('prod') would make `parse(undefined)` resolve to
|
|
283
|
+
// the literal 'prod' instead of staying `undefined` — collapsing the
|
|
284
|
+
// env > config > modeDefault precedence chain that resolveDeploymentName
|
|
285
|
+
// (operating-mode/deployment-name.ts) implements: config would then always
|
|
286
|
+
// "win" over modeDefault (masking dev's real default of 'local'), and the env
|
|
287
|
+
// var would just be racing config's baked-in 'prod' instead of a true absence.
|
|
288
|
+
// `.optional()` here is what keeps an omitted deploymentName reaching
|
|
289
|
+
// resolveDeploymentName as `undefined`, so it can fall through to modeDefault.
|
|
290
|
+
// Do not "fix" this by removing `.optional()`.
|
|
270
291
|
deploymentName: deploymentNameSchema.optional(),
|
|
271
292
|
contentRoot: contentRootSchema.default("content"),
|
|
272
293
|
sourceRoot: sourceRootSchema.optional(),
|
|
@@ -323,12 +344,21 @@ var init_flatten = __esm({
|
|
|
323
344
|
}
|
|
324
345
|
});
|
|
325
346
|
|
|
347
|
+
// dist/operating-mode/mode-env.js
|
|
348
|
+
var init_mode_env = __esm({
|
|
349
|
+
"dist/operating-mode/mode-env.js"() {
|
|
350
|
+
"use strict";
|
|
351
|
+
init_logger();
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
|
|
326
355
|
// dist/config/validation.js
|
|
327
356
|
var init_validation = __esm({
|
|
328
357
|
"dist/config/validation.js"() {
|
|
329
358
|
"use strict";
|
|
330
359
|
init_config();
|
|
331
360
|
init_flatten();
|
|
361
|
+
init_mode_env();
|
|
332
362
|
}
|
|
333
363
|
});
|
|
334
364
|
|
|
@@ -356,14 +386,59 @@ var init_config2 = __esm({
|
|
|
356
386
|
}
|
|
357
387
|
});
|
|
358
388
|
|
|
389
|
+
// dist/utils/error.js
|
|
390
|
+
function getErrorMessage(err) {
|
|
391
|
+
if (err instanceof Error) {
|
|
392
|
+
return err.message;
|
|
393
|
+
}
|
|
394
|
+
if (typeof err === "string") {
|
|
395
|
+
return err;
|
|
396
|
+
}
|
|
397
|
+
return String(err);
|
|
398
|
+
}
|
|
399
|
+
function isNodeError(err) {
|
|
400
|
+
return err instanceof Error && "code" in err;
|
|
401
|
+
}
|
|
402
|
+
function isNotFoundError(err) {
|
|
403
|
+
return isNodeError(err) && err.code === "ENOENT";
|
|
404
|
+
}
|
|
405
|
+
var init_error = __esm({
|
|
406
|
+
"dist/utils/error.js"() {
|
|
407
|
+
"use strict";
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// dist/utils/fs.js
|
|
412
|
+
import fs from "node:fs/promises";
|
|
413
|
+
async function filePathExists(filePath) {
|
|
414
|
+
try {
|
|
415
|
+
await fs.stat(filePath);
|
|
416
|
+
return true;
|
|
417
|
+
} catch (err) {
|
|
418
|
+
if (isNotFoundError(err))
|
|
419
|
+
return false;
|
|
420
|
+
throw err;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
var init_fs = __esm({
|
|
424
|
+
"dist/utils/fs.js"() {
|
|
425
|
+
"use strict";
|
|
426
|
+
init_error();
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
359
430
|
// dist/cli/templates.js
|
|
360
431
|
var templates_exports = {};
|
|
361
432
|
__export(templates_exports, {
|
|
433
|
+
SCAFFOLD_STACK_NAME: () => SCAFFOLD_STACK_NAME,
|
|
362
434
|
aiConfig: () => aiConfig,
|
|
363
435
|
aiRoute: () => aiRoute,
|
|
364
436
|
apiRoute: () => apiRoute,
|
|
365
437
|
canopyCmsConfig: () => canopyCmsConfig,
|
|
366
438
|
canopyContext: () => canopyContext,
|
|
439
|
+
cdkApp: () => cdkApp,
|
|
440
|
+
cdkJson: () => cdkJson,
|
|
441
|
+
cmsStack: () => cmsStack,
|
|
367
442
|
dockerfileCms: () => dockerfileCms,
|
|
368
443
|
dockerignore: () => dockerignore,
|
|
369
444
|
editPage: () => editPage,
|
|
@@ -427,21 +502,205 @@ async function nextConfig(options) {
|
|
|
427
502
|
const templateName = options.staticBuild ? "next.config-static.ts.template" : "next.config.ts.template";
|
|
428
503
|
return readTemplate(templateName);
|
|
429
504
|
}
|
|
430
|
-
async function dockerfileCms() {
|
|
431
|
-
|
|
505
|
+
async function dockerfileCms(options) {
|
|
506
|
+
const template = await readTemplate("Dockerfile.cms.template");
|
|
507
|
+
return template.replace("{{DOCKER_COPY}}", options.copy).replace("{{DOCKER_INSTALL}}", options.install).replace("{{DOCKER_BUILD}}", options.build);
|
|
432
508
|
}
|
|
433
509
|
async function dockerignore() {
|
|
434
510
|
return readTemplate("dockerignore.template");
|
|
435
511
|
}
|
|
436
|
-
async function githubWorkflowCms() {
|
|
437
|
-
|
|
512
|
+
async function githubWorkflowCms(options) {
|
|
513
|
+
const template = await readTemplate("deploy-cms.yml.template");
|
|
514
|
+
return template.replace("{{DEFAULT_BRANCH}}", options.defaultBranch).replace("{{LOCKFILE}}", options.lockfile).replace("{{CI_INSTALL}}", options.ciInstall).replaceAll("{{ADD_DEV}}", options.addDev).replace("{{STACK_NAME}}", SCAFFOLD_STACK_NAME);
|
|
515
|
+
}
|
|
516
|
+
async function cdkJson() {
|
|
517
|
+
return readTemplate("cdk.json.template");
|
|
518
|
+
}
|
|
519
|
+
async function cdkApp(options) {
|
|
520
|
+
const template = await readTemplate("cdk-app.ts.template");
|
|
521
|
+
return template.replace("{{STACK_NAME}}", SCAFFOLD_STACK_NAME).replace("{{GITHUB_OWNER}}", options.githubOwner).replace("{{GITHUB_REPO}}", options.githubRepo);
|
|
438
522
|
}
|
|
439
|
-
|
|
523
|
+
async function cmsStack() {
|
|
524
|
+
return readTemplate("cms-stack.ts.template");
|
|
525
|
+
}
|
|
526
|
+
var __dirname, TEMPLATES_DIR, SCAFFOLD_STACK_NAME;
|
|
440
527
|
var init_templates = __esm({
|
|
441
528
|
"dist/cli/templates.js"() {
|
|
442
529
|
"use strict";
|
|
443
530
|
__dirname = path2.dirname(fileURLToPath(import.meta.url));
|
|
444
531
|
TEMPLATES_DIR = path2.join(__dirname, "template-files");
|
|
532
|
+
SCAFFOLD_STACK_NAME = "CanopyCms";
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// dist/cli/project-detect.js
|
|
537
|
+
var project_detect_exports = {};
|
|
538
|
+
__export(project_detect_exports, {
|
|
539
|
+
CDK_DEPENDENCIES: () => CDK_DEPENDENCIES,
|
|
540
|
+
commandsFor: () => commandsFor,
|
|
541
|
+
detectDefaultBranch: () => detectDefaultBranch,
|
|
542
|
+
detectGitHubRepo: () => detectGitHubRepo,
|
|
543
|
+
detectPackageManager: () => detectPackageManager,
|
|
544
|
+
missingCdkDependencies: () => missingCdkDependencies,
|
|
545
|
+
readPackageJson: () => readPackageJson
|
|
546
|
+
});
|
|
547
|
+
import fs3 from "node:fs/promises";
|
|
548
|
+
import path3 from "node:path";
|
|
549
|
+
import { simpleGit } from "simple-git";
|
|
550
|
+
function commandsFor(manager) {
|
|
551
|
+
return COMMANDS[manager];
|
|
552
|
+
}
|
|
553
|
+
async function detectPackageManager(projectDir) {
|
|
554
|
+
for (const dir of await workspaceSearchPath(projectDir)) {
|
|
555
|
+
const declared = await readDeclaredPackageManager(dir);
|
|
556
|
+
if (declared)
|
|
557
|
+
return declared;
|
|
558
|
+
if (await filePathExists(path3.join(dir, "pnpm-lock.yaml")))
|
|
559
|
+
return "pnpm";
|
|
560
|
+
if (await filePathExists(path3.join(dir, "yarn.lock"))) {
|
|
561
|
+
return await isYarnBerryLockfile(dir) ? "yarn-berry" : "yarn";
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return "npm";
|
|
565
|
+
}
|
|
566
|
+
async function workspaceSearchPath(projectDir) {
|
|
567
|
+
const start = path3.resolve(projectDir);
|
|
568
|
+
const dirs = [start];
|
|
569
|
+
if (!await filePathExists(path3.join(start, "package.json")))
|
|
570
|
+
return dirs;
|
|
571
|
+
let dir = start;
|
|
572
|
+
for (let depth = 0; depth < MAX_WORKSPACE_DEPTH; depth++) {
|
|
573
|
+
if (await filePathExists(path3.join(dir, ".git")))
|
|
574
|
+
break;
|
|
575
|
+
const parent = path3.dirname(dir);
|
|
576
|
+
if (parent === dir)
|
|
577
|
+
break;
|
|
578
|
+
dir = parent;
|
|
579
|
+
dirs.push(dir);
|
|
580
|
+
}
|
|
581
|
+
return dirs;
|
|
582
|
+
}
|
|
583
|
+
async function readDeclaredPackageManager(projectDir) {
|
|
584
|
+
const pkg = await readPackageJson(projectDir);
|
|
585
|
+
const declared = pkg?.["packageManager"];
|
|
586
|
+
if (typeof declared !== "string")
|
|
587
|
+
return null;
|
|
588
|
+
if (declared.startsWith("pnpm@"))
|
|
589
|
+
return "pnpm";
|
|
590
|
+
if (declared.startsWith("npm@"))
|
|
591
|
+
return "npm";
|
|
592
|
+
if (declared.startsWith("yarn@")) {
|
|
593
|
+
const major = Number.parseInt(declared.slice("yarn@".length), 10);
|
|
594
|
+
if (Number.isFinite(major) && major >= 2)
|
|
595
|
+
return "yarn-berry";
|
|
596
|
+
if (Number.isFinite(major))
|
|
597
|
+
return "yarn";
|
|
598
|
+
return await isYarnBerryLockfile(projectDir) ? "yarn-berry" : "yarn";
|
|
599
|
+
}
|
|
600
|
+
return null;
|
|
601
|
+
}
|
|
602
|
+
async function isYarnBerryLockfile(projectDir) {
|
|
603
|
+
try {
|
|
604
|
+
const content = await fs3.readFile(path3.join(projectDir, "yarn.lock"), "utf-8");
|
|
605
|
+
return content.includes("__metadata:");
|
|
606
|
+
} catch {
|
|
607
|
+
return false;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
async function detectDefaultBranch(projectDir) {
|
|
611
|
+
const head = await gitRaw(projectDir, ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"]);
|
|
612
|
+
if (!head)
|
|
613
|
+
return "main";
|
|
614
|
+
const slash = head.indexOf("/");
|
|
615
|
+
const branch = slash === -1 ? head : head.slice(slash + 1);
|
|
616
|
+
return branch || "main";
|
|
617
|
+
}
|
|
618
|
+
async function detectGitHubRepo(projectDir) {
|
|
619
|
+
const url = await gitRaw(projectDir, ["remote", "get-url", "origin"]);
|
|
620
|
+
if (!url)
|
|
621
|
+
return null;
|
|
622
|
+
const match = /github\.com[:/]+([^/]+)\/(.+?)(?:\.git)?\/?$/.exec(url);
|
|
623
|
+
if (!match)
|
|
624
|
+
return null;
|
|
625
|
+
return { owner: match[1], repo: match[2] };
|
|
626
|
+
}
|
|
627
|
+
async function gitRaw(projectDir, args) {
|
|
628
|
+
try {
|
|
629
|
+
const output = await simpleGit({ baseDir: projectDir }).raw(args);
|
|
630
|
+
const trimmed = output.trim();
|
|
631
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
632
|
+
} catch {
|
|
633
|
+
return null;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
async function readPackageJson(projectDir) {
|
|
637
|
+
try {
|
|
638
|
+
const raw = await fs3.readFile(path3.join(projectDir, "package.json"), "utf-8");
|
|
639
|
+
const parsed = JSON.parse(raw);
|
|
640
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
641
|
+
} catch {
|
|
642
|
+
return null;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
async function missingCdkDependencies(projectDir) {
|
|
646
|
+
const pkg = await readPackageJson(projectDir);
|
|
647
|
+
const declared = /* @__PURE__ */ new Set();
|
|
648
|
+
for (const field of ["dependencies", "devDependencies", "peerDependencies"]) {
|
|
649
|
+
const section = pkg?.[field];
|
|
650
|
+
if (typeof section === "object" && section !== null) {
|
|
651
|
+
for (const name of Object.keys(section))
|
|
652
|
+
declared.add(name);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return CDK_DEPENDENCIES.filter((name) => !declared.has(name));
|
|
656
|
+
}
|
|
657
|
+
var COMMANDS, MAX_WORKSPACE_DEPTH, CDK_DEPENDENCIES;
|
|
658
|
+
var init_project_detect = __esm({
|
|
659
|
+
"dist/cli/project-detect.js"() {
|
|
660
|
+
"use strict";
|
|
661
|
+
init_fs();
|
|
662
|
+
COMMANDS = {
|
|
663
|
+
npm: {
|
|
664
|
+
lockfile: "package-lock.json",
|
|
665
|
+
ciInstall: "npm ci",
|
|
666
|
+
dockerCopy: "COPY package*.json ./",
|
|
667
|
+
dockerInstall: "RUN npm ci",
|
|
668
|
+
build: "npm run build",
|
|
669
|
+
addDev: "npm install --save-dev"
|
|
670
|
+
},
|
|
671
|
+
pnpm: {
|
|
672
|
+
lockfile: "pnpm-lock.yaml",
|
|
673
|
+
ciInstall: "corepack enable && pnpm install --frozen-lockfile",
|
|
674
|
+
dockerCopy: "COPY package.json pnpm-lock.yaml ./",
|
|
675
|
+
dockerInstall: "RUN corepack enable && pnpm install --frozen-lockfile",
|
|
676
|
+
build: "pnpm run build",
|
|
677
|
+
addDev: "pnpm add -D"
|
|
678
|
+
},
|
|
679
|
+
yarn: {
|
|
680
|
+
lockfile: "yarn.lock",
|
|
681
|
+
ciInstall: "corepack enable && yarn install --frozen-lockfile",
|
|
682
|
+
dockerCopy: "COPY package.json yarn.lock ./",
|
|
683
|
+
dockerInstall: "RUN corepack enable && yarn install --frozen-lockfile",
|
|
684
|
+
build: "yarn build",
|
|
685
|
+
addDev: "yarn add -D"
|
|
686
|
+
},
|
|
687
|
+
"yarn-berry": {
|
|
688
|
+
lockfile: "yarn.lock",
|
|
689
|
+
ciInstall: "corepack enable && yarn install --immutable",
|
|
690
|
+
dockerCopy: "COPY package.json yarn.lock .yarnrc.yml ./",
|
|
691
|
+
dockerInstall: "RUN corepack enable && yarn install --immutable",
|
|
692
|
+
build: "yarn build",
|
|
693
|
+
addDev: "yarn add -D"
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
MAX_WORKSPACE_DEPTH = 8;
|
|
697
|
+
CDK_DEPENDENCIES = [
|
|
698
|
+
"canopycms-cdk",
|
|
699
|
+
"aws-cdk-lib",
|
|
700
|
+
"constructs",
|
|
701
|
+
"tsx",
|
|
702
|
+
"aws-cdk"
|
|
703
|
+
];
|
|
445
704
|
}
|
|
446
705
|
});
|
|
447
706
|
|
|
@@ -450,15 +709,15 @@ var task_queue_config_exports = {};
|
|
|
450
709
|
__export(task_queue_config_exports, {
|
|
451
710
|
getTaskQueueDir: () => getTaskQueueDir
|
|
452
711
|
});
|
|
453
|
-
import
|
|
712
|
+
import path4 from "node:path";
|
|
454
713
|
function getTaskQueueDir(config) {
|
|
455
714
|
switch (config.mode) {
|
|
456
715
|
case "prod": {
|
|
457
716
|
const workspace = process.env.CANOPYCMS_WORKSPACE_ROOT ?? DEFAULT_PROD_WORKSPACE;
|
|
458
|
-
return
|
|
717
|
+
return path4.join(path4.resolve(workspace), ".tasks");
|
|
459
718
|
}
|
|
460
719
|
case "dev": {
|
|
461
|
-
return
|
|
720
|
+
return path4.join(process.cwd(), ".canopy-dev", ".tasks");
|
|
462
721
|
}
|
|
463
722
|
}
|
|
464
723
|
}
|
|
@@ -495,10 +754,21 @@ var init_debug = __esm({
|
|
|
495
754
|
const minLevel = this.options.minLevel ?? "DEBUG";
|
|
496
755
|
return LOG_LEVELS[level] >= LOG_LEVELS[minLevel];
|
|
497
756
|
}
|
|
757
|
+
/**
|
|
758
|
+
* The ISO-8601 timestamp leads the line BARE - not wrapped in brackets as it
|
|
759
|
+
* once was. `CANOPYCMS_DEBUG=true` can be set on the EC2 worker, whose stdout
|
|
760
|
+
* appends to /var/log/canopy-worker/worker.log; the CloudWatch agent's
|
|
761
|
+
* `multi_line_start_pattern` matches the timestamp at the START of a line
|
|
762
|
+
* (see worker/log.ts's INVARIANT and cms-service.ts's agent config), so a
|
|
763
|
+
* leading `[` meant every debug line was silently folded into the previous
|
|
764
|
+
* event instead of starting its own. The bracketed `[prefix:category]` and
|
|
765
|
+
* `[level]` fields still follow, so the human-readable shape is unchanged
|
|
766
|
+
* apart from those two characters.
|
|
767
|
+
*/
|
|
498
768
|
formatMessage(level, category, message) {
|
|
499
769
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
500
770
|
const prefix = this.options.prefix ?? "CanopyCMS";
|
|
501
|
-
return
|
|
771
|
+
return `${timestamp} [${prefix}:${category}] [${level}] ${message}`;
|
|
502
772
|
}
|
|
503
773
|
debug(category, message, data) {
|
|
504
774
|
if (this.shouldLog("DEBUG")) {
|
|
@@ -567,17 +837,17 @@ var init_debug = __esm({
|
|
|
567
837
|
});
|
|
568
838
|
|
|
569
839
|
// dist/utils/atomic-write.js
|
|
570
|
-
import
|
|
571
|
-
import
|
|
840
|
+
import fs4 from "node:fs/promises";
|
|
841
|
+
import path5 from "node:path";
|
|
572
842
|
async function atomicWriteFile(filePath, content) {
|
|
573
|
-
const dir =
|
|
574
|
-
await
|
|
843
|
+
const dir = path5.dirname(filePath);
|
|
844
|
+
await fs4.mkdir(dir, { recursive: true });
|
|
575
845
|
const tempPath = `${filePath}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
576
|
-
await
|
|
846
|
+
await fs4.writeFile(tempPath, content, typeof content === "string" ? "utf-8" : void 0);
|
|
577
847
|
try {
|
|
578
|
-
await
|
|
848
|
+
await fs4.rename(tempPath, filePath);
|
|
579
849
|
} catch (err) {
|
|
580
|
-
await
|
|
850
|
+
await fs4.unlink(tempPath).catch(() => {
|
|
581
851
|
});
|
|
582
852
|
throw err;
|
|
583
853
|
}
|
|
@@ -589,15 +859,15 @@ var init_atomic_write = __esm({
|
|
|
589
859
|
});
|
|
590
860
|
|
|
591
861
|
// dist/task-queue/task-queue.js
|
|
592
|
-
import
|
|
593
|
-
import
|
|
862
|
+
import fs5 from "node:fs/promises";
|
|
863
|
+
import path6 from "node:path";
|
|
594
864
|
import crypto from "node:crypto";
|
|
595
865
|
function isNotFoundError2(err) {
|
|
596
866
|
return err instanceof Error && "code" in err && err.code === "ENOENT";
|
|
597
867
|
}
|
|
598
868
|
async function enqueueTask(taskDir, task, logger = nullLogger) {
|
|
599
869
|
const id = crypto.randomUUID();
|
|
600
|
-
const pendingDir =
|
|
870
|
+
const pendingDir = path6.join(taskDir, "pending");
|
|
601
871
|
const queuedTask = {
|
|
602
872
|
id,
|
|
603
873
|
action: task.action,
|
|
@@ -607,17 +877,17 @@ async function enqueueTask(taskDir, task, logger = nullLogger) {
|
|
|
607
877
|
retryCount: 0,
|
|
608
878
|
maxRetries: task.maxRetries ?? DEFAULT_MAX_RETRIES
|
|
609
879
|
};
|
|
610
|
-
const filePath =
|
|
880
|
+
const filePath = path6.join(pendingDir, `${id}.json`);
|
|
611
881
|
await atomicWriteFile(filePath, JSON.stringify(queuedTask, null, 2));
|
|
612
882
|
logger.debug("Enqueued task", { id, action: task.action });
|
|
613
883
|
return id;
|
|
614
884
|
}
|
|
615
885
|
async function dequeueTask(taskDir, logger = nullLogger) {
|
|
616
|
-
const pendingDir =
|
|
617
|
-
const processingDir =
|
|
886
|
+
const pendingDir = path6.join(taskDir, "pending");
|
|
887
|
+
const processingDir = path6.join(taskDir, "processing");
|
|
618
888
|
let files;
|
|
619
889
|
try {
|
|
620
|
-
files = await
|
|
890
|
+
files = await fs5.readdir(pendingDir);
|
|
621
891
|
} catch {
|
|
622
892
|
return null;
|
|
623
893
|
}
|
|
@@ -628,7 +898,7 @@ async function dequeueTask(taskDir, logger = nullLogger) {
|
|
|
628
898
|
const tasks = [];
|
|
629
899
|
for (const fileName of jsonFiles) {
|
|
630
900
|
try {
|
|
631
|
-
const content = await
|
|
901
|
+
const content = await fs5.readFile(path6.join(pendingDir, fileName), "utf-8");
|
|
632
902
|
const task = parseTaskJson(content);
|
|
633
903
|
if (!task) {
|
|
634
904
|
await moveToCorrupt(taskDir, pendingDir, fileName, "Invalid JSON", logger);
|
|
@@ -649,17 +919,17 @@ async function dequeueTask(taskDir, logger = nullLogger) {
|
|
|
649
919
|
tasks.sort((a, b) => a.task.createdAt.localeCompare(b.task.createdAt) || a.task.id.localeCompare(b.task.id));
|
|
650
920
|
for (const { fileName, task } of tasks) {
|
|
651
921
|
if (await taskExistsIn(taskDir, task.id, ["completed", "failed"])) {
|
|
652
|
-
await
|
|
922
|
+
await fs5.unlink(path6.join(pendingDir, fileName)).catch(() => {
|
|
653
923
|
});
|
|
654
924
|
logger.debug("Skipped already-finished task", { id: task.id });
|
|
655
925
|
continue;
|
|
656
926
|
}
|
|
657
|
-
const sourcePath =
|
|
658
|
-
const destPath =
|
|
927
|
+
const sourcePath = path6.join(pendingDir, fileName);
|
|
928
|
+
const destPath = path6.join(processingDir, fileName);
|
|
659
929
|
try {
|
|
660
930
|
task.status = "processing";
|
|
661
931
|
await atomicWriteFile(destPath, JSON.stringify(task, null, 2));
|
|
662
|
-
await
|
|
932
|
+
await fs5.unlink(sourcePath);
|
|
663
933
|
logger.debug("Dequeued task", { id: task.id, action: task.action });
|
|
664
934
|
return task;
|
|
665
935
|
} catch (err) {
|
|
@@ -671,16 +941,16 @@ async function dequeueTask(taskDir, logger = nullLogger) {
|
|
|
671
941
|
return null;
|
|
672
942
|
}
|
|
673
943
|
async function completeTask(taskDir, taskId, result, logger = nullLogger) {
|
|
674
|
-
const processingPath =
|
|
675
|
-
const completedDir =
|
|
676
|
-
const completedPath =
|
|
944
|
+
const processingPath = path6.join(taskDir, "processing", `${taskId}.json`);
|
|
945
|
+
const completedDir = path6.join(taskDir, "completed");
|
|
946
|
+
const completedPath = path6.join(completedDir, `${taskId}.json`);
|
|
677
947
|
let task;
|
|
678
948
|
try {
|
|
679
|
-
const content = await
|
|
949
|
+
const content = await fs5.readFile(processingPath, "utf-8");
|
|
680
950
|
const parsed = parseTaskJson(content);
|
|
681
951
|
if (!parsed) {
|
|
682
952
|
logger.debug("Corrupt task file in processing, removing", { id: taskId });
|
|
683
|
-
await
|
|
953
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
684
954
|
});
|
|
685
955
|
return;
|
|
686
956
|
}
|
|
@@ -694,21 +964,21 @@ async function completeTask(taskDir, taskId, result, logger = nullLogger) {
|
|
|
694
964
|
task.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
695
965
|
task.result = result;
|
|
696
966
|
await atomicWriteFile(completedPath, JSON.stringify(task, null, 2));
|
|
697
|
-
await
|
|
967
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
698
968
|
});
|
|
699
969
|
logger.debug("Completed task", { id: taskId });
|
|
700
970
|
}
|
|
701
971
|
async function failTask(taskDir, taskId, error, logger = nullLogger) {
|
|
702
|
-
const processingPath =
|
|
703
|
-
const failedDir =
|
|
704
|
-
const failedPath =
|
|
972
|
+
const processingPath = path6.join(taskDir, "processing", `${taskId}.json`);
|
|
973
|
+
const failedDir = path6.join(taskDir, "failed");
|
|
974
|
+
const failedPath = path6.join(failedDir, `${taskId}.json`);
|
|
705
975
|
let task;
|
|
706
976
|
try {
|
|
707
|
-
const content = await
|
|
977
|
+
const content = await fs5.readFile(processingPath, "utf-8");
|
|
708
978
|
const parsed = parseTaskJson(content);
|
|
709
979
|
if (!parsed) {
|
|
710
980
|
logger.debug("Corrupt task file in processing, removing", { id: taskId });
|
|
711
|
-
await
|
|
981
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
712
982
|
});
|
|
713
983
|
return;
|
|
714
984
|
}
|
|
@@ -722,21 +992,21 @@ async function failTask(taskDir, taskId, error, logger = nullLogger) {
|
|
|
722
992
|
task.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
723
993
|
task.error = error;
|
|
724
994
|
await atomicWriteFile(failedPath, JSON.stringify(task, null, 2));
|
|
725
|
-
await
|
|
995
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
726
996
|
});
|
|
727
997
|
logger.debug("Failed task", { id: taskId, error });
|
|
728
998
|
}
|
|
729
999
|
async function retryTask(taskDir, taskId, error, logger = nullLogger) {
|
|
730
|
-
const processingPath =
|
|
731
|
-
const pendingDir =
|
|
732
|
-
const pendingPath =
|
|
1000
|
+
const processingPath = path6.join(taskDir, "processing", `${taskId}.json`);
|
|
1001
|
+
const pendingDir = path6.join(taskDir, "pending");
|
|
1002
|
+
const pendingPath = path6.join(pendingDir, `${taskId}.json`);
|
|
733
1003
|
let task;
|
|
734
1004
|
try {
|
|
735
|
-
const content = await
|
|
1005
|
+
const content = await fs5.readFile(processingPath, "utf-8");
|
|
736
1006
|
const parsed = parseTaskJson(content);
|
|
737
1007
|
if (!parsed) {
|
|
738
1008
|
logger.debug("Corrupt task file in processing, removing", { id: taskId });
|
|
739
|
-
await
|
|
1009
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
740
1010
|
});
|
|
741
1011
|
return;
|
|
742
1012
|
}
|
|
@@ -753,15 +1023,15 @@ async function retryTask(taskDir, taskId, error, logger = nullLogger) {
|
|
|
753
1023
|
task.retryAfter = new Date(Date.now() + backoffMs).toISOString();
|
|
754
1024
|
task.error = error;
|
|
755
1025
|
await atomicWriteFile(pendingPath, JSON.stringify(task, null, 2));
|
|
756
|
-
await
|
|
1026
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
757
1027
|
});
|
|
758
1028
|
logger.debug("Retrying task", { id: taskId, retryCount, backoffMs });
|
|
759
1029
|
}
|
|
760
1030
|
async function requeueFailedTask(taskDir, taskId, logger = nullLogger) {
|
|
761
|
-
const failedPath =
|
|
1031
|
+
const failedPath = path6.join(taskDir, "failed", `${taskId}.json`);
|
|
762
1032
|
let content;
|
|
763
1033
|
try {
|
|
764
|
-
content = await
|
|
1034
|
+
content = await fs5.readFile(failedPath, "utf-8");
|
|
765
1035
|
} catch (err) {
|
|
766
1036
|
if (isNotFoundError2(err))
|
|
767
1037
|
return { error: "not-found" };
|
|
@@ -780,37 +1050,37 @@ async function requeueFailedTask(taskDir, taskId, logger = nullLogger) {
|
|
|
780
1050
|
retryCount: 0,
|
|
781
1051
|
maxRetries: original.maxRetries
|
|
782
1052
|
};
|
|
783
|
-
const pendingPath =
|
|
1053
|
+
const pendingPath = path6.join(taskDir, "pending", `${newTaskId}.json`);
|
|
784
1054
|
await atomicWriteFile(pendingPath, JSON.stringify(newTask, null, 2));
|
|
785
|
-
await
|
|
1055
|
+
await fs5.unlink(failedPath).catch(() => {
|
|
786
1056
|
});
|
|
787
1057
|
logger.debug("Requeued failed task", { originalId: taskId, newTaskId });
|
|
788
1058
|
return { newTaskId };
|
|
789
1059
|
}
|
|
790
1060
|
async function recoverOrphanedTasks(taskDir, maxAgeMs = 5 * 6e4, logger = nullLogger) {
|
|
791
|
-
const processingDir =
|
|
792
|
-
const pendingDir =
|
|
1061
|
+
const processingDir = path6.join(taskDir, "processing");
|
|
1062
|
+
const pendingDir = path6.join(taskDir, "pending");
|
|
793
1063
|
let files;
|
|
794
1064
|
try {
|
|
795
|
-
files = await
|
|
1065
|
+
files = await fs5.readdir(processingDir);
|
|
796
1066
|
} catch {
|
|
797
1067
|
return 0;
|
|
798
1068
|
}
|
|
799
1069
|
const now = Date.now();
|
|
800
1070
|
let recovered = 0;
|
|
801
1071
|
for (const fileName of files.filter((f) => f.endsWith(".json"))) {
|
|
802
|
-
const filePath =
|
|
1072
|
+
const filePath = path6.join(processingDir, fileName);
|
|
803
1073
|
try {
|
|
804
|
-
const stat = await
|
|
1074
|
+
const stat = await fs5.stat(filePath);
|
|
805
1075
|
if (now - stat.mtimeMs >= maxAgeMs) {
|
|
806
|
-
const content = await
|
|
1076
|
+
const content = await fs5.readFile(filePath, "utf-8");
|
|
807
1077
|
const task = parseTaskJson(content);
|
|
808
1078
|
if (!task) {
|
|
809
1079
|
await moveToCorrupt(taskDir, processingDir, fileName, "Invalid JSON during recovery", logger);
|
|
810
1080
|
continue;
|
|
811
1081
|
}
|
|
812
1082
|
if (await taskExistsIn(taskDir, task.id, ["completed", "failed"])) {
|
|
813
|
-
await
|
|
1083
|
+
await fs5.unlink(filePath).catch(() => {
|
|
814
1084
|
});
|
|
815
1085
|
logger.debug("Cleaned up orphaned task (already finished)", {
|
|
816
1086
|
id: task.id
|
|
@@ -818,8 +1088,8 @@ async function recoverOrphanedTasks(taskDir, maxAgeMs = 5 * 6e4, logger = nullLo
|
|
|
818
1088
|
continue;
|
|
819
1089
|
}
|
|
820
1090
|
task.status = "pending";
|
|
821
|
-
await atomicWriteFile(
|
|
822
|
-
await
|
|
1091
|
+
await atomicWriteFile(path6.join(pendingDir, fileName), JSON.stringify(task, null, 2));
|
|
1092
|
+
await fs5.unlink(filePath);
|
|
823
1093
|
logger.debug("Recovered orphaned task", {
|
|
824
1094
|
id: task.id,
|
|
825
1095
|
action: task.action
|
|
@@ -838,19 +1108,19 @@ async function cleanupOldTasks(taskDir, maxAgeMs = 30 * 24 * 60 * 6e4, logger =
|
|
|
838
1108
|
const now = Date.now();
|
|
839
1109
|
let cleaned = 0;
|
|
840
1110
|
for (const subdir of ["completed", "failed"]) {
|
|
841
|
-
const dir =
|
|
1111
|
+
const dir = path6.join(taskDir, subdir);
|
|
842
1112
|
let files;
|
|
843
1113
|
try {
|
|
844
|
-
files = await
|
|
1114
|
+
files = await fs5.readdir(dir);
|
|
845
1115
|
} catch {
|
|
846
1116
|
continue;
|
|
847
1117
|
}
|
|
848
1118
|
for (const fileName of files.filter((f) => f.endsWith(".json"))) {
|
|
849
1119
|
try {
|
|
850
|
-
const filePath =
|
|
851
|
-
const stat = await
|
|
1120
|
+
const filePath = path6.join(dir, fileName);
|
|
1121
|
+
const stat = await fs5.stat(filePath);
|
|
852
1122
|
if (now - stat.mtimeMs >= maxAgeMs) {
|
|
853
|
-
await
|
|
1123
|
+
await fs5.unlink(filePath);
|
|
854
1124
|
cleaned++;
|
|
855
1125
|
}
|
|
856
1126
|
} catch {
|
|
@@ -864,9 +1134,9 @@ async function cleanupOldTasks(taskDir, maxAgeMs = 30 * 24 * 60 * 6e4, logger =
|
|
|
864
1134
|
}
|
|
865
1135
|
async function getTask(taskDir, taskId) {
|
|
866
1136
|
for (const subdir of ["completed", "failed", "processing", "pending"]) {
|
|
867
|
-
const filePath =
|
|
1137
|
+
const filePath = path6.join(taskDir, subdir, `${taskId}.json`);
|
|
868
1138
|
try {
|
|
869
|
-
const content = await
|
|
1139
|
+
const content = await fs5.readFile(filePath, "utf-8");
|
|
870
1140
|
return parseTaskJson(content);
|
|
871
1141
|
} catch {
|
|
872
1142
|
continue;
|
|
@@ -875,10 +1145,10 @@ async function getTask(taskDir, taskId) {
|
|
|
875
1145
|
return null;
|
|
876
1146
|
}
|
|
877
1147
|
async function listTasks(taskDir, status, limit = 100) {
|
|
878
|
-
const dir =
|
|
1148
|
+
const dir = path6.join(taskDir, status);
|
|
879
1149
|
let files;
|
|
880
1150
|
try {
|
|
881
|
-
files = await
|
|
1151
|
+
files = await fs5.readdir(dir);
|
|
882
1152
|
} catch {
|
|
883
1153
|
return [];
|
|
884
1154
|
}
|
|
@@ -887,7 +1157,7 @@ async function listTasks(taskDir, status, limit = 100) {
|
|
|
887
1157
|
if (tasks.length >= limit)
|
|
888
1158
|
break;
|
|
889
1159
|
try {
|
|
890
|
-
const content = await
|
|
1160
|
+
const content = await fs5.readFile(path6.join(dir, fileName), "utf-8");
|
|
891
1161
|
const task = parseTaskJson(content);
|
|
892
1162
|
if (task)
|
|
893
1163
|
tasks.push(task);
|
|
@@ -907,9 +1177,9 @@ async function getQueueStats(taskDir) {
|
|
|
907
1177
|
corrupt: 0
|
|
908
1178
|
};
|
|
909
1179
|
for (const status of ["pending", "processing", "completed", "failed", "corrupt"]) {
|
|
910
|
-
const dir =
|
|
1180
|
+
const dir = path6.join(taskDir, status);
|
|
911
1181
|
try {
|
|
912
|
-
const files = await
|
|
1182
|
+
const files = await fs5.readdir(dir);
|
|
913
1183
|
stats[status] = files.filter((f) => f.endsWith(".json")).length;
|
|
914
1184
|
} catch {
|
|
915
1185
|
}
|
|
@@ -917,10 +1187,10 @@ async function getQueueStats(taskDir) {
|
|
|
917
1187
|
return stats;
|
|
918
1188
|
}
|
|
919
1189
|
async function listCorruptTaskFiles(taskDir, limit = 50, logger = nullLogger) {
|
|
920
|
-
const corruptDir =
|
|
1190
|
+
const corruptDir = path6.join(taskDir, "corrupt");
|
|
921
1191
|
let files;
|
|
922
1192
|
try {
|
|
923
|
-
files = await
|
|
1193
|
+
files = await fs5.readdir(corruptDir);
|
|
924
1194
|
} catch (err) {
|
|
925
1195
|
if (isNotFoundError2(err))
|
|
926
1196
|
return [];
|
|
@@ -928,9 +1198,9 @@ async function listCorruptTaskFiles(taskDir, limit = 50, logger = nullLogger) {
|
|
|
928
1198
|
}
|
|
929
1199
|
const entries = [];
|
|
930
1200
|
for (const fileName of files.filter((f) => f.endsWith(".json"))) {
|
|
931
|
-
const filePath =
|
|
1201
|
+
const filePath = path6.join(corruptDir, fileName);
|
|
932
1202
|
try {
|
|
933
|
-
const stat = await
|
|
1203
|
+
const stat = await fs5.stat(filePath);
|
|
934
1204
|
entries.push({
|
|
935
1205
|
fileName,
|
|
936
1206
|
size: stat.size,
|
|
@@ -947,7 +1217,7 @@ async function listCorruptTaskFiles(taskDir, limit = 50, logger = nullLogger) {
|
|
|
947
1217
|
return entries.slice(0, limit);
|
|
948
1218
|
}
|
|
949
1219
|
async function readSnippet(filePath, maxBytes) {
|
|
950
|
-
const handle = await
|
|
1220
|
+
const handle = await fs5.open(filePath, "r");
|
|
951
1221
|
try {
|
|
952
1222
|
const buffer = Buffer.alloc(maxBytes);
|
|
953
1223
|
const { bytesRead } = await handle.read(buffer, 0, maxBytes, 0);
|
|
@@ -970,7 +1240,7 @@ function parseTaskJson(content) {
|
|
|
970
1240
|
async function taskExistsIn(taskDir, taskId, subdirs) {
|
|
971
1241
|
for (const subdir of subdirs) {
|
|
972
1242
|
try {
|
|
973
|
-
await
|
|
1243
|
+
await fs5.stat(path6.join(taskDir, subdir, `${taskId}.json`));
|
|
974
1244
|
return true;
|
|
975
1245
|
} catch {
|
|
976
1246
|
}
|
|
@@ -978,13 +1248,13 @@ async function taskExistsIn(taskDir, taskId, subdirs) {
|
|
|
978
1248
|
return false;
|
|
979
1249
|
}
|
|
980
1250
|
async function moveToCorrupt(taskDir, sourceDir, fileName, reason, logger) {
|
|
981
|
-
const corruptDir =
|
|
1251
|
+
const corruptDir = path6.join(taskDir, "corrupt");
|
|
982
1252
|
try {
|
|
983
|
-
await
|
|
984
|
-
await
|
|
1253
|
+
await fs5.mkdir(corruptDir, { recursive: true });
|
|
1254
|
+
await fs5.rename(path6.join(sourceDir, fileName), path6.join(corruptDir, fileName));
|
|
985
1255
|
logger.debug("Moved corrupt task file", { fileName, reason });
|
|
986
1256
|
} catch {
|
|
987
|
-
await
|
|
1257
|
+
await fs5.unlink(path6.join(sourceDir, fileName)).catch(() => {
|
|
988
1258
|
});
|
|
989
1259
|
}
|
|
990
1260
|
}
|
|
@@ -1041,8 +1311,8 @@ var init_task_queue3 = __esm({
|
|
|
1041
1311
|
});
|
|
1042
1312
|
|
|
1043
1313
|
// dist/cli/init.js
|
|
1044
|
-
import
|
|
1045
|
-
import
|
|
1314
|
+
import fs6 from "node:fs/promises";
|
|
1315
|
+
import path7 from "node:path";
|
|
1046
1316
|
import * as p from "@clack/prompts";
|
|
1047
1317
|
import { createJiti } from "jiti";
|
|
1048
1318
|
|
|
@@ -1112,6 +1382,28 @@ var DevClientSafeStrategy = class {
|
|
|
1112
1382
|
|
|
1113
1383
|
// dist/operating-mode/client-unsafe-strategy.js
|
|
1114
1384
|
import path from "node:path";
|
|
1385
|
+
|
|
1386
|
+
// dist/operating-mode/deployment-name.js
|
|
1387
|
+
init_logger();
|
|
1388
|
+
var warned = false;
|
|
1389
|
+
var VALID_DEPLOYMENT_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
1390
|
+
var isValidDeploymentName = (name) => VALID_DEPLOYMENT_NAME.test(name) && !name.includes("..") && !name.endsWith(".") && !name.endsWith(".lock");
|
|
1391
|
+
function resolveDeploymentName(config, modeDefault) {
|
|
1392
|
+
const envValue = process.env.CANOPYCMS_DEPLOYMENT_NAME?.trim();
|
|
1393
|
+
const configValue = config.deploymentName;
|
|
1394
|
+
if (envValue && configValue && envValue !== configValue && !warned) {
|
|
1395
|
+
canopyLogWarn(`CanopyCMS: CANOPYCMS_DEPLOYMENT_NAME ("${envValue}") differs from config.deploymentName ("${configValue}") \u2014 using the env var (infra-stamped env wins over shared-repo config by design; see resolveDeploymentName's doc comment). Update config.deploymentName to match if this mismatch was unintentional.`);
|
|
1396
|
+
warned = true;
|
|
1397
|
+
}
|
|
1398
|
+
const resolved = envValue || configValue || modeDefault;
|
|
1399
|
+
if (!isValidDeploymentName(resolved)) {
|
|
1400
|
+
const source = envValue ? "CANOPYCMS_DEPLOYMENT_NAME" : configValue ? "config.deploymentName" : "the mode default";
|
|
1401
|
+
throw new Error(`CanopyCMS: invalid deploymentName ${JSON.stringify(resolved)} (from ${source}). It is interpolated into the settings branch name (canopycms-settings-<deploymentName>), so it must start with a letter or digit, contain only letters, digits, '.', '_' or '-', and must not contain '..' or end with '.' or '.lock'.`);
|
|
1402
|
+
}
|
|
1403
|
+
return resolved;
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
// dist/operating-mode/client-unsafe-strategy.js
|
|
1115
1407
|
init_config2();
|
|
1116
1408
|
var ProdStrategy = class extends ProdClientSafeStrategy {
|
|
1117
1409
|
// All client-safe methods inherited automatically from ProdClientSafeStrategy:
|
|
@@ -1122,8 +1414,8 @@ var ProdStrategy = class extends ProdClientSafeStrategy {
|
|
|
1122
1414
|
getWorkspaceRoot(_sourceRoot) {
|
|
1123
1415
|
return path.resolve(process.env.CANOPYCMS_WORKSPACE_ROOT ?? DEFAULT_PROD_WORKSPACE);
|
|
1124
1416
|
}
|
|
1125
|
-
getContentRoot(sourceRoot) {
|
|
1126
|
-
return path.resolve(sourceRoot ?? process.cwd(),
|
|
1417
|
+
getContentRoot(contentRoot, sourceRoot) {
|
|
1418
|
+
return path.resolve(sourceRoot ?? process.cwd(), contentRoot);
|
|
1127
1419
|
}
|
|
1128
1420
|
getContentBranchesRoot(sourceRoot) {
|
|
1129
1421
|
return path.join(this.getWorkspaceRoot(sourceRoot), "content-branches");
|
|
@@ -1154,8 +1446,7 @@ var ProdStrategy = class extends ProdClientSafeStrategy {
|
|
|
1154
1446
|
getSettingsBranchName(config) {
|
|
1155
1447
|
if (config.settingsBranch)
|
|
1156
1448
|
return config.settingsBranch;
|
|
1157
|
-
|
|
1158
|
-
return `canopycms-settings-${deploymentName}`;
|
|
1449
|
+
return `canopycms-settings-${resolveDeploymentName(config, "prod")}`;
|
|
1159
1450
|
}
|
|
1160
1451
|
getSettingsRoot(sourceRoot) {
|
|
1161
1452
|
return path.join(this.getWorkspaceRoot(sourceRoot), "settings");
|
|
@@ -1177,8 +1468,8 @@ var DevStrategy = class extends DevClientSafeStrategy {
|
|
|
1177
1468
|
getWorkspaceRoot(sourceRoot) {
|
|
1178
1469
|
return path.resolve(sourceRoot ?? process.cwd(), ".canopy-dev");
|
|
1179
1470
|
}
|
|
1180
|
-
getContentRoot(sourceRoot) {
|
|
1181
|
-
return path.resolve(sourceRoot ?? process.cwd(),
|
|
1471
|
+
getContentRoot(contentRoot, sourceRoot) {
|
|
1472
|
+
return path.resolve(sourceRoot ?? process.cwd(), contentRoot);
|
|
1182
1473
|
}
|
|
1183
1474
|
getContentBranchesRoot(sourceRoot) {
|
|
1184
1475
|
return path.join(this.getWorkspaceRoot(sourceRoot), "content-branches");
|
|
@@ -1208,8 +1499,7 @@ var DevStrategy = class extends DevClientSafeStrategy {
|
|
|
1208
1499
|
getSettingsBranchName(config) {
|
|
1209
1500
|
if (config.settingsBranch)
|
|
1210
1501
|
return config.settingsBranch;
|
|
1211
|
-
|
|
1212
|
-
return `canopycms-settings-${deploymentName}`;
|
|
1502
|
+
return `canopycms-settings-${resolveDeploymentName(config, "local")}`;
|
|
1213
1503
|
}
|
|
1214
1504
|
getSettingsRoot(sourceRoot) {
|
|
1215
1505
|
return path.join(this.getWorkspaceRoot(sourceRoot), "settings");
|
|
@@ -1245,6 +1535,9 @@ function operatingStrategy(mode) {
|
|
|
1245
1535
|
return strategy;
|
|
1246
1536
|
}
|
|
1247
1537
|
|
|
1538
|
+
// dist/operating-mode/index.js
|
|
1539
|
+
init_mode_env();
|
|
1540
|
+
|
|
1248
1541
|
// dist/auth/plugin.js
|
|
1249
1542
|
function assertAuthPluginAllowedForMode(plugin, mode) {
|
|
1250
1543
|
if (mode === "prod" && plugin.verifiesCredentials !== true) {
|
|
@@ -1252,41 +1545,11 @@ function assertAuthPluginAllowedForMode(plugin, mode) {
|
|
|
1252
1545
|
}
|
|
1253
1546
|
}
|
|
1254
1547
|
|
|
1255
|
-
// dist/utils/fs.js
|
|
1256
|
-
import fs from "node:fs/promises";
|
|
1257
|
-
|
|
1258
|
-
// dist/utils/error.js
|
|
1259
|
-
function getErrorMessage(err) {
|
|
1260
|
-
if (err instanceof Error) {
|
|
1261
|
-
return err.message;
|
|
1262
|
-
}
|
|
1263
|
-
if (typeof err === "string") {
|
|
1264
|
-
return err;
|
|
1265
|
-
}
|
|
1266
|
-
return String(err);
|
|
1267
|
-
}
|
|
1268
|
-
function isNodeError(err) {
|
|
1269
|
-
return err instanceof Error && "code" in err;
|
|
1270
|
-
}
|
|
1271
|
-
function isNotFoundError(err) {
|
|
1272
|
-
return isNodeError(err) && err.code === "ENOENT";
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
// dist/utils/fs.js
|
|
1276
|
-
async function filePathExists(filePath) {
|
|
1277
|
-
try {
|
|
1278
|
-
await fs.stat(filePath);
|
|
1279
|
-
return true;
|
|
1280
|
-
} catch (err) {
|
|
1281
|
-
if (isNotFoundError(err))
|
|
1282
|
-
return false;
|
|
1283
|
-
throw err;
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
1548
|
// dist/cli/init.js
|
|
1549
|
+
init_fs();
|
|
1550
|
+
init_error();
|
|
1288
1551
|
async function writeFile(filePath, content, options) {
|
|
1289
|
-
const relativePath =
|
|
1552
|
+
const relativePath = path7.relative(process.cwd(), filePath);
|
|
1290
1553
|
if (await filePathExists(filePath)) {
|
|
1291
1554
|
if (options.force) {
|
|
1292
1555
|
} else if (options.nonInteractive) {
|
|
@@ -1303,8 +1566,8 @@ async function writeFile(filePath, content, options) {
|
|
|
1303
1566
|
}
|
|
1304
1567
|
}
|
|
1305
1568
|
}
|
|
1306
|
-
await
|
|
1307
|
-
await
|
|
1569
|
+
await fs6.mkdir(path7.dirname(filePath), { recursive: true });
|
|
1570
|
+
await fs6.writeFile(filePath, content, "utf-8");
|
|
1308
1571
|
p.log.success(`created: ${relativePath}`);
|
|
1309
1572
|
return true;
|
|
1310
1573
|
}
|
|
@@ -1356,24 +1619,24 @@ async function init(options) {
|
|
|
1356
1619
|
}
|
|
1357
1620
|
const serverPageExt = staticBuild ? "page.server.tsx" : "page.tsx";
|
|
1358
1621
|
const serverRouteExt = staticBuild ? "route.server.ts" : "route.ts";
|
|
1359
|
-
await writeFile(
|
|
1360
|
-
await writeFile(
|
|
1361
|
-
await writeFile(
|
|
1362
|
-
await writeFile(
|
|
1622
|
+
await writeFile(path7.join(projectDir, "canopycms.config.ts"), await canopyCmsConfig2({ mode, staticBuild }), writeOpts);
|
|
1623
|
+
await writeFile(path7.join(projectDir, appDir, "lib/canopy.ts"), await canopyContext2({ configImport: configImportPath(appDir, 1), authProvider }), writeOpts);
|
|
1624
|
+
await writeFile(path7.join(projectDir, appDir, "schemas.ts"), await schemasTemplate2(), writeOpts);
|
|
1625
|
+
await writeFile(path7.join(projectDir, appDir, `api/canopycms/[...canopycms]/${serverRouteExt}`), await apiRoute2({
|
|
1363
1626
|
canopyImport: "../".repeat(3) + "lib/canopy"
|
|
1364
1627
|
}), writeOpts);
|
|
1365
|
-
await writeFile(
|
|
1628
|
+
await writeFile(path7.join(projectDir, appDir, `edit/${serverPageExt}`), await editPage2({ configImport: configImportPath(appDir, 1), authProvider }), writeOpts);
|
|
1366
1629
|
if (ai) {
|
|
1367
|
-
await writeFile(
|
|
1368
|
-
await writeFile(
|
|
1630
|
+
await writeFile(path7.join(projectDir, appDir, "ai/config.ts"), await aiConfig2(), writeOpts);
|
|
1631
|
+
await writeFile(path7.join(projectDir, appDir, `ai/[...path]/${serverRouteExt}`), await aiRoute2({ configImport: configImportPath(appDir, 2) }), writeOpts);
|
|
1369
1632
|
}
|
|
1370
|
-
await writeFile(
|
|
1371
|
-
await writeFile(
|
|
1372
|
-
const gitignorePath =
|
|
1633
|
+
await writeFile(path7.join(projectDir, "next.config.ts"), await nextConfig2({ staticBuild }), writeOpts);
|
|
1634
|
+
await writeFile(path7.join(projectDir, "middleware.ts"), await middleware2({ authProvider }), writeOpts);
|
|
1635
|
+
const gitignorePath = path7.join(projectDir, ".gitignore");
|
|
1373
1636
|
if (await filePathExists(gitignorePath)) {
|
|
1374
|
-
const content = await
|
|
1637
|
+
const content = await fs6.readFile(gitignorePath, "utf-8");
|
|
1375
1638
|
if (!content.includes(".canopy-dev")) {
|
|
1376
|
-
await
|
|
1639
|
+
await fs6.appendFile(gitignorePath, "\n# CanopyCMS\n.canopy-dev/\n");
|
|
1377
1640
|
p.log.success("updated: .gitignore");
|
|
1378
1641
|
}
|
|
1379
1642
|
}
|
|
@@ -1398,34 +1661,78 @@ async function init(options) {
|
|
|
1398
1661
|
async function initDeployAws(options) {
|
|
1399
1662
|
const { projectDir, force, nonInteractive } = options;
|
|
1400
1663
|
const writeOpts = { force, nonInteractive };
|
|
1401
|
-
const { dockerfileCms: dockerfileCms2, dockerignore: dockerignore2, githubWorkflowCms: githubWorkflowCms2 } = await Promise.resolve().then(() => (init_templates(), templates_exports));
|
|
1664
|
+
const { dockerfileCms: dockerfileCms2, dockerignore: dockerignore2, githubWorkflowCms: githubWorkflowCms2, cdkJson: cdkJson2, cdkApp: cdkApp2, cmsStack: cmsStack2 } = await Promise.resolve().then(() => (init_templates(), templates_exports));
|
|
1665
|
+
const { detectPackageManager: detectPackageManager2, detectDefaultBranch: detectDefaultBranch2, detectGitHubRepo: detectGitHubRepo2, commandsFor: commandsFor2, missingCdkDependencies: missingCdkDependencies2, CDK_DEPENDENCIES: CDK_DEPENDENCIES2 } = await Promise.resolve().then(() => (init_project_detect(), project_detect_exports));
|
|
1402
1666
|
p.intro("CanopyCMS init-deploy aws");
|
|
1403
|
-
|
|
1404
|
-
const
|
|
1667
|
+
const packageManager = await detectPackageManager2(projectDir);
|
|
1668
|
+
const pm = commandsFor2(packageManager);
|
|
1669
|
+
const defaultBranch = await detectDefaultBranch2(projectDir);
|
|
1670
|
+
const repo = await detectGitHubRepo2(projectDir);
|
|
1671
|
+
await writeFile(path7.join(projectDir, "Dockerfile.cms"), await dockerfileCms2({ copy: pm.dockerCopy, install: pm.dockerInstall, build: pm.build }), writeOpts);
|
|
1672
|
+
const dockerignoreWritten = await writeFile(path7.join(projectDir, ".dockerignore"), await dockerignore2(), writeOpts);
|
|
1405
1673
|
if (!dockerignoreWritten) {
|
|
1406
|
-
p.log.warn("Existing .dockerignore kept \u2014 verify it excludes .env* (secrets would otherwise enter the build context) and does NOT exclude vendor/ (needed
|
|
1674
|
+
p.log.warn("Existing .dockerignore kept \u2014 verify it excludes .env* (secrets would otherwise enter the build context) and does NOT exclude vendor/ (needed by the Dockerfile.cms install step with file: deps).");
|
|
1407
1675
|
}
|
|
1408
|
-
await writeFile(
|
|
1409
|
-
|
|
1410
|
-
|
|
1676
|
+
await writeFile(path7.join(projectDir, ".github/workflows/deploy-cms.yml"), await githubWorkflowCms2({
|
|
1677
|
+
defaultBranch,
|
|
1678
|
+
lockfile: pm.lockfile,
|
|
1679
|
+
ciInstall: pm.ciInstall,
|
|
1680
|
+
addDev: pm.addDev
|
|
1681
|
+
}), writeOpts);
|
|
1682
|
+
const cdkJsonPath = path7.join(projectDir, "cdk.json");
|
|
1683
|
+
const existingCdkJson = await filePathExists(cdkJsonPath) ? await fs6.readFile(cdkJsonPath, "utf-8") : null;
|
|
1684
|
+
const cdkJsonWritten = await writeFile(cdkJsonPath, await cdkJson2(), writeOpts);
|
|
1685
|
+
await writeFile(path7.join(projectDir, "infrastructure/bin/app.ts"), await cdkApp2({
|
|
1686
|
+
githubOwner: repo?.owner ?? "your-org",
|
|
1687
|
+
githubRepo: repo?.repo ?? "your-docs-site"
|
|
1688
|
+
}), writeOpts);
|
|
1689
|
+
await writeFile(path7.join(projectDir, "infrastructure/lib/cms-stack.ts"), await cmsStack2(), writeOpts);
|
|
1690
|
+
if (!cdkJsonWritten && existingCdkJson && !existingCdkJson.includes("infrastructure/bin/app.ts")) {
|
|
1691
|
+
p.log.warn("Existing cdk.json kept, and it does not point at infrastructure/bin/app.ts \u2014 the scaffolded CDK app will not be deployed. Either wire CmsStack into your own app entry point, or re-run with --force to replace cdk.json.");
|
|
1692
|
+
}
|
|
1693
|
+
const nextConfigPath = path7.join(projectDir, "next.config.ts");
|
|
1694
|
+
const nextConfigMjsPath = path7.join(projectDir, "next.config.mjs");
|
|
1411
1695
|
const configPath = await filePathExists(nextConfigPath) ? nextConfigPath : await filePathExists(nextConfigMjsPath) ? nextConfigMjsPath : null;
|
|
1412
1696
|
if (configPath) {
|
|
1413
|
-
const content = await
|
|
1697
|
+
const content = await fs6.readFile(configPath, "utf-8");
|
|
1414
1698
|
if (!content.includes("CANOPY_BUILD")) {
|
|
1415
1699
|
p.note([
|
|
1416
|
-
`Add dual build support to ${
|
|
1700
|
+
`Add dual build support to ${path7.basename(configPath)}:`,
|
|
1417
1701
|
"",
|
|
1418
1702
|
" output: process.env.CANOPY_BUILD === 'cms' ? 'standalone' : 'export',"
|
|
1419
1703
|
].join("\n"), "Manual step");
|
|
1420
1704
|
}
|
|
1421
1705
|
}
|
|
1422
|
-
|
|
1706
|
+
if (packageManager === "yarn" || packageManager === "yarn-berry") {
|
|
1707
|
+
p.log.warn(`Yarn detected (${packageManager === "yarn-berry" ? "Berry" : "classic"}). The generated install lines are a best effort and are not exercised by CanopyCMS tests \u2014 review them in Dockerfile.cms and .github/workflows/deploy-cms.yml.` + (packageManager === "yarn-berry" ? " Berry additionally requires nodeLinker: node-modules; PnP is incompatible with Next.js standalone output, which the CMS image's runner stage copies." : ""));
|
|
1708
|
+
}
|
|
1709
|
+
const missing = await missingCdkDependencies2(projectDir);
|
|
1710
|
+
if (missing.length > 0) {
|
|
1711
|
+
p.log.warn(`Not installed: ${missing.join(", ")}. cdk.json runs \`node --import tsx infrastructure/bin/app.ts\`, so the deploy fails without them:
|
|
1712
|
+
${pm.addDev} ${CDK_DEPENDENCIES2.join(" ")}`);
|
|
1713
|
+
}
|
|
1714
|
+
p.note([
|
|
1715
|
+
"1. Install the CDK dependencies (if you have not already):",
|
|
1716
|
+
` ${pm.addDev} ${CDK_DEPENDENCIES2.join(" ")}`,
|
|
1717
|
+
"",
|
|
1718
|
+
"2. Fill in infrastructure/lib/cms-stack.ts and infrastructure/bin/app.ts",
|
|
1719
|
+
` (worker repo currently set to ${repo ? `${repo.owner}/${repo.repo}` : "your-org/your-docs-site"})`,
|
|
1720
|
+
"",
|
|
1721
|
+
"3. Bootstrap CDK in the target account/region: cdk bootstrap",
|
|
1722
|
+
"",
|
|
1723
|
+
"4. Set the repository secrets and variables listed at the top of",
|
|
1724
|
+
" .github/workflows/deploy-cms.yml \u2014 the deploy fails at synth without them.",
|
|
1725
|
+
"",
|
|
1726
|
+
`Deploys trigger on pushes to '${defaultBranch}'; edit the workflow to change that.`,
|
|
1727
|
+
"",
|
|
1728
|
+
"Full walkthrough: docs/deploying-to-aws.md"
|
|
1729
|
+
].join("\n"), "AWS deployment");
|
|
1423
1730
|
p.outro("Done!");
|
|
1424
1731
|
}
|
|
1425
1732
|
async function detectMode(projectDir) {
|
|
1426
|
-
const cfgPath =
|
|
1733
|
+
const cfgPath = path7.join(projectDir, "canopycms.config.ts");
|
|
1427
1734
|
try {
|
|
1428
|
-
await
|
|
1735
|
+
await fs6.stat(cfgPath);
|
|
1429
1736
|
} catch (err) {
|
|
1430
1737
|
if (isNotFoundError(err))
|
|
1431
1738
|
return "dev";
|
|
@@ -1456,7 +1763,7 @@ async function workerRunOnce(options) {
|
|
|
1456
1763
|
assertAuthPluginAllowedForMode(options.authPlugin, mode);
|
|
1457
1764
|
}
|
|
1458
1765
|
const taskDir = getTaskQueueDir2({ mode });
|
|
1459
|
-
const cachePath = process.env.CANOPY_AUTH_CACHE_PATH ??
|
|
1766
|
+
const cachePath = process.env.CANOPY_AUTH_CACHE_PATH ?? path7.join(operatingStrategy(mode).getWorkspaceRoot(options.projectDir), ".cache");
|
|
1460
1767
|
let refreshAuthCache;
|
|
1461
1768
|
const authMode = process.env.CANOPY_AUTH_MODE || "dev";
|
|
1462
1769
|
if (options.authPlugin?.createCacheRefresher) {
|