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
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single resolution point for `deploymentName`.
|
|
3
|
+
*
|
|
4
|
+
* `deploymentName` namespaces the settings branch
|
|
5
|
+
* (`canopycms-settings-{deploymentName}`) so two CanopyCMS deployments can
|
|
6
|
+
* share one GitHub repo without both resolving to `canopycms-settings-prod`
|
|
7
|
+
* and fighting over the same orphan branch.
|
|
8
|
+
*
|
|
9
|
+
* Precedence (highest wins):
|
|
10
|
+
* 1. `process.env.CANOPYCMS_DEPLOYMENT_NAME` (trimmed; empty string ignored)
|
|
11
|
+
* 2. `config.deploymentName`
|
|
12
|
+
* 3. `modeDefault` (the caller's mode-specific fallback, e.g. 'prod'/'local')
|
|
13
|
+
*
|
|
14
|
+
* Env wins over config DELIBERATELY. The env var is stamped per-stack by
|
|
15
|
+
* infrastructure (CDK's `CanopyCmsServiceProps.deploymentName` ->
|
|
16
|
+
* `CANOPYCMS_DEPLOYMENT_NAME`), so it is the value GUARANTEED TO DIFFER
|
|
17
|
+
* between two deployments sharing a repo. `config.deploymentName` lives in
|
|
18
|
+
* the shared repo's `canopycms.config.ts`, so it is the value GUARANTEED TO
|
|
19
|
+
* BE IDENTICAL across both deployments (both Lambdas run the same checked-out
|
|
20
|
+
* config). If config won instead, an adopter who already wrote
|
|
21
|
+
* `deploymentName` into their shared config would find the CDK
|
|
22
|
+
* `deploymentName` prop silently doing nothing — exactly the two-stacks-one-repo
|
|
23
|
+
* case this feature exists to fix.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Exported so `canopycms-cdk`'s suite can assert that its own synth-time copy
|
|
27
|
+
* of this rule (constructs/cms-service.ts) still agrees with this one. The
|
|
28
|
+
* construct itself must NOT import this: `canopycms-cdk` publishes without a
|
|
29
|
+
* runtime dependency on `canopycms`, so a source-level import would break the
|
|
30
|
+
* published construct. The drift check is therefore test-only — see
|
|
31
|
+
* `deployment-name-fixtures.ts`.
|
|
32
|
+
*/
|
|
33
|
+
export declare const isValidDeploymentName: (name: string) => boolean;
|
|
34
|
+
export declare function resolveDeploymentName(config: {
|
|
35
|
+
deploymentName?: string;
|
|
36
|
+
}, modeDefault: string): string;
|
|
37
|
+
//# sourceMappingURL=deployment-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-name.d.ts","sourceRoot":"","sources":["../../src/operating-mode/deployment-name.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAsBH;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,KAAG,OAI5B,CAAA;AAEzB,wBAAgB,qBAAqB,CACnC,MAAM,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,EACnC,WAAW,EAAE,MAAM,GAClB,MAAM,CAqCR"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single resolution point for `deploymentName`.
|
|
3
|
+
*
|
|
4
|
+
* `deploymentName` namespaces the settings branch
|
|
5
|
+
* (`canopycms-settings-{deploymentName}`) so two CanopyCMS deployments can
|
|
6
|
+
* share one GitHub repo without both resolving to `canopycms-settings-prod`
|
|
7
|
+
* and fighting over the same orphan branch.
|
|
8
|
+
*
|
|
9
|
+
* Precedence (highest wins):
|
|
10
|
+
* 1. `process.env.CANOPYCMS_DEPLOYMENT_NAME` (trimmed; empty string ignored)
|
|
11
|
+
* 2. `config.deploymentName`
|
|
12
|
+
* 3. `modeDefault` (the caller's mode-specific fallback, e.g. 'prod'/'local')
|
|
13
|
+
*
|
|
14
|
+
* Env wins over config DELIBERATELY. The env var is stamped per-stack by
|
|
15
|
+
* infrastructure (CDK's `CanopyCmsServiceProps.deploymentName` ->
|
|
16
|
+
* `CANOPYCMS_DEPLOYMENT_NAME`), so it is the value GUARANTEED TO DIFFER
|
|
17
|
+
* between two deployments sharing a repo. `config.deploymentName` lives in
|
|
18
|
+
* the shared repo's `canopycms.config.ts`, so it is the value GUARANTEED TO
|
|
19
|
+
* BE IDENTICAL across both deployments (both Lambdas run the same checked-out
|
|
20
|
+
* config). If config won instead, an adopter who already wrote
|
|
21
|
+
* `deploymentName` into their shared config would find the CDK
|
|
22
|
+
* `deploymentName` prop silently doing nothing — exactly the two-stacks-one-repo
|
|
23
|
+
* case this feature exists to fix.
|
|
24
|
+
*/
|
|
25
|
+
import { canopyLogWarn } from '../utils/logger.js';
|
|
26
|
+
let warned = false;
|
|
27
|
+
/**
|
|
28
|
+
* Conservative charset for a deployment name. The resolved value is
|
|
29
|
+
* interpolated straight into a git ref (`canopycms-settings-{name}`), and the
|
|
30
|
+
* env var route bypasses the config schema entirely — nothing else validates
|
|
31
|
+
* an infra-stamped value before it becomes a branch name. Rejecting anything
|
|
32
|
+
* outside this set keeps the result a single, well-formed ref component:
|
|
33
|
+
* no `/` (would add a ref hierarchy level and break sanitizeBranchName
|
|
34
|
+
* round-trips), no whitespace, no `..`/`~`/`^`/`:` (git-forbidden), no
|
|
35
|
+
* leading `-` (would parse as a git option).
|
|
36
|
+
*
|
|
37
|
+
* The charset alone is not sufficient: `..`, a trailing `.`, and a `.lock`
|
|
38
|
+
* suffix are all built from allowed characters but are still rejected by
|
|
39
|
+
* git's own ref rules (git-check-ref-format), so they are excluded separately.
|
|
40
|
+
*/
|
|
41
|
+
const VALID_DEPLOYMENT_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
42
|
+
/**
|
|
43
|
+
* Exported so `canopycms-cdk`'s suite can assert that its own synth-time copy
|
|
44
|
+
* of this rule (constructs/cms-service.ts) still agrees with this one. The
|
|
45
|
+
* construct itself must NOT import this: `canopycms-cdk` publishes without a
|
|
46
|
+
* runtime dependency on `canopycms`, so a source-level import would break the
|
|
47
|
+
* published construct. The drift check is therefore test-only — see
|
|
48
|
+
* `deployment-name-fixtures.ts`.
|
|
49
|
+
*/
|
|
50
|
+
export const isValidDeploymentName = (name) => VALID_DEPLOYMENT_NAME.test(name) &&
|
|
51
|
+
!name.includes('..') &&
|
|
52
|
+
!name.endsWith('.') &&
|
|
53
|
+
!name.endsWith('.lock');
|
|
54
|
+
export function resolveDeploymentName(config, modeDefault) {
|
|
55
|
+
const envValue = process.env.CANOPYCMS_DEPLOYMENT_NAME?.trim();
|
|
56
|
+
const configValue = config.deploymentName;
|
|
57
|
+
if (envValue && configValue && envValue !== configValue && !warned) {
|
|
58
|
+
// canopyLogWarn, not console.warn: cms-worker.ts imports this module and
|
|
59
|
+
// resolves through it inside start(), so this line lands in worker.log,
|
|
60
|
+
// where an unprefixed line is folded into the previous CloudWatch event.
|
|
61
|
+
// The mismatch this reports is exactly what an operator would be grepping
|
|
62
|
+
// for. Plain console under Lambda/dev, as everywhere else. See
|
|
63
|
+
// utils/logger.ts. (Missed by the worker-log sweep, which went by directory
|
|
64
|
+
// name and by the modules the finding named, rather than by the worker's
|
|
65
|
+
// real import graph.)
|
|
66
|
+
canopyLogWarn(`CanopyCMS: CANOPYCMS_DEPLOYMENT_NAME ("${envValue}") differs from config.deploymentName ` +
|
|
67
|
+
`("${configValue}") — using the env var (infra-stamped env wins over shared-repo config ` +
|
|
68
|
+
`by design; see resolveDeploymentName's doc comment). Update config.deploymentName to ` +
|
|
69
|
+
`match if this mismatch was unintentional.`);
|
|
70
|
+
warned = true;
|
|
71
|
+
}
|
|
72
|
+
const resolved = envValue || configValue || modeDefault;
|
|
73
|
+
if (!isValidDeploymentName(resolved)) {
|
|
74
|
+
const source = envValue
|
|
75
|
+
? 'CANOPYCMS_DEPLOYMENT_NAME'
|
|
76
|
+
: configValue
|
|
77
|
+
? 'config.deploymentName'
|
|
78
|
+
: 'the mode default';
|
|
79
|
+
throw new Error(`CanopyCMS: invalid deploymentName ${JSON.stringify(resolved)} (from ${source}). ` +
|
|
80
|
+
`It is interpolated into the settings branch name (canopycms-settings-<deploymentName>), ` +
|
|
81
|
+
`so it must start with a letter or digit, contain only letters, digits, '.', '_' or '-', ` +
|
|
82
|
+
`and must not contain '..' or end with '.' or '.lock'.`);
|
|
83
|
+
}
|
|
84
|
+
return resolved;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=deployment-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-name.js","sourceRoot":"","sources":["../../src/operating-mode/deployment-name.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE/C,IAAI,MAAM,GAAG,KAAK,CAAA;AAElB;;;;;;;;;;;;;GAaG;AACH,MAAM,qBAAqB,GAAG,8BAA8B,CAAA;AAE5D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAY,EAAW,EAAE,CAC7D,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;IAChC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IACpB,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;IACnB,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AAEzB,MAAM,UAAU,qBAAqB,CACnC,MAAmC,EACnC,WAAmB;IAEnB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,EAAE,CAAA;IAC9D,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CAAA;IAEzC,IAAI,QAAQ,IAAI,WAAW,IAAI,QAAQ,KAAK,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC;QACnE,yEAAyE;QACzE,wEAAwE;QACxE,yEAAyE;QACzE,0EAA0E;QAC1E,+DAA+D;QAC/D,4EAA4E;QAC5E,yEAAyE;QACzE,sBAAsB;QACtB,aAAa,CACX,0CAA0C,QAAQ,wCAAwC;YACxF,KAAK,WAAW,yEAAyE;YACzF,uFAAuF;YACvF,2CAA2C,CAC9C,CAAA;QACD,MAAM,GAAG,IAAI,CAAA;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,IAAI,WAAW,IAAI,WAAW,CAAA;IACvD,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,QAAQ;YACrB,CAAC,CAAC,2BAA2B;YAC7B,CAAC,CAAC,WAAW;gBACX,CAAC,CAAC,uBAAuB;gBACzB,CAAC,CAAC,kBAAkB,CAAA;QACxB,MAAM,IAAI,KAAK,CACb,qCAAqC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,MAAM,KAAK;YAChF,0FAA0F;YAC1F,0FAA0F;YAC1F,uDAAuD,CAC1D,CAAA;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
* Server code:
|
|
16
16
|
* import { operatingStrategy } from '@/operating-mode'
|
|
17
17
|
* const strategy = operatingStrategy(mode)
|
|
18
|
-
*
|
|
18
|
+
* // contentRoot is REQUIRED: pass config.contentRoot (falling back to 'content'
|
|
19
|
+
* // at the call site), never a bare call — see getContentRoot's doc comment in
|
|
20
|
+
* // types.ts for why a default here would silently disarm a caller.
|
|
21
|
+
* const contentRoot = strategy.getContentRoot(config.contentRoot ?? 'content')
|
|
19
22
|
* const branchesRoot = strategy.getContentBranchesRoot()
|
|
20
23
|
* const branchRoot = strategy.getContentBranchRoot('my-branch')
|
|
21
24
|
* const settingsRoot = strategy.getSettingsRoot()
|
|
@@ -23,6 +26,8 @@
|
|
|
23
26
|
*/
|
|
24
27
|
export { clientOperatingStrategy, clearClientStrategyCache } from './client-safe-strategy';
|
|
25
28
|
export { operatingStrategy, clearStrategyCache } from './client-unsafe-strategy';
|
|
29
|
+
export { resolveDeploymentName, isValidDeploymentName } from './deployment-name';
|
|
30
|
+
export { resolveOperatingMode, SERVER_MODE_ENV_VAR, BROWSER_MODE_ENV_VAR } from './mode-env';
|
|
26
31
|
export type OperatingMode = 'prod' | 'dev';
|
|
27
32
|
export type { ClientSafeStrategy, ClientUnsafeStrategy, ResolveRemoteUrlOptions } from './types';
|
|
28
33
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/operating-mode/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/operating-mode/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AAG1F,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAIhF,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAIhF,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAE5F,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,KAAK,CAAA;AAG1C,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
* Server code:
|
|
16
16
|
* import { operatingStrategy } from '@/operating-mode'
|
|
17
17
|
* const strategy = operatingStrategy(mode)
|
|
18
|
-
*
|
|
18
|
+
* // contentRoot is REQUIRED: pass config.contentRoot (falling back to 'content'
|
|
19
|
+
* // at the call site), never a bare call — see getContentRoot's doc comment in
|
|
20
|
+
* // types.ts for why a default here would silently disarm a caller.
|
|
21
|
+
* const contentRoot = strategy.getContentRoot(config.contentRoot ?? 'content')
|
|
19
22
|
* const branchesRoot = strategy.getContentBranchesRoot()
|
|
20
23
|
* const branchRoot = strategy.getContentBranchRoot('my-branch')
|
|
21
24
|
* const settingsRoot = strategy.getSettingsRoot()
|
|
@@ -25,4 +28,10 @@
|
|
|
25
28
|
export { clientOperatingStrategy, clearClientStrategyCache } from './client-safe-strategy.js';
|
|
26
29
|
// Client-unsafe factory and strategy (server-side only)
|
|
27
30
|
export { operatingStrategy, clearStrategyCache } from './client-unsafe-strategy.js';
|
|
31
|
+
// Single resolution point for deploymentName (env > config > mode default) —
|
|
32
|
+
// server-only (reads process.env), used by the strategies' getSettingsBranchName.
|
|
33
|
+
export { resolveDeploymentName, isValidDeploymentName } from './deployment-name.js';
|
|
34
|
+
// Single resolution point for `mode` (env > config.mode) — isomorphic, applied
|
|
35
|
+
// inside validateCanopyConfig so every config-authoring path gets it.
|
|
36
|
+
export { resolveOperatingMode, SERVER_MODE_ENV_VAR, BROWSER_MODE_ENV_VAR } from './mode-env.js';
|
|
28
37
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/operating-mode/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/operating-mode/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,6DAA6D;AAC7D,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AAE1F,wDAAwD;AACxD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAEhF,6EAA6E;AAC7E,kFAAkF;AAClF,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAEhF,+EAA+E;AAC/E,sEAAsE;AACtE,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single resolution point for the operating `mode`.
|
|
3
|
+
*
|
|
4
|
+
* `mode` is required in `canopycms.config.ts` (SEC-C1) and that file lives in
|
|
5
|
+
* the adopter's repo — the SAME file is loaded by `next dev` locally, by
|
|
6
|
+
* `next build` inside the image builder, and by the deployed Lambda. Those
|
|
7
|
+
* three want different answers, so a literal in the config file cannot be
|
|
8
|
+
* right for all of them:
|
|
9
|
+
*
|
|
10
|
+
* - `next dev` must be `dev` (workspace at `<cwd>/.canopy-dev`).
|
|
11
|
+
* - `next build` must be `dev` too: prod-mode build reads would try to open
|
|
12
|
+
* a branch workspace on EFS that cannot exist in an image builder (see
|
|
13
|
+
* the note in `cli/template-files/Dockerfile.cms.template`).
|
|
14
|
+
* - The deployed Lambda must be `prod`: dev mode resolves the workspace to
|
|
15
|
+
* `<cwd>/.canopy-dev`, and Lambda's filesystem is read-only outside /tmp,
|
|
16
|
+
* so the first write fails with EROFS.
|
|
17
|
+
*
|
|
18
|
+
* Only a value resolved at RUN time can satisfy all three, which is why this
|
|
19
|
+
* is an environment override rather than a flag baked into the generated
|
|
20
|
+
* config file. `CANOPY_MODE` is the name the deployment templates already
|
|
21
|
+
* referred to; before this module existed nothing read it.
|
|
22
|
+
*
|
|
23
|
+
* Precedence (highest wins):
|
|
24
|
+
* 1. the environment value for the current runtime (see `readModeEnv`)
|
|
25
|
+
* 2. `config.mode` (the literal in `canopycms.config.ts`)
|
|
26
|
+
*
|
|
27
|
+
* ## Two variable names, on purpose
|
|
28
|
+
*
|
|
29
|
+
* Server code reads `CANOPY_MODE`, which the CDK construct stamps onto the
|
|
30
|
+
* Lambda (`CanopyCmsService` sets `CANOPY_MODE=prod`). It is deliberately NOT
|
|
31
|
+
* set during `next build`, so build-time content reads stay in dev mode.
|
|
32
|
+
*
|
|
33
|
+
* Browser code cannot read a runtime environment at all — the editor page
|
|
34
|
+
* imports `canopycms.config.ts` directly (`config.client()`), so the browser's
|
|
35
|
+
* copy of `mode` is whatever was inlined when the bundle was built. Next.js
|
|
36
|
+
* only inlines `NEXT_PUBLIC_*`, so the browser reads
|
|
37
|
+
* `NEXT_PUBLIC_CANOPY_MODE`, which the generated CDK stack passes as a Docker
|
|
38
|
+
* build arg. Both names must be spelled as literal `process.env.X` member
|
|
39
|
+
* expressions here or the bundler cannot substitute them.
|
|
40
|
+
*
|
|
41
|
+
* An unrecognized value throws rather than falling back. Falling back would
|
|
42
|
+
* turn a typo (`CANOPY_MODE=production`) into a silent dev-mode deployment
|
|
43
|
+
* running header-trusting dev auth semantics — the exact failure SEC-C1 made
|
|
44
|
+
* `mode` required to prevent.
|
|
45
|
+
*/
|
|
46
|
+
import type { OperatingMode } from './types';
|
|
47
|
+
export declare const SERVER_MODE_ENV_VAR = "CANOPY_MODE";
|
|
48
|
+
export declare const BROWSER_MODE_ENV_VAR = "NEXT_PUBLIC_CANOPY_MODE";
|
|
49
|
+
/** Reset the once-per-process warning latch. Test-only. */
|
|
50
|
+
export declare function resetModeWarning(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Resolve the effective operating mode from the environment and the config
|
|
53
|
+
* literal. Called from `validateCanopyConfig`, the one point every documented
|
|
54
|
+
* config-authoring path (`defineCanopyConfig`, `composeCanopyConfig`) funnels
|
|
55
|
+
* through.
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveOperatingMode(configMode: OperatingMode): OperatingMode;
|
|
58
|
+
//# sourceMappingURL=mode-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode-env.d.ts","sourceRoot":"","sources":["../../src/operating-mode/mode-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,eAAO,MAAM,mBAAmB,gBAAgB,CAAA;AAChD,eAAO,MAAM,oBAAoB,4BAA4B,CAAA;AAI7D,2DAA2D;AAC3D,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAkBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,aAAa,GAAG,aAAa,CA0B7E"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single resolution point for the operating `mode`.
|
|
3
|
+
*
|
|
4
|
+
* `mode` is required in `canopycms.config.ts` (SEC-C1) and that file lives in
|
|
5
|
+
* the adopter's repo — the SAME file is loaded by `next dev` locally, by
|
|
6
|
+
* `next build` inside the image builder, and by the deployed Lambda. Those
|
|
7
|
+
* three want different answers, so a literal in the config file cannot be
|
|
8
|
+
* right for all of them:
|
|
9
|
+
*
|
|
10
|
+
* - `next dev` must be `dev` (workspace at `<cwd>/.canopy-dev`).
|
|
11
|
+
* - `next build` must be `dev` too: prod-mode build reads would try to open
|
|
12
|
+
* a branch workspace on EFS that cannot exist in an image builder (see
|
|
13
|
+
* the note in `cli/template-files/Dockerfile.cms.template`).
|
|
14
|
+
* - The deployed Lambda must be `prod`: dev mode resolves the workspace to
|
|
15
|
+
* `<cwd>/.canopy-dev`, and Lambda's filesystem is read-only outside /tmp,
|
|
16
|
+
* so the first write fails with EROFS.
|
|
17
|
+
*
|
|
18
|
+
* Only a value resolved at RUN time can satisfy all three, which is why this
|
|
19
|
+
* is an environment override rather than a flag baked into the generated
|
|
20
|
+
* config file. `CANOPY_MODE` is the name the deployment templates already
|
|
21
|
+
* referred to; before this module existed nothing read it.
|
|
22
|
+
*
|
|
23
|
+
* Precedence (highest wins):
|
|
24
|
+
* 1. the environment value for the current runtime (see `readModeEnv`)
|
|
25
|
+
* 2. `config.mode` (the literal in `canopycms.config.ts`)
|
|
26
|
+
*
|
|
27
|
+
* ## Two variable names, on purpose
|
|
28
|
+
*
|
|
29
|
+
* Server code reads `CANOPY_MODE`, which the CDK construct stamps onto the
|
|
30
|
+
* Lambda (`CanopyCmsService` sets `CANOPY_MODE=prod`). It is deliberately NOT
|
|
31
|
+
* set during `next build`, so build-time content reads stay in dev mode.
|
|
32
|
+
*
|
|
33
|
+
* Browser code cannot read a runtime environment at all — the editor page
|
|
34
|
+
* imports `canopycms.config.ts` directly (`config.client()`), so the browser's
|
|
35
|
+
* copy of `mode` is whatever was inlined when the bundle was built. Next.js
|
|
36
|
+
* only inlines `NEXT_PUBLIC_*`, so the browser reads
|
|
37
|
+
* `NEXT_PUBLIC_CANOPY_MODE`, which the generated CDK stack passes as a Docker
|
|
38
|
+
* build arg. Both names must be spelled as literal `process.env.X` member
|
|
39
|
+
* expressions here or the bundler cannot substitute them.
|
|
40
|
+
*
|
|
41
|
+
* An unrecognized value throws rather than falling back. Falling back would
|
|
42
|
+
* turn a typo (`CANOPY_MODE=production`) into a silent dev-mode deployment
|
|
43
|
+
* running header-trusting dev auth semantics — the exact failure SEC-C1 made
|
|
44
|
+
* `mode` required to prevent.
|
|
45
|
+
*/
|
|
46
|
+
import { canopyLogWarn } from '../utils/logger.js';
|
|
47
|
+
export const SERVER_MODE_ENV_VAR = 'CANOPY_MODE';
|
|
48
|
+
export const BROWSER_MODE_ENV_VAR = 'NEXT_PUBLIC_CANOPY_MODE';
|
|
49
|
+
let warned = false;
|
|
50
|
+
/** Reset the once-per-process warning latch. Test-only. */
|
|
51
|
+
export function resetModeWarning() {
|
|
52
|
+
warned = false;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The environment value for the current runtime, or undefined when unset.
|
|
56
|
+
*
|
|
57
|
+
* Guarded with `typeof process` because a non-Next bundler may leave no
|
|
58
|
+
* `process` shim in the browser at all; the member expressions themselves stay
|
|
59
|
+
* literal so Next's DefinePlugin substitution still applies.
|
|
60
|
+
*/
|
|
61
|
+
function readModeEnv() {
|
|
62
|
+
if (typeof process === 'undefined' || typeof process.env === 'undefined')
|
|
63
|
+
return undefined;
|
|
64
|
+
const inBrowser = typeof window !== 'undefined';
|
|
65
|
+
const name = inBrowser ? BROWSER_MODE_ENV_VAR : SERVER_MODE_ENV_VAR;
|
|
66
|
+
const raw = inBrowser ? process.env.NEXT_PUBLIC_CANOPY_MODE : process.env.CANOPY_MODE;
|
|
67
|
+
const value = raw?.trim();
|
|
68
|
+
return value ? { name, value } : undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolve the effective operating mode from the environment and the config
|
|
72
|
+
* literal. Called from `validateCanopyConfig`, the one point every documented
|
|
73
|
+
* config-authoring path (`defineCanopyConfig`, `composeCanopyConfig`) funnels
|
|
74
|
+
* through.
|
|
75
|
+
*/
|
|
76
|
+
export function resolveOperatingMode(configMode) {
|
|
77
|
+
const env = readModeEnv();
|
|
78
|
+
if (!env)
|
|
79
|
+
return configMode;
|
|
80
|
+
if (env.value !== 'prod' && env.value !== 'dev') {
|
|
81
|
+
throw new Error(`CanopyCMS: invalid ${env.name}=${JSON.stringify(env.value)}. ` +
|
|
82
|
+
`It must be exactly "prod" or "dev". Refusing to fall back to the configured mode ` +
|
|
83
|
+
`(${JSON.stringify(configMode)}): a typo here would silently deploy dev auth semantics.`);
|
|
84
|
+
}
|
|
85
|
+
if (env.value !== configMode && !warned) {
|
|
86
|
+
// canopyLogWarn, not console.warn: shared modules can run inside the
|
|
87
|
+
// worker daemon, where an unprefixed line is folded into the previous
|
|
88
|
+
// CloudWatch event (see utils/logger.ts).
|
|
89
|
+
canopyLogWarn(`CanopyCMS: ${env.name}="${env.value}" overrides config.mode="${configMode}". ` +
|
|
90
|
+
`The environment wins by design — it is the per-deployment value, while ` +
|
|
91
|
+
`canopycms.config.ts is shared by local dev, the image build and the deployment. ` +
|
|
92
|
+
`See operating-mode/mode-env.ts.`);
|
|
93
|
+
warned = true;
|
|
94
|
+
}
|
|
95
|
+
return env.value;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=mode-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode-env.js","sourceRoot":"","sources":["../../src/operating-mode/mode-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAG/C,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAA;AAChD,MAAM,CAAC,MAAM,oBAAoB,GAAG,yBAAyB,CAAA;AAE7D,IAAI,MAAM,GAAG,KAAK,CAAA;AAElB,2DAA2D;AAC3D,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,KAAK,CAAA;AAChB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW;IAClB,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,WAAW;QAAE,OAAO,SAAS,CAAA;IAC1F,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAA;IAC/C,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,mBAAmB,CAAA;IACnE,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;IACrF,MAAM,KAAK,GAAG,GAAG,EAAE,IAAI,EAAE,CAAA;IACzB,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAyB;IAC5D,MAAM,GAAG,GAAG,WAAW,EAAE,CAAA;IACzB,IAAI,CAAC,GAAG;QAAE,OAAO,UAAU,CAAA;IAE3B,IAAI,GAAG,CAAC,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,sBAAsB,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI;YAC7D,mFAAmF;YACnF,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,0DAA0D,CAC3F,CAAA;IACH,CAAC;IAED,IAAI,GAAG,CAAC,KAAK,KAAK,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;QACxC,qEAAqE;QACrE,sEAAsE;QACtE,0CAA0C;QAC1C,aAAa,CACX,cAAc,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,KAAK,4BAA4B,UAAU,KAAK;YAC7E,yEAAyE;YACzE,kFAAkF;YAClF,iCAAiC,CACpC,CAAA;QACD,MAAM,GAAG,IAAI,CAAA;IACf,CAAC;IAED,OAAO,GAAG,CAAC,KAAK,CAAA;AAClB,CAAC"}
|
|
@@ -79,10 +79,20 @@ export interface ClientUnsafeStrategy extends ClientSafeStrategy {
|
|
|
79
79
|
getWorkspaceRoot(sourceRoot?: string): string;
|
|
80
80
|
/**
|
|
81
81
|
* Get the content directory path (at project/workspace root).
|
|
82
|
-
* - dev: {cwd}/
|
|
83
|
-
* - prod (in workspaces): {
|
|
82
|
+
* - dev: {sourceRoot ?? cwd}/{contentRoot}
|
|
83
|
+
* - prod (in workspaces): {sourceRoot ?? cwd}/{contentRoot}
|
|
84
|
+
*
|
|
85
|
+
* `contentRoot` is REQUIRED and must be the caller's already-resolved
|
|
86
|
+
* `config.contentRoot` (falling back to 'content' at the call site, not here).
|
|
87
|
+
* A default here is deliberately not provided: this method used to hardcode
|
|
88
|
+
* the literal 'content', which silently disarmed callers configured with a
|
|
89
|
+
* non-default contentRoot (e.g. dev-content-watcher.ts's divergence watcher
|
|
90
|
+
* resolved a content directory that never existed, hit its existsSync guard,
|
|
91
|
+
* and permanently no-op'd — with no error, since a missing directory looks
|
|
92
|
+
* like "nothing to watch yet"). Making the parameter required means a future
|
|
93
|
+
* caller cannot silently reintroduce that bug by omitting it.
|
|
84
94
|
*/
|
|
85
|
-
getContentRoot(sourceRoot?: string): string;
|
|
95
|
+
getContentRoot(contentRoot: string, sourceRoot?: string): string;
|
|
86
96
|
/**
|
|
87
97
|
* Get the parent directory of all content branch workspaces (contains branches.json and branch directories).
|
|
88
98
|
* - dev: {cwd}/.canopy-dev/content-branches
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/operating-mode/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,IAAI,EAAE,EAAE,MAAM,GAAG,CAAA;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAG7C,MAAM,MAAM,aAAa,GAAG,EAAE,CAAA;AAE9B;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,aAAa,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,mBAAmB,EAAE,OAAO,CAAA;IAC5B,oEAAoE;IACpE,iBAAiB,EAAE,MAAM,CAAA;IACzB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAM5B,4DAA4D;IAC5D,iBAAiB,IAAI,OAAO,CAAA;IAE5B,yCAAyC;IACzC,mBAAmB,IAAI,OAAO,CAAA;IAE9B,0DAA0D;IAC1D,gBAAgB,IAAI,OAAO,CAAA;IAE3B,kDAAkD;IAClD,oBAAoB,IAAI,OAAO,CAAA;IAM/B,2FAA2F;IAC3F,sBAAsB,IAAI,MAAM,CAAA;IAEhC,4EAA4E;IAC5E,iBAAiB,IAAI,MAAM,CAAA;IAE3B,sDAAsD;IACtD,YAAY,IAAI,OAAO,CAAA;IAEvB,qDAAqD;IACrD,UAAU,IAAI,OAAO,CAAA;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAK9D;;;;;OAKG;IACH,gBAAgB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAE7C
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/operating-mode/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,4 +17,42 @@ import type { SanitizedBranchName } from './types';
|
|
|
17
17
|
* - Trims leading/trailing dots
|
|
18
18
|
*/
|
|
19
19
|
export declare function sanitizeBranchName(branchName: string): SanitizedBranchName;
|
|
20
|
+
/**
|
|
21
|
+
* Prefix reserved for CanopyCMS settings branches (`canopycms-settings-{name}`,
|
|
22
|
+
* see operating-mode/client-unsafe-strategy.ts's `getSettingsBranchName` and
|
|
23
|
+
* operating-mode/deployment-name.ts's `resolveDeploymentName`). Exported from
|
|
24
|
+
* this dependency-free module -- not constructed ad hoc at each call site --
|
|
25
|
+
* so every consumer that needs to recognize the settings-branch namespace
|
|
26
|
+
* agrees on the exact string: worker/cms-worker.ts's `pushSettingsBranches`
|
|
27
|
+
* (never push a `canopycms-settings-*` branch this deployment doesn't own),
|
|
28
|
+
* and api/branch.ts's `createBranchHandler` (reject a user-requested branch
|
|
29
|
+
* whose SANITIZED name falls in this namespace).
|
|
30
|
+
*
|
|
31
|
+
* Two CanopyCMS deployments can share one GitHub repo, each with its own
|
|
32
|
+
* settings branch under this prefix (`canopycms-settings-prod` vs
|
|
33
|
+
* `canopycms-settings-staging`, say). A content-branch request that lands on
|
|
34
|
+
* ANOTHER deployment's settings branch name would silently corrupt that
|
|
35
|
+
* deployment's permissions/groups the next time its worker treats the ref as
|
|
36
|
+
* an orphan settings branch -- so the whole prefix is reserved for branch
|
|
37
|
+
* creation, not just this deployment's own settings branch name.
|
|
38
|
+
*/
|
|
39
|
+
export declare const RESERVED_SETTINGS_BRANCH_PREFIX = "canopycms-settings-";
|
|
40
|
+
/**
|
|
41
|
+
* Branch names that collide with a static top-level API route namespace.
|
|
42
|
+
*
|
|
43
|
+
* http/router.ts's `compareSpecificity` ranks a literal pattern segment above a
|
|
44
|
+
* `:param`, so a branch named e.g. `admin` has its `/:branch/...` routes
|
|
45
|
+
* shadowed by the static `/admin/...` ones. The failure is a *partial* one,
|
|
46
|
+
* which is what makes it confusing: bare `GET /admin` still reaches the branch
|
|
47
|
+
* handler (there is no single-segment static `/admin` route), so the branch
|
|
48
|
+
* looks half-alive while every nested route 404s or 403s.
|
|
49
|
+
*
|
|
50
|
+
* Lives in this dependency-free module for the same reason as
|
|
51
|
+
* {@link RESERVED_SETTINGS_BRANCH_PREFIX}: api/validators.ts is imported *by*
|
|
52
|
+
* the route modules, so nothing on the validation side can import the router to
|
|
53
|
+
* derive this at runtime without a cycle. http/router.test.ts derives the same
|
|
54
|
+
* set from the live route table and asserts it equals this constant, so adding
|
|
55
|
+
* a new top-level namespace fails that test until this list is updated.
|
|
56
|
+
*/
|
|
57
|
+
export declare const RESERVED_ROUTE_BRANCH_NAMES: readonly string[];
|
|
20
58
|
//# sourceMappingURL=branch-name.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch-name.d.ts","sourceRoot":"","sources":["../../src/paths/branch-name.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAElD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB,CAK1E"}
|
|
1
|
+
{"version":3,"file":"branch-name.d.ts","sourceRoot":"","sources":["../../src/paths/branch-name.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAElD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB,CAK1E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,+BAA+B,wBAAwB,CAAA;AAEpE;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAQxD,CAAA"}
|
|
@@ -21,4 +21,50 @@ export function sanitizeBranchName(branchName) {
|
|
|
21
21
|
const trimmedDots = squashed.replace(/^\.+/, '').replace(/(?<!\.)\.+$/, '');
|
|
22
22
|
return (trimmedDots || 'branch');
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Prefix reserved for CanopyCMS settings branches (`canopycms-settings-{name}`,
|
|
26
|
+
* see operating-mode/client-unsafe-strategy.ts's `getSettingsBranchName` and
|
|
27
|
+
* operating-mode/deployment-name.ts's `resolveDeploymentName`). Exported from
|
|
28
|
+
* this dependency-free module -- not constructed ad hoc at each call site --
|
|
29
|
+
* so every consumer that needs to recognize the settings-branch namespace
|
|
30
|
+
* agrees on the exact string: worker/cms-worker.ts's `pushSettingsBranches`
|
|
31
|
+
* (never push a `canopycms-settings-*` branch this deployment doesn't own),
|
|
32
|
+
* and api/branch.ts's `createBranchHandler` (reject a user-requested branch
|
|
33
|
+
* whose SANITIZED name falls in this namespace).
|
|
34
|
+
*
|
|
35
|
+
* Two CanopyCMS deployments can share one GitHub repo, each with its own
|
|
36
|
+
* settings branch under this prefix (`canopycms-settings-prod` vs
|
|
37
|
+
* `canopycms-settings-staging`, say). A content-branch request that lands on
|
|
38
|
+
* ANOTHER deployment's settings branch name would silently corrupt that
|
|
39
|
+
* deployment's permissions/groups the next time its worker treats the ref as
|
|
40
|
+
* an orphan settings branch -- so the whole prefix is reserved for branch
|
|
41
|
+
* creation, not just this deployment's own settings branch name.
|
|
42
|
+
*/
|
|
43
|
+
export const RESERVED_SETTINGS_BRANCH_PREFIX = 'canopycms-settings-';
|
|
44
|
+
/**
|
|
45
|
+
* Branch names that collide with a static top-level API route namespace.
|
|
46
|
+
*
|
|
47
|
+
* http/router.ts's `compareSpecificity` ranks a literal pattern segment above a
|
|
48
|
+
* `:param`, so a branch named e.g. `admin` has its `/:branch/...` routes
|
|
49
|
+
* shadowed by the static `/admin/...` ones. The failure is a *partial* one,
|
|
50
|
+
* which is what makes it confusing: bare `GET /admin` still reaches the branch
|
|
51
|
+
* handler (there is no single-segment static `/admin` route), so the branch
|
|
52
|
+
* looks half-alive while every nested route 404s or 403s.
|
|
53
|
+
*
|
|
54
|
+
* Lives in this dependency-free module for the same reason as
|
|
55
|
+
* {@link RESERVED_SETTINGS_BRANCH_PREFIX}: api/validators.ts is imported *by*
|
|
56
|
+
* the route modules, so nothing on the validation side can import the router to
|
|
57
|
+
* derive this at runtime without a cycle. http/router.test.ts derives the same
|
|
58
|
+
* set from the live route table and asserts it equals this constant, so adding
|
|
59
|
+
* a new top-level namespace fails that test until this list is updated.
|
|
60
|
+
*/
|
|
61
|
+
export const RESERVED_ROUTE_BRANCH_NAMES = [
|
|
62
|
+
'admin',
|
|
63
|
+
'assets',
|
|
64
|
+
'branches',
|
|
65
|
+
'groups',
|
|
66
|
+
'permissions',
|
|
67
|
+
'users',
|
|
68
|
+
'whoami',
|
|
69
|
+
];
|
|
24
70
|
//# sourceMappingURL=branch-name.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch-name.js","sourceRoot":"","sources":["../../src/paths/branch-name.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB;IACnD,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;IAC5D,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAC7C,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;IAC3E,OAAO,CAAC,WAAW,IAAI,QAAQ,CAAwB,CAAA;AACzD,CAAC"}
|
|
1
|
+
{"version":3,"file":"branch-name.js","sourceRoot":"","sources":["../../src/paths/branch-name.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB;IACnD,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;IAC5D,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAC7C,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;IAC3E,OAAO,CAAC,WAAW,IAAI,QAAQ,CAAwB,CAAA;AACzD,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,qBAAqB,CAAA;AAEpE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAsB;IAC5D,OAAO;IACP,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,aAAa;IACb,OAAO;IACP,QAAQ;CACT,CAAA"}
|
package/dist/paths/index.d.ts
CHANGED
|
@@ -19,5 +19,5 @@ export { validateAndNormalizePath } from './normalize-server';
|
|
|
19
19
|
export { validateContentPath, isValidCollectionPath, sanitizeForPath, hasEmbeddedContentId, looksLikePhysicalPath, looksLikeLogicalPath, parseLogicalPath, parsePhysicalPath, isValidContentId, parseContentId, parseBranchName, parseSlug, } from './validation';
|
|
20
20
|
export { resolveLogicalPath } from './resolve';
|
|
21
21
|
export { resolveBranchPath, ensureBranchRoot, getDefaultBranchBase, resolveBranchPaths, BranchPathError, type BranchPathOptions, type BranchPathResult, } from './branch';
|
|
22
|
-
export { sanitizeBranchName } from './branch-name';
|
|
22
|
+
export { sanitizeBranchName, RESERVED_SETTINGS_BRANCH_PREFIX, RESERVED_ROUTE_BRANCH_NAMES, } from './branch-name';
|
|
23
23
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,YAAY,EACV,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,IAAI,EACJ,oBAAoB,GACrB,MAAM,SAAS,CAAA;AAGhB,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,WAAW,GACZ,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAG7D,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EAEf,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAEhB,cAAc,EACd,eAAe,EACf,SAAS,GACV,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAG9C,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAA;AAGjB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,YAAY,EACV,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,IAAI,EACJ,oBAAoB,GACrB,MAAM,SAAS,CAAA;AAGhB,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,WAAW,GACZ,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAG7D,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EAEf,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAEhB,cAAc,EACd,eAAe,EACf,SAAS,GACV,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAG9C,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAA;AAGjB,OAAO,EACL,kBAAkB,EAClB,+BAA+B,EAC/B,2BAA2B,GAC5B,MAAM,eAAe,CAAA"}
|
package/dist/paths/index.js
CHANGED
|
@@ -29,5 +29,5 @@ export { resolveLogicalPath } from './resolve.js';
|
|
|
29
29
|
export { resolveBranchPath, ensureBranchRoot, getDefaultBranchBase, resolveBranchPaths, BranchPathError, } from './branch.js';
|
|
30
30
|
// From the dependency-free module (NOT ./branch, which imports node:fs) so
|
|
31
31
|
// client-reachable importers of 'canopycms/src/paths' stay browser-safe.
|
|
32
|
-
export { sanitizeBranchName } from './branch-name.js';
|
|
32
|
+
export { sanitizeBranchName, RESERVED_SETTINGS_BRANCH_PREFIX, RESERVED_ROUTE_BRANCH_NAMES, } from './branch-name.js';
|
|
33
33
|
//# sourceMappingURL=index.js.map
|
package/dist/paths/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH,wCAAwC;AACxC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,WAAW,GACZ,MAAM,aAAa,CAAA;AAEpB,sEAAsE;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAE7D,uBAAuB;AACvB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,eAAe;AACf,kCAAkC;AAClC,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB;AAChB,sCAAsC;AACtC,cAAc,EACd,eAAe,EACf,SAAS,GACV,MAAM,cAAc,CAAA;AAErB,4BAA4B;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAE9C,wBAAwB;AACxB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,GAGhB,MAAM,UAAU,CAAA;AACjB,2EAA2E;AAC3E,yEAAyE;AACzE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH,wCAAwC;AACxC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,WAAW,GACZ,MAAM,aAAa,CAAA;AAEpB,sEAAsE;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAE7D,uBAAuB;AACvB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,eAAe;AACf,kCAAkC;AAClC,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB;AAChB,sCAAsC;AACtC,cAAc,EACd,eAAe,EACf,SAAS,GACV,MAAM,cAAc,CAAA;AAErB,4BAA4B;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAE9C,wBAAwB;AACxB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,GAGhB,MAAM,UAAU,CAAA;AACjB,2EAA2E;AAC3E,yEAAyE;AACzE,OAAO,EACL,kBAAkB,EAClB,+BAA+B,EAC/B,2BAA2B,GAC5B,MAAM,eAAe,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ContentStore } from './content-store';
|
|
2
2
|
import type { ContentIdIndex } from './content-id-index';
|
|
3
|
-
import type { LogicalPath, Slug } from './paths';
|
|
3
|
+
import type { LogicalPath, PhysicalPath, Slug } from './paths';
|
|
4
4
|
export interface ResolvedReference {
|
|
5
5
|
id: string;
|
|
6
6
|
exists: boolean;
|
|
@@ -44,8 +44,12 @@ export declare class ReferenceResolver {
|
|
|
44
44
|
* @param displayField - Field to use for option labels (default: 'title')
|
|
45
45
|
* @param search - Optional search string to filter options
|
|
46
46
|
* @param entryTypes - Optional entry type names to filter by (e.g., ['partner'])
|
|
47
|
+
* @param canAccess - Optional permission predicate, called with each candidate's
|
|
48
|
+
* relative path before it is read. Returning false skips the entry entirely --
|
|
49
|
+
* no file I/O, no label, no option -- so a caller who can't read a path never
|
|
50
|
+
* triggers a read for content they won't be allowed to see anyway.
|
|
47
51
|
*/
|
|
48
|
-
loadReferenceOptions(collections?: LogicalPath[], displayField?: string, search?: string, entryTypes?: string[]): Promise<ReferenceOption[]>;
|
|
52
|
+
loadReferenceOptions(collections?: LogicalPath[], displayField?: string, search?: string, entryTypes?: string[], canAccess?: (relativePath: PhysicalPath) => boolean): Promise<ReferenceOption[]>;
|
|
49
53
|
/**
|
|
50
54
|
* Resolve multiple IDs at once.
|
|
51
55
|
* Useful for displaying lists of referenced items.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reference-resolver.d.ts","sourceRoot":"","sources":["../src/reference-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,oBAAoB,CAAA;AAEpE,OAAO,KAAK,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"reference-resolver.d.ts","sourceRoot":"","sources":["../src/reference-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,oBAAoB,CAAA;AAEpE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE9D,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,OAAO,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,WAAW,CAAA;IACxB,IAAI,CAAC,EAAE,IAAI,CAAA;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;GAQG;AACH,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;gBADP,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,cAAc;IAGjC;;;;;;OAMG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,SAAU,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAgCpF;;;;;;;;;;;;;;OAcG;IACG,oBAAoB,CACxB,WAAW,CAAC,EAAE,WAAW,EAAE,EAC3B,YAAY,SAAU,EACtB,MAAM,CAAC,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,OAAO,GAClD,OAAO,CAAC,eAAe,EAAE,CAAC;IAuE7B;;;OAGG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,YAAY,SAAU,GAAG,OAAO,CAAC,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,CAAC;CAGhG"}
|
|
@@ -60,8 +60,12 @@ export class ReferenceResolver {
|
|
|
60
60
|
* @param displayField - Field to use for option labels (default: 'title')
|
|
61
61
|
* @param search - Optional search string to filter options
|
|
62
62
|
* @param entryTypes - Optional entry type names to filter by (e.g., ['partner'])
|
|
63
|
+
* @param canAccess - Optional permission predicate, called with each candidate's
|
|
64
|
+
* relative path before it is read. Returning false skips the entry entirely --
|
|
65
|
+
* no file I/O, no label, no option -- so a caller who can't read a path never
|
|
66
|
+
* triggers a read for content they won't be allowed to see anyway.
|
|
63
67
|
*/
|
|
64
|
-
async loadReferenceOptions(collections, displayField = 'title', search, entryTypes) {
|
|
68
|
+
async loadReferenceOptions(collections, displayField = 'title', search, entryTypes, canAccess) {
|
|
65
69
|
const options = [];
|
|
66
70
|
let candidates;
|
|
67
71
|
if (collections && collections.length > 0) {
|
|
@@ -86,6 +90,9 @@ export class ReferenceResolver {
|
|
|
86
90
|
for (const location of candidates) {
|
|
87
91
|
if (!location.collection || !location.slug)
|
|
88
92
|
continue;
|
|
93
|
+
// Skip denied paths before any file I/O.
|
|
94
|
+
if (canAccess && !canAccess(location.relativePath))
|
|
95
|
+
continue;
|
|
89
96
|
const id = this.idIndex.findByPath(location.relativePath);
|
|
90
97
|
if (!id)
|
|
91
98
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reference-resolver.js","sourceRoot":"","sources":["../src/reference-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,WAAW,CAAA;AAIhC,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAA;AAiB1F;;;;;;;;GAQG;AACH,MAAM,OAAO,iBAAiB;IAC5B,YACU,KAAmB,EACnB,OAAuB;QADvB,UAAK,GAAL,KAAK,CAAc;QACnB,YAAO,GAAP,OAAO,CAAgB;IAC9B,CAAC;IAEJ;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,CAAC,EAAU,EAAE,YAAY,GAAG,OAAO;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;QAE1C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3C,OAAO;gBACL,EAAE;gBACF,MAAM,EAAE,KAAK;gBACb,YAAY,EAAE,EAAE,EAAE,oCAAoC;aACvD,CAAA;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAW,EAAE,QAAQ,CAAC,IAAK,CAAC,CAAA;YACvE,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAA;YAEtF,OAAO;gBACL,EAAE;gBACF,MAAM,EAAE,IAAI;gBACZ,YAAY;gBACZ,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,IAAI,EAAE,QAAQ,CAAC,IAAI;aACpB,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;YAC5D,OAAO;gBACL,EAAE;gBACF,MAAM,EAAE,KAAK;gBACb,YAAY,EAAE,EAAE;aACjB,CAAA;QACH,CAAC;IACH,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"reference-resolver.js","sourceRoot":"","sources":["../src/reference-resolver.ts"],"names":[],"mappings":"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"}
|