canopycms 0.0.61-int.75 → 0.0.61
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/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 +252 -13
- package/dist/api/branch.js.map +1 -1
- package/dist/api/content.d.ts.map +1 -1
- package/dist/api/content.js +12 -4
- package/dist/api/content.js.map +1 -1
- package/dist/api/entries.d.ts.map +1 -1
- package/dist/api/entries.js +11 -9
- 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.map +1 -1
- package/dist/api/schema.js +3 -2
- 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 +1 -10
- 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-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 +1442 -828
- package/dist/cli/generate-ai-content.js +404 -136
- package/dist/cli/init.d.ts +8 -2
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +440 -151
- 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 +11 -6
- 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 +124 -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/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/validation.d.ts +9 -0
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +22 -12
- package/dist/config/validation.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 +11 -0
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +2 -1
- 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 +43 -9
- package/dist/editor/BranchManager.js.map +1 -1
- package/dist/editor/CanopyEditor.d.ts.map +1 -1
- package/dist/editor/CanopyEditor.js +2 -2
- package/dist/editor/CanopyEditor.js.map +1 -1
- package/dist/editor/Editor.d.ts.map +1 -1
- package/dist/editor/Editor.js +110 -48
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/admin/SystemHealthPanel.d.ts.map +1 -1
- package/dist/editor/admin/SystemHealthPanel.js +9 -8
- 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.map +1 -1
- package/dist/editor/components/EntryCreateModal.js +21 -6
- 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/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/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 +68 -32
- 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.map +1 -1
- package/dist/editor/hooks/useDraftManager.js +32 -18
- 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 +8 -15
- package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
- package/dist/editor/hooks/useEntryManager.js +259 -117
- 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/git-manager.d.ts +126 -9
- package/dist/git-manager.d.ts.map +1 -1
- package/dist/git-manager.js +251 -27
- 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 +8 -2
- package/dist/http/handler.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.d.ts +28 -0
- package/dist/operating-mode/deployment-name.d.ts.map +1 -0
- package/dist/operating-mode/deployment-name.js +78 -0
- package/dist/operating-mode/deployment-name.js.map +1 -0
- package/dist/operating-mode/index.d.ts +5 -1
- package/dist/operating-mode/index.d.ts.map +1 -1
- package/dist/operating-mode/index.js +7 -1
- package/dist/operating-mode/index.js.map +1 -1
- 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/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 +11 -2
- package/dist/schema/schema-store.d.ts.map +1 -1
- package/dist/schema/schema-store.js +23 -11
- package/dist/schema/schema-store.js.map +1 -1
- package/dist/settings-workspace.d.ts +0 -15
- package/dist/settings-workspace.d.ts.map +1 -1
- package/dist/settings-workspace.js +97 -1
- package/dist/settings-workspace.js.map +1 -1
- package/dist/types.d.ts +63 -2
- package/dist/types.d.ts.map +1 -1
- 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/git.d.ts +38 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +69 -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/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/worker/cms-worker.d.ts +232 -3
- package/dist/worker/cms-worker.d.ts.map +1 -1
- package/dist/worker/cms-worker.js +856 -87
- 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 +3 -1
package/dist/utils/git.d.ts
CHANGED
|
@@ -18,6 +18,44 @@ import type { OperatingMode } from '../operating-mode';
|
|
|
18
18
|
* `@`-required heuristic for scp-like syntax.
|
|
19
19
|
*/
|
|
20
20
|
export declare function isNetworkRemoteUrl(url: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Whether a git push failure message is git's non-fast-forward rejection --
|
|
23
|
+
* the remote has diverged (moved ahead with commits this side never fetched),
|
|
24
|
+
* so retrying the IDENTICAL push can never succeed. In CanopyCMS this is the
|
|
25
|
+
* signature of two CanopyCMS deployments sharing one GitHub repo and picking
|
|
26
|
+
* the same content-branch name, or someone pushing directly to GitHub.
|
|
27
|
+
*
|
|
28
|
+
* Deliberately narrow: ordinary transient push failures -- network drops,
|
|
29
|
+
* auth/permission denial, lock contention -- must keep retrying with backoff
|
|
30
|
+
* (see worker/cms-worker.ts's `isPermanentTaskFailure`, which treats git
|
|
31
|
+
* failures as transient precisely so those cases still get retried). Only
|
|
32
|
+
* this specific, structurally-unretryable shape should fail fast (worker) or
|
|
33
|
+
* return 409 (API) instead.
|
|
34
|
+
*
|
|
35
|
+
* Matches git's literal (English) rejection text, which is gettext-
|
|
36
|
+
* translated -- callers MUST run the underlying git command with a
|
|
37
|
+
* locale-pinning env (see `gitChildEnv` in `../git-manager.ts`) or an ambient
|
|
38
|
+
* LANG/LC_ALL could silently turn this into a permanent no-op.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isNonFastForwardRejection(message: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Whether a git push failure message is a refused `--force-with-lease` --
|
|
43
|
+
* the remote ref is NOT at the commit the pusher expected, so the forced
|
|
44
|
+
* update was declined and nothing was overwritten.
|
|
45
|
+
*
|
|
46
|
+
* A SEPARATE predicate from `isNonFastForwardRejection` because git's output
|
|
47
|
+
* for the two is disjoint: a refused lease prints
|
|
48
|
+
* ` ! [rejected] branch -> branch (stale info)` and, unlike an
|
|
49
|
+
* ordinary rejection, emits NEITHER `non-fast-forward`/`fetch first` NOR the
|
|
50
|
+
* `Updates were rejected because` hint. Without this predicate every lease
|
|
51
|
+
* refusal would be classified transient and retried -- three identical,
|
|
52
|
+
* guaranteed-to-fail force attempts -- instead of surfacing as the permanent,
|
|
53
|
+
* human-actionable state it is.
|
|
54
|
+
*
|
|
55
|
+
* Same locale caveat as above: the reason text is gettext-translated, so
|
|
56
|
+
* callers MUST pin the locale (`gitChildEnv`/`gitNetworkChildEnv`).
|
|
57
|
+
*/
|
|
58
|
+
export declare function isStaleLeaseRejection(message: string): boolean;
|
|
21
59
|
/**
|
|
22
60
|
* Detect the current HEAD branch name for a given repository root.
|
|
23
61
|
* Returns the branch name, or the provided fallback (default 'main')
|
package/dist/utils/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAmBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOvD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAe,GACxB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,IAAI,EAAE,aAAa,CAAA;IACnB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAMlB"}
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAmBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOvD;AAyBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAKlE;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAe,GACxB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,IAAI,EAAE,aAAa,CAAA;IACnB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAMlB"}
|
package/dist/utils/git.js
CHANGED
|
@@ -46,6 +46,75 @@ export function isNetworkRemoteUrl(url) {
|
|
|
46
46
|
return false;
|
|
47
47
|
return COLON_BEFORE_SLASH_PATTERN.test(url);
|
|
48
48
|
}
|
|
49
|
+
// Matches git's per-ref push-status summary line marking a ref as rejected.
|
|
50
|
+
// Present verbatim in BOTH output shapes CanopyCMS's push call sites produce:
|
|
51
|
+
// the plain CLI form (`GitManager.push()`'s `.raw(['push', ...])`, e.g.
|
|
52
|
+
// ` ! [rejected] branch -> branch (non-fast-forward)`) and the
|
|
53
|
+
// machine-readable `--porcelain` form simple-git's `.push()` wrapper requests
|
|
54
|
+
// (`CmsWorker.pushBranchToGitHub`/`pushSettingsBranches`, e.g.
|
|
55
|
+
// `!\trefs/heads/branch:refs/heads/branch\t[rejected] (non-fast-forward)`) --
|
|
56
|
+
// `--porcelain` only changes the per-ref summary's leading fields, not this
|
|
57
|
+
// trailing human-readable bracket text.
|
|
58
|
+
const REJECTED_MARKER = '[rejected]';
|
|
59
|
+
// git's two names for the SAME underlying condition: `non-fast-forward` fires
|
|
60
|
+
// when the pusher's own remote-tracking ref is present but stale;
|
|
61
|
+
// `fetch first` fires when no local knowledge of the remote ref exists at all
|
|
62
|
+
// (e.g. it was never fetched). Both mean the remote has commits this side
|
|
63
|
+
// doesn't have -- retrying the identical push can never succeed until the
|
|
64
|
+
// caller fetches and integrates (or picks a different branch name).
|
|
65
|
+
const NON_FAST_FORWARD_REASONS = ['non-fast-forward', 'fetch first'];
|
|
66
|
+
// git always prints this stderr hint immediately after a rejected push,
|
|
67
|
+
// regardless of --porcelain (porcelain only affects the machine-readable
|
|
68
|
+
// summary line, not the human hint text that follows it) -- a second,
|
|
69
|
+
// independent signal for the same condition.
|
|
70
|
+
const REJECTION_HINT = 'Updates were rejected because';
|
|
71
|
+
/**
|
|
72
|
+
* Whether a git push failure message is git's non-fast-forward rejection --
|
|
73
|
+
* the remote has diverged (moved ahead with commits this side never fetched),
|
|
74
|
+
* so retrying the IDENTICAL push can never succeed. In CanopyCMS this is the
|
|
75
|
+
* signature of two CanopyCMS deployments sharing one GitHub repo and picking
|
|
76
|
+
* the same content-branch name, or someone pushing directly to GitHub.
|
|
77
|
+
*
|
|
78
|
+
* Deliberately narrow: ordinary transient push failures -- network drops,
|
|
79
|
+
* auth/permission denial, lock contention -- must keep retrying with backoff
|
|
80
|
+
* (see worker/cms-worker.ts's `isPermanentTaskFailure`, which treats git
|
|
81
|
+
* failures as transient precisely so those cases still get retried). Only
|
|
82
|
+
* this specific, structurally-unretryable shape should fail fast (worker) or
|
|
83
|
+
* return 409 (API) instead.
|
|
84
|
+
*
|
|
85
|
+
* Matches git's literal (English) rejection text, which is gettext-
|
|
86
|
+
* translated -- callers MUST run the underlying git command with a
|
|
87
|
+
* locale-pinning env (see `gitChildEnv` in `../git-manager.ts`) or an ambient
|
|
88
|
+
* LANG/LC_ALL could silently turn this into a permanent no-op.
|
|
89
|
+
*/
|
|
90
|
+
export function isNonFastForwardRejection(message) {
|
|
91
|
+
const hasNonFastForwardRejection = message.includes(REJECTED_MARKER) &&
|
|
92
|
+
NON_FAST_FORWARD_REASONS.some((reason) => message.includes(reason));
|
|
93
|
+
return hasNonFastForwardRejection || message.includes(REJECTION_HINT);
|
|
94
|
+
}
|
|
95
|
+
// git's reason text when a `--force-with-lease=<ref>:<sha>` push is refused
|
|
96
|
+
// because the remote is not at `<sha>`.
|
|
97
|
+
const STALE_LEASE_REASON = 'stale info';
|
|
98
|
+
/**
|
|
99
|
+
* Whether a git push failure message is a refused `--force-with-lease` --
|
|
100
|
+
* the remote ref is NOT at the commit the pusher expected, so the forced
|
|
101
|
+
* update was declined and nothing was overwritten.
|
|
102
|
+
*
|
|
103
|
+
* A SEPARATE predicate from `isNonFastForwardRejection` because git's output
|
|
104
|
+
* for the two is disjoint: a refused lease prints
|
|
105
|
+
* ` ! [rejected] branch -> branch (stale info)` and, unlike an
|
|
106
|
+
* ordinary rejection, emits NEITHER `non-fast-forward`/`fetch first` NOR the
|
|
107
|
+
* `Updates were rejected because` hint. Without this predicate every lease
|
|
108
|
+
* refusal would be classified transient and retried -- three identical,
|
|
109
|
+
* guaranteed-to-fail force attempts -- instead of surfacing as the permanent,
|
|
110
|
+
* human-actionable state it is.
|
|
111
|
+
*
|
|
112
|
+
* Same locale caveat as above: the reason text is gettext-translated, so
|
|
113
|
+
* callers MUST pin the locale (`gitChildEnv`/`gitNetworkChildEnv`).
|
|
114
|
+
*/
|
|
115
|
+
export function isStaleLeaseRejection(message) {
|
|
116
|
+
return message.includes(REJECTED_MARKER) && message.includes(STALE_LEASE_REASON);
|
|
117
|
+
}
|
|
49
118
|
/**
|
|
50
119
|
* Detect the current HEAD branch name for a given repository root.
|
|
51
120
|
* Returns the branch name, or the provided fallback (default 'main')
|
package/dist/utils/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAItC,wEAAwE;AACxE,MAAM,sBAAsB,GAAG,yBAAyB,CAAA;AACxD,6EAA6E;AAC7E,8EAA8E;AAC9E,6DAA6D;AAC7D,MAAM,wBAAwB,GAAG,uBAAuB,CAAA;AACxD,4EAA4E;AAC5E,4EAA4E;AAC5E,MAAM,sBAAsB,GAAG,IAAI,CAAA;AACnC,uEAAuE;AACvE,6EAA6E;AAC7E,8EAA8E;AAC9E,uEAAuE;AACvE,8BAA8B;AAC9B,MAAM,qBAAqB,GAAG,iBAAiB,CAAA;AAC/C,MAAM,0BAA0B,GAAG,aAAa,CAAA;AAEhD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAA;IACzC,IAAI,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACjD,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACnD,IAAI,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACjD,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAA;IACjD,OAAO,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,WAAmB,MAAM;IAEzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC5C,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAClE,OAAO,IAAI,IAAI,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAA;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAKvC;IACC,IAAI,OAAO,CAAC,iBAAiB;QAAE,OAAO,OAAO,CAAC,iBAAiB,CAAA;IAC/D,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3B,OAAO,gBAAgB,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;IAC9D,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-scoped logger indirection for modules that run in BOTH the worker
|
|
3
|
+
* daemon and the Lambda/dev server.
|
|
4
|
+
*
|
|
5
|
+
* ## Why this exists
|
|
6
|
+
*
|
|
7
|
+
* `worker/log.ts` documents a hard invariant: every line written to
|
|
8
|
+
* `/var/log/canopy-worker/worker.log` must start with an ISO-8601 timestamp,
|
|
9
|
+
* because the CloudWatch agent's `multi_line_start_pattern` is keyed on that
|
|
10
|
+
* prefix (see `canopycms-cdk/src/constructs/cms-service.ts`). A line WITHOUT
|
|
11
|
+
* the prefix is not a new event - it is appended to the PREVIOUS one,
|
|
12
|
+
* inheriting that event's timestamp and carrying none of its own severity tag.
|
|
13
|
+
*
|
|
14
|
+
* The worker's own code honoured that by calling `workerLog*`. But the worker
|
|
15
|
+
* process also executes shared modules that were never worker-specific and
|
|
16
|
+
* called bare `console.warn`: `github-service.ts` (the throttling plugin's
|
|
17
|
+
* rate-limit callbacks fire on the worker's own Octokit, and the PR
|
|
18
|
+
* create/update path runs on the worker's submit task) and `branch-registry.ts`
|
|
19
|
+
* (registry regeneration, reached from every worker `meta.save()`). Their
|
|
20
|
+
* output landed in worker.log unprefixed, so an operationally interesting
|
|
21
|
+
* warning - "GitHub throttled us" - was silently folded into a minutes-old
|
|
22
|
+
* event and became invisible to `filter @message like /WARN/`. Invisible
|
|
23
|
+
* locally too, since vitest intercepts console.
|
|
24
|
+
*
|
|
25
|
+
* ## Why process-scoped rather than a threaded parameter
|
|
26
|
+
*
|
|
27
|
+
* The invariant is a property of the PROCESS's stdout/stderr, not of any
|
|
28
|
+
* particular call: the same `branch-registry.ts` line is correct as bare
|
|
29
|
+
* console under Lambda and wrong under the worker. Threading a logger down to
|
|
30
|
+
* it would mean touching every signature between `CmsWorker.rebase*` and
|
|
31
|
+
* `BranchMetadataFileManager.loadOnly` to carry a logging concern. One
|
|
32
|
+
* process-wide switch, set once at the worker entrypoint, expresses exactly
|
|
33
|
+
* the thing that is actually true.
|
|
34
|
+
*
|
|
35
|
+
* Lambda and the dev server install nothing and keep plain `console`, which is
|
|
36
|
+
* correct there - CloudWatch's Lambda integration stamps and delimits events
|
|
37
|
+
* on its own.
|
|
38
|
+
*
|
|
39
|
+
* ## Usage
|
|
40
|
+
*
|
|
41
|
+
* Shared server-side modules call `canopyLogWarn`/`canopyLogError`/`canopyLog`
|
|
42
|
+
* instead of `console.*`. The worker entrypoint calls `installWorkerLogger()`
|
|
43
|
+
* (`worker/log.ts`, re-exported from `worker/cms-worker.ts`) once, before doing
|
|
44
|
+
* any work.
|
|
45
|
+
*
|
|
46
|
+
* Not for browser/editor code: those keep `console` directly. This module is
|
|
47
|
+
* dependency-free so importing it can never drag a server-only dependency into
|
|
48
|
+
* a client bundle, but there is nothing for it to do in a browser.
|
|
49
|
+
*/
|
|
50
|
+
/** The three levels the shared modules use. Structurally satisfied by `console`. */
|
|
51
|
+
export interface CanopyLogger {
|
|
52
|
+
log(...args: unknown[]): void;
|
|
53
|
+
warn(...args: unknown[]): void;
|
|
54
|
+
error(...args: unknown[]): void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Route subsequent `canopyLog*` calls through `logger`. Idempotent, and safe to
|
|
58
|
+
* call after the modules that use the helpers have already been imported.
|
|
59
|
+
*/
|
|
60
|
+
export declare function setCanopyLogger(logger: CanopyLogger): void;
|
|
61
|
+
/** Restore the default (`console`). Exists for tests; production installs once and never reverts. */
|
|
62
|
+
export declare function resetCanopyLogger(): void;
|
|
63
|
+
/** The logger currently installed. Exported for assertions; prefer the helpers below. */
|
|
64
|
+
export declare function getCanopyLogger(): CanopyLogger;
|
|
65
|
+
/** Informational. Routes to stdout (or the worker's timestamped stdout). */
|
|
66
|
+
export declare function canopyLog(...args: unknown[]): void;
|
|
67
|
+
/** Recoverable problem - the caller carries on. Routes to stderr. */
|
|
68
|
+
export declare function canopyLogWarn(...args: unknown[]): void;
|
|
69
|
+
/** Failure worth alerting on. Routes to stderr. */
|
|
70
|
+
export declare function canopyLogError(...args: unknown[]): void;
|
|
71
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC7B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAChC;AAWD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAE1D;AAED,qGAAqG;AACrG,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,yFAAyF;AACzF,wBAAgB,eAAe,IAAI,YAAY,CAE9C;AAED,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAElD;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAEtD;AAED,mDAAmD;AACnD,wBAAgB,cAAc,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAEvD"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-scoped logger indirection for modules that run in BOTH the worker
|
|
3
|
+
* daemon and the Lambda/dev server.
|
|
4
|
+
*
|
|
5
|
+
* ## Why this exists
|
|
6
|
+
*
|
|
7
|
+
* `worker/log.ts` documents a hard invariant: every line written to
|
|
8
|
+
* `/var/log/canopy-worker/worker.log` must start with an ISO-8601 timestamp,
|
|
9
|
+
* because the CloudWatch agent's `multi_line_start_pattern` is keyed on that
|
|
10
|
+
* prefix (see `canopycms-cdk/src/constructs/cms-service.ts`). A line WITHOUT
|
|
11
|
+
* the prefix is not a new event - it is appended to the PREVIOUS one,
|
|
12
|
+
* inheriting that event's timestamp and carrying none of its own severity tag.
|
|
13
|
+
*
|
|
14
|
+
* The worker's own code honoured that by calling `workerLog*`. But the worker
|
|
15
|
+
* process also executes shared modules that were never worker-specific and
|
|
16
|
+
* called bare `console.warn`: `github-service.ts` (the throttling plugin's
|
|
17
|
+
* rate-limit callbacks fire on the worker's own Octokit, and the PR
|
|
18
|
+
* create/update path runs on the worker's submit task) and `branch-registry.ts`
|
|
19
|
+
* (registry regeneration, reached from every worker `meta.save()`). Their
|
|
20
|
+
* output landed in worker.log unprefixed, so an operationally interesting
|
|
21
|
+
* warning - "GitHub throttled us" - was silently folded into a minutes-old
|
|
22
|
+
* event and became invisible to `filter @message like /WARN/`. Invisible
|
|
23
|
+
* locally too, since vitest intercepts console.
|
|
24
|
+
*
|
|
25
|
+
* ## Why process-scoped rather than a threaded parameter
|
|
26
|
+
*
|
|
27
|
+
* The invariant is a property of the PROCESS's stdout/stderr, not of any
|
|
28
|
+
* particular call: the same `branch-registry.ts` line is correct as bare
|
|
29
|
+
* console under Lambda and wrong under the worker. Threading a logger down to
|
|
30
|
+
* it would mean touching every signature between `CmsWorker.rebase*` and
|
|
31
|
+
* `BranchMetadataFileManager.loadOnly` to carry a logging concern. One
|
|
32
|
+
* process-wide switch, set once at the worker entrypoint, expresses exactly
|
|
33
|
+
* the thing that is actually true.
|
|
34
|
+
*
|
|
35
|
+
* Lambda and the dev server install nothing and keep plain `console`, which is
|
|
36
|
+
* correct there - CloudWatch's Lambda integration stamps and delimits events
|
|
37
|
+
* on its own.
|
|
38
|
+
*
|
|
39
|
+
* ## Usage
|
|
40
|
+
*
|
|
41
|
+
* Shared server-side modules call `canopyLogWarn`/`canopyLogError`/`canopyLog`
|
|
42
|
+
* instead of `console.*`. The worker entrypoint calls `installWorkerLogger()`
|
|
43
|
+
* (`worker/log.ts`, re-exported from `worker/cms-worker.ts`) once, before doing
|
|
44
|
+
* any work.
|
|
45
|
+
*
|
|
46
|
+
* Not for browser/editor code: those keep `console` directly. This module is
|
|
47
|
+
* dependency-free so importing it can never drag a server-only dependency into
|
|
48
|
+
* a client bundle, but there is nothing for it to do in a browser.
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* Deliberately mutable module state, read at CALL time by the helpers below
|
|
52
|
+
* rather than captured at import time. Module import order is not something a
|
|
53
|
+
* call site controls, so a captured reference would mean whether a line got its
|
|
54
|
+
* prefix depended on whether `github-service.ts` happened to be imported before
|
|
55
|
+
* or after the entrypoint installed the worker logger.
|
|
56
|
+
*/
|
|
57
|
+
let active = console;
|
|
58
|
+
/**
|
|
59
|
+
* Route subsequent `canopyLog*` calls through `logger`. Idempotent, and safe to
|
|
60
|
+
* call after the modules that use the helpers have already been imported.
|
|
61
|
+
*/
|
|
62
|
+
export function setCanopyLogger(logger) {
|
|
63
|
+
active = logger;
|
|
64
|
+
}
|
|
65
|
+
/** Restore the default (`console`). Exists for tests; production installs once and never reverts. */
|
|
66
|
+
export function resetCanopyLogger() {
|
|
67
|
+
active = console;
|
|
68
|
+
}
|
|
69
|
+
/** The logger currently installed. Exported for assertions; prefer the helpers below. */
|
|
70
|
+
export function getCanopyLogger() {
|
|
71
|
+
return active;
|
|
72
|
+
}
|
|
73
|
+
/** Informational. Routes to stdout (or the worker's timestamped stdout). */
|
|
74
|
+
export function canopyLog(...args) {
|
|
75
|
+
active.log(...args);
|
|
76
|
+
}
|
|
77
|
+
/** Recoverable problem - the caller carries on. Routes to stderr. */
|
|
78
|
+
export function canopyLogWarn(...args) {
|
|
79
|
+
active.warn(...args);
|
|
80
|
+
}
|
|
81
|
+
/** Failure worth alerting on. Routes to stderr. */
|
|
82
|
+
export function canopyLogError(...args) {
|
|
83
|
+
active.error(...args);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AASH;;;;;;GAMG;AACH,IAAI,MAAM,GAAiB,OAAO,CAAA;AAElC;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,MAAM,GAAG,MAAM,CAAA;AACjB,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,OAAO,CAAA;AAClB,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,eAAe;IAC7B,OAAO,MAAM,CAAA;AACf,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,SAAS,CAAC,GAAG,IAAe;IAC1C,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;AACrB,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,aAAa,CAAC,GAAG,IAAe;IAC9C,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;AACtB,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,cAAc,CAAC,GAAG,IAAe;IAC/C,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;AACvB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates that every reference field's `entryTypes` names an entry type that
|
|
3
|
+
* actually exists in the resolved schema.
|
|
4
|
+
*
|
|
5
|
+
* Without this, a typo (`entryTypes: ['parter']` for `'partner'`) is accepted
|
|
6
|
+
* silently and surfaces much later as a reference picker that returns zero
|
|
7
|
+
* results, with nothing pointing at the cause.
|
|
8
|
+
*
|
|
9
|
+
* This runs after schema resolution rather than at config-validation time on
|
|
10
|
+
* purpose: entry types are declared per-collection in `.collection.json` files
|
|
11
|
+
* on disk, so the set of valid names only exists once a branch's schema has
|
|
12
|
+
* been resolved. `config/validation.ts`'s `ensureReferenceFieldsHaveScope` runs
|
|
13
|
+
* at entry-schema *registration* (entry-schema-registry.ts), before any branch
|
|
14
|
+
* schema exists, and so cannot perform this check.
|
|
15
|
+
*/
|
|
16
|
+
import type { RootCollectionConfig } from '../config';
|
|
17
|
+
/**
|
|
18
|
+
* Collect every entry type name defined anywhere in the schema.
|
|
19
|
+
*
|
|
20
|
+
* Entry types are scoped per collection, and the same name may legitimately
|
|
21
|
+
* appear in several collections, so this is a flat set of names: a reference
|
|
22
|
+
* field's `entryTypes` is matched against entries across all collections
|
|
23
|
+
* (see reference-resolver.ts, which filters resolved entries by entry type name
|
|
24
|
+
* without regard to which collection defined it).
|
|
25
|
+
*/
|
|
26
|
+
export declare const collectEntryTypeNames: (schema: RootCollectionConfig) => Set<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Check every reference field's `entryTypes` against the schema's entry types.
|
|
29
|
+
*
|
|
30
|
+
* @returns One human-readable message per offending value; empty when valid.
|
|
31
|
+
*/
|
|
32
|
+
export declare const validateReferenceEntryTypes: (schema: RootCollectionConfig) => string[];
|
|
33
|
+
//# sourceMappingURL=entry-type-reference-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-type-reference-validator.d.ts","sourceRoot":"","sources":["../../src/validation/entry-type-reference-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAqC,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAyDxF;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,oBAAoB,KAAG,GAAG,CAAC,MAAM,CAQ9E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GAAI,QAAQ,oBAAoB,KAAG,MAAM,EA8BhF,CAAA"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates that every reference field's `entryTypes` names an entry type that
|
|
3
|
+
* actually exists in the resolved schema.
|
|
4
|
+
*
|
|
5
|
+
* Without this, a typo (`entryTypes: ['parter']` for `'partner'`) is accepted
|
|
6
|
+
* silently and surfaces much later as a reference picker that returns zero
|
|
7
|
+
* results, with nothing pointing at the cause.
|
|
8
|
+
*
|
|
9
|
+
* This runs after schema resolution rather than at config-validation time on
|
|
10
|
+
* purpose: entry types are declared per-collection in `.collection.json` files
|
|
11
|
+
* on disk, so the set of valid names only exists once a branch's schema has
|
|
12
|
+
* been resolved. `config/validation.ts`'s `ensureReferenceFieldsHaveScope` runs
|
|
13
|
+
* at entry-schema *registration* (entry-schema-registry.ts), before any branch
|
|
14
|
+
* schema exists, and so cannot perform this check.
|
|
15
|
+
*/
|
|
16
|
+
import { forEachReferenceField } from '../config/validation.js';
|
|
17
|
+
/**
|
|
18
|
+
* Levenshtein edit distance, bounded use only (short identifier strings).
|
|
19
|
+
* Kept local and tiny rather than pulling in a runtime dependency purely to
|
|
20
|
+
* produce a "did you mean" hint in an error message.
|
|
21
|
+
*/
|
|
22
|
+
const editDistance = (a, b) => {
|
|
23
|
+
let prev = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
24
|
+
for (let i = 1; i <= a.length; i++) {
|
|
25
|
+
const curr = [i];
|
|
26
|
+
for (let j = 1; j <= b.length; j++) {
|
|
27
|
+
curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
28
|
+
}
|
|
29
|
+
prev = curr;
|
|
30
|
+
}
|
|
31
|
+
return prev[b.length];
|
|
32
|
+
};
|
|
33
|
+
/** Closest known name within a small edit distance, if there is one. */
|
|
34
|
+
const closestName = (name, known) => {
|
|
35
|
+
let best;
|
|
36
|
+
let bestDistance = Infinity;
|
|
37
|
+
for (const candidate of known) {
|
|
38
|
+
const distance = editDistance(name.toLowerCase(), candidate.toLowerCase());
|
|
39
|
+
if (distance < bestDistance) {
|
|
40
|
+
bestDistance = distance;
|
|
41
|
+
best = candidate;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Allow a little more slack for longer names, but never suggest something
|
|
45
|
+
// that shares almost nothing with what was written.
|
|
46
|
+
const threshold = Math.max(2, Math.floor(name.length / 3));
|
|
47
|
+
return best !== undefined && bestDistance <= threshold ? best : undefined;
|
|
48
|
+
};
|
|
49
|
+
/** Walk the collection tree, visiting every entry type with its collection path. */
|
|
50
|
+
const forEachEntryType = (schema, visit) => {
|
|
51
|
+
const walk = (node, nodePath) => {
|
|
52
|
+
for (const entryType of node.entries ?? []) {
|
|
53
|
+
visit(entryType, nodePath);
|
|
54
|
+
}
|
|
55
|
+
for (const child of node.collections ?? []) {
|
|
56
|
+
walk(child, child.path ?? (nodePath ? `${nodePath}/${child.name}` : child.name));
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
walk(schema, '');
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Collect every entry type name defined anywhere in the schema.
|
|
63
|
+
*
|
|
64
|
+
* Entry types are scoped per collection, and the same name may legitimately
|
|
65
|
+
* appear in several collections, so this is a flat set of names: a reference
|
|
66
|
+
* field's `entryTypes` is matched against entries across all collections
|
|
67
|
+
* (see reference-resolver.ts, which filters resolved entries by entry type name
|
|
68
|
+
* without regard to which collection defined it).
|
|
69
|
+
*/
|
|
70
|
+
export const collectEntryTypeNames = (schema) => {
|
|
71
|
+
const names = new Set();
|
|
72
|
+
forEachEntryType(schema, (entryType) => {
|
|
73
|
+
if (typeof entryType.name === 'string' && entryType.name.length > 0) {
|
|
74
|
+
names.add(entryType.name);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return names;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Check every reference field's `entryTypes` against the schema's entry types.
|
|
81
|
+
*
|
|
82
|
+
* @returns One human-readable message per offending value; empty when valid.
|
|
83
|
+
*/
|
|
84
|
+
export const validateReferenceEntryTypes = (schema) => {
|
|
85
|
+
const known = collectEntryTypeNames(schema);
|
|
86
|
+
const knownList = [...known].sort();
|
|
87
|
+
const issues = [];
|
|
88
|
+
forEachEntryType(schema, (entryType, collectionPath) => {
|
|
89
|
+
const location = collectionPath ? `${collectionPath}/${entryType.name}` : entryType.name;
|
|
90
|
+
forEachReferenceField(entryType.schema, (field) => {
|
|
91
|
+
const entryTypes = field.entryTypes;
|
|
92
|
+
if (!Array.isArray(entryTypes))
|
|
93
|
+
return;
|
|
94
|
+
const fieldName = typeof field.name === 'string' ? field.name : 'unknown';
|
|
95
|
+
for (const value of entryTypes) {
|
|
96
|
+
if (typeof value !== 'string' || known.has(value))
|
|
97
|
+
continue;
|
|
98
|
+
const suggestion = closestName(value, knownList);
|
|
99
|
+
issues.push(`Reference field "${fieldName}" in "${location}" specifies entryType ` +
|
|
100
|
+
`"${value}", which is not defined in any collection.` +
|
|
101
|
+
(suggestion ? ` Did you mean "${suggestion}"?` : '') +
|
|
102
|
+
(knownList.length > 0
|
|
103
|
+
? ` Known entry types: ${knownList.join(', ')}.`
|
|
104
|
+
: ' No entry types are defined in this schema.'));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
return issues;
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=entry-type-reference-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-type-reference-validator.js","sourceRoot":"","sources":["../../src/validation/entry-type-reference-validator.ts"],"names":[],"mappings":"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"}
|