canopycms 0.0.61 → 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/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/branch.d.ts.map +1 -1
- package/dist/api/branch.js +16 -2
- 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 +79 -6
- 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 +40 -15
- package/dist/api/entries.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 +13 -13
- package/dist/api/schema.js.map +1 -1
- package/dist/assets/transform.d.ts.map +1 -1
- package/dist/assets/transform.js +19 -6
- package/dist/assets/transform.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/cli/cli.js +858 -537
- package/dist/cli/generate-ai-content.js +760 -455
- package/dist/cli/init.js +25 -7
- package/dist/cli/template-files/Dockerfile.cms.template +19 -1
- package/dist/cli/template-files/canopycms.config.ts.template +7 -0
- package/dist/cli/template-files/cms-stack.ts.template +7 -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/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 +9 -0
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +14 -0
- 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-store.d.ts +81 -7
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +443 -258
- package/dist/content-store.js.map +1 -1
- package/dist/editor/BranchManager.d.ts.map +1 -1
- package/dist/editor/BranchManager.js +18 -6
- 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/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 +58 -24
- 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.js +6 -2
- package/dist/editor/admin/SystemHealthPanel.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 +4 -1
- package/dist/editor/components/EntryCreateModal.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/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/hooks/useBranchManager.d.ts.map +1 -1
- package/dist/editor/hooks/useBranchManager.js +115 -26
- package/dist/editor/hooks/useBranchManager.js.map +1 -1
- 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 +261 -21
- package/dist/editor/hooks/useDraftManager.js.map +1 -1
- package/dist/editor/hooks/useEntryManager.d.ts +21 -0
- package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
- package/dist/editor/hooks/useEntryManager.js +25 -2
- package/dist/editor/hooks/useEntryManager.js.map +1 -1
- package/dist/editor/theme.d.ts +8 -8
- package/dist/git-manager.d.ts +51 -7
- package/dist/git-manager.d.ts.map +1 -1
- package/dist/git-manager.js +105 -14
- package/dist/git-manager.js.map +1 -1
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/handler.js +70 -27
- 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/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 +9 -0
- package/dist/operating-mode/deployment-name.d.ts.map +1 -1
- package/dist/operating-mode/deployment-name.js +9 -1
- package/dist/operating-mode/deployment-name.js.map +1 -1
- package/dist/operating-mode/index.d.ts +2 -1
- package/dist/operating-mode/index.d.ts.map +1 -1
- package/dist/operating-mode/index.js +4 -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/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/schema-store.d.ts +53 -2
- package/dist/schema/schema-store.d.ts.map +1 -1
- package/dist/schema/schema-store.js +92 -21
- 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 +40 -0
- package/dist/settings-workspace.d.ts.map +1 -1
- package/dist/settings-workspace.js +139 -151
- package/dist/settings-workspace.js.map +1 -1
- package/dist/types.d.ts +10 -0
- 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/error.d.ts +1 -1
- package/dist/utils/error.js +1 -1
- package/dist/utils/git.d.ts +16 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +22 -0
- package/dist/utils/git.js.map +1 -1
- 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-validator.js +1 -1
- package/dist/validation/entry-validator.js.map +1 -1
- package/dist/worker/cms-worker.d.ts +13 -0
- package/dist/worker/cms-worker.d.ts.map +1 -1
- package/dist/worker/cms-worker.js +326 -264
- package/dist/worker/cms-worker.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/http/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAenD;;;;;;;;GAQG;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,CAAA;AAEhG;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;IACnD,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,OAAO,EAAE,aAAa,CAAA;IAEtB,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KACtE;QACE,EAAE,EAAE,IAAI,CAAA;QACR,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,IAAI,CAAC,EAAE,OAAO,CAAA;KACf,GACD;QACE,EAAE,EAAE,KAAK,CAAA;QACT,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACL;;;;;OAKG;IACH,UAAU,CAAC,EAAE,WAAW,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,aAAa,CAAA;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE9B,QAAQ,CAAC,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IACtC,UAAU,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAA;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,CAAA;IAElC,mEAAmE;IACnE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,UAAU,GAAG,IAAI,CAAA;CAC7D;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/http/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAenD;;;;;;;;GAQG;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,CAAA;AAEhG;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;IACnD,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,OAAO,EAAE,aAAa,CAAA;IAEtB,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KACtE;QACE,EAAE,EAAE,IAAI,CAAA;QACR,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,IAAI,CAAC,EAAE,OAAO,CAAA;KACf,GACD;QACE,EAAE,EAAE,KAAK,CAAA;QACT,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACL;;;;;OAKG;IACH,UAAU,CAAC,EAAE,WAAW,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,aAAa,CAAA;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE9B,QAAQ,CAAC,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IACtC,UAAU,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAA;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,CAAA;IAElC,mEAAmE;IACnE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,UAAU,GAAG,IAAI,CAAA;CAC7D;AA+ID;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAAE,GACjB,UAAU,GAAG,IAAI,CA6CnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAOjD"}
|
package/dist/http/router.js
CHANGED
|
@@ -47,6 +47,15 @@ function buildCanopyRoutes() {
|
|
|
47
47
|
/**
|
|
48
48
|
* Match a route pattern against actual path segments.
|
|
49
49
|
* Supports :param for single-segment params and ...slug for catch-all.
|
|
50
|
+
*
|
|
51
|
+
* Params are returned RAW (undecoded) here on purpose (C5): matching is
|
|
52
|
+
* purely structural (segment counts, static-segment equality) and must never
|
|
53
|
+
* throw. Decoding happens exactly once, uniformly for :param and catch-all
|
|
54
|
+
* alike, in matchRoute() below - after the winning route has been picked, so
|
|
55
|
+
* a malformed `%` escape is handled in a single place instead of aborting
|
|
56
|
+
* mid-match (which previously let a URIError from a bad :param escape to
|
|
57
|
+
* `decodeURIComponent` bubble all the way to http/handler.ts's top-level
|
|
58
|
+
* catch and surface as a 500).
|
|
50
59
|
*/
|
|
51
60
|
const matchPattern = (pattern, actual) => {
|
|
52
61
|
const params = {};
|
|
@@ -63,8 +72,8 @@ const matchPattern = (pattern, actual) => {
|
|
|
63
72
|
if (!next)
|
|
64
73
|
return null;
|
|
65
74
|
if (part.startsWith(':')) {
|
|
66
|
-
// Dynamic segment - extract param
|
|
67
|
-
params[part.slice(1)] =
|
|
75
|
+
// Dynamic segment - extract param (still raw; see decode note above)
|
|
76
|
+
params[part.slice(1)] = next;
|
|
68
77
|
}
|
|
69
78
|
else if (part !== next) {
|
|
70
79
|
// Static segment - must match exactly
|
|
@@ -76,6 +85,17 @@ const matchPattern = (pattern, actual) => {
|
|
|
76
85
|
return null;
|
|
77
86
|
return { params };
|
|
78
87
|
};
|
|
88
|
+
/**
|
|
89
|
+
* Synthetic handler for a request whose matched route params contain a
|
|
90
|
+
* malformed `%` escape sequence (C5) - e.g. a lone `%` or `%zz`. Reported as
|
|
91
|
+
* a 400 (the request is malformed), never registered in the real route
|
|
92
|
+
* table, and only ever reachable via matchRoute()'s decode step below.
|
|
93
|
+
*/
|
|
94
|
+
const malformedPathHandler = async () => ({
|
|
95
|
+
ok: false,
|
|
96
|
+
status: 400,
|
|
97
|
+
error: 'Malformed URL-encoded path segment',
|
|
98
|
+
});
|
|
79
99
|
/**
|
|
80
100
|
* Specificity rank of a pattern segment. Higher wins.
|
|
81
101
|
* A literal ("static") segment is more specific than a `:param`, which is
|
|
@@ -149,9 +169,26 @@ export function matchRoute(routes, method, segments) {
|
|
|
149
169
|
}
|
|
150
170
|
if (!best)
|
|
151
171
|
return null;
|
|
172
|
+
// Decode every matched param exactly once, here - uniformly for :param and
|
|
173
|
+
// catch-all values alike (C5). A malformed escape must produce a 400, not
|
|
174
|
+
// an uncaught URIError that would otherwise reach http/handler.ts's
|
|
175
|
+
// top-level catch and get reported as a 500. Downstream consumers
|
|
176
|
+
// (Zod's logicalPathSchema/branchNameSchema etc. in each route's
|
|
177
|
+
// `validate`, and any handler-local re-check such as entries.ts's
|
|
178
|
+
// parseLogicalPath call) still run their own traversal validation against
|
|
179
|
+
// this same final decoded value - decoding centrally here does not skip
|
|
180
|
+
// that, it just removes the redundant second decode that used to run
|
|
181
|
+
// alongside it in a few handlers.
|
|
182
|
+
let decodedParams;
|
|
183
|
+
try {
|
|
184
|
+
decodedParams = Object.fromEntries(Object.entries(best.params).map(([key, value]) => [key, decodeURIComponent(value)]));
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return { handler: malformedPathHandler, params: {} };
|
|
188
|
+
}
|
|
152
189
|
return {
|
|
153
190
|
handler: best.route.handler,
|
|
154
|
-
params:
|
|
191
|
+
params: decodedParams,
|
|
155
192
|
validate: best.route.validate, // Include validation function if present
|
|
156
193
|
bodyFormat: best.route.bodyFormat,
|
|
157
194
|
};
|
package/dist/http/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/http/router.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAgE3C;;;;;;;GAOG;AACH,SAAS,iBAAiB;IACxB,OAAO;QACL,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC;QAC/B,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC;QACjC,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC;QAChC,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC;QAChC,GAAG,MAAM,CAAC,MAAM,CAAC,wBAAwB,CAAC;QAC1C,GAAG,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC;QAC3C,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;QAC9B,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;QAC9B,aAAa;QACb,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC;QACnC,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;QAC9B,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;QAC7B,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC;QAC/B,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;KAC/B,CAAC,GAAG,CACH,CAAC,KAAK,EAAmB,EAAE,CAAC,CAAC;QAC3B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,gFAAgF;QAChF,QAAQ,EAAE,UAAU,IAAI,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,QAAwC,CAAC,CAAC,CAAC,SAAS;QAC3F,UAAU,EACR,YAAY,IAAI,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,UAA4C,CAAC,CAAC,CAAC,SAAS;KAC1F,CAAC,CACH,CAAA;AACH,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/http/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared deployment-name test fixture.
|
|
3
|
+
*
|
|
4
|
+
* The rule that decides whether a `deploymentName` is usable exists TWICE, by
|
|
5
|
+
* necessity: once at runtime (`deployment-name.ts`'s `isValidDeploymentName`)
|
|
6
|
+
* and once at synth time (`canopycms-cdk`'s `constructs/cms-service.ts`).
|
|
7
|
+
* `canopycms-cdk` publishes without a runtime dependency on `canopycms`, so
|
|
8
|
+
* the construct cannot import the real thing.
|
|
9
|
+
*
|
|
10
|
+
* The dangerous drift is asymmetric: a rule TIGHTENED at runtime but not at
|
|
11
|
+
* synth produces a stack that synths clean and then crash-loops the Lambda at
|
|
12
|
+
* boot — precisely what the synth guard exists to prevent. So both packages'
|
|
13
|
+
* suites assert against this one list, and `canopycms-cdk`'s suite additionally
|
|
14
|
+
* asserts that the construct's verdict matches this package's predicate for
|
|
15
|
+
* every name here. Add a case here when you change either copy of the rule.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately dependency-free (plain arrays, no vitest import) so the CDK
|
|
18
|
+
* suite can import it across the package boundary without dragging anything
|
|
19
|
+
* along.
|
|
20
|
+
*/
|
|
21
|
+
/** Names both copies of the rule must ACCEPT. */
|
|
22
|
+
export declare const VALID_DEPLOYMENT_NAMES: readonly ["prod", "staging", "acme-prod_2.1", "a", "9lives", "team.prod", "PROD", "x.locked"];
|
|
23
|
+
/**
|
|
24
|
+
* Names both copies of the rule must REJECT, each with the reason it exists —
|
|
25
|
+
* every entry is a value git itself would refuse as a ref component, or one
|
|
26
|
+
* that would corrupt the worker's `.env` heredoc.
|
|
27
|
+
*/
|
|
28
|
+
export declare const INVALID_DEPLOYMENT_NAMES: readonly [readonly ["a slash (would add a ref hierarchy level)", "team/prod"], readonly ["whitespace", "my prod"], readonly ["a leading dash (parses as a git option)", "-prod"], readonly ["a git-forbidden character", "prod:1"], readonly ["dot-dot", "a..b"], readonly ["a leading dot", ".prod"], readonly ["a trailing dot", "prod."], readonly ["a .lock suffix", "prod.lock"], readonly ["a tilde", "prod~1"], readonly ["a caret", "prod^1"], readonly ["a question mark", "prod?"], readonly ["an asterisk", "prod*"], readonly ["an open bracket", "prod["], readonly ["a backslash", "prod\\1"], readonly ["the empty string", ""], readonly ["a newline (would inject a line into the worker .env)", "prod\nEVIL=1"]];
|
|
29
|
+
//# sourceMappingURL=deployment-name-fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-name-fixtures.d.ts","sourceRoot":"","sources":["../../src/operating-mode/deployment-name-fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,+FASzB,CAAA;AAEV;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,osBAiB3B,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared deployment-name test fixture.
|
|
3
|
+
*
|
|
4
|
+
* The rule that decides whether a `deploymentName` is usable exists TWICE, by
|
|
5
|
+
* necessity: once at runtime (`deployment-name.ts`'s `isValidDeploymentName`)
|
|
6
|
+
* and once at synth time (`canopycms-cdk`'s `constructs/cms-service.ts`).
|
|
7
|
+
* `canopycms-cdk` publishes without a runtime dependency on `canopycms`, so
|
|
8
|
+
* the construct cannot import the real thing.
|
|
9
|
+
*
|
|
10
|
+
* The dangerous drift is asymmetric: a rule TIGHTENED at runtime but not at
|
|
11
|
+
* synth produces a stack that synths clean and then crash-loops the Lambda at
|
|
12
|
+
* boot — precisely what the synth guard exists to prevent. So both packages'
|
|
13
|
+
* suites assert against this one list, and `canopycms-cdk`'s suite additionally
|
|
14
|
+
* asserts that the construct's verdict matches this package's predicate for
|
|
15
|
+
* every name here. Add a case here when you change either copy of the rule.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately dependency-free (plain arrays, no vitest import) so the CDK
|
|
18
|
+
* suite can import it across the package boundary without dragging anything
|
|
19
|
+
* along.
|
|
20
|
+
*/
|
|
21
|
+
/** Names both copies of the rule must ACCEPT. */
|
|
22
|
+
export const VALID_DEPLOYMENT_NAMES = [
|
|
23
|
+
'prod',
|
|
24
|
+
'staging',
|
|
25
|
+
'acme-prod_2.1',
|
|
26
|
+
'a',
|
|
27
|
+
'9lives',
|
|
28
|
+
'team.prod',
|
|
29
|
+
'PROD',
|
|
30
|
+
'x.locked',
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Names both copies of the rule must REJECT, each with the reason it exists —
|
|
34
|
+
* every entry is a value git itself would refuse as a ref component, or one
|
|
35
|
+
* that would corrupt the worker's `.env` heredoc.
|
|
36
|
+
*/
|
|
37
|
+
export const INVALID_DEPLOYMENT_NAMES = [
|
|
38
|
+
['a slash (would add a ref hierarchy level)', 'team/prod'],
|
|
39
|
+
['whitespace', 'my prod'],
|
|
40
|
+
['a leading dash (parses as a git option)', '-prod'],
|
|
41
|
+
['a git-forbidden character', 'prod:1'],
|
|
42
|
+
['dot-dot', 'a..b'],
|
|
43
|
+
['a leading dot', '.prod'],
|
|
44
|
+
['a trailing dot', 'prod.'],
|
|
45
|
+
['a .lock suffix', 'prod.lock'],
|
|
46
|
+
['a tilde', 'prod~1'],
|
|
47
|
+
['a caret', 'prod^1'],
|
|
48
|
+
['a question mark', 'prod?'],
|
|
49
|
+
['an asterisk', 'prod*'],
|
|
50
|
+
['an open bracket', 'prod['],
|
|
51
|
+
['a backslash', 'prod\\1'],
|
|
52
|
+
['the empty string', ''],
|
|
53
|
+
['a newline (would inject a line into the worker .env)', 'prod\nEVIL=1'],
|
|
54
|
+
];
|
|
55
|
+
//# sourceMappingURL=deployment-name-fixtures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-name-fixtures.js","sourceRoot":"","sources":["../../src/operating-mode/deployment-name-fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,iDAAiD;AACjD,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,MAAM;IACN,SAAS;IACT,eAAe;IACf,GAAG;IACH,QAAQ;IACR,WAAW;IACX,MAAM;IACN,UAAU;CACF,CAAA;AAEV;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,CAAC,2CAA2C,EAAE,WAAW,CAAC;IAC1D,CAAC,YAAY,EAAE,SAAS,CAAC;IACzB,CAAC,yCAAyC,EAAE,OAAO,CAAC;IACpD,CAAC,2BAA2B,EAAE,QAAQ,CAAC;IACvC,CAAC,SAAS,EAAE,MAAM,CAAC;IACnB,CAAC,eAAe,EAAE,OAAO,CAAC;IAC1B,CAAC,gBAAgB,EAAE,OAAO,CAAC;IAC3B,CAAC,gBAAgB,EAAE,WAAW,CAAC;IAC/B,CAAC,SAAS,EAAE,QAAQ,CAAC;IACrB,CAAC,SAAS,EAAE,QAAQ,CAAC;IACrB,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAC5B,CAAC,aAAa,EAAE,OAAO,CAAC;IACxB,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAC5B,CAAC,aAAa,EAAE,SAAS,CAAC;IAC1B,CAAC,kBAAkB,EAAE,EAAE,CAAC;IACxB,CAAC,sDAAsD,EAAE,cAAc,CAAC;CAChE,CAAA"}
|
|
@@ -22,6 +22,15 @@
|
|
|
22
22
|
* `deploymentName` prop silently doing nothing — exactly the two-stacks-one-repo
|
|
23
23
|
* case this feature exists to fix.
|
|
24
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;
|
|
25
34
|
export declare function resolveDeploymentName(config: {
|
|
26
35
|
deploymentName?: string;
|
|
27
36
|
}, modeDefault: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployment-name.d.ts","sourceRoot":"","sources":["../../src/operating-mode/deployment-name.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
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"}
|
|
@@ -39,7 +39,15 @@ let warned = false;
|
|
|
39
39
|
* git's own ref rules (git-check-ref-format), so they are excluded separately.
|
|
40
40
|
*/
|
|
41
41
|
const VALID_DEPLOYMENT_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
42
|
-
|
|
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) &&
|
|
43
51
|
!name.includes('..') &&
|
|
44
52
|
!name.endsWith('.') &&
|
|
45
53
|
!name.endsWith('.lock');
|
|
@@ -1 +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,MAAM,qBAAqB,GAAG,CAAC,IAAY,EAAW,EAAE,
|
|
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"}
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
*/
|
|
27
27
|
export { clientOperatingStrategy, clearClientStrategyCache } from './client-safe-strategy';
|
|
28
28
|
export { operatingStrategy, clearStrategyCache } from './client-unsafe-strategy';
|
|
29
|
-
export { resolveDeploymentName } from './deployment-name';
|
|
29
|
+
export { resolveDeploymentName, isValidDeploymentName } from './deployment-name';
|
|
30
|
+
export { resolveOperatingMode, SERVER_MODE_ENV_VAR, BROWSER_MODE_ENV_VAR } from './mode-env';
|
|
30
31
|
export type OperatingMode = 'prod' | 'dev';
|
|
31
32
|
export type { ClientSafeStrategy, ClientUnsafeStrategy, ResolveRemoteUrlOptions } from './types';
|
|
32
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;;;;;;;;;;;;;;;;;;;;;;;;;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,MAAM,mBAAmB,CAAA;
|
|
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"}
|
|
@@ -30,5 +30,8 @@ export { clientOperatingStrategy, clearClientStrategyCache } from './client-safe
|
|
|
30
30
|
export { operatingStrategy, clearStrategyCache } from './client-unsafe-strategy.js';
|
|
31
31
|
// Single resolution point for deploymentName (env > config > mode default) —
|
|
32
32
|
// server-only (reads process.env), used by the strategies' getSettingsBranchName.
|
|
33
|
-
export { resolveDeploymentName } from './deployment-name.js';
|
|
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';
|
|
34
37
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
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,MAAM,mBAAmB,CAAA"}
|
|
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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AuthenticationResult } from './auth/types';
|
|
2
|
+
import type { CanopyUser } from './user';
|
|
3
|
+
import type { OperatingMode } from './operating-mode';
|
|
4
|
+
/** Test-only: reset the once-per-process "no admins configured" warning latch. */
|
|
5
|
+
export declare function resetResolveCanopyUserWarningForTests(): void;
|
|
6
|
+
export interface ResolveCanopyUserDeps {
|
|
7
|
+
/**
|
|
8
|
+
* Resolves (and ensures) the settings workspace root. Internal groups are
|
|
9
|
+
* the single source of truth for group-based privileges and MUST be
|
|
10
|
+
* loaded from here — the same root `createContentAccessChecker`
|
|
11
|
+
* (authorization/content.ts) uses for path permissions — never from a
|
|
12
|
+
* content branch clone.
|
|
13
|
+
*
|
|
14
|
+
* Must THROW if the settings workspace cannot be ensured, matching
|
|
15
|
+
* `createContentAccessChecker`'s fail-loud contract: a caught error here
|
|
16
|
+
* and a silent fallback to an empty group list would read as "no
|
|
17
|
+
* privileges", which is a silent authorization change, not a safe
|
|
18
|
+
* degradation.
|
|
19
|
+
*/
|
|
20
|
+
getSettingsBranchRoot: () => Promise<string>;
|
|
21
|
+
mode: OperatingMode;
|
|
22
|
+
bootstrapAdminIds: Set<string>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the CanopyUser for a request: load internal groups from the
|
|
26
|
+
* settings workspace and merge them (plus bootstrap admins) into an
|
|
27
|
+
* authentication result via `authResultToCanopyUser`.
|
|
28
|
+
*
|
|
29
|
+
* Framework-agnostic: callers supply the already-computed `authResult` (from
|
|
30
|
+
* whatever auth-plugin invocation their transport uses) and a small deps
|
|
31
|
+
* bag drawn from `CanopyServices`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveCanopyUser(authResult: AuthenticationResult, deps: ResolveCanopyUserDeps): Promise<CanopyUser>;
|
|
34
|
+
//# sourceMappingURL=resolve-canopy-user.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-canopy-user.d.ts","sourceRoot":"","sources":["../src/resolve-canopy-user.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAGxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAKrD,kFAAkF;AAClF,wBAAgB,qCAAqC,IAAI,IAAI,CAE5D;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;;;;OAYG;IACH,qBAAqB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IAC5C,IAAI,EAAE,aAAa,CAAA;IACnB,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC/B;AAcD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,oBAAoB,EAChC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAOrB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared "authenticate -> resolve internal groups -> merge into CanopyUser"
|
|
3
|
+
* pipeline.
|
|
4
|
+
*
|
|
5
|
+
* This used to be duplicated between `http/handler.ts` (the core API
|
|
6
|
+
* handler) and `canopycms-next`'s `context-wrapper.ts` (Next.js SSR user
|
|
7
|
+
* extraction) - including a module-level `warnedNoAdmins` flag in each copy.
|
|
8
|
+
* The duplication let the two drift: `http/handler.ts` loaded internal
|
|
9
|
+
* groups from the BASE BRANCH content clone's `groups.json`, which nothing
|
|
10
|
+
* in the product ever writes (writes go to the settings workspace via
|
|
11
|
+
* `mutateGroupsFile` - `api/groups.ts`), so group-based privileges never
|
|
12
|
+
* actually took effect. Consolidating the pipeline here means both callers
|
|
13
|
+
* read from the same place and cannot silently diverge again.
|
|
14
|
+
*
|
|
15
|
+
* canopyLogWarn, not console.warn: this module has no worker-specific logic,
|
|
16
|
+
* but nothing prevents it from becoming reachable from the worker's runtime
|
|
17
|
+
* import closure later, and the existing "no admins configured" warning is
|
|
18
|
+
* exactly the kind of operationally interesting line that must not be
|
|
19
|
+
* silently folded into an unrelated worker.log event (see utils/logger.ts).
|
|
20
|
+
*/
|
|
21
|
+
import { canopyLogWarn } from './utils/logger.js';
|
|
22
|
+
import { authResultToCanopyUser } from './user.js';
|
|
23
|
+
import { loadInternalGroups, RESERVED_GROUPS } from './authorization/index.js';
|
|
24
|
+
/** Module-level, matching the pre-extraction behavior: warn at most once per process. */
|
|
25
|
+
let warnedNoAdmins = false;
|
|
26
|
+
/** Test-only: reset the once-per-process "no admins configured" warning latch. */
|
|
27
|
+
export function resetResolveCanopyUserWarningForTests() {
|
|
28
|
+
warnedNoAdmins = false;
|
|
29
|
+
}
|
|
30
|
+
function warnIfNoAdmins(internalGroups, bootstrapAdminIds) {
|
|
31
|
+
if (warnedNoAdmins)
|
|
32
|
+
return;
|
|
33
|
+
const adminsGroup = internalGroups.find((g) => g.id === RESERVED_GROUPS.ADMINS);
|
|
34
|
+
const hasAdmins = (adminsGroup?.members.length ?? 0) > 0 || bootstrapAdminIds.size > 0;
|
|
35
|
+
if (!hasAdmins) {
|
|
36
|
+
canopyLogWarn('CanopyCMS: No admin users configured. Set CANOPY_BOOTSTRAP_ADMIN_IDS or add members to the Admins group.');
|
|
37
|
+
}
|
|
38
|
+
warnedNoAdmins = true;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolve the CanopyUser for a request: load internal groups from the
|
|
42
|
+
* settings workspace and merge them (plus bootstrap admins) into an
|
|
43
|
+
* authentication result via `authResultToCanopyUser`.
|
|
44
|
+
*
|
|
45
|
+
* Framework-agnostic: callers supply the already-computed `authResult` (from
|
|
46
|
+
* whatever auth-plugin invocation their transport uses) and a small deps
|
|
47
|
+
* bag drawn from `CanopyServices`.
|
|
48
|
+
*/
|
|
49
|
+
export async function resolveCanopyUser(authResult, deps) {
|
|
50
|
+
const settingsRoot = await deps.getSettingsBranchRoot();
|
|
51
|
+
const internalGroups = await loadInternalGroups(settingsRoot, deps.mode, deps.bootstrapAdminIds);
|
|
52
|
+
warnIfNoAdmins(internalGroups, deps.bootstrapAdminIds);
|
|
53
|
+
return authResultToCanopyUser(authResult, deps.bootstrapAdminIds, internalGroups);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=resolve-canopy-user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-canopy-user.js","sourceRoot":"","sources":["../src/resolve-canopy-user.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAG9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAsB,MAAM,iBAAiB,CAAA;AAGzF,yFAAyF;AACzF,IAAI,cAAc,GAAG,KAAK,CAAA;AAE1B,kFAAkF;AAClF,MAAM,UAAU,qCAAqC;IACnD,cAAc,GAAG,KAAK,CAAA;AACxB,CAAC;AAqBD,SAAS,cAAc,CAAC,cAA+B,EAAE,iBAA8B;IACrF,IAAI,cAAc;QAAE,OAAM;IAC1B,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,MAAM,CAAC,CAAA;IAC/E,MAAM,SAAS,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC,IAAI,GAAG,CAAC,CAAA;IACtF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,aAAa,CACX,0GAA0G,CAC3G,CAAA;IACH,CAAC;IACD,cAAc,GAAG,IAAI,CAAA;AACvB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAgC,EAChC,IAA2B;IAE3B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAA;IACvD,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAEhG,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAEtD,OAAO,sBAAsB,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;AACnF,CAAC"}
|