canopycms 0.0.16 → 0.0.18
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/README.md +120 -34
- package/dist/ai/generate.js +3 -3
- package/dist/ai/handler.js +5 -5
- package/dist/ai/index.js +3 -3
- package/dist/ai/json-to-markdown.js +1 -1
- package/dist/ai/json-to-markdown.js.map +1 -1
- package/dist/ai/resolve-branch.js +2 -2
- package/dist/api/__test__/mock-client.js +1 -1
- package/dist/api/assets.js +1 -1
- package/dist/api/branch-merge.js +3 -3
- package/dist/api/branch-review.js +4 -4
- package/dist/api/branch-status.js +8 -8
- package/dist/api/branch-withdraw.js +5 -5
- package/dist/api/branch.js +9 -9
- package/dist/api/comments.js +4 -4
- package/dist/api/content.d.ts.map +1 -1
- package/dist/api/content.js +17 -16
- package/dist/api/content.js.map +1 -1
- package/dist/api/entries.js +8 -8
- package/dist/api/github-sync.js +3 -3
- package/dist/api/groups.js +4 -4
- package/dist/api/guards.js +1 -1
- package/dist/api/index.js +3 -3
- package/dist/api/permissions.js +4 -4
- package/dist/api/reference-options.js +5 -5
- package/dist/api/resolve-references.js +4 -4
- package/dist/api/route-builder.js +1 -1
- package/dist/api/schema.js +5 -5
- package/dist/api/settings-helpers.js +1 -1
- package/dist/api/user.js +1 -1
- package/dist/api/validators.js +3 -3
- package/dist/asset-store.js +1 -1
- package/dist/auth/cache.js +2 -2
- package/dist/auth/caching-auth-plugin.js +1 -1
- package/dist/auth/file-based-auth-cache.js +1 -1
- package/dist/auth/index.js +1 -1
- package/dist/authorization/branch.js +1 -1
- package/dist/authorization/content.js +3 -3
- package/dist/authorization/groups/index.js +2 -2
- package/dist/authorization/groups/loader.js +4 -4
- package/dist/authorization/index.js +8 -8
- package/dist/authorization/path.js +1 -1
- package/dist/authorization/permissions/index.js +2 -2
- package/dist/authorization/permissions/loader.js +3 -3
- package/dist/authorization/permissions/schema.js +1 -1
- package/dist/authorization/test-utils.js +1 -1
- package/dist/authorization/validation.js +1 -1
- package/dist/branch-metadata.js +3 -3
- package/dist/branch-registry.js +2 -2
- package/dist/branch-schema-cache.js +2 -2
- package/dist/branch-workspace.js +6 -6
- package/dist/build/generate-ai-content.js +4 -4
- package/dist/build/index.js +1 -1
- package/dist/cli/cli.js +5 -5
- package/dist/cli/generate-ai-content.js +40 -29
- package/dist/cli/init.d.ts +5 -0
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +68 -25
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/sync.js +1 -1
- package/dist/cli/template-files/canopy.ts.template +10 -6
- package/dist/cli/template-files/edit-page-dev.tsx.template +16 -0
- package/dist/cli/template-files/edit-page.tsx.template +14 -21
- package/dist/cli/template-files/middleware-clerk.ts.template +13 -0
- package/dist/cli/template-files/middleware.ts.template +30 -0
- package/dist/cli/template-files/next.config-static.ts.template +13 -0
- package/dist/cli/template-files/next.config.ts.template +5 -0
- package/dist/cli/template-files/schemas.ts.template +4 -2
- package/dist/cli/templates.d.ts +8 -0
- package/dist/cli/templates.d.ts.map +1 -1
- package/dist/cli/templates.js +22 -2
- package/dist/cli/templates.js.map +1 -1
- package/dist/client.js +9 -9
- package/dist/config/flatten.js +2 -2
- package/dist/config/helpers.js +3 -3
- package/dist/config/index.js +9 -9
- package/dist/config/schemas/collection.js +1 -1
- package/dist/config/schemas/config.js +2 -2
- package/dist/config/schemas/field.d.ts +21 -0
- package/dist/config/schemas/field.d.ts.map +1 -1
- package/dist/config/schemas/field.js +2 -1
- package/dist/config/schemas/field.js.map +1 -1
- package/dist/config/types.d.ts +7 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/validation.js +2 -2
- package/dist/config-test.js +2 -2
- package/dist/config.js +2 -2
- package/dist/content-id-index.js +2 -2
- package/dist/content-listing.d.ts +3 -2
- package/dist/content-listing.d.ts.map +1 -1
- package/dist/content-listing.js +15 -12
- package/dist/content-listing.js.map +1 -1
- package/dist/content-reader.d.ts.map +1 -1
- package/dist/content-reader.js +18 -14
- package/dist/content-reader.js.map +1 -1
- package/dist/content-store.d.ts +5 -0
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +34 -24
- package/dist/content-store.js.map +1 -1
- package/dist/content-tree.d.ts.map +1 -1
- package/dist/content-tree.js +8 -3
- package/dist/content-tree.js.map +1 -1
- package/dist/context.d.ts +38 -7
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +38 -6
- package/dist/context.js.map +1 -1
- package/dist/editor/BranchManager.js +4 -4
- package/dist/editor/CanopyEditor.js +3 -3
- package/dist/editor/CanopyEditorPage.js +1 -1
- package/dist/editor/CommentsPanel.js +1 -1
- package/dist/editor/Editor.js +18 -18
- package/dist/editor/EntryNavigator.js +1 -1
- package/dist/editor/FormRenderer.js +12 -12
- package/dist/editor/GroupManager.js +1 -1
- package/dist/editor/PermissionManager.js +1 -1
- package/dist/editor/client-reference-resolver.js +1 -1
- package/dist/editor/comments/BranchComments.js +1 -1
- package/dist/editor/comments/EntryComments.js +1 -1
- package/dist/editor/comments/FieldWrapper.js +1 -1
- package/dist/editor/comments/InlineCommentThread.js +1 -1
- package/dist/editor/comments/ThreadCarousel.js +1 -1
- package/dist/editor/components/EditorHeader.js +1 -1
- package/dist/editor/components/UserBadge.js +1 -1
- package/dist/editor/components/index.js +3 -3
- package/dist/editor/context/ApiClientContext.js +1 -1
- package/dist/editor/context/index.js +2 -2
- package/dist/editor/editor-config.js +2 -2
- package/dist/editor/editor-config.js.map +1 -1
- package/dist/editor/editor-utils.js +1 -1
- package/dist/editor/fields/BlockField.js +1 -1
- package/dist/editor/fields/ObjectField.js +1 -1
- package/dist/editor/fields/ReferenceField.js +1 -1
- package/dist/editor/group-manager/GroupCard.js +1 -1
- package/dist/editor/group-manager/InternalGroupsTab.js +1 -1
- package/dist/editor/group-manager/MemberList.js +1 -1
- package/dist/editor/group-manager/index.js +9 -9
- package/dist/editor/hooks/__test__/test-utils.js +3 -3
- package/dist/editor/hooks/index.js +11 -11
- package/dist/editor/hooks/useBranchActions.js +1 -1
- package/dist/editor/hooks/useBranchManager.js +1 -1
- package/dist/editor/hooks/useCommentSystem.js +2 -2
- package/dist/editor/hooks/useDraftManager.js +1 -1
- package/dist/editor/hooks/useEntryManager.js +3 -3
- package/dist/editor/hooks/useGroupManager.js +1 -1
- package/dist/editor/hooks/usePermissionManager.js +1 -1
- package/dist/editor/hooks/useReferenceResolution.js +1 -1
- package/dist/editor/hooks/useSchemaManager.js +1 -1
- package/dist/editor/hooks/useUserContext.js +1 -1
- package/dist/editor/permission-manager/PermissionEditor.js +4 -4
- package/dist/editor/permission-manager/PermissionLevelBadge.js +1 -1
- package/dist/editor/permission-manager/PermissionTree.js +3 -3
- package/dist/editor/permission-manager/UserSelector.js +1 -1
- package/dist/editor/permission-manager/hooks/usePermissionTree.js +2 -2
- package/dist/editor/permission-manager/index.js +6 -6
- package/dist/editor/preview-bridge.js +1 -1
- package/dist/editor/schema-editor/CollectionEditor.js +2 -2
- package/dist/editor/schema-editor/index.js +2 -2
- package/dist/entry-schema-registry.d.ts.map +1 -1
- package/dist/entry-schema-registry.js +12 -3
- package/dist/entry-schema-registry.js.map +1 -1
- package/dist/entry-schema.d.ts +1 -0
- package/dist/entry-schema.d.ts.map +1 -1
- package/dist/entry-schema.js.map +1 -1
- package/dist/git-manager.js +4 -4
- package/dist/github-service.d.ts.map +1 -1
- package/dist/github-service.js +12 -8
- package/dist/github-service.js.map +1 -1
- package/dist/http/handler.js +7 -7
- package/dist/http/index.js +3 -3
- package/dist/http/router.js +12 -12
- package/dist/id.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/operating-mode/client-unsafe-strategy.js +2 -2
- package/dist/operating-mode/client.js +1 -1
- package/dist/operating-mode/index.js +2 -2
- package/dist/paths/branch.js +1 -1
- package/dist/paths/index.d.ts +1 -1
- package/dist/paths/index.d.ts.map +1 -1
- package/dist/paths/index.js +6 -6
- package/dist/paths/index.js.map +1 -1
- package/dist/paths/normalize.d.ts +8 -0
- package/dist/paths/normalize.d.ts.map +1 -1
- package/dist/paths/normalize.js +17 -0
- package/dist/paths/normalize.js.map +1 -1
- package/dist/paths/test-utils.js +1 -1
- package/dist/paths/validation.js +1 -1
- package/dist/reference-resolver.js +1 -1
- package/dist/schema/index.js +2 -2
- package/dist/schema/meta-loader.js +1 -1
- package/dist/schema/resolver.js +1 -1
- package/dist/schema/schema-store.js +4 -4
- package/dist/server.js +13 -13
- package/dist/services.js +12 -12
- package/dist/settings-branch-utils.js +1 -1
- package/dist/settings-workspace.js +3 -3
- package/dist/task-queue/index.js +1 -1
- package/dist/task-queue/task-queue.js +1 -1
- package/dist/url-path-resolver.d.ts +16 -0
- package/dist/url-path-resolver.d.ts.map +1 -0
- package/dist/url-path-resolver.js +31 -0
- package/dist/url-path-resolver.js.map +1 -0
- package/dist/user.js +1 -1
- package/dist/utils/body-field.d.ts +18 -0
- package/dist/utils/body-field.d.ts.map +1 -0
- package/dist/utils/body-field.js +39 -0
- package/dist/utils/body-field.js.map +1 -0
- package/dist/utils/fs.js +1 -1
- package/dist/utils/sanitize-href.d.ts +19 -0
- package/dist/utils/sanitize-href.d.ts.map +1 -0
- package/dist/utils/sanitize-href.js +30 -0
- package/dist/utils/sanitize-href.js.map +1 -0
- package/dist/validation/reference-validator.js +2 -2
- package/dist/worker/cms-worker.js +5 -5
- package/dist/worker/task-queue-config.js +1 -1
- package/dist/worker/task-queue.js +2 -2
- package/package.json +1 -1
package/dist/paths/index.js
CHANGED
|
@@ -10,21 +10,21 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Usage:
|
|
12
12
|
* ```ts
|
|
13
|
-
* import { normalizeFilesystemPath, createLogicalPath, parseSlug } from '../paths'
|
|
13
|
+
* import { normalizeFilesystemPath, createLogicalPath, parseSlug } from '../paths/index.js'
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
// Normalization utilities (client-safe)
|
|
17
|
-
export { normalizeFilesystemPath, normalizeCollectionPath, hasTraversalSequence, createLogicalPath, createPhysicalPath, joinPath, } from './normalize';
|
|
17
|
+
export { normalizeFilesystemPath, normalizeCollectionPath, hasTraversalSequence, createLogicalPath, createPhysicalPath, joinPath, trimSlashes, } from './normalize.js';
|
|
18
18
|
// Normalization utilities (server-only, requires Node.js path module)
|
|
19
|
-
export { validateAndNormalizePath } from './normalize-server';
|
|
19
|
+
export { validateAndNormalizePath } from './normalize-server.js';
|
|
20
20
|
// Validation utilities
|
|
21
21
|
export { validateContentPath, isValidCollectionPath, sanitizeForPath,
|
|
22
22
|
// Path type detection and parsing
|
|
23
23
|
hasEmbeddedContentId, looksLikePhysicalPath, looksLikeLogicalPath, parseLogicalPath, parsePhysicalPath, isValidContentId,
|
|
24
24
|
// Branded type validation and parsing
|
|
25
|
-
parseContentId, parseBranchName, parseSlug, } from './validation';
|
|
25
|
+
parseContentId, parseBranchName, parseSlug, } from './validation.js';
|
|
26
26
|
// Path resolution utilities
|
|
27
|
-
export { resolveLogicalPath } from './resolve';
|
|
27
|
+
export { resolveLogicalPath } from './resolve.js';
|
|
28
28
|
// Branch path utilities
|
|
29
|
-
export { resolveBranchPath, ensureBranchRoot, getDefaultBranchBase, resolveBranchPaths, sanitizeBranchName, BranchPathError, } from './branch';
|
|
29
|
+
export { resolveBranchPath, ensureBranchRoot, getDefaultBranchBase, resolveBranchPaths, sanitizeBranchName, BranchPathError, } from './branch.js';
|
|
30
30
|
//# sourceMappingURL=index.js.map
|
package/dist/paths/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH,wCAAwC;AACxC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH,wCAAwC;AACxC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,WAAW,GACZ,MAAM,aAAa,CAAA;AAEpB,sEAAsE;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAE7D,uBAAuB;AACvB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,eAAe;AACf,kCAAkC;AAClC,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB;AAChB,sCAAsC;AACtC,cAAc,EACd,eAAe,EACf,SAAS,GACV,MAAM,cAAc,CAAA;AAErB,4BAA4B;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAE9C,wBAAwB;AACxB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,GAGhB,MAAM,UAAU,CAAA"}
|
|
@@ -51,6 +51,14 @@ export declare function createLogicalPath(...segments: string[]): LogicalPath;
|
|
|
51
51
|
* createPhysicalPath('content', 'posts', 'my-post.ABC123.mdx') // as PhysicalPath
|
|
52
52
|
*/
|
|
53
53
|
export declare function createPhysicalPath(...segments: string[]): PhysicalPath;
|
|
54
|
+
/**
|
|
55
|
+
* Strip leading and trailing slashes from a path or URL segment.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* trimSlashes('/docs/guides/') // 'docs/guides'
|
|
59
|
+
* trimSlashes('///multi///') // 'multi'
|
|
60
|
+
*/
|
|
61
|
+
export declare function trimSlashes(path: string): string;
|
|
54
62
|
/**
|
|
55
63
|
* Join path segments with forward slashes.
|
|
56
64
|
* Does not validate - use createLogicalPath/createPhysicalPath for validation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/paths/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAExD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,SAAY,GAAG,MAAM,CAO/F;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAWpE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,YAAY,CAWtE;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAKtD"}
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/paths/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAExD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,SAAY,GAAG,MAAM,CAO/F;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAWpE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,YAAY,CAWtE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOhD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAKtD"}
|
package/dist/paths/normalize.js
CHANGED
|
@@ -83,6 +83,23 @@ export function createPhysicalPath(...segments) {
|
|
|
83
83
|
}
|
|
84
84
|
return normalized;
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Strip leading and trailing slashes from a path or URL segment.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* trimSlashes('/docs/guides/') // 'docs/guides'
|
|
91
|
+
* trimSlashes('///multi///') // 'multi'
|
|
92
|
+
*/
|
|
93
|
+
export function trimSlashes(path) {
|
|
94
|
+
// Linear scan instead of regex to avoid polynomial ReDoS on repeated '/' chars
|
|
95
|
+
let start = 0;
|
|
96
|
+
let end = path.length;
|
|
97
|
+
while (start < end && path[start] === '/')
|
|
98
|
+
start++;
|
|
99
|
+
while (end > start && path[end - 1] === '/')
|
|
100
|
+
end--;
|
|
101
|
+
return path.slice(start, end);
|
|
102
|
+
}
|
|
86
103
|
/**
|
|
87
104
|
* Join path segments with forward slashes.
|
|
88
105
|
* Does not validate - use createLogicalPath/createPhysicalPath for validation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/paths/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,IAAI;SACR,KAAK,CAAC,QAAQ,CAAC;SACf,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,cAAsB,EAAE,WAAW,GAAG,SAAS;IACrF,MAAM,UAAU,GAAG,uBAAuB,CAAC,cAAc,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,GAAG,WAAW,GAAG,CAAA;IAChC,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACxC,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IAChD,OAAO,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG,QAAkB;IACrD,MAAM,UAAU,GAAG,QAAQ;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;SACtC,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAA;IAEZ,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,8CAA8C,UAAU,EAAE,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,UAAyB,CAAA;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAG,QAAkB;IACtD,MAAM,UAAU,GAAG,QAAQ;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;SACtC,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAA;IAEZ,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,8CAA8C,UAAU,EAAE,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,UAA0B,CAAA;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAG,QAAkB;IAC5C,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;SACtC,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC"}
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/paths/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,IAAI;SACR,KAAK,CAAC,QAAQ,CAAC;SACf,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,cAAsB,EAAE,WAAW,GAAG,SAAS;IACrF,MAAM,UAAU,GAAG,uBAAuB,CAAC,cAAc,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,GAAG,WAAW,GAAG,CAAA;IAChC,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACxC,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IAChD,OAAO,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG,QAAkB;IACrD,MAAM,UAAU,GAAG,QAAQ;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;SACtC,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAA;IAEZ,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,8CAA8C,UAAU,EAAE,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,UAAyB,CAAA;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAG,QAAkB;IACtD,MAAM,UAAU,GAAG,QAAQ;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;SACtC,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAA;IAEZ,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,8CAA8C,UAAU,EAAE,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,UAA0B,CAAA;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,+EAA+E;IAC/E,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAA;IACrB,OAAO,KAAK,GAAG,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG;QAAE,KAAK,EAAE,CAAA;IAClD,OAAO,GAAG,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG;QAAE,GAAG,EAAE,CAAA;IAClD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAG,QAAkB;IAC5C,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;SACtC,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC"}
|
package/dist/paths/test-utils.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* // In test files only:
|
|
9
|
-
* import { unsafeAsLogicalPath, unsafeAsSlug } from '../paths/test-utils'
|
|
9
|
+
* import { unsafeAsLogicalPath, unsafeAsSlug } from '../paths/test-utils.js'
|
|
10
10
|
*/
|
|
11
11
|
/** Test-only: cast a string to LogicalPath without validation. */
|
|
12
12
|
export const unsafeAsLogicalPath = (path) => path;
|
package/dist/paths/validation.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Security-focused validation for content paths and slugs.
|
|
5
5
|
*/
|
|
6
|
-
import { normalizeFilesystemPath, hasTraversalSequence } from './normalize';
|
|
6
|
+
import { normalizeFilesystemPath, hasTraversalSequence } from './normalize.js';
|
|
7
7
|
/**
|
|
8
8
|
* Base58 alphabet used for content IDs (excludes ambiguous: 0, O, I, l)
|
|
9
9
|
*/
|
package/dist/schema/index.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
15
|
// Meta loader (low-level API)
|
|
16
|
-
export { loadCollectionMetaFiles, resolveCollectionReferences, watchCollectionMetaFiles, } from './meta-loader';
|
|
16
|
+
export { loadCollectionMetaFiles, resolveCollectionReferences, watchCollectionMetaFiles, } from './meta-loader.js';
|
|
17
17
|
// Resolver (high-level API)
|
|
18
|
-
export { resolveSchema, hasSchemaFiles, isValidSchema } from './resolver';
|
|
18
|
+
export { resolveSchema, hasSchemaFiles, isValidSchema } from './resolver.js';
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -2,7 +2,7 @@ import { promises as fs } from 'fs';
|
|
|
2
2
|
import { join } from 'pathe';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import chokidar from 'chokidar';
|
|
5
|
-
import { extractSlugFromFilename, extractIdFromFilename } from '../content-id-index';
|
|
5
|
+
import { extractSlugFromFilename, extractIdFromFilename } from '../content-id-index.js';
|
|
6
6
|
/**
|
|
7
7
|
* Zod schema for entry type metadata in .collection.json files.
|
|
8
8
|
* Each entry type has a name, format, and schema reference to the entry schema registry.
|
package/dist/schema/resolver.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Field schemas are defined in the entry schema registry and referenced by name
|
|
8
8
|
* in .collection.json files for reusability and type safety.
|
|
9
9
|
*/
|
|
10
|
-
import { loadCollectionMetaFiles, resolveCollectionReferences } from './meta-loader';
|
|
10
|
+
import { loadCollectionMetaFiles, resolveCollectionReferences } from './meta-loader.js';
|
|
11
11
|
/**
|
|
12
12
|
* Resolve schema from .collection.json files.
|
|
13
13
|
*
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
import { promises as fs } from 'node:fs';
|
|
12
12
|
import path from 'node:path';
|
|
13
13
|
import { z } from 'zod';
|
|
14
|
-
import { atomicWriteFile } from '../utils/atomic-write';
|
|
15
|
-
import { resolveCollectionPath } from '../content-id-index';
|
|
16
|
-
import { generateId, isValidId } from '../id';
|
|
17
|
-
import { createLogicalPath, validateAndNormalizePath } from '../paths';
|
|
14
|
+
import { atomicWriteFile } from '../utils/atomic-write.js';
|
|
15
|
+
import { resolveCollectionPath } from '../content-id-index.js';
|
|
16
|
+
import { generateId, isValidId } from '../id.js';
|
|
17
|
+
import { createLogicalPath, validateAndNormalizePath } from '../paths/index.js';
|
|
18
18
|
// ============================================================================
|
|
19
19
|
// Zod Schemas for Validation
|
|
20
20
|
// ============================================================================
|
package/dist/server.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
export * from './content-reader';
|
|
2
|
-
export * from './services';
|
|
3
|
-
export * from './build-mode';
|
|
4
|
-
export * from './context';
|
|
5
|
-
export { operatingStrategy } from './operating-mode';
|
|
6
|
-
export * from './authorization/groups';
|
|
7
|
-
export * from './branch-workspace';
|
|
8
|
-
export * from './content-store';
|
|
9
|
-
export { loadCollectionMetaFiles, resolveCollectionReferences, watchCollectionMetaFiles, resolveSchema, } from './schema';
|
|
10
|
-
export { createEntrySchemaRegistry, validateEntrySchemaRegistry } from './entry-schema-registry';
|
|
11
|
-
export { generateId, isValidId } from './id';
|
|
12
|
-
export { buildContentTree } from './content-tree';
|
|
13
|
-
export { listEntries } from './content-listing';
|
|
1
|
+
export * from './content-reader.js';
|
|
2
|
+
export * from './services.js';
|
|
3
|
+
export * from './build-mode.js';
|
|
4
|
+
export * from './context.js';
|
|
5
|
+
export { operatingStrategy } from './operating-mode/index.js';
|
|
6
|
+
export * from './authorization/groups/index.js';
|
|
7
|
+
export * from './branch-workspace.js';
|
|
8
|
+
export * from './content-store.js';
|
|
9
|
+
export { loadCollectionMetaFiles, resolveCollectionReferences, watchCollectionMetaFiles, resolveSchema, } from './schema/index.js';
|
|
10
|
+
export { createEntrySchemaRegistry, validateEntrySchemaRegistry } from './entry-schema-registry.js';
|
|
11
|
+
export { generateId, isValidId } from './id.js';
|
|
12
|
+
export { buildContentTree } from './content-tree.js';
|
|
13
|
+
export { listEntries } from './content-listing.js';
|
|
14
14
|
//# sourceMappingURL=server.js.map
|
package/dist/services.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { getConfigDefaults } from './config';
|
|
3
|
-
import { createCheckPathAccess, createCheckBranchAccess, createCheckContentAccess, loadPathPermissions, } from './authorization';
|
|
4
|
-
import { GitManager } from './git-manager';
|
|
5
|
-
import { BranchRegistry } from './branch-registry';
|
|
6
|
-
import { SettingsWorkspaceManager } from './settings-workspace';
|
|
7
|
-
import { getDefaultBranchBase } from './paths';
|
|
8
|
-
import { createGitHubService } from './github-service';
|
|
9
|
-
import { operatingStrategy } from './operating-mode';
|
|
10
|
-
import { BranchSchemaCache } from './branch-schema-cache';
|
|
11
|
-
import { enqueueTask } from './worker/task-queue';
|
|
12
|
-
import { getTaskQueueDir } from './worker/task-queue-config';
|
|
13
|
-
import { detectHeadBranch } from './utils/git';
|
|
2
|
+
import { getConfigDefaults } from './config/index.js';
|
|
3
|
+
import { createCheckPathAccess, createCheckBranchAccess, createCheckContentAccess, loadPathPermissions, } from './authorization/index.js';
|
|
4
|
+
import { GitManager } from './git-manager.js';
|
|
5
|
+
import { BranchRegistry } from './branch-registry.js';
|
|
6
|
+
import { SettingsWorkspaceManager } from './settings-workspace.js';
|
|
7
|
+
import { getDefaultBranchBase } from './paths/index.js';
|
|
8
|
+
import { createGitHubService } from './github-service.js';
|
|
9
|
+
import { operatingStrategy } from './operating-mode/index.js';
|
|
10
|
+
import { BranchSchemaCache } from './branch-schema-cache.js';
|
|
11
|
+
import { enqueueTask } from './worker/task-queue.js';
|
|
12
|
+
import { getTaskQueueDir } from './worker/task-queue-config.js';
|
|
13
|
+
import { detectHeadBranch } from './utils/git.js';
|
|
14
14
|
/**
|
|
15
15
|
* In dev mode, auto-detect the current HEAD branch if defaultBaseBranch is not set.
|
|
16
16
|
* Eliminates the need to manually update defaultBaseBranch when working on a feature branch.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { GitManager } from './git-manager';
|
|
4
|
-
import { createDebugLogger } from './utils/debug';
|
|
5
|
-
import { isFileExistsError } from './utils/error';
|
|
3
|
+
import { GitManager } from './git-manager.js';
|
|
4
|
+
import { createDebugLogger } from './utils/debug.js';
|
|
5
|
+
import { isFileExistsError } from './utils/error.js';
|
|
6
6
|
const log = createDebugLogger({ prefix: 'SettingsWorkspace' });
|
|
7
7
|
// In-memory lock to prevent concurrent workspace initialization within the same process.
|
|
8
8
|
// Settings only need one lock (not per-branch like content branches).
|
package/dist/task-queue/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { enqueueTask, dequeueTask, completeTask, failTask, retryTask, recoverOrphanedTasks, cleanupOldTasks, getTask, listTasks, getQueueStats, } from './task-queue';
|
|
1
|
+
export { enqueueTask, dequeueTask, completeTask, failTask, retryTask, recoverOrphanedTasks, cleanupOldTasks, getTask, listTasks, getQueueStats, } from './task-queue.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -21,7 +21,7 @@ import crypto from 'node:crypto';
|
|
|
21
21
|
const DEFAULT_MAX_RETRIES = 3;
|
|
22
22
|
// Silent no-op logger
|
|
23
23
|
const nullLogger = { debug: () => { } };
|
|
24
|
-
import { atomicWriteFile } from '../utils/atomic-write';
|
|
24
|
+
import { atomicWriteFile } from '../utils/atomic-write.js';
|
|
25
25
|
// Local helper — only stdlib dependency, keeps task-queue easy to extract.
|
|
26
26
|
function isNotFoundError(err) {
|
|
27
27
|
return err instanceof Error && 'code' in err && err.code === 'ENOENT';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a URL path to candidate entryPath/slug pairs for content lookup.
|
|
3
|
+
*
|
|
4
|
+
* Returns an ordered list of attempts:
|
|
5
|
+
* 1. Direct entry: last segment is slug, rest is collection path
|
|
6
|
+
* 2. Index fallback: full path is collection, slug is 'index'
|
|
7
|
+
*
|
|
8
|
+
* @param urlPath - URL path like '/docs/guides/getting-started' or 'docs/guides'
|
|
9
|
+
* @param contentRoot - Content root directory name (default: 'content')
|
|
10
|
+
* @returns Array of { entryPath, slug } candidates to try in order
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveUrlPathCandidates(urlPath: string, contentRoot: string): Array<{
|
|
13
|
+
entryPath: string;
|
|
14
|
+
slug: string;
|
|
15
|
+
}>;
|
|
16
|
+
//# sourceMappingURL=url-path-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-path-resolver.d.ts","sourceRoot":"","sources":["../src/url-path-resolver.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB5C"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { trimSlashes } from './paths/normalize.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a URL path to candidate entryPath/slug pairs for content lookup.
|
|
4
|
+
*
|
|
5
|
+
* Returns an ordered list of attempts:
|
|
6
|
+
* 1. Direct entry: last segment is slug, rest is collection path
|
|
7
|
+
* 2. Index fallback: full path is collection, slug is 'index'
|
|
8
|
+
*
|
|
9
|
+
* @param urlPath - URL path like '/docs/guides/getting-started' or 'docs/guides'
|
|
10
|
+
* @param contentRoot - Content root directory name (default: 'content')
|
|
11
|
+
* @returns Array of { entryPath, slug } candidates to try in order
|
|
12
|
+
*/
|
|
13
|
+
export function resolveUrlPathCandidates(urlPath, contentRoot) {
|
|
14
|
+
const normalized = trimSlashes(urlPath);
|
|
15
|
+
const segments = normalized.split('/').filter(Boolean);
|
|
16
|
+
if (segments.length === 0)
|
|
17
|
+
return [];
|
|
18
|
+
const candidates = [];
|
|
19
|
+
// Try 1: last segment is the entry slug, rest is the collection path
|
|
20
|
+
const slug = segments[segments.length - 1];
|
|
21
|
+
const collectionSegments = segments.slice(0, -1);
|
|
22
|
+
const entryPath = collectionSegments.length > 0 ? `${contentRoot}/${collectionSegments.join('/')}` : contentRoot;
|
|
23
|
+
candidates.push({ entryPath, slug });
|
|
24
|
+
// Try 2: full path is a collection with an index entry
|
|
25
|
+
candidates.push({
|
|
26
|
+
entryPath: `${contentRoot}/${segments.join('/')}`,
|
|
27
|
+
slug: 'index',
|
|
28
|
+
});
|
|
29
|
+
return candidates;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=url-path-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-path-resolver.js","sourceRoot":"","sources":["../src/url-path-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAe,EACf,WAAmB;IAEnB,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAEpC,MAAM,UAAU,GAA+C,EAAE,CAAA;IAEjE,qEAAqE;IACrE,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC1C,MAAM,kBAAkB,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAChD,MAAM,SAAS,GACb,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAA;IAEhG,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEpC,uDAAuD;IACvD,UAAU,CAAC,IAAI,CAAC;QACd,SAAS,EAAE,GAAG,WAAW,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QACjD,IAAI,EAAE,OAAO;KACd,CAAC,CAAA;IAEF,OAAO,UAAU,CAAA;AACnB,CAAC"}
|
package/dist/user.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Import from client-safe subpaths to avoid pulling in server-only loader code
|
|
2
|
-
import { RESERVED_GROUPS } from './authorization/helpers';
|
|
2
|
+
import { RESERVED_GROUPS } from './authorization/helpers.js';
|
|
3
3
|
/**
|
|
4
4
|
* Branded ANONYMOUS_USER constant - use this for intentional anonymous access.
|
|
5
5
|
* Callers must explicitly pass this to indicate anonymous access is intended.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FieldConfig } from '../config';
|
|
2
|
+
/**
|
|
3
|
+
* Count the number of top-level fields marked `isBody: true` in a schema.
|
|
4
|
+
* Does NOT recurse into objects — isBody only makes sense at the top level
|
|
5
|
+
* because it maps to the file's markdown content.
|
|
6
|
+
*/
|
|
7
|
+
export declare function countBodyFields(fields: readonly FieldConfig[]): number;
|
|
8
|
+
/**
|
|
9
|
+
* Find the name of the field marked `isBody: true`, or `'body'` as the default.
|
|
10
|
+
* Used at read time to map the markdown file's content to the correct data field.
|
|
11
|
+
*/
|
|
12
|
+
export declare function findBodyFieldName(fields: readonly FieldConfig[]): string;
|
|
13
|
+
/**
|
|
14
|
+
* Find isBody fields that have an invalid type (not 'markdown' or 'mdx').
|
|
15
|
+
* Returns field names that fail validation.
|
|
16
|
+
*/
|
|
17
|
+
export declare function findInvalidBodyFields(fields: readonly FieldConfig[]): string[];
|
|
18
|
+
//# sourceMappingURL=body-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body-field.d.ts","sourceRoot":"","sources":["../../src/utils/body-field.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAI5C;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAMtE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAKxE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,EAAE,CAQ9E"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const BODY_FIELD_TYPES = new Set(['markdown', 'mdx']);
|
|
2
|
+
/**
|
|
3
|
+
* Count the number of top-level fields marked `isBody: true` in a schema.
|
|
4
|
+
* Does NOT recurse into objects — isBody only makes sense at the top level
|
|
5
|
+
* because it maps to the file's markdown content.
|
|
6
|
+
*/
|
|
7
|
+
export function countBodyFields(fields) {
|
|
8
|
+
let count = 0;
|
|
9
|
+
for (const field of fields) {
|
|
10
|
+
if ('isBody' in field && field.isBody)
|
|
11
|
+
count++;
|
|
12
|
+
}
|
|
13
|
+
return count;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Find the name of the field marked `isBody: true`, or `'body'` as the default.
|
|
17
|
+
* Used at read time to map the markdown file's content to the correct data field.
|
|
18
|
+
*/
|
|
19
|
+
export function findBodyFieldName(fields) {
|
|
20
|
+
for (const field of fields) {
|
|
21
|
+
if ('isBody' in field && field.isBody)
|
|
22
|
+
return field.name;
|
|
23
|
+
}
|
|
24
|
+
return 'body';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Find isBody fields that have an invalid type (not 'markdown' or 'mdx').
|
|
28
|
+
* Returns field names that fail validation.
|
|
29
|
+
*/
|
|
30
|
+
export function findInvalidBodyFields(fields) {
|
|
31
|
+
const invalid = [];
|
|
32
|
+
for (const field of fields) {
|
|
33
|
+
if ('isBody' in field && field.isBody && !BODY_FIELD_TYPES.has(field.type)) {
|
|
34
|
+
invalid.push(field.name);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return invalid;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=body-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body-field.js","sourceRoot":"","sources":["../../src/utils/body-field.ts"],"names":[],"mappings":"AAEA,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAA;AAErD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAA8B;IAC5D,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,QAAQ,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM;YAAE,KAAK,EAAE,CAAA;IAChD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA8B;IAC9D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,QAAQ,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC,IAAI,CAAA;IAC1D,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAA8B;IAClE,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,QAAQ,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3E,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
package/dist/utils/fs.js
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitize an untrusted URL for use in `href` attributes.
|
|
3
|
+
*
|
|
4
|
+
* Parses the input with `new URL()` and only allows `http:` and `https:` protocols,
|
|
5
|
+
* blocking `javascript:`, `data:`, `vbscript:`, and other dangerous schemes.
|
|
6
|
+
* Returns the fallback (default `'#'`) for invalid or disallowed URLs.
|
|
7
|
+
*
|
|
8
|
+
* This utility breaks CodeQL's taint chain by constructing a new string from
|
|
9
|
+
* the parsed URL rather than passing the original input through.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { sanitizeHref } from 'canopycms'
|
|
14
|
+
*
|
|
15
|
+
* <a href={sanitizeHref(cta.link)}>{cta.text}</a>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function sanitizeHref(url: string, fallback?: string): string;
|
|
19
|
+
//# sourceMappingURL=sanitize-href.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize-href.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize-href.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAM,GAAG,MAAM,CAUhE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitize an untrusted URL for use in `href` attributes.
|
|
3
|
+
*
|
|
4
|
+
* Parses the input with `new URL()` and only allows `http:` and `https:` protocols,
|
|
5
|
+
* blocking `javascript:`, `data:`, `vbscript:`, and other dangerous schemes.
|
|
6
|
+
* Returns the fallback (default `'#'`) for invalid or disallowed URLs.
|
|
7
|
+
*
|
|
8
|
+
* This utility breaks CodeQL's taint chain by constructing a new string from
|
|
9
|
+
* the parsed URL rather than passing the original input through.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { sanitizeHref } from 'canopycms'
|
|
14
|
+
*
|
|
15
|
+
* <a href={sanitizeHref(cta.link)}>{cta.text}</a>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export function sanitizeHref(url, fallback = '#') {
|
|
19
|
+
try {
|
|
20
|
+
const parsed = new URL(url);
|
|
21
|
+
if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {
|
|
22
|
+
return parsed.href;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// invalid URL
|
|
27
|
+
}
|
|
28
|
+
return fallback;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=sanitize-href.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize-href.js","sourceRoot":"","sources":["../../src/utils/sanitize-href.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,QAAQ,GAAG,GAAG;IACtD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAC3B,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChE,OAAO,MAAM,CAAC,IAAI,CAAA;QACpB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isValidId } from '../id';
|
|
2
|
-
import { findFieldsByType } from './field-traversal';
|
|
1
|
+
import { isValidId } from '../id.js';
|
|
2
|
+
import { findFieldsByType } from './field-traversal.js';
|
|
3
3
|
/**
|
|
4
4
|
* ReferenceValidator validates that referenced content IDs exist and match collection constraints.
|
|
5
5
|
*
|
|
@@ -2,11 +2,11 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { simpleGit } from 'simple-git';
|
|
4
4
|
import { Octokit } from '@octokit/rest';
|
|
5
|
-
import { dequeueTask, completeTask, failTask, retryTask, recoverOrphanedTasks, cleanupOldTasks, cmsTaskQueueLogger, } from './task-queue';
|
|
6
|
-
import { getBranchMetadataFileManager, BranchMetadataFileManager } from '../branch-metadata';
|
|
7
|
-
import { extractIdFromFilename } from '../content-id-index';
|
|
8
|
-
import { ROOT_COLLECTION_ID } from '../paths/types';
|
|
9
|
-
import { isFileExistsError } from '../utils/error';
|
|
5
|
+
import { dequeueTask, completeTask, failTask, retryTask, recoverOrphanedTasks, cleanupOldTasks, cmsTaskQueueLogger, } from './task-queue.js';
|
|
6
|
+
import { getBranchMetadataFileManager, BranchMetadataFileManager } from '../branch-metadata.js';
|
|
7
|
+
import { extractIdFromFilename } from '../content-id-index.js';
|
|
8
|
+
import { ROOT_COLLECTION_ID } from '../paths/types.js';
|
|
9
|
+
import { isFileExistsError } from '../utils/error.js';
|
|
10
10
|
const DEFAULT_TASK_TIMEOUT = 60_000;
|
|
11
11
|
const DEFAULT_MAX_RETRIES = 3;
|
|
12
12
|
// Payload validation helpers — fail fast with clear errors instead of silent `as` casts
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* CanopyCMS task queue — re-exports from the generic task-queue module
|
|
3
3
|
* with CMS-specific action types and a WorkerTask alias.
|
|
4
4
|
*/
|
|
5
|
-
import { createDebugLogger } from '../utils/debug';
|
|
5
|
+
import { createDebugLogger } from '../utils/debug.js';
|
|
6
6
|
// ============================================================================
|
|
7
7
|
// Shared logger instance for CMS task queue operations
|
|
8
8
|
// ============================================================================
|
|
@@ -16,5 +16,5 @@ export const cmsTaskQueueLogger = {
|
|
|
16
16
|
// Re-exports from generic task-queue module
|
|
17
17
|
// ============================================================================
|
|
18
18
|
export { enqueueTask, dequeueTask, completeTask, failTask, retryTask, recoverOrphanedTasks, cleanupOldTasks, getTask, getTask as getTaskResult, // backward-compatible alias
|
|
19
|
-
listTasks, getQueueStats, } from '../task-queue';
|
|
19
|
+
listTasks, getQueueStats, } from '../task-queue/index.js';
|
|
20
20
|
//# sourceMappingURL=task-queue.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//": "@codemirror/language, @lezer/highlight: workaround — @mdxeditor/editor uses cm6-theme-basic-light which peer-requires these but mdxeditor doesn't declare them as dependencies",
|
|
3
3
|
"name": "canopycms",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.18",
|
|
5
5
|
"description": "CanopyCMS core package: schema-driven content, branch-aware editing, and editor UI for Next.js.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|