canopycms 0.0.56 → 0.0.58
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 +74 -3
- package/dist/ai/json-to-markdown.js.map +1 -1
- package/dist/api/__test__/mock-client.d.ts +9 -5
- package/dist/api/__test__/mock-client.d.ts.map +1 -1
- package/dist/api/__test__/mock-client.js +15 -7
- package/dist/api/__test__/mock-client.js.map +1 -1
- package/dist/api/assets.d.ts +100 -36
- package/dist/api/assets.d.ts.map +1 -1
- package/dist/api/assets.js +338 -51
- package/dist/api/assets.js.map +1 -1
- package/dist/api/branch.d.ts +6 -0
- package/dist/api/branch.d.ts.map +1 -1
- package/dist/api/branch.js +63 -19
- package/dist/api/branch.js.map +1 -1
- package/dist/api/client.d.ts +16 -5
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +24 -6
- package/dist/api/client.js.map +1 -1
- package/dist/api/content.d.ts +2 -2
- package/dist/api/entries.d.ts +4 -4
- package/dist/api/entries.d.ts.map +1 -1
- package/dist/api/entries.js +10 -2
- package/dist/api/entries.js.map +1 -1
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/route-builder.d.ts +9 -0
- package/dist/api/route-builder.d.ts.map +1 -1
- package/dist/api/route-builder.js +1 -0
- package/dist/api/route-builder.js.map +1 -1
- package/dist/api/schema.d.ts +4 -4
- package/dist/api/types.d.ts +11 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/assets/asset-prefixes.d.ts +31 -0
- package/dist/assets/asset-prefixes.d.ts.map +1 -0
- package/dist/assets/asset-prefixes.js +20 -0
- package/dist/assets/asset-prefixes.js.map +1 -0
- package/dist/assets/asset-src.d.ts +23 -0
- package/dist/assets/asset-src.d.ts.map +1 -0
- package/dist/assets/asset-src.js +28 -0
- package/dist/assets/asset-src.js.map +1 -0
- package/dist/assets/asset-url.d.ts +35 -0
- package/dist/assets/asset-url.d.ts.map +1 -0
- package/dist/assets/asset-url.js +77 -0
- package/dist/assets/asset-url.js.map +1 -0
- package/dist/assets/factory.d.ts +18 -0
- package/dist/assets/factory.d.ts.map +1 -0
- package/dist/assets/factory.js +42 -0
- package/dist/assets/factory.js.map +1 -0
- package/dist/assets/finalize.d.ts +36 -0
- package/dist/assets/finalize.d.ts.map +1 -0
- package/dist/assets/finalize.js +72 -0
- package/dist/assets/finalize.js.map +1 -0
- package/dist/assets/index.d.ts +20 -0
- package/dist/assets/index.d.ts.map +1 -0
- package/dist/assets/index.js +19 -0
- package/dist/assets/index.js.map +1 -0
- package/dist/assets/keys.d.ts +56 -0
- package/dist/assets/keys.d.ts.map +1 -0
- package/dist/assets/keys.js +88 -0
- package/dist/assets/keys.js.map +1 -0
- package/dist/assets/pipeline.d.ts +50 -0
- package/dist/assets/pipeline.d.ts.map +1 -0
- package/dist/assets/pipeline.js +202 -0
- package/dist/assets/pipeline.js.map +1 -0
- package/dist/assets/store-local.d.ts +84 -0
- package/dist/assets/store-local.d.ts.map +1 -0
- package/dist/assets/store-local.js +254 -0
- package/dist/assets/store-local.js.map +1 -0
- package/dist/assets/store-s3.d.ts +71 -0
- package/dist/assets/store-s3.d.ts.map +1 -0
- package/dist/assets/store-s3.js +183 -0
- package/dist/assets/store-s3.js.map +1 -0
- package/dist/assets/svg-sanitizer.d.ts +37 -0
- package/dist/assets/svg-sanitizer.d.ts.map +1 -0
- package/dist/assets/svg-sanitizer.js +222 -0
- package/dist/assets/svg-sanitizer.js.map +1 -0
- package/dist/assets/transform-directives.d.ts +97 -0
- package/dist/assets/transform-directives.d.ts.map +1 -0
- package/dist/assets/transform-directives.js +267 -0
- package/dist/assets/transform-directives.js.map +1 -0
- package/dist/assets/transform.d.ts +51 -0
- package/dist/assets/transform.d.ts.map +1 -0
- package/dist/assets/transform.js +190 -0
- package/dist/assets/transform.js.map +1 -0
- package/dist/assets/types.d.ts +82 -0
- package/dist/assets/types.d.ts.map +1 -0
- package/dist/assets/types.js +10 -0
- package/dist/assets/types.js.map +1 -0
- package/dist/authorization/groups/schema.d.ts +2 -2
- package/dist/authorization/permissions/schema.d.ts +2 -2
- package/dist/branch-metadata.d.ts +71 -6
- package/dist/branch-metadata.d.ts.map +1 -1
- package/dist/branch-metadata.js +132 -116
- package/dist/branch-metadata.js.map +1 -1
- package/dist/branch-registry.d.ts +78 -9
- package/dist/branch-registry.d.ts.map +1 -1
- package/dist/branch-registry.js +155 -29
- package/dist/branch-registry.js.map +1 -1
- package/dist/branch-schema-cache.d.ts +126 -11
- package/dist/branch-schema-cache.d.ts.map +1 -1
- package/dist/branch-schema-cache.js +208 -58
- package/dist/branch-schema-cache.js.map +1 -1
- package/dist/cli/generate-ai-content.js +1993 -1506
- package/dist/cli/init.js +16 -4
- package/dist/cli/migrate.d.ts.map +1 -1
- package/dist/cli/migrate.js +25 -0
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/sync.js +5 -5
- package/dist/cli/sync.js.map +1 -1
- package/dist/comment-store.d.ts +45 -15
- package/dist/comment-store.d.ts.map +1 -1
- package/dist/comment-store.js +80 -101
- package/dist/comment-store.js.map +1 -1
- package/dist/config/helpers.d.ts.map +1 -1
- package/dist/config/helpers.js +2 -1
- package/dist/config/helpers.js.map +1 -1
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/schemas/config.d.ts +10 -0
- package/dist/config/schemas/config.d.ts.map +1 -1
- package/dist/config/schemas/field.d.ts +38 -3
- package/dist/config/schemas/field.d.ts.map +1 -1
- package/dist/config/schemas/field.js +18 -0
- package/dist/config/schemas/field.js.map +1 -1
- package/dist/config/schemas/media.d.ts +8 -0
- package/dist/config/schemas/media.d.ts.map +1 -1
- package/dist/config/schemas/media.js +9 -0
- package/dist/config/schemas/media.js.map +1 -1
- package/dist/config/types.d.ts +43 -3
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +4 -1
- package/dist/config/types.js.map +1 -1
- package/dist/content-index-generation.d.ts +40 -4
- package/dist/content-index-generation.d.ts.map +1 -1
- package/dist/content-index-generation.js +70 -73
- package/dist/content-index-generation.js.map +1 -1
- package/dist/content-store.d.ts +63 -0
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +421 -194
- package/dist/content-store.js.map +1 -1
- package/dist/editor/CanopyEditor.d.ts.map +1 -1
- package/dist/editor/CanopyEditor.js +1 -1
- package/dist/editor/CanopyEditor.js.map +1 -1
- package/dist/editor/Editor.d.ts +2 -0
- package/dist/editor/Editor.d.ts.map +1 -1
- package/dist/editor/Editor.js +82 -80
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/FormRenderer.d.ts.map +1 -1
- package/dist/editor/FormRenderer.js +9 -0
- package/dist/editor/FormRenderer.js.map +1 -1
- package/dist/editor/components/EditorSidebar.d.ts +6 -1
- package/dist/editor/components/EditorSidebar.d.ts.map +1 -1
- package/dist/editor/components/EditorSidebar.js +4 -3
- package/dist/editor/components/EditorSidebar.js.map +1 -1
- package/dist/editor/context/AssetContext.d.ts +25 -0
- package/dist/editor/context/AssetContext.d.ts.map +1 -0
- package/dist/editor/context/AssetContext.js +26 -0
- package/dist/editor/context/AssetContext.js.map +1 -0
- package/dist/editor/context/index.d.ts +1 -0
- package/dist/editor/context/index.d.ts.map +1 -1
- package/dist/editor/context/index.js +1 -0
- package/dist/editor/context/index.js.map +1 -1
- package/dist/editor/fields/ImageField.d.ts +22 -0
- package/dist/editor/fields/ImageField.d.ts.map +1 -0
- package/dist/editor/fields/ImageField.js +100 -0
- package/dist/editor/fields/ImageField.js.map +1 -0
- package/dist/editor/fields/MarkdownField.d.ts.map +1 -1
- package/dist/editor/fields/MarkdownField.js +30 -4
- package/dist/editor/fields/MarkdownField.js.map +1 -1
- package/dist/editor/fields/MdxImageDialog.d.ts +16 -0
- package/dist/editor/fields/MdxImageDialog.d.ts.map +1 -0
- package/dist/editor/fields/MdxImageDialog.js +73 -0
- package/dist/editor/fields/MdxImageDialog.js.map +1 -0
- package/dist/editor/media/AssetCard.d.ts +21 -0
- package/dist/editor/media/AssetCard.d.ts.map +1 -0
- package/dist/editor/media/AssetCard.js +41 -0
- package/dist/editor/media/AssetCard.js.map +1 -0
- package/dist/editor/media/CropStep.d.ts +26 -0
- package/dist/editor/media/CropStep.d.ts.map +1 -0
- package/dist/editor/media/CropStep.js +38 -0
- package/dist/editor/media/CropStep.js.map +1 -0
- package/dist/editor/media/MediaLibrary.d.ts +22 -0
- package/dist/editor/media/MediaLibrary.d.ts.map +1 -0
- package/dist/editor/media/MediaLibrary.js +17 -0
- package/dist/editor/media/MediaLibrary.js.map +1 -0
- package/dist/editor/media/MediaLibraryBody.d.ts +17 -0
- package/dist/editor/media/MediaLibraryBody.d.ts.map +1 -0
- package/dist/editor/media/MediaLibraryBody.js +133 -0
- package/dist/editor/media/MediaLibraryBody.js.map +1 -0
- package/dist/editor/media/crop-math.d.ts +37 -0
- package/dist/editor/media/crop-math.d.ts.map +1 -0
- package/dist/editor/media/crop-math.js +62 -0
- package/dist/editor/media/crop-math.js.map +1 -0
- package/dist/editor/media/upload-asset.d.ts +31 -0
- package/dist/editor/media/upload-asset.d.ts.map +1 -0
- package/dist/editor/media/upload-asset.js +56 -0
- package/dist/editor/media/upload-asset.js.map +1 -0
- package/dist/editor/media/upload-constants.d.ts +27 -0
- package/dist/editor/media/upload-constants.d.ts.map +1 -0
- package/dist/editor/media/upload-constants.js +40 -0
- package/dist/editor/media/upload-constants.js.map +1 -0
- package/dist/editor/media/useAssetUpload.d.ts +19 -0
- package/dist/editor/media/useAssetUpload.d.ts.map +1 -0
- package/dist/editor/media/useAssetUpload.js +53 -0
- package/dist/editor/media/useAssetUpload.js.map +1 -0
- package/dist/editor/media/xhr-upload.d.ts +20 -0
- package/dist/editor/media/xhr-upload.d.ts.map +1 -0
- package/dist/editor/media/xhr-upload.js +42 -0
- package/dist/editor/media/xhr-upload.js.map +1 -0
- package/dist/editor/theme.d.ts +2 -1
- package/dist/editor/theme.d.ts.map +1 -1
- package/dist/editor/theme.js +1 -0
- package/dist/editor/theme.js.map +1 -1
- package/dist/entry-schema.d.ts +19 -0
- package/dist/entry-schema.d.ts.map +1 -1
- package/dist/entry-schema.js.map +1 -1
- package/dist/git-manager.d.ts +15 -10
- package/dist/git-manager.d.ts.map +1 -1
- package/dist/git-manager.js +16 -11
- package/dist/git-manager.js.map +1 -1
- package/dist/http/handler.d.ts +5 -2
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/handler.js +13 -4
- package/dist/http/handler.js.map +1 -1
- package/dist/http/index.d.ts +2 -2
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +1 -1
- package/dist/http/index.js.map +1 -1
- package/dist/http/router.d.ts +14 -1
- package/dist/http/router.d.ts.map +1 -1
- package/dist/http/router.js +4 -1
- package/dist/http/router.js.map +1 -1
- package/dist/http/types.d.ts +40 -0
- package/dist/http/types.d.ts.map +1 -1
- package/dist/http/types.js +9 -0
- package/dist/http/types.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/resource-generation.d.ts +54 -0
- package/dist/resource-generation.d.ts.map +1 -0
- package/dist/resource-generation.js +156 -0
- package/dist/resource-generation.js.map +1 -0
- package/dist/schema/schema-store.d.ts +31 -4
- package/dist/schema/schema-store.d.ts.map +1 -1
- package/dist/schema/schema-store.js +47 -8
- package/dist/schema/schema-store.js.map +1 -1
- package/dist/server.d.ts +45 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +41 -0
- package/dist/server.js.map +1 -1
- package/dist/sync-core.js +2 -2
- package/dist/sync-core.js.map +1 -1
- package/dist/utils/occ-json-write.d.ts +100 -0
- package/dist/utils/occ-json-write.d.ts.map +1 -0
- package/dist/utils/occ-json-write.js +234 -0
- package/dist/utils/occ-json-write.js.map +1 -0
- package/dist/validation/entry-validator.d.ts.map +1 -1
- package/dist/validation/entry-validator.js +56 -1
- package/dist/validation/entry-validator.js.map +1 -1
- package/dist/worker/cms-worker.d.ts.map +1 -1
- package/dist/worker/cms-worker.js +21 -3
- package/dist/worker/cms-worker.js.map +1 -1
- package/package.json +13 -1
- package/dist/asset-store.d.ts +0 -32
- package/dist/asset-store.d.ts.map +0 -1
- package/dist/asset-store.js +0 -85
- package/dist/asset-store.js.map +0 -1
package/dist/http/handler.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsonResponse } from './types.js';
|
|
1
|
+
import { jsonResponse, isCanopyBinaryResponse } from './types.js';
|
|
2
2
|
import { createCanopyRouter } from './router.js';
|
|
3
3
|
import { assertAuthPluginAllowedForMode } from '../auth/plugin.js';
|
|
4
4
|
import { createCanopyServices } from '../services.js';
|
|
@@ -193,9 +193,11 @@ export function createCanopyRequestHandler(options) {
|
|
|
193
193
|
// Parse query params and merge with route params
|
|
194
194
|
const queryParams = parseQueryParams(req.url);
|
|
195
195
|
const mergedParams = { ...queryParams, ...match.params };
|
|
196
|
-
// Parse body for non-GET requests
|
|
196
|
+
// Parse body for non-GET requests. Multipart routes opt out (bodyFormat)
|
|
197
|
+
// so their handler can read the (single-use) body stream itself via
|
|
198
|
+
// req.formData() - calling req.json() first would consume it.
|
|
197
199
|
let body;
|
|
198
|
-
if (req.method !== 'GET') {
|
|
200
|
+
if (req.method !== 'GET' && match.bodyFormat !== 'multipart') {
|
|
199
201
|
try {
|
|
200
202
|
body = await req.json();
|
|
201
203
|
}
|
|
@@ -206,7 +208,7 @@ export function createCanopyRequestHandler(options) {
|
|
|
206
208
|
// Build API request
|
|
207
209
|
const branch = mergedParams?.branch ??
|
|
208
210
|
body?.branch;
|
|
209
|
-
const apiReq = { user, body, branch, query: queryParams };
|
|
211
|
+
const apiReq = { user, body, branch, query: queryParams, rawRequest: req };
|
|
210
212
|
// Validate params and body using the route's validation function (if available)
|
|
211
213
|
if (match.validate) {
|
|
212
214
|
const validationResult = match.validate({ params: mergedParams, body });
|
|
@@ -222,12 +224,19 @@ export function createCanopyRequestHandler(options) {
|
|
|
222
224
|
handlerArgs.push(validationResult.body);
|
|
223
225
|
}
|
|
224
226
|
const result = await match.handler(...handlerArgs);
|
|
227
|
+
// Binary routes (e.g. asset serving) carry their own status/headers and
|
|
228
|
+
// must reach the adapter untouched - wrapping them in jsonResponse would
|
|
229
|
+
// JSON-serialize raw bytes and lose contentType/contentDisposition/etc.
|
|
230
|
+
if (isCanopyBinaryResponse(result))
|
|
231
|
+
return result;
|
|
225
232
|
return jsonResponse(result, result.status);
|
|
226
233
|
}
|
|
227
234
|
else {
|
|
228
235
|
// Should not happen - all routes should use defineEndpoint now
|
|
229
236
|
// This is here for safety in case any route doesn't have validation
|
|
230
237
|
const result = await match.handler(apiCtx, apiReq, mergedParams);
|
|
238
|
+
if (isCanopyBinaryResponse(result))
|
|
239
|
+
return result;
|
|
231
240
|
return jsonResponse(result, result.status);
|
|
232
241
|
}
|
|
233
242
|
};
|
package/dist/http/handler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/http/handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/http/handler.ts"],"names":[],"mappings":"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"}
|
package/dist/http/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type { CanopyRequest, CanopyResponse } from './types';
|
|
2
|
-
export { jsonResponse } from './types';
|
|
1
|
+
export type { CanopyRequest, CanopyResponse, CanopyBinaryResponse } from './types';
|
|
2
|
+
export { jsonResponse, isCanopyBinaryResponse } from './types';
|
|
3
3
|
export type { CanopyHandler, RouteDefinition, RouteMatch, CanopyRouter } from './router';
|
|
4
4
|
export { createCanopyRouter } from './router';
|
|
5
5
|
export type { CanopyHandlerOptions, CanopyRequestHandler } from './handler';
|
package/dist/http/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAG9D,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAG7C,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAC3E,OAAO,EAAE,0BAA0B,EAAE,oCAAoC,EAAE,MAAM,WAAW,CAAA"}
|
package/dist/http/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { jsonResponse } from './types.js';
|
|
1
|
+
export { jsonResponse, isCanopyBinaryResponse } from './types.js';
|
|
2
2
|
export { createCanopyRouter } from './router.js';
|
|
3
3
|
export { createCanopyRequestHandler, createCanopyRequestHandlerFromConfig } from './handler.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/http/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAI9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAI7C,OAAO,EAAE,0BAA0B,EAAE,oCAAoC,EAAE,MAAM,WAAW,CAAA"}
|
package/dist/http/router.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { ApiResponse } from '../api/types';
|
|
2
|
+
import type { CanopyBinaryResponse } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* Handler function signature for Canopy API routes.
|
|
4
5
|
* Uses `any` to accommodate different handler signatures in the codebase.
|
|
5
6
|
* Some handlers take (ctx, req, params), others take (ctx, params) directly.
|
|
7
|
+
* Return type is widened to include `CanopyBinaryResponse` so routes that
|
|
8
|
+
* stream bytes (e.g. asset serving) can be registered in the same route
|
|
9
|
+
* table as ordinary JSON routes; the core handler discriminates on `kind`
|
|
10
|
+
* before deciding whether to wrap the result in a JSON envelope.
|
|
6
11
|
*/
|
|
7
|
-
export type CanopyHandler = (...args: any[]) => Promise<ApiResponse<any
|
|
12
|
+
export type CanopyHandler = (...args: any[]) => Promise<ApiResponse<any> | CanopyBinaryResponse>;
|
|
8
13
|
/**
|
|
9
14
|
* Route definition for the Canopy API.
|
|
10
15
|
* Maps HTTP method + path pattern to a handler.
|
|
@@ -24,6 +29,13 @@ export interface RouteDefinition {
|
|
|
24
29
|
ok: false;
|
|
25
30
|
error: string;
|
|
26
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* Opt out of the core handler's default eager `req.json()` body parsing
|
|
34
|
+
* (see http/handler.ts). Set by routes that accept a non-JSON body (e.g.
|
|
35
|
+
* multipart/form-data uploads) - the handler must read the body itself via
|
|
36
|
+
* `req.formData()` instead, since a body stream can only be consumed once.
|
|
37
|
+
*/
|
|
38
|
+
bodyFormat?: 'multipart';
|
|
27
39
|
}
|
|
28
40
|
/**
|
|
29
41
|
* Result of route matching.
|
|
@@ -32,6 +44,7 @@ export interface RouteMatch {
|
|
|
32
44
|
handler: CanopyHandler;
|
|
33
45
|
params: Record<string, string>;
|
|
34
46
|
validate?: RouteDefinition['validate'];
|
|
47
|
+
bodyFormat?: RouteDefinition['bodyFormat'];
|
|
35
48
|
}
|
|
36
49
|
/**
|
|
37
50
|
* Core router - framework-agnostic route matching.
|
|
@@ -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;
|
|
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;AAcnD;;;;;;;;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;AAyHD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAAE,GACjB,UAAU,GAAG,IAAI,CA0BnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAOjD"}
|
package/dist/http/router.js
CHANGED
|
@@ -5,7 +5,7 @@ import { CONTENT_ROUTES } from '../api/content.js';
|
|
|
5
5
|
import { REFERENCE_OPTIONS_ROUTES } from '../api/reference-options.js';
|
|
6
6
|
import { RESOLVE_REFERENCES_ROUTES } from '../api/resolve-references.js';
|
|
7
7
|
import { ENTRY_ROUTES } from '../api/entries.js';
|
|
8
|
-
import { ASSET_ROUTES } from '../api/assets.js';
|
|
8
|
+
import { ASSET_ROUTES, assetRawRoute } from '../api/assets.js';
|
|
9
9
|
import { PERMISSION_ROUTES } from '../api/permissions.js';
|
|
10
10
|
import { GROUP_ROUTES } from '../api/groups.js';
|
|
11
11
|
import { USER_ROUTES } from '../api/user.js';
|
|
@@ -28,6 +28,7 @@ function buildCanopyRoutes() {
|
|
|
28
28
|
...Object.values(RESOLVE_REFERENCES_ROUTES),
|
|
29
29
|
...Object.values(ENTRY_ROUTES),
|
|
30
30
|
...Object.values(ASSET_ROUTES),
|
|
31
|
+
assetRawRoute,
|
|
31
32
|
...Object.values(PERMISSION_ROUTES),
|
|
32
33
|
...Object.values(GROUP_ROUTES),
|
|
33
34
|
...Object.values(USER_ROUTES),
|
|
@@ -38,6 +39,7 @@ function buildCanopyRoutes() {
|
|
|
38
39
|
handler: route.handler,
|
|
39
40
|
// Include validation function if present (new-style routes from defineEndpoint)
|
|
40
41
|
validate: 'validate' in route ? route.validate : undefined,
|
|
42
|
+
bodyFormat: 'bodyFormat' in route ? route.bodyFormat : undefined,
|
|
41
43
|
}));
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
@@ -149,6 +151,7 @@ export function matchRoute(routes, method, segments) {
|
|
|
149
151
|
handler: best.route.handler,
|
|
150
152
|
params: best.params,
|
|
151
153
|
validate: best.route.validate, // Include validation function if present
|
|
154
|
+
bodyFormat: best.route.bodyFormat,
|
|
152
155
|
};
|
|
153
156
|
}
|
|
154
157
|
/**
|
package/dist/http/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/http/router.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/http/router.ts"],"names":[],"mappings":"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"}
|
package/dist/http/types.d.ts
CHANGED
|
@@ -17,6 +17,22 @@ export interface CanopyRequest {
|
|
|
17
17
|
* Returns undefined for GET requests or empty bodies.
|
|
18
18
|
*/
|
|
19
19
|
json(): Promise<unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* Read the raw request body as bytes, bypassing JSON parsing.
|
|
22
|
+
* Optional: only wired by adapters that need to support non-JSON bodies
|
|
23
|
+
* (e.g. proxied binary/multipart uploads). Bare CanopyRequest mocks/test
|
|
24
|
+
* harnesses that omit this keep compiling.
|
|
25
|
+
*
|
|
26
|
+
* Like the underlying platform Request, the body stream can only be
|
|
27
|
+
* consumed once - callers must not also call `json()`/`formData()` on the
|
|
28
|
+
* same request.
|
|
29
|
+
*/
|
|
30
|
+
rawBody?(): Promise<Uint8Array>;
|
|
31
|
+
/**
|
|
32
|
+
* Parse the request body as multipart/form-data.
|
|
33
|
+
* Optional for the same reason as `rawBody` above.
|
|
34
|
+
*/
|
|
35
|
+
formData?(): Promise<FormData>;
|
|
20
36
|
}
|
|
21
37
|
/**
|
|
22
38
|
* Framework-agnostic HTTP response.
|
|
@@ -27,8 +43,32 @@ export interface CanopyResponse<T = unknown> {
|
|
|
27
43
|
readonly body: T;
|
|
28
44
|
readonly headers?: Record<string, string>;
|
|
29
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Framework-agnostic binary HTTP response (e.g. serving image/PDF bytes).
|
|
48
|
+
* Distinct from `CanopyResponse` via the `kind` discriminant so adapters can
|
|
49
|
+
* dispatch on response shape without a cast: `body` is arbitrary bytes
|
|
50
|
+
* (or a stream of them), not a JSON-serializable value.
|
|
51
|
+
*/
|
|
52
|
+
export interface CanopyBinaryResponse {
|
|
53
|
+
readonly kind: 'binary';
|
|
54
|
+
readonly status: number;
|
|
55
|
+
readonly body: Uint8Array | ReadableStream<Uint8Array>;
|
|
56
|
+
readonly headers: {
|
|
57
|
+
contentType?: string;
|
|
58
|
+
contentDisposition?: string;
|
|
59
|
+
cacheControl?: string;
|
|
60
|
+
etag?: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
30
63
|
/**
|
|
31
64
|
* Create a JSON response with the given body and status code.
|
|
32
65
|
*/
|
|
33
66
|
export declare function jsonResponse<T>(body: T, status?: number, headers?: Record<string, string>): CanopyResponse<T>;
|
|
67
|
+
/**
|
|
68
|
+
* Type guard distinguishing `CanopyBinaryResponse` from any other route
|
|
69
|
+
* result (`ApiResponse`/`CanopyResponse`, neither of which declare `kind`).
|
|
70
|
+
* Framework adapters and the core handler use this to decide whether to
|
|
71
|
+
* pass a route result through untouched or wrap it via `jsonResponse`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function isCanopyBinaryResponse(value: unknown): value is CanopyBinaryResponse;
|
|
34
74
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/http/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/http/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IAEvB,iCAAiC;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEnC;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/http/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IAEvB,iCAAiC;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEnC;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IAExB;;;;;;;;;OASG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,CAAA;IAE/B;;;OAGG;IACH,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAA;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAChB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC1C;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,CAAA;IACtD,QAAQ,CAAC,OAAO,EAAE;QAChB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,IAAI,EAAE,CAAC,EACP,MAAM,SAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,cAAc,CAAC,CAAC,CAAC,CAEnB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAIpF"}
|
package/dist/http/types.js
CHANGED
|
@@ -4,4 +4,13 @@
|
|
|
4
4
|
export function jsonResponse(body, status = 200, headers) {
|
|
5
5
|
return { status, body, headers };
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Type guard distinguishing `CanopyBinaryResponse` from any other route
|
|
9
|
+
* result (`ApiResponse`/`CanopyResponse`, neither of which declare `kind`).
|
|
10
|
+
* Framework adapters and the core handler use this to decide whether to
|
|
11
|
+
* pass a route result through untouched or wrap it via `jsonResponse`.
|
|
12
|
+
*/
|
|
13
|
+
export function isCanopyBinaryResponse(value) {
|
|
14
|
+
return (typeof value === 'object' && value !== null && value.kind === 'binary');
|
|
15
|
+
}
|
|
7
16
|
//# sourceMappingURL=types.js.map
|
package/dist/http/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/http/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/http/types.ts"],"names":[],"mappings":"AAsEA;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAO,EACP,MAAM,GAAG,GAAG,EACZ,OAAgC;IAEhC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAClC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAA4B,CAAC,IAAI,KAAK,QAAQ,CAC/F,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,4 +11,7 @@ export { isCanopyRequest, isHeadersLike, extractHeaders, validateAuthContext, }
|
|
|
11
11
|
export type { HeadersLike } from './auth/context-helpers';
|
|
12
12
|
export type { ContentTreeNode, BuildContentTreeOptions, ContentTreeExtractMeta, EntryTypeMap, DefaultEntryTypes, } from './content-tree';
|
|
13
13
|
export type { ListEntriesItem, ListEntriesOptions } from './content-listing';
|
|
14
|
+
export { assetUrl, assetSrcSet } from './assets/asset-url';
|
|
15
|
+
export type { AssetRef, AssetUrlOptions } from './assets/asset-url';
|
|
16
|
+
export type { OutputFormat, CropRect, TransformDirectives } from './assets/transform-directives';
|
|
14
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AAGtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAClD,YAAY,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,YAAY,CAAA;AAGnB,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAClE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACzF,OAAO,EACL,eAAe,EACf,aAAa,EACb,cAAc,EACd,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACzD,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,YAAY,EACZ,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AAGtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAClD,YAAY,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,YAAY,CAAA;AAGnB,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAClE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACzF,OAAO,EACL,eAAe,EACf,aAAa,EACb,cAAc,EACd,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACzD,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,YAAY,EACZ,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAI5E,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAC1D,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACnE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -7,4 +7,8 @@ export * from './user.js';
|
|
|
7
7
|
// Server-only AI features (handler, generator) are in 'canopycms/ai'.
|
|
8
8
|
export { defineAIContentConfig } from './ai/types.js';
|
|
9
9
|
export { isCanopyRequest, isHeadersLike, extractHeaders, validateAuthContext, } from './auth/context-helpers.js';
|
|
10
|
+
// Asset URL helpers — client-safe (no node: imports). Build/adjust transform
|
|
11
|
+
// URLs for <img>/srcset from stored asset refs without pulling in the
|
|
12
|
+
// server-only transform engine (canopycms's assets/transform.ts, sharp).
|
|
13
|
+
export { assetUrl, assetSrcSet } from './assets/asset-url.js';
|
|
10
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,6DAA6D;AAC7D,sEAAsE;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAalD,OAAO,EACL,eAAe,EACf,aAAa,EACb,cAAc,EACd,mBAAmB,GACpB,MAAM,wBAAwB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,6DAA6D;AAC7D,sEAAsE;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAalD,OAAO,EACL,eAAe,EACf,aAAa,EACb,cAAc,EACd,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;AAU/B,6EAA6E;AAC7E,sEAAsE;AACtE,yEAAyE;AACzE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Absolute path of the generation marker for `resource` under `root`. */
|
|
2
|
+
export declare function resourceGenerationPath(root: string, resource: string): string;
|
|
3
|
+
export interface BumpResourceGenerationOptions {
|
|
4
|
+
/**
|
|
5
|
+
* When true, a failed bump rethrows instead of being logged and swallowed.
|
|
6
|
+
* Use this for callers where a lost bump means indefinitely stale durable
|
|
7
|
+
* data with no bounding backstop (e.g. a registry's invalidate()) — those
|
|
8
|
+
* callers must not silently succeed while leaving stale readers unaware.
|
|
9
|
+
* Default false (hint flavor): log-warn and swallow, since the mutation
|
|
10
|
+
* itself is already durable and a lost bump only degrades to pre-marker
|
|
11
|
+
* staleness behavior plus whatever backstop the consumer has.
|
|
12
|
+
*/
|
|
13
|
+
mustSucceed?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Record on disk that `resource` changed under `root`, so consumers in OTHER
|
|
17
|
+
* processes rebuild. Must be called AFTER the filesystem mutation.
|
|
18
|
+
*
|
|
19
|
+
* Returns the token written, or null if the write failed and `mustSucceed`
|
|
20
|
+
* was not set (logged and swallowed).
|
|
21
|
+
*/
|
|
22
|
+
export declare function bumpResourceGeneration(root: string, resource: string, options?: BumpResourceGenerationOptions): Promise<string | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Result of reading a generation marker. `ok: false` means the read failed
|
|
25
|
+
* for a reason OTHER than "marker doesn't exist yet" — callers should treat
|
|
26
|
+
* this as "force regenerate" rather than folding it into a token value,
|
|
27
|
+
* because a legitimate snapshot can embed `token: null` (a fresh clone,
|
|
28
|
+
* regenerated before any bump ever occurred) and that must stay
|
|
29
|
+
* distinguishable from "we don't actually know the current token".
|
|
30
|
+
*/
|
|
31
|
+
export type GenerationReadResult = {
|
|
32
|
+
ok: true;
|
|
33
|
+
token: string | null;
|
|
34
|
+
} | {
|
|
35
|
+
ok: false;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Read the current generation token for `resource` under `root`.
|
|
39
|
+
*
|
|
40
|
+
* ENOENT maps to `{ok: true, token: null}` — a valid "never bumped" state,
|
|
41
|
+
* distinct from every real token. Any OTHER read error maps to `{ok: false}`
|
|
42
|
+
* (logged) so callers can force-regenerate instead of trusting a null they
|
|
43
|
+
* cannot actually attribute to "never bumped".
|
|
44
|
+
*/
|
|
45
|
+
export declare function readResourceGeneration(root: string, resource: string): Promise<GenerationReadResult>;
|
|
46
|
+
/**
|
|
47
|
+
* True when a previously-captured snapshot token is still current: the read
|
|
48
|
+
* succeeded AND its token matches the snapshot's. A failed read (`ok: false`)
|
|
49
|
+
* is never current, even if the snapshot's token happens to be null — an
|
|
50
|
+
* unreadable marker means we cannot vouch for freshness either way, and the
|
|
51
|
+
* safe default is to treat it as stale.
|
|
52
|
+
*/
|
|
53
|
+
export declare function isGenerationCurrent(snapshotToken: string | null, read: GenerationReadResult): boolean;
|
|
54
|
+
//# sourceMappingURL=resource-generation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-generation.d.ts","sourceRoot":"","sources":["../src/resource-generation.ts"],"names":[],"mappings":"AAqGA,0EAA0E;AAC1E,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,MAAM,WAAW,6BAA6B;IAC5C;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,6BAA6B,GACtC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAA;AAErF;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAW/B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAET"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { atomicWriteFile } from './utils/atomic-write.js';
|
|
5
|
+
import { getErrorMessage, isNodeError } from './utils/error.js';
|
|
6
|
+
import { createDebugLogger } from './utils/debug.js';
|
|
7
|
+
/**
|
|
8
|
+
* Generalized cross-process generation marker for any on-disk resource that
|
|
9
|
+
* is durably cached under a branch-clone (or similar) root.
|
|
10
|
+
*
|
|
11
|
+
* Some in-process cache is kept per resource per process (an in-memory index,
|
|
12
|
+
* a parsed schema, a registry snapshot). Within one process, mutating code can
|
|
13
|
+
* invalidate that cache directly. Across processes (several warm Lambda
|
|
14
|
+
* containers + the EC2 worker sharing branch clones on EFS) there is no
|
|
15
|
+
* shared memory and no cross-host file watching, so the shared filesystem
|
|
16
|
+
* itself is the coordination medium: every operation that mutates the
|
|
17
|
+
* resource also rewrites a small marker file with a fresh random token, and
|
|
18
|
+
* every consumer cheaply re-reads that marker (throttled) to decide whether
|
|
19
|
+
* its cached snapshot is still current.
|
|
20
|
+
*
|
|
21
|
+
* The marker for a given `resource` lives at {root}/.canopy-meta/{resource}.generation:
|
|
22
|
+
* `.canopy-meta/` is the established per-clone internal dir — dot-prefixed (so
|
|
23
|
+
* content and index scans skip it) and excluded from git via .git/info/exclude.
|
|
24
|
+
*
|
|
25
|
+
* ## Why a random token instead of a monotonic counter
|
|
26
|
+
*
|
|
27
|
+
* Readers only need "did it change since I captured it", so inequality against
|
|
28
|
+
* the captured value suffices. A counter would need read-modify-write, which
|
|
29
|
+
* silently loses concurrent bumps without a lock (two bumpers read 5, both
|
|
30
|
+
* write 6 — a reader that recorded 6 after the first bump never learns of the
|
|
31
|
+
* second mutation). A unique token per bump has no lost-update problem, needs
|
|
32
|
+
* no lock, and avoids NFS mtime-granularity / cross-host clock-skew issues.
|
|
33
|
+
* Each bump is a single atomic temp-file + rename.
|
|
34
|
+
*
|
|
35
|
+
* ## Ordering protocol (correctness)
|
|
36
|
+
*
|
|
37
|
+
* - Bumpers write the marker strictly AFTER their filesystem mutations.
|
|
38
|
+
* - Readers capture the marker token strictly BEFORE scanning/rebuilding the
|
|
39
|
+
* resource, and record it only after the rebuild completes. A bump landing
|
|
40
|
+
* mid-rebuild therefore leaves the recorded token older than the file,
|
|
41
|
+
* forcing another rebuild on the next probe.
|
|
42
|
+
*
|
|
43
|
+
* ## Consistency guarantees and residual staleness windows (EFS/NFSv4)
|
|
44
|
+
*
|
|
45
|
+
* Guaranteed: any completed mutation that bumps the marker is observed by
|
|
46
|
+
* every consumer on that root at its next freshness probe. Residual windows
|
|
47
|
+
* (bounded in practice by per-request lifetimes and, where implemented, a
|
|
48
|
+
* suspicious-lookup backstop):
|
|
49
|
+
*
|
|
50
|
+
* - (A) NFS attribute caching (benign direction): another host may not see a
|
|
51
|
+
* new marker for up to the attribute-cache timeout (~3-60s on default EFS
|
|
52
|
+
* mounts; `noac` cannot be assumed). The reader acts on a stale token and
|
|
53
|
+
* keeps a stale snapshot until the cache expires.
|
|
54
|
+
* - (B) Probe throttle: however long the consumer debounces freshness checks.
|
|
55
|
+
* - (C) Self-adoption: after its own mutation a consumer adopts the token it
|
|
56
|
+
* wrote; if a concurrent foreign bump landed just before ours, we miss that
|
|
57
|
+
* one notification (window: from our last token observation to our rename).
|
|
58
|
+
* - (E) Fresh-token/stale-scan (malignant direction, cross-host only): NFS
|
|
59
|
+
* revalidates the marker file on open, but a rebuild's reads may be served
|
|
60
|
+
* from dentry/attribute caches — a rebuild can record a NEW token against
|
|
61
|
+
* PRE-mutation data, leaving that consumer confidently stale until the next
|
|
62
|
+
* bump. Structurally unfixable with a filesystem marker; bounded by
|
|
63
|
+
* per-request lifetimes and any backstop the consumer implements.
|
|
64
|
+
*
|
|
65
|
+
* ## Guarantee delta for DURABLE snapshot consumers (registry / schema-cache)
|
|
66
|
+
*
|
|
67
|
+
* The in-memory ContentIdIndex tolerates window (E) because a stale index is
|
|
68
|
+
* scoped to one process's memory: it self-heals on the next probe or process
|
|
69
|
+
* recycle, and a wrong-file write is independently guarded by ContentStore's
|
|
70
|
+
* existence check. Consumers that persist a durable snapshot ALONGSIDE this
|
|
71
|
+
* marker — a branch registry list, a resolved-schema cache file — do not get
|
|
72
|
+
* that same containment. If such a consumer's regeneration scan is served
|
|
73
|
+
* from stale NFS dentry/attribute caches, window (E) produces a snapshot that
|
|
74
|
+
* embeds a FRESH token over STALE data, and that snapshot is written to disk.
|
|
75
|
+
* Every other host that reads the marker sees the fresh token, concludes the
|
|
76
|
+
* durable snapshot is current, and serves the stale data too — this is now a
|
|
77
|
+
* durable, SHARED staleness visible to all hosts until the next bump, not a
|
|
78
|
+
* transient one-process condition. A random token cannot distinguish "fresh
|
|
79
|
+
* token over fresh data" from "fresh token over stale data" — the token only
|
|
80
|
+
* proves a bump happened, not that the bumping host's own scan observed it.
|
|
81
|
+
*
|
|
82
|
+
* Durable-snapshot consumers must therefore implement mitigations this module
|
|
83
|
+
* cannot provide on their behalf:
|
|
84
|
+
*
|
|
85
|
+
* - Eager regeneration on the mutating host, performed immediately after its
|
|
86
|
+
* own bump (in the same request/operation). That host's own scan is
|
|
87
|
+
* necessarily coherent with the mutation it just made (no NFS round trip
|
|
88
|
+
* was needed to observe its own writes), so regenerating there rather than
|
|
89
|
+
* waiting for a lazy pull on some other host avoids handing window (E) a
|
|
90
|
+
* chance to run at all for the common case.
|
|
91
|
+
* - A get-miss / suspicious-lookup backstop: if a consumer looks up something
|
|
92
|
+
* that "should" exist per the durable snapshot but is missing (or vice
|
|
93
|
+
* versa), that mismatch is a signal to force a fresh regeneration rather
|
|
94
|
+
* than trusting the token match, bounding how long a bad snapshot survives.
|
|
95
|
+
*/
|
|
96
|
+
const log = createDebugLogger({ prefix: 'ResourceGeneration' });
|
|
97
|
+
const META_DIR = '.canopy-meta';
|
|
98
|
+
/** Absolute path of the generation marker for `resource` under `root`. */
|
|
99
|
+
export function resourceGenerationPath(root, resource) {
|
|
100
|
+
return path.resolve(root, META_DIR, `${resource}.generation`);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Record on disk that `resource` changed under `root`, so consumers in OTHER
|
|
104
|
+
* processes rebuild. Must be called AFTER the filesystem mutation.
|
|
105
|
+
*
|
|
106
|
+
* Returns the token written, or null if the write failed and `mustSucceed`
|
|
107
|
+
* was not set (logged and swallowed).
|
|
108
|
+
*/
|
|
109
|
+
export async function bumpResourceGeneration(root, resource, options) {
|
|
110
|
+
const token = randomUUID();
|
|
111
|
+
try {
|
|
112
|
+
await atomicWriteFile(resourceGenerationPath(root, resource), token);
|
|
113
|
+
return token;
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
log.warn('generation', `Failed to bump ${resource} generation for ${root}`, {
|
|
117
|
+
error: getErrorMessage(err),
|
|
118
|
+
});
|
|
119
|
+
if (options?.mustSucceed)
|
|
120
|
+
throw err;
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Read the current generation token for `resource` under `root`.
|
|
126
|
+
*
|
|
127
|
+
* ENOENT maps to `{ok: true, token: null}` — a valid "never bumped" state,
|
|
128
|
+
* distinct from every real token. Any OTHER read error maps to `{ok: false}`
|
|
129
|
+
* (logged) so callers can force-regenerate instead of trusting a null they
|
|
130
|
+
* cannot actually attribute to "never bumped".
|
|
131
|
+
*/
|
|
132
|
+
export async function readResourceGeneration(root, resource) {
|
|
133
|
+
try {
|
|
134
|
+
const token = await fs.readFile(resourceGenerationPath(root, resource), 'utf-8');
|
|
135
|
+
return { ok: true, token };
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
if (isNodeError(err) && err.code === 'ENOENT')
|
|
139
|
+
return { ok: true, token: null };
|
|
140
|
+
log.warn('generation', `Failed to read ${resource} generation for ${root}`, {
|
|
141
|
+
error: getErrorMessage(err),
|
|
142
|
+
});
|
|
143
|
+
return { ok: false };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* True when a previously-captured snapshot token is still current: the read
|
|
148
|
+
* succeeded AND its token matches the snapshot's. A failed read (`ok: false`)
|
|
149
|
+
* is never current, even if the snapshot's token happens to be null — an
|
|
150
|
+
* unreadable marker means we cannot vouch for freshness either way, and the
|
|
151
|
+
* safe default is to treat it as stale.
|
|
152
|
+
*/
|
|
153
|
+
export function isGenerationCurrent(snapshotToken, read) {
|
|
154
|
+
return read.ok && read.token === snapshotToken;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=resource-generation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-generation.js","sourceRoot":"","sources":["../src/resource-generation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AAEH,MAAM,GAAG,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAA;AAE/D,MAAM,QAAQ,GAAG,cAAc,CAAA;AAE/B,0EAA0E;AAC1E,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,QAAgB;IACnE,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,QAAQ,aAAa,CAAC,CAAA;AAC/D,CAAC;AAeD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAAY,EACZ,QAAgB,EAChB,OAAuC;IAEvC,MAAM,KAAK,GAAG,UAAU,EAAE,CAAA;IAC1B,IAAI,CAAC;QACH,MAAM,eAAe,CAAC,sBAAsB,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAA;QACpE,OAAO,KAAK,CAAA;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,kBAAkB,QAAQ,mBAAmB,IAAI,EAAE,EAAE;YAC1E,KAAK,EAAE,eAAe,CAAC,GAAG,CAAC;SAC5B,CAAC,CAAA;QACF,IAAI,OAAO,EAAE,WAAW;YAAE,MAAM,GAAG,CAAA;QACnC,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAYD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAAY,EACZ,QAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAA;QAChF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;QAC/E,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,kBAAkB,QAAQ,mBAAmB,IAAI,EAAE,EAAE;YAC1E,KAAK,EAAE,eAAe,CAAC,GAAG,CAAC;SAC5B,CAAC,CAAA;QACF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA;IACtB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,aAA4B,EAC5B,IAA0B;IAE1B,OAAO,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,KAAK,aAAa,CAAA;AAChD,CAAC"}
|
|
@@ -143,14 +143,14 @@ declare const updateEntryTypeInputSchema: z.ZodObject<{
|
|
|
143
143
|
maxItems: z.ZodOptional<z.ZodNumber>;
|
|
144
144
|
}, "strip", z.ZodTypeAny, {
|
|
145
145
|
default?: boolean | undefined;
|
|
146
|
-
label?: string | undefined;
|
|
147
146
|
format?: "mdx" | "md" | "json" | "yaml" | undefined;
|
|
147
|
+
label?: string | undefined;
|
|
148
148
|
schema?: string | undefined;
|
|
149
149
|
maxItems?: number | undefined;
|
|
150
150
|
}, {
|
|
151
151
|
default?: boolean | undefined;
|
|
152
|
-
label?: string | undefined;
|
|
153
152
|
format?: "mdx" | "md" | "json" | "yaml" | undefined;
|
|
153
|
+
label?: string | undefined;
|
|
154
154
|
schema?: string | undefined;
|
|
155
155
|
maxItems?: number | undefined;
|
|
156
156
|
}>;
|
|
@@ -160,8 +160,28 @@ export declare class SchemaOps {
|
|
|
160
160
|
private readonly services?;
|
|
161
161
|
constructor(contentRoot: string, entrySchemaRegistry: EntrySchemaRegistry, services?: CanopyServices | undefined);
|
|
162
162
|
/**
|
|
163
|
-
* Invalidate schema cache for this branch after mutations
|
|
164
|
-
*
|
|
163
|
+
* Invalidate schema cache for this branch after mutations, then eagerly
|
|
164
|
+
* re-resolve on THIS host.
|
|
165
|
+
*
|
|
166
|
+
* The eager re-resolve is the durable-snapshot window-E mitigation (see
|
|
167
|
+
* BranchSchemaCache's class docs): the mutating host's own scan is
|
|
168
|
+
* necessarily coherent with the mutation it just made, whereas the
|
|
169
|
+
* editor's follow-up schema read is a separate Lambda invocation with no
|
|
170
|
+
* container affinity — exactly the lazy foreign-host pull whose scan can
|
|
171
|
+
* be served from stale NFS caches and durably persist a fresh-token
|
|
172
|
+
* snapshot of pre-mutation schema. Regen failures are logged and
|
|
173
|
+
* swallowed (mirroring BranchRegistry.invalidate()): the bump alone
|
|
174
|
+
* already restored correctness for every future reader, and a mutation
|
|
175
|
+
* that leaves no valid schema behind (e.g. deleting the last collection)
|
|
176
|
+
* must not fail the request over an uncacheable resolve.
|
|
177
|
+
*
|
|
178
|
+
* Uses `resolveAndPersist()`, NOT `getSchema()`: getSchema()'s cache-read
|
|
179
|
+
* fast path can return a snapshot a DIFFERENT, concurrent host just wrote
|
|
180
|
+
* (its own eager re-resolve, raced against this one, embedding the
|
|
181
|
+
* now-current marker token over ITS OWN stale-NFS-cache scan) — silently
|
|
182
|
+
* skipping the one scan this call exists to guarantee. resolveAndPersist()
|
|
183
|
+
* never reads the cache file, so it cannot be short-circuited that way.
|
|
184
|
+
* See BranchSchemaCache.resolveAndPersist()'s doc comment for the full race.
|
|
165
185
|
*/
|
|
166
186
|
private invalidateSchemaCache;
|
|
167
187
|
/**
|
|
@@ -171,6 +191,13 @@ export declare class SchemaOps {
|
|
|
171
191
|
* indexes for this branch: in-process via the registry and cross-process via
|
|
172
192
|
* the on-disk generation marker. ContentStores (and the marker) are rooted
|
|
173
193
|
* at the branch root, the contentRoot's parent.
|
|
194
|
+
*
|
|
195
|
+
* Uses the combined invalidateBranchContentCaches() helper rather than the
|
|
196
|
+
* content-index-only invalidateContentIndexesDurable(): every call site here
|
|
197
|
+
* is already followed by its own invalidateSchemaCache() call below, so this
|
|
198
|
+
* double-bumps the schema generation marker. That's harmless (bumps are
|
|
199
|
+
* idempotent hints, not counters) and keeps this call uniform with the other
|
|
200
|
+
* bulk-mutation call sites that use the combined helper.
|
|
174
201
|
*/
|
|
175
202
|
private invalidateContentIdIndexes;
|
|
176
203
|
/**
|