canopycms 0.0.15 → 0.0.17

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.
Files changed (187) hide show
  1. package/dist/ai/generate.js +5 -5
  2. package/dist/ai/generate.js.map +1 -1
  3. package/dist/ai/handler.js +5 -5
  4. package/dist/ai/index.js +3 -3
  5. package/dist/ai/resolve-branch.js +2 -2
  6. package/dist/api/__test__/mock-client.js +1 -1
  7. package/dist/api/assets.js +1 -1
  8. package/dist/api/branch-merge.js +3 -3
  9. package/dist/api/branch-review.js +4 -4
  10. package/dist/api/branch-status.js +8 -8
  11. package/dist/api/branch-withdraw.js +5 -5
  12. package/dist/api/branch.js +9 -9
  13. package/dist/api/comments.js +4 -4
  14. package/dist/api/content.js +5 -5
  15. package/dist/api/entries.d.ts.map +1 -1
  16. package/dist/api/entries.js +57 -145
  17. package/dist/api/entries.js.map +1 -1
  18. package/dist/api/github-sync.js +3 -3
  19. package/dist/api/groups.js +4 -4
  20. package/dist/api/guards.js +1 -1
  21. package/dist/api/index.js +3 -3
  22. package/dist/api/permissions.js +4 -4
  23. package/dist/api/reference-options.js +5 -5
  24. package/dist/api/resolve-references.js +4 -4
  25. package/dist/api/route-builder.js +1 -1
  26. package/dist/api/schema.js +5 -5
  27. package/dist/api/settings-helpers.js +1 -1
  28. package/dist/api/user.js +1 -1
  29. package/dist/api/validators.js +3 -3
  30. package/dist/asset-store.js +1 -1
  31. package/dist/auth/cache.js +2 -2
  32. package/dist/auth/caching-auth-plugin.js +1 -1
  33. package/dist/auth/file-based-auth-cache.js +1 -1
  34. package/dist/auth/index.js +1 -1
  35. package/dist/authorization/branch.js +1 -1
  36. package/dist/authorization/content.js +3 -3
  37. package/dist/authorization/groups/index.js +2 -2
  38. package/dist/authorization/groups/loader.js +4 -4
  39. package/dist/authorization/index.js +8 -8
  40. package/dist/authorization/path.js +1 -1
  41. package/dist/authorization/permissions/index.js +2 -2
  42. package/dist/authorization/permissions/loader.js +3 -3
  43. package/dist/authorization/permissions/schema.js +1 -1
  44. package/dist/authorization/test-utils.js +1 -1
  45. package/dist/authorization/validation.js +1 -1
  46. package/dist/branch-metadata.js +3 -3
  47. package/dist/branch-registry.js +2 -2
  48. package/dist/branch-schema-cache.js +2 -2
  49. package/dist/branch-workspace.js +6 -6
  50. package/dist/build/generate-ai-content.js +4 -4
  51. package/dist/build/index.js +1 -1
  52. package/dist/cli/cli.js +5 -5
  53. package/dist/cli/generate-ai-content.js +12 -13
  54. package/dist/cli/init.js +4 -11
  55. package/dist/cli/sync.js +1 -1
  56. package/dist/client.js +9 -9
  57. package/dist/config/flatten.js +2 -2
  58. package/dist/config/helpers.js +3 -3
  59. package/dist/config/index.js +9 -9
  60. package/dist/config/schemas/collection.js +1 -1
  61. package/dist/config/schemas/config.js +2 -2
  62. package/dist/config/schemas/field.d.ts +21 -0
  63. package/dist/config/schemas/field.d.ts.map +1 -1
  64. package/dist/config/schemas/field.js +2 -1
  65. package/dist/config/schemas/field.js.map +1 -1
  66. package/dist/config/types.d.ts +2 -0
  67. package/dist/config/types.d.ts.map +1 -1
  68. package/dist/config/validation.js +2 -2
  69. package/dist/config-test.js +2 -2
  70. package/dist/config.js +2 -2
  71. package/dist/content-id-index.js +2 -2
  72. package/dist/content-listing.d.ts +67 -2
  73. package/dist/content-listing.d.ts.map +1 -1
  74. package/dist/content-listing.js +95 -13
  75. package/dist/content-listing.js.map +1 -1
  76. package/dist/content-reader.js +5 -5
  77. package/dist/content-store.d.ts +1 -1
  78. package/dist/content-store.d.ts.map +1 -1
  79. package/dist/content-store.js +6 -6
  80. package/dist/content-store.js.map +1 -1
  81. package/dist/content-tree.d.ts +11 -5
  82. package/dist/content-tree.d.ts.map +1 -1
  83. package/dist/content-tree.js +3 -1
  84. package/dist/content-tree.js.map +1 -1
  85. package/dist/context.d.ts +3 -0
  86. package/dist/context.d.ts.map +1 -1
  87. package/dist/context.js +24 -6
  88. package/dist/context.js.map +1 -1
  89. package/dist/editor/BranchManager.js +4 -4
  90. package/dist/editor/CanopyEditor.js +3 -3
  91. package/dist/editor/CanopyEditorPage.js +1 -1
  92. package/dist/editor/CommentsPanel.js +1 -1
  93. package/dist/editor/Editor.js +18 -18
  94. package/dist/editor/EntryNavigator.js +1 -1
  95. package/dist/editor/FormRenderer.js +12 -12
  96. package/dist/editor/GroupManager.js +1 -1
  97. package/dist/editor/PermissionManager.js +1 -1
  98. package/dist/editor/client-reference-resolver.js +1 -1
  99. package/dist/editor/comments/BranchComments.js +1 -1
  100. package/dist/editor/comments/EntryComments.js +1 -1
  101. package/dist/editor/comments/FieldWrapper.js +1 -1
  102. package/dist/editor/comments/InlineCommentThread.js +1 -1
  103. package/dist/editor/comments/ThreadCarousel.js +1 -1
  104. package/dist/editor/components/EditorHeader.js +1 -1
  105. package/dist/editor/components/UserBadge.js +1 -1
  106. package/dist/editor/components/index.js +3 -3
  107. package/dist/editor/context/ApiClientContext.js +1 -1
  108. package/dist/editor/context/index.js +2 -2
  109. package/dist/editor/editor-utils.js +1 -1
  110. package/dist/editor/fields/BlockField.js +1 -1
  111. package/dist/editor/fields/ObjectField.js +1 -1
  112. package/dist/editor/fields/ReferenceField.js +1 -1
  113. package/dist/editor/group-manager/GroupCard.js +1 -1
  114. package/dist/editor/group-manager/InternalGroupsTab.js +1 -1
  115. package/dist/editor/group-manager/MemberList.js +1 -1
  116. package/dist/editor/group-manager/index.js +9 -9
  117. package/dist/editor/hooks/__test__/test-utils.js +3 -3
  118. package/dist/editor/hooks/index.js +11 -11
  119. package/dist/editor/hooks/useBranchActions.js +1 -1
  120. package/dist/editor/hooks/useBranchManager.js +1 -1
  121. package/dist/editor/hooks/useCommentSystem.js +2 -2
  122. package/dist/editor/hooks/useDraftManager.js +1 -1
  123. package/dist/editor/hooks/useEntryManager.js +3 -3
  124. package/dist/editor/hooks/useGroupManager.js +1 -1
  125. package/dist/editor/hooks/usePermissionManager.js +1 -1
  126. package/dist/editor/hooks/useReferenceResolution.js +1 -1
  127. package/dist/editor/hooks/useSchemaManager.js +1 -1
  128. package/dist/editor/hooks/useUserContext.js +1 -1
  129. package/dist/editor/permission-manager/PermissionEditor.js +4 -4
  130. package/dist/editor/permission-manager/PermissionLevelBadge.js +1 -1
  131. package/dist/editor/permission-manager/PermissionTree.js +3 -3
  132. package/dist/editor/permission-manager/UserSelector.js +1 -1
  133. package/dist/editor/permission-manager/hooks/usePermissionTree.js +2 -2
  134. package/dist/editor/permission-manager/index.js +6 -6
  135. package/dist/editor/preview-bridge.js +1 -1
  136. package/dist/editor/schema-editor/CollectionEditor.js +2 -2
  137. package/dist/editor/schema-editor/index.js +2 -2
  138. package/dist/entry-schema-registry.d.ts.map +1 -1
  139. package/dist/entry-schema-registry.js +34 -2
  140. package/dist/entry-schema-registry.js.map +1 -1
  141. package/dist/entry-schema.d.ts +1 -0
  142. package/dist/entry-schema.d.ts.map +1 -1
  143. package/dist/entry-schema.js.map +1 -1
  144. package/dist/git-manager.js +4 -4
  145. package/dist/github-service.js +1 -1
  146. package/dist/http/handler.js +7 -7
  147. package/dist/http/index.js +3 -3
  148. package/dist/http/router.js +12 -12
  149. package/dist/id.js +1 -1
  150. package/dist/index.d.ts +2 -1
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/index.js +6 -6
  153. package/dist/operating-mode/client-unsafe-strategy.js +2 -2
  154. package/dist/operating-mode/client.js +1 -1
  155. package/dist/operating-mode/index.js +2 -2
  156. package/dist/paths/branch.js +1 -1
  157. package/dist/paths/index.js +6 -6
  158. package/dist/paths/test-utils.js +1 -1
  159. package/dist/paths/validation.js +1 -1
  160. package/dist/reference-resolver.js +2 -2
  161. package/dist/reference-resolver.js.map +1 -1
  162. package/dist/schema/index.js +2 -2
  163. package/dist/schema/meta-loader.d.ts.map +1 -1
  164. package/dist/schema/meta-loader.js +11 -1
  165. package/dist/schema/meta-loader.js.map +1 -1
  166. package/dist/schema/resolver.js +1 -1
  167. package/dist/schema/schema-store.js +4 -4
  168. package/dist/server.d.ts +3 -1
  169. package/dist/server.d.ts.map +1 -1
  170. package/dist/server.js +13 -12
  171. package/dist/server.js.map +1 -1
  172. package/dist/services.js +12 -12
  173. package/dist/settings-branch-utils.js +1 -1
  174. package/dist/settings-workspace.js +3 -3
  175. package/dist/task-queue/index.js +1 -1
  176. package/dist/task-queue/task-queue.js +1 -1
  177. package/dist/user.js +1 -1
  178. package/dist/utils/fs.js +1 -1
  179. package/dist/utils/title-field.d.ts +40 -0
  180. package/dist/utils/title-field.d.ts.map +1 -0
  181. package/dist/utils/title-field.js +126 -0
  182. package/dist/utils/title-field.js.map +1 -0
  183. package/dist/validation/reference-validator.js +2 -2
  184. package/dist/worker/cms-worker.js +5 -5
  185. package/dist/worker/task-queue-config.js +1 -1
  186. package/dist/worker/task-queue.js +2 -2
  187. package/package.json +1 -1
@@ -15,7 +15,7 @@
15
15
  * })
16
16
  * ```
17
17
  */
18
- import { isAdmin, isReviewer, isPrivileged } from '../authorization/helpers';
18
+ import { isAdmin, isReviewer, isPrivileged } from '../authorization/helpers.js';
19
19
  // ============================================================================
20
20
  // Guard runner implementations
21
21
  // ============================================================================
package/dist/api/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  // Content API uses path-based routing now - no separate params/body types exported
2
2
  // Export route definitions
3
- export { USER_ROUTES } from './user';
3
+ export { USER_ROUTES } from './user.js';
4
4
  // Note: SCHEMA_ROUTES is not exported here because it imports server-only code (fs module).
5
- // Import it directly from './schema' in server-side code when needed.
5
+ // Import it directly from './schema.js' in server-side code when needed.
6
6
  // Export client
7
- export { CanopyApiClient, createApiClient } from './client';
7
+ export { CanopyApiClient, createApiClient } from './client.js';
8
8
  //# sourceMappingURL=index.js.map
@@ -1,8 +1,8 @@
1
1
  import { z } from 'zod';
2
- import { loadPathPermissions, savePathPermissions, loadPermissionsFile } from '../authorization';
3
- import { permissionPathSchema } from './validators';
4
- import { defineEndpoint } from './route-builder';
5
- import { getSettingsBranchContext, commitSettings } from './settings-helpers';
2
+ import { loadPathPermissions, savePathPermissions, loadPermissionsFile } from '../authorization/index.js';
3
+ import { permissionPathSchema } from './validators.js';
4
+ import { defineEndpoint } from './route-builder.js';
5
+ import { getSettingsBranchContext, commitSettings } from './settings-helpers.js';
6
6
  // ============================================================================
7
7
  // Zod Schemas for Validation
8
8
  // ============================================================================
@@ -1,9 +1,9 @@
1
1
  import { z } from 'zod';
2
- import { ContentStore } from '../content-store';
3
- import { defineEndpoint } from './route-builder';
4
- import { ReferenceResolver } from '../reference-resolver';
5
- import { parseLogicalPath } from '../paths';
6
- import { branchNameSchema } from './validators';
2
+ import { ContentStore } from '../content-store.js';
3
+ import { defineEndpoint } from './route-builder.js';
4
+ import { ReferenceResolver } from '../reference-resolver.js';
5
+ import { parseLogicalPath } from '../paths/index.js';
6
+ import { branchNameSchema } from './validators.js';
7
7
  // ============================================================================
8
8
  // Zod Schemas for Validation
9
9
  // ============================================================================
@@ -1,8 +1,8 @@
1
1
  import { z } from 'zod';
2
- import { ContentStore } from '../content-store';
3
- import { defineEndpoint } from './route-builder';
4
- import { ReferenceResolver } from '../reference-resolver';
5
- import { branchNameSchema, contentIdSchema } from './validators';
2
+ import { ContentStore } from '../content-store.js';
3
+ import { defineEndpoint } from './route-builder.js';
4
+ import { ReferenceResolver } from '../reference-resolver.js';
5
+ import { branchNameSchema, contentIdSchema } from './validators.js';
6
6
  // ============================================================================
7
7
  // Zod Schemas for Validation
8
8
  // ============================================================================
@@ -8,7 +8,7 @@
8
8
  * - Makes code generation trivial (no regex parsing needed)
9
9
  * - Self-documents the API surface
10
10
  */
11
- import { executeGuards } from './guards';
11
+ import { executeGuards } from './guards.js';
12
12
  /**
13
13
  * Global registry - generator reads this
14
14
  */
@@ -11,11 +11,11 @@
11
11
  */
12
12
  import { z } from 'zod';
13
13
  import path from 'node:path';
14
- import { defineEndpoint } from './route-builder';
15
- import { getErrorMessage } from '../utils/error';
16
- import { branchNameSchema, logicalPathSchema } from './validators';
17
- import { SchemaOps, createCollectionInputSchema, updateCollectionInputSchema, entryTypeInputSchema, updateEntryTypeInputSchema, } from '../schema/schema-store';
18
- import { parseLogicalPath } from '../paths';
14
+ import { defineEndpoint } from './route-builder.js';
15
+ import { getErrorMessage } from '../utils/error.js';
16
+ import { branchNameSchema, logicalPathSchema } from './validators.js';
17
+ import { SchemaOps, createCollectionInputSchema, updateCollectionInputSchema, entryTypeInputSchema, updateEntryTypeInputSchema, } from '../schema/schema-store.js';
18
+ import { parseLogicalPath } from '../paths/index.js';
19
19
  /**
20
20
  * Resolve the schemaRef for an entry type. Uses the explicit schemaRef if set,
21
21
  * otherwise does a reverse lookup in the registry by matching the schema array.
@@ -1,4 +1,4 @@
1
- import { operatingStrategy } from '../operating-mode';
1
+ import { operatingStrategy } from '../operating-mode/index.js';
2
2
  /**
3
3
  * Get the appropriate root path for settings (permissions/groups).
4
4
  * Returns the settings root managed by the settings workspace.
package/dist/api/user.js CHANGED
@@ -1,4 +1,4 @@
1
- import { defineEndpoint } from './route-builder';
1
+ import { defineEndpoint } from './route-builder.js';
2
2
  /**
3
3
  * Get current user info
4
4
  * This is a PUBLIC endpoint - no special permissions required
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Usage:
8
8
  * ```ts
9
- * import { branchNameSchema, logicalPathSchema } from './validators'
9
+ * import { branchNameSchema, logicalPathSchema } from './validators.js'
10
10
  *
11
11
  * const paramsSchema = z.object({
12
12
  * branch: branchNameSchema,
@@ -20,8 +20,8 @@
20
20
  * ```
21
21
  */
22
22
  import { z } from 'zod';
23
- import { parseBranchName, parseLogicalPath, parseContentId, parseSlug, } from '../paths';
24
- import { parsePermissionPath } from '../authorization';
23
+ import { parseBranchName, parseLogicalPath, parseContentId, parseSlug, } from '../paths/index.js';
24
+ import { parsePermissionPath } from '../authorization/index.js';
25
25
  /**
26
26
  * Zod schema for BranchName - validates git branch naming rules and brands.
27
27
  *
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { isNotFoundError } from './utils/error';
3
+ import { isNotFoundError } from './utils/error.js';
4
4
  const normalizeKey = (key) => key.replace(/^\/+/, '');
5
5
  /**
6
6
  * Local filesystem asset store for dev and tests. In production, swap with S3 adapter.
@@ -3,6 +3,6 @@
3
3
  * These use node:fs/promises and must NOT be imported in client bundles.
4
4
  * Use 'canopycms/auth/cache' as the import path.
5
5
  */
6
- export { FileBasedAuthCache, writeAuthCacheSnapshot } from './file-based-auth-cache';
7
- export { CachingAuthPlugin } from './caching-auth-plugin';
6
+ export { FileBasedAuthCache, writeAuthCacheSnapshot } from './file-based-auth-cache.js';
7
+ export { CachingAuthPlugin } from './caching-auth-plugin.js';
8
8
  //# sourceMappingURL=cache.js.map
@@ -1,4 +1,4 @@
1
- import { createDebugLogger } from '../utils/debug';
1
+ import { createDebugLogger } from '../utils/debug.js';
2
2
  const log = createDebugLogger({ prefix: 'CachingAuthPlugin' });
3
3
  /**
4
4
  * Auth plugin that wraps a token verifier with cached metadata lookups.
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { createDebugLogger } from '../utils/debug';
3
+ import { createDebugLogger } from '../utils/debug.js';
4
4
  const log = createDebugLogger({ prefix: 'FileBasedAuthCache' });
5
5
  /**
6
6
  * Resolve the active cache directory.
@@ -1,2 +1,2 @@
1
- export { isCanopyRequest, isHeadersLike, extractHeaders, validateAuthContext, } from './context-helpers';
1
+ export { isCanopyRequest, isHeadersLike, extractHeaders, validateAuthContext, } from './context-helpers.js';
2
2
  //# sourceMappingURL=index.js.map
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Handles checking if a user can access a branch based on ACLs.
5
5
  */
6
- import { isAdmin, isReviewer } from './helpers';
6
+ import { isAdmin, isReviewer } from './helpers.js';
7
7
  /**
8
8
  * Check if user has access to a branch with explicit default behavior.
9
9
  */
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Usage:
8
8
  * ```ts
9
- * import { checkContentAccess } from './authorization'
9
+ * import { checkContentAccess } from './authorization.js'
10
10
  *
11
11
  * const result = await checkContentAccess(deps, context, branchRoot, 'content/posts/my-post.mdx', user, 'edit')
12
12
  * if (result.allowed) {
@@ -14,8 +14,8 @@
14
14
  * }
15
15
  * ```
16
16
  */
17
- import { operatingStrategy } from '../operating-mode';
18
- import { createCheckPathAccess } from './path';
17
+ import { operatingStrategy } from '../operating-mode/index.js';
18
+ import { createCheckPathAccess } from './path.js';
19
19
  /**
20
20
  * Check content access by evaluating both branch and path permissions.
21
21
  * Path permissions are loaded dynamically from the branch root.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Groups module exports
3
3
  */
4
- export { GroupsFileSchema, createDefaultGroupsFile, } from './schema';
5
- export { loadGroupsFile, loadInternalGroups, saveInternalGroups } from './loader';
4
+ export { GroupsFileSchema, createDefaultGroupsFile, } from './schema.js';
5
+ export { loadGroupsFile, loadInternalGroups, saveInternalGroups } from './loader.js';
6
6
  //# sourceMappingURL=index.js.map
@@ -4,10 +4,10 @@
4
4
  * Handles loading and saving internal groups from the filesystem.
5
5
  */
6
6
  import { promises as fs } from 'node:fs';
7
- import { GroupsFileSchema } from './schema';
8
- import { operatingStrategy } from '../../operating-mode';
9
- import { RESERVED_GROUPS } from '../helpers';
10
- import { atomicWriteFile } from '../../utils/atomic-write';
7
+ import { GroupsFileSchema } from './schema.js';
8
+ import { operatingStrategy } from '../../operating-mode/index.js';
9
+ import { RESERVED_GROUPS } from '../helpers.js';
10
+ import { atomicWriteFile } from '../../utils/atomic-write.js';
11
11
  /**
12
12
  * Get the appropriate groups file path based on mode
13
13
  */
@@ -8,7 +8,7 @@
8
8
  * For most use cases, use `checkContentAccess` which handles both branch and path permissions:
9
9
  *
10
10
  * ```ts
11
- * import { checkContentAccess } from './authorization'
11
+ * import { checkContentAccess } from './authorization.js'
12
12
  *
13
13
  * const result = await checkContentAccess(deps, context, branchRoot, 'content/posts/post.mdx', user, 'edit')
14
14
  * if (result.allowed) {
@@ -26,17 +26,17 @@
26
26
  * - `groups/` - Groups file schema and loader
27
27
  */
28
28
  // Validation
29
- export { parsePermissionPath } from './validation';
29
+ export { parsePermissionPath } from './validation.js';
30
30
  // Main content access (recommended for most cases)
31
- export { checkContentAccess, createCheckContentAccess } from './content';
31
+ export { checkContentAccess, createCheckContentAccess } from './content.js';
32
32
  // Branch-level access
33
- export { checkBranchAccessWithDefault, createCheckBranchAccess, canPerformWorkflowAction, } from './branch';
33
+ export { checkBranchAccessWithDefault, createCheckBranchAccess, canPerformWorkflowAction, } from './branch.js';
34
34
  // Path-level access
35
- export { checkPathAccess, createCheckPathAccess } from './path';
35
+ export { checkPathAccess, createCheckPathAccess } from './path.js';
36
36
  // Helper functions
37
- export { RESERVED_GROUPS, isReservedGroup, isAdmin, isReviewer, isPrivileged, } from './helpers';
37
+ export { RESERVED_GROUPS, isReservedGroup, isAdmin, isReviewer, isPrivileged, } from './helpers.js';
38
38
  // Permissions file handling
39
- export { PermissionsFileSchema, createDefaultPermissionsFile, loadPermissionsFile, loadPathPermissions, savePathPermissions, ensurePermissionsFile, } from './permissions';
39
+ export { PermissionsFileSchema, createDefaultPermissionsFile, loadPermissionsFile, loadPathPermissions, savePathPermissions, ensurePermissionsFile, } from './permissions/index.js';
40
40
  // Groups file handling
41
- export { GroupsFileSchema, createDefaultGroupsFile, loadGroupsFile, loadInternalGroups, saveInternalGroups, } from './groups';
41
+ export { GroupsFileSchema, createDefaultGroupsFile, loadGroupsFile, loadInternalGroups, saveInternalGroups, } from './groups/index.js';
42
42
  //# sourceMappingURL=index.js.map
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import path from 'node:path';
7
7
  import { minimatch } from 'minimatch';
8
- import { isAdmin } from './helpers';
8
+ import { isAdmin } from './helpers.js';
9
9
  /**
10
10
  * Normalize a path for consistent matching
11
11
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Permissions module exports
3
3
  */
4
- export { PermissionsFileSchema, createDefaultPermissionsFile } from './schema';
5
- export { loadPermissionsFile, loadPathPermissions, savePathPermissions, ensurePermissionsFile, } from './loader';
4
+ export { PermissionsFileSchema, createDefaultPermissionsFile } from './schema.js';
5
+ export { loadPermissionsFile, loadPathPermissions, savePathPermissions, ensurePermissionsFile, } from './loader.js';
6
6
  //# sourceMappingURL=index.js.map
@@ -4,9 +4,9 @@
4
4
  * Handles loading and saving path permissions from the filesystem.
5
5
  */
6
6
  import fs from 'node:fs/promises';
7
- import { PermissionsFileSchema } from './schema';
8
- import { operatingStrategy } from '../../operating-mode';
9
- import { atomicWriteFile } from '../../utils/atomic-write';
7
+ import { PermissionsFileSchema } from './schema.js';
8
+ import { operatingStrategy } from '../../operating-mode/index.js';
9
+ import { atomicWriteFile } from '../../utils/atomic-write.js';
10
10
  /**
11
11
  * Get the appropriate permissions file path based on mode
12
12
  */
@@ -2,7 +2,7 @@
2
2
  * Schema for permissions.json file
3
3
  */
4
4
  import { z } from 'zod';
5
- import { parsePermissionPath } from '../validation';
5
+ import { parsePermissionPath } from '../validation.js';
6
6
  const permissionTargetSchema = z.object({
7
7
  allowedUsers: z.array(z.string()).optional(),
8
8
  allowedGroups: z.array(z.string()).optional(),
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @example
8
8
  * // In test files only:
9
- * import { unsafeAsPermissionPath } from '../authorization/test-utils'
9
+ * import { unsafeAsPermissionPath } from '../authorization/test-utils.js'
10
10
  */
11
11
  /** Test-only: cast a string to PermissionPath without validation. */
12
12
  export const unsafeAsPermissionPath = (path) => path;
@@ -4,7 +4,7 @@
4
4
  * SECURITY CRITICAL: These functions validate permission paths
5
5
  * to prevent path traversal attacks.
6
6
  */
7
- import { hasTraversalSequence } from '../paths/normalize';
7
+ import { hasTraversalSequence } from '../paths/normalize.js';
8
8
  /**
9
9
  * Parse and validate a PermissionPath.
10
10
  *
@@ -1,9 +1,9 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
- import { BranchRegistry } from './branch-registry';
5
- import { resolveBranchPath } from './paths';
6
- import { isFileExistsError, isNotFoundError } from './utils/error';
4
+ import { BranchRegistry } from './branch-registry.js';
5
+ import { resolveBranchPath } from './paths/index.js';
6
+ import { isFileExistsError, isNotFoundError } from './utils/error.js';
7
7
  const BRANCH_META_DIR = '.canopy-meta';
8
8
  const BRANCH_META_FILE = 'branch.json';
9
9
  const CURRENT_SCHEMA_VERSION = 1;
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { BranchMetadataFileManager } from './branch-metadata';
4
- import { isNotFoundError } from './utils/error';
3
+ import { BranchMetadataFileManager } from './branch-metadata.js';
4
+ import { isNotFoundError } from './utils/error.js';
5
5
  // Registry files are stored directly in the branches root (not in a subdirectory)
6
6
  const REGISTRY_FILE = 'branches.json';
7
7
  const REGISTRY_STALE_FILE = 'branches.stale.json';
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { resolveSchema, isValidSchema } from './schema/resolver';
4
- import { flattenSchema } from './config/flatten';
3
+ import { resolveSchema, isValidSchema } from './schema/resolver.js';
4
+ import { flattenSchema } from './config/flatten.js';
5
5
  /** Bump when BranchSchemaCacheEntry shape changes to auto-invalidate stale caches */
6
6
  const SCHEMA_CACHE_VERSION = 2;
7
7
  /** Minimum interval between mtime staleness checks (ms) */
@@ -1,8 +1,8 @@
1
- import { ensureBranchRoot } from './paths';
2
- import { getBranchMetadataFileManager, loadBranchContext } from './branch-metadata';
3
- import { isDeployedStatic } from './build-mode';
4
- import { GitManager } from './git-manager';
5
- import { createDebugLogger } from './utils/debug';
1
+ import { ensureBranchRoot } from './paths/index.js';
2
+ import { getBranchMetadataFileManager, loadBranchContext } from './branch-metadata.js';
3
+ import { isDeployedStatic } from './build-mode.js';
4
+ import { GitManager } from './git-manager.js';
5
+ import { createDebugLogger } from './utils/debug.js';
6
6
  const log = createDebugLogger({ prefix: 'BranchWorkspace' });
7
7
  // In-memory lock to prevent concurrent workspace initialization
8
8
  const workspaceInitLocks = new Map();
@@ -84,7 +84,7 @@ export class BranchWorkspaceManager {
84
84
  };
85
85
  }
86
86
  }
87
- export { loadBranchContext } from './branch-metadata';
87
+ export { loadBranchContext } from './branch-metadata.js';
88
88
  /**
89
89
  * Load an existing branch context, or create the workspace if it doesn't exist yet.
90
90
  *
@@ -6,10 +6,10 @@
6
6
  */
7
7
  import fs from 'node:fs/promises';
8
8
  import path from 'node:path';
9
- import { ContentStore } from '../content-store';
10
- import { BranchSchemaCache } from '../branch-schema-cache';
11
- import { generateAIContent } from '../ai/generate';
12
- import { resolveBranchRoot } from '../ai/resolve-branch';
9
+ import { ContentStore } from '../content-store.js';
10
+ import { BranchSchemaCache } from '../branch-schema-cache.js';
11
+ import { generateAIContent } from '../ai/generate.js';
12
+ import { resolveBranchRoot } from '../ai/resolve-branch.js';
13
13
  /**
14
14
  * Generate AI content files and write them to disk.
15
15
  *
@@ -3,5 +3,5 @@
3
3
  *
4
4
  * Provides static build utilities for pre-generating content.
5
5
  */
6
- export { generateAIContentFiles } from './generate-ai-content';
6
+ export { generateAIContentFiles } from './generate-ai-content.js';
7
7
  //# sourceMappingURL=index.js.map
package/dist/cli/cli.js CHANGED
@@ -33,7 +33,7 @@ export function resolveSyncDirection(push, pull, abort) {
33
33
  async function main() {
34
34
  const { argv, flags, command } = parseArgs(process.argv.slice(2));
35
35
  if (command === 'init') {
36
- const { init } = await import('./init');
36
+ const { init } = await import('./init.js');
37
37
  const nonInteractive = flags['non-interactive'] === true;
38
38
  const force = flags['force'] === true;
39
39
  const mode = 'dev';
@@ -84,7 +84,7 @@ async function main() {
84
84
  });
85
85
  }
86
86
  else if (command === 'init-deploy') {
87
- const { initDeployAws } = await import('./init');
87
+ const { initDeployAws } = await import('./init.js');
88
88
  const cloud = argv._[1];
89
89
  if (cloud !== 'aws') {
90
90
  console.error('Usage: canopycms init-deploy aws');
@@ -99,7 +99,7 @@ async function main() {
99
99
  });
100
100
  }
101
101
  else if (command === 'worker') {
102
- const { workerRunOnce } = await import('./init');
102
+ const { workerRunOnce } = await import('./init.js');
103
103
  const subcommand = argv._[1];
104
104
  if (subcommand !== 'run-once') {
105
105
  console.error('Usage: canopycms worker run-once');
@@ -127,7 +127,7 @@ async function main() {
127
127
  await workerRunOnce({ projectDir: process.cwd(), authPlugin });
128
128
  }
129
129
  else if (command === 'generate-ai-content') {
130
- const { generateAIContentCLI } = await import('./generate-ai-content');
130
+ const { generateAIContentCLI } = await import('./generate-ai-content.js');
131
131
  await generateAIContentCLI({
132
132
  projectDir: process.cwd(),
133
133
  outputDir: typeof flags['output'] === 'string' ? flags['output'] : undefined,
@@ -136,7 +136,7 @@ async function main() {
136
136
  });
137
137
  }
138
138
  else if (command === 'sync') {
139
- const { sync } = await import('./sync');
139
+ const { sync } = await import('./sync.js');
140
140
  const direction = resolveSyncDirection(flags['push'] === true, flags['pull'] === true, flags['abort'] === true);
141
141
  await sync({
142
142
  projectDir: process.cwd(),
@@ -161,7 +161,8 @@ var init_field = __esm({
161
161
  label: z.string().optional(),
162
162
  description: z.string().optional(),
163
163
  required: z.boolean().optional(),
164
- list: z.boolean().optional()
164
+ list: z.boolean().optional(),
165
+ isTitle: z.boolean().optional()
165
166
  });
166
167
  selectOptionSchema = z.union([
167
168
  z.string(),
@@ -515,14 +516,6 @@ var init_config2 = __esm({
515
516
  }
516
517
  });
517
518
 
518
- // dist/config.js
519
- var init_config3 = __esm({
520
- "dist/config.js"() {
521
- "use strict";
522
- init_config2();
523
- }
524
- });
525
-
526
519
  // dist/operating-mode/client-unsafe-strategy.js
527
520
  import path3 from "node:path";
528
521
  function operatingStrategy(mode) {
@@ -553,7 +546,7 @@ var init_client_unsafe_strategy = __esm({
553
546
  "dist/operating-mode/client-unsafe-strategy.js"() {
554
547
  "use strict";
555
548
  init_client_safe_strategy();
556
- init_config3();
549
+ init_config2();
557
550
  ProdStrategy = class extends ProdClientSafeStrategy {
558
551
  // All client-safe methods inherited automatically from ProdClientSafeStrategy:
559
552
  // - mode, supportsBranching(), supportsStatusBadge(), supportsComments()
@@ -1486,7 +1479,7 @@ var ContentStore = class {
1486
1479
  * Returns array of entry metadata (relativePath, collection, slug).
1487
1480
  * Returns empty array if the collection doesn't exist.
1488
1481
  */
1489
- async listCollectionEntries(collectionPath) {
1482
+ async getCollectionEntryPaths(collectionPath) {
1490
1483
  const idIndex = await this.idIndex();
1491
1484
  const normalized = normalizeFilesystemPath(collectionPath);
1492
1485
  let item = this.schemaIndex.get(normalized);
@@ -1698,6 +1691,12 @@ function resolveEntryTypes(entryTypes, entrySchemaRegistry, contextName) {
1698
1691
  if (!resolvedSchema) {
1699
1692
  throw new Error(`Schema reference "${entryType.schema}" in entry type "${entryType.name}" (${contextName}) not found in registry. Available schemas: ${Object.keys(entrySchemaRegistry).join(", ")}`);
1700
1693
  }
1694
+ if (entryType.format === "md" || entryType.format === "mdx") {
1695
+ const hasBodyField = resolvedSchema.some((field) => field.name === "body");
1696
+ if (hasBodyField) {
1697
+ throw new Error(`Entry type "${entryType.name}" in ${contextName} has format "${entryType.format}" but schema "${entryType.schema}" contains a field named "body". "body" is reserved for markdown content in md/mdx formats. Rename the field or use format "json".`);
1698
+ }
1699
+ }
1701
1700
  return {
1702
1701
  name: entryType.name,
1703
1702
  label: entryType.label,
@@ -2215,7 +2214,7 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
2215
2214
  const entries = [];
2216
2215
  const cleanPath = stripContentRoot(collection.logicalPath, contentRoot);
2217
2216
  const manifestEntries = [];
2218
- const listed = await store.listCollectionEntries(collection.logicalPath);
2217
+ const listed = await store.getCollectionEntryPaths(collection.logicalPath);
2219
2218
  const directEntries = listed.filter((e) => e.collection === collection.logicalPath);
2220
2219
  for (const listEntry of directEntries) {
2221
2220
  const entryTypeName = extractEntryTypeFromFilename(path7.basename(listEntry.relativePath));
@@ -2280,7 +2279,7 @@ async function processRootEntries(store, rootCollection, contentRoot, config) {
2280
2279
  const files = /* @__PURE__ */ new Map();
2281
2280
  const entries = [];
2282
2281
  const manifestEntries = [];
2283
- const listed = await store.listCollectionEntries(rootCollection.logicalPath);
2282
+ const listed = await store.getCollectionEntryPaths(rootCollection.logicalPath);
2284
2283
  const directEntries = listed.filter((e) => e.collection === rootCollection.logicalPath);
2285
2284
  for (const listEntry of directEntries) {
2286
2285
  const entryTypeName = extractEntryTypeFromFilename(path7.basename(listEntry.relativePath));
package/dist/cli/init.js CHANGED
@@ -47,7 +47,8 @@ var init_field = __esm({
47
47
  label: z.string().optional(),
48
48
  description: z.string().optional(),
49
49
  required: z.boolean().optional(),
50
- list: z.boolean().optional()
50
+ list: z.boolean().optional(),
51
+ isTitle: z.boolean().optional()
51
52
  });
52
53
  selectOptionSchema = z.union([
53
54
  z.string(),
@@ -313,14 +314,6 @@ var init_config2 = __esm({
313
314
  }
314
315
  });
315
316
 
316
- // dist/config.js
317
- var init_config3 = __esm({
318
- "dist/config.js"() {
319
- "use strict";
320
- init_config2();
321
- }
322
- });
323
-
324
317
  // dist/cli/templates.js
325
318
  var templates_exports = {};
326
319
  __export(templates_exports, {
@@ -401,7 +394,7 @@ function getTaskQueueDir(config) {
401
394
  var init_task_queue_config = __esm({
402
395
  "dist/worker/task-queue-config.js"() {
403
396
  "use strict";
404
- init_config3();
397
+ init_config2();
405
398
  }
406
399
  });
407
400
 
@@ -973,7 +966,7 @@ var DevClientSafeStrategy = class {
973
966
 
974
967
  // dist/operating-mode/client-unsafe-strategy.js
975
968
  import path from "node:path";
976
- init_config3();
969
+ init_config2();
977
970
  var ProdStrategy = class extends ProdClientSafeStrategy {
978
971
  // All client-safe methods inherited automatically from ProdClientSafeStrategy:
979
972
  // - mode, supportsBranching(), supportsStatusBadge(), supportsComments()
package/dist/cli/sync.js CHANGED
@@ -16,7 +16,7 @@ import fs from 'node:fs/promises';
16
16
  import path from 'node:path';
17
17
  import { simpleGit } from 'simple-git';
18
18
  import * as p from '@clack/prompts';
19
- import { filePathExists } from '../utils/fs';
19
+ import { filePathExists } from '../utils/fs.js';
20
20
  /** Validate that a resolved path stays within the expected parent directory. */
21
21
  function assertWithinDir(resolved, parent, label) {
22
22
  const normalizedResolved = path.resolve(resolved);
package/dist/client.js CHANGED
@@ -1,11 +1,11 @@
1
1
  'use client';
2
- export * from './editor/EditorPanes';
3
- export * from './editor/EntryNavigator';
4
- export * from './editor/Editor';
5
- export * from './editor/preview-bridge';
6
- export * from './editor/canopy-path';
7
- export * from './editor/theme';
8
- export * from './editor/editor-config';
9
- export * from './editor/CanopyEditor';
10
- export * from './editor/CanopyEditorPage';
2
+ export * from './editor/EditorPanes.js';
3
+ export * from './editor/EntryNavigator.js';
4
+ export * from './editor/Editor.js';
5
+ export * from './editor/preview-bridge.js';
6
+ export * from './editor/canopy-path.js';
7
+ export * from './editor/theme.js';
8
+ export * from './editor/editor-config.js';
9
+ export * from './editor/CanopyEditor.js';
10
+ export * from './editor/CanopyEditorPage.js';
11
11
  //# sourceMappingURL=client.js.map
@@ -2,8 +2,8 @@
2
2
  * Schema flattening utilities for O(1) lookups.
3
3
  */
4
4
  import { join, normalize } from 'pathe';
5
- import { createLogicalPath } from '../paths/normalize';
6
- import { ROOT_COLLECTION_ID } from '../paths/types';
5
+ import { createLogicalPath } from '../paths/normalize.js';
6
+ import { ROOT_COLLECTION_ID } from '../paths/types.js';
7
7
  /**
8
8
  * Normalize a path value by splitting, filtering empty segments, and rejoining.
9
9
  */