canopycms 0.0.61 → 0.0.63
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/index.d.ts +9 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +9 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/json-to-markdown.js +1 -2
- package/dist/ai/json-to-markdown.js.map +1 -1
- package/dist/ai/to-plain-text.d.ts +57 -0
- package/dist/ai/to-plain-text.d.ts.map +1 -0
- package/dist/ai/to-plain-text.js +255 -0
- package/dist/ai/to-plain-text.js.map +1 -0
- package/dist/ai/transform-components.d.ts.map +1 -1
- package/dist/ai/transform-components.js +70 -5
- package/dist/ai/transform-components.js.map +1 -1
- package/dist/api/__test__/mock-client.d.ts +5 -1
- package/dist/api/__test__/mock-client.d.ts.map +1 -1
- package/dist/api/__test__/mock-client.js +9 -2
- package/dist/api/__test__/mock-client.js.map +1 -1
- package/dist/api/admin-branch-health.d.ts +36 -1
- package/dist/api/admin-branch-health.d.ts.map +1 -1
- package/dist/api/admin-branch-health.js +176 -2
- package/dist/api/admin-branch-health.js.map +1 -1
- package/dist/api/admin.d.ts +8 -1
- package/dist/api/admin.d.ts.map +1 -1
- package/dist/api/admin.js.map +1 -1
- package/dist/api/branch.d.ts.map +1 -1
- package/dist/api/branch.js +16 -2
- package/dist/api/branch.js.map +1 -1
- package/dist/api/client.d.ts +5 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +6 -0
- package/dist/api/client.js.map +1 -1
- package/dist/api/content.d.ts +11 -5
- package/dist/api/content.d.ts.map +1 -1
- package/dist/api/content.js +79 -6
- package/dist/api/content.js.map +1 -1
- package/dist/api/entries.d.ts +10 -0
- package/dist/api/entries.d.ts.map +1 -1
- package/dist/api/entries.js +40 -15
- package/dist/api/entries.js.map +1 -1
- package/dist/api/schema.d.ts +4 -4
- package/dist/api/schema.d.ts.map +1 -1
- package/dist/api/schema.js +13 -13
- package/dist/api/schema.js.map +1 -1
- package/dist/assets/transform.d.ts.map +1 -1
- package/dist/assets/transform.js +19 -6
- package/dist/assets/transform.js.map +1 -1
- package/dist/authorization/branch.d.ts +55 -3
- package/dist/authorization/branch.d.ts.map +1 -1
- package/dist/authorization/branch.js +55 -9
- package/dist/authorization/branch.js.map +1 -1
- package/dist/authorization/types.d.ts +1 -1
- package/dist/authorization/types.d.ts.map +1 -1
- package/dist/branch-health.d.ts +13 -0
- package/dist/branch-health.d.ts.map +1 -1
- package/dist/branch-health.js +23 -0
- package/dist/branch-health.js.map +1 -1
- package/dist/build-canopy.d.ts +49 -0
- package/dist/build-canopy.d.ts.map +1 -0
- package/dist/build-canopy.js +51 -0
- package/dist/build-canopy.js.map +1 -0
- package/dist/cli/cli.js +935 -562
- package/dist/cli/generate-ai-content.js +837 -480
- package/dist/cli/init.js +25 -7
- package/dist/cli/template-files/Dockerfile.cms.template +19 -1
- package/dist/cli/template-files/canopycms.config.ts.template +25 -1
- package/dist/cli/template-files/cms-stack.ts.template +7 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/config/schemas/field.d.ts +15 -15
- package/dist/config/types.d.ts +2 -2
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +0 -1
- package/dist/config/types.js.map +1 -1
- package/dist/config/validation.d.ts +9 -0
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +14 -0
- package/dist/config/validation.js.map +1 -1
- package/dist/content-id-index.d.ts +97 -5
- package/dist/content-id-index.d.ts.map +1 -1
- package/dist/content-id-index.js +170 -18
- package/dist/content-id-index.js.map +1 -1
- package/dist/content-listing.d.ts +110 -5
- package/dist/content-listing.d.ts.map +1 -1
- package/dist/content-listing.js +164 -23
- package/dist/content-listing.js.map +1 -1
- package/dist/content-reader.d.ts +41 -4
- package/dist/content-reader.d.ts.map +1 -1
- package/dist/content-reader.js +17 -4
- package/dist/content-reader.js.map +1 -1
- package/dist/content-store.d.ts +91 -8
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +443 -258
- package/dist/content-store.js.map +1 -1
- package/dist/content-tree.d.ts +31 -2
- package/dist/content-tree.d.ts.map +1 -1
- package/dist/content-tree.js +22 -5
- package/dist/content-tree.js.map +1 -1
- package/dist/context.d.ts +30 -10
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +55 -4
- package/dist/context.js.map +1 -1
- package/dist/editor/BranchManager.d.ts.map +1 -1
- package/dist/editor/BranchManager.js +18 -6
- package/dist/editor/BranchManager.js.map +1 -1
- package/dist/editor/CanopyEditor.d.ts.map +1 -1
- package/dist/editor/CanopyEditor.js +2 -2
- package/dist/editor/CanopyEditor.js.map +1 -1
- package/dist/editor/CanopyEditorPage.d.ts +9 -1
- package/dist/editor/CanopyEditorPage.d.ts.map +1 -1
- package/dist/editor/CanopyEditorPage.js +9 -2
- package/dist/editor/CanopyEditorPage.js.map +1 -1
- package/dist/editor/Editor.d.ts +9 -1
- package/dist/editor/Editor.d.ts.map +1 -1
- package/dist/editor/Editor.js +58 -24
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/FormRenderer.d.ts.map +1 -1
- package/dist/editor/FormRenderer.js +12 -0
- package/dist/editor/FormRenderer.js.map +1 -1
- package/dist/editor/admin/SystemHealthPanel.js +6 -2
- package/dist/editor/admin/SystemHealthPanel.js.map +1 -1
- package/dist/editor/components/EntryCreateModal.d.ts +9 -1
- package/dist/editor/components/EntryCreateModal.d.ts.map +1 -1
- package/dist/editor/components/EntryCreateModal.js +4 -1
- package/dist/editor/components/EntryCreateModal.js.map +1 -1
- package/dist/editor/fields/DateTimeField.d.ts +46 -0
- package/dist/editor/fields/DateTimeField.d.ts.map +1 -0
- package/dist/editor/fields/DateTimeField.js +66 -0
- package/dist/editor/fields/DateTimeField.js.map +1 -0
- package/dist/editor/fields/NumberField.d.ts +34 -0
- package/dist/editor/fields/NumberField.d.ts.map +1 -0
- package/dist/editor/fields/NumberField.js +53 -0
- package/dist/editor/fields/NumberField.js.map +1 -0
- package/dist/editor/fields/NumberListField.d.ts +25 -0
- package/dist/editor/fields/NumberListField.d.ts.map +1 -0
- package/dist/editor/fields/NumberListField.js +53 -0
- package/dist/editor/fields/NumberListField.js.map +1 -0
- package/dist/editor/hooks/useBranchManager.d.ts.map +1 -1
- package/dist/editor/hooks/useBranchManager.js +115 -26
- package/dist/editor/hooks/useBranchManager.js.map +1 -1
- package/dist/editor/hooks/useDraftManager.d.ts +8 -0
- package/dist/editor/hooks/useDraftManager.d.ts.map +1 -1
- package/dist/editor/hooks/useDraftManager.js +261 -21
- package/dist/editor/hooks/useDraftManager.js.map +1 -1
- package/dist/editor/hooks/useEntryManager.d.ts +21 -0
- package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
- package/dist/editor/hooks/useEntryManager.js +25 -2
- package/dist/editor/hooks/useEntryManager.js.map +1 -1
- package/dist/editor/theme.d.ts +8 -8
- package/dist/entry-schema.d.ts +228 -8
- package/dist/entry-schema.d.ts.map +1 -1
- package/dist/entry-schema.js +124 -0
- package/dist/entry-schema.js.map +1 -1
- package/dist/git-manager.d.ts +51 -7
- package/dist/git-manager.d.ts.map +1 -1
- package/dist/git-manager.js +105 -14
- package/dist/git-manager.js.map +1 -1
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/handler.js +70 -27
- package/dist/http/handler.js.map +1 -1
- package/dist/http/router.d.ts.map +1 -1
- package/dist/http/router.js +40 -3
- package/dist/http/router.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/operating-mode/deployment-name-fixtures.d.ts +29 -0
- package/dist/operating-mode/deployment-name-fixtures.d.ts.map +1 -0
- package/dist/operating-mode/deployment-name-fixtures.js +55 -0
- package/dist/operating-mode/deployment-name-fixtures.js.map +1 -0
- package/dist/operating-mode/deployment-name.d.ts +9 -0
- package/dist/operating-mode/deployment-name.d.ts.map +1 -1
- package/dist/operating-mode/deployment-name.js +9 -1
- package/dist/operating-mode/deployment-name.js.map +1 -1
- package/dist/operating-mode/index.d.ts +2 -1
- package/dist/operating-mode/index.d.ts.map +1 -1
- package/dist/operating-mode/index.js +4 -1
- package/dist/operating-mode/index.js.map +1 -1
- package/dist/operating-mode/mode-env.d.ts +58 -0
- package/dist/operating-mode/mode-env.d.ts.map +1 -0
- package/dist/operating-mode/mode-env.js +97 -0
- package/dist/operating-mode/mode-env.js.map +1 -0
- package/dist/resolve-canopy-user.d.ts +34 -0
- package/dist/resolve-canopy-user.d.ts.map +1 -0
- package/dist/resolve-canopy-user.js +55 -0
- package/dist/resolve-canopy-user.js.map +1 -0
- package/dist/schema/schema-store.d.ts +53 -2
- package/dist/schema/schema-store.d.ts.map +1 -1
- package/dist/schema/schema-store.js +92 -21
- package/dist/schema/schema-store.js.map +1 -1
- package/dist/server.d.ts +60 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +58 -0
- package/dist/server.js.map +1 -1
- package/dist/services.d.ts +1 -2
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +42 -12
- package/dist/services.js.map +1 -1
- package/dist/settings-workspace.d.ts +40 -0
- package/dist/settings-workspace.d.ts.map +1 -1
- package/dist/settings-workspace.js +139 -151
- package/dist/settings-workspace.js.map +1 -1
- package/dist/static/index.d.ts +65 -5
- package/dist/static/index.d.ts.map +1 -1
- package/dist/static/index.js +65 -12
- package/dist/static/index.js.map +1 -1
- package/dist/static/seo.d.ts +150 -0
- package/dist/static/seo.d.ts.map +1 -0
- package/dist/static/seo.js +189 -0
- package/dist/static/seo.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/content-write-lock.d.ts +127 -0
- package/dist/utils/content-write-lock.d.ts.map +1 -0
- package/dist/utils/content-write-lock.js +170 -0
- package/dist/utils/content-write-lock.js.map +1 -0
- package/dist/utils/error.d.ts +1 -1
- package/dist/utils/error.js +1 -1
- package/dist/utils/git.d.ts +16 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +22 -0
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/sanitize-href.d.ts +74 -3
- package/dist/utils/sanitize-href.d.ts.map +1 -1
- package/dist/utils/sanitize-href.js +125 -6
- package/dist/utils/sanitize-href.js.map +1 -1
- package/dist/validation/entry-link-validator.d.ts +1 -1
- package/dist/validation/entry-link-validator.js +3 -3
- package/dist/validation/entry-link-validator.js.map +1 -1
- package/dist/validation/entry-validator.js +1 -1
- package/dist/validation/entry-validator.js.map +1 -1
- package/dist/worker/cms-worker.d.ts +13 -0
- package/dist/worker/cms-worker.d.ts.map +1 -1
- package/dist/worker/cms-worker.js +326 -264
- package/dist/worker/cms-worker.js.map +1 -1
- package/package.json +2 -2
package/dist/content-listing.js
CHANGED
|
@@ -15,6 +15,7 @@ import { isNotFoundError, getErrorMessage } from './utils/error.js';
|
|
|
15
15
|
import { createDebugLogger } from './utils/debug.js';
|
|
16
16
|
import { isValidId } from './id.js';
|
|
17
17
|
import { ContentStoreError } from './content-store.js';
|
|
18
|
+
import { isBuildMode } from './build-mode.js';
|
|
18
19
|
const log = createDebugLogger({ prefix: 'ContentListing' });
|
|
19
20
|
/**
|
|
20
21
|
* Validate and normalize a path relative to root.
|
|
@@ -58,10 +59,61 @@ export const readEntryData = async (filePath, format, bodyFieldName = 'body') =>
|
|
|
58
59
|
}
|
|
59
60
|
};
|
|
60
61
|
/**
|
|
61
|
-
* Parse a filename
|
|
62
|
-
*
|
|
62
|
+
* Parse a Canopy content filename into its `{type}.{slug}.{id}.{ext}` parts.
|
|
63
|
+
*
|
|
64
|
+
* ## Filename grammar
|
|
65
|
+
*
|
|
66
|
+
* Every entry file on disk is named `{type}.{slug}.{id}.{ext}`:
|
|
67
|
+
* - `type` — the entry type name (a key in the collection's `entries` config).
|
|
68
|
+
* - `slug` — the entry's URL slug. May itself contain dots (e.g. a slug of
|
|
69
|
+
* `getting.started.guide`), so the type and ID anchor the split: the ID is
|
|
70
|
+
* always the second-to-last dot-separated segment, and the slug is
|
|
71
|
+
* everything between the type and the ID. The returned `slug` is
|
|
72
|
+
* lowercased.
|
|
73
|
+
* - `id` — a 12-character Base58 content ID (`generateId()`/`isValidId()`).
|
|
74
|
+
* Base58 excludes the ambiguous characters `0`, `O`, `I`, `l` so IDs are
|
|
75
|
+
* unambiguous when read aloud or hand-transcribed. A filename whose
|
|
76
|
+
* would-be ID segment doesn't pass `isValidId` is rejected — the whole
|
|
77
|
+
* parse returns `null`, even if the rest of the shape looks right.
|
|
78
|
+
* - `ext` — the format extension (`.md`, `.mdx`, `.json`, `.yaml`), stripped
|
|
79
|
+
* before parsing and not part of the returned result.
|
|
80
|
+
*
|
|
81
|
+
* @param filename - The bare filename (no directory component). **This precondition is
|
|
82
|
+
* not enforced.** The parser splits purely on `.`, so a `/` or `\` you pass in is not
|
|
83
|
+
* rejected and is not treated as special — it becomes part of whichever segment it
|
|
84
|
+
* falls in, most often the `type` segment (e.g. `'foo/bar.slug.<validId>.md'` parses
|
|
85
|
+
* to `type: 'foo/bar'`). Strip any directory component yourself (e.g.
|
|
86
|
+
* `path.basename(filePath)`) before calling this — every internal caller already does.
|
|
87
|
+
* @param entryTypes - When provided, the parsed `type` segment must match one
|
|
88
|
+
* of these entry types by name, or the parse is rejected (this is how
|
|
89
|
+
* `listCollectionEntries` filters out files that don't belong to the
|
|
90
|
+
* collection's configured entry types). Omit this argument to parse
|
|
91
|
+
* structurally without validating the type against a known list — useful
|
|
92
|
+
* for adopter code that needs to recover `{type, slug, id}` from a
|
|
93
|
+
* filename without having a schema/entry-types list on hand (e.g. a
|
|
94
|
+
* filesystem walk over content for tooling or diagnostics). Even without
|
|
95
|
+
* `entryTypes`, a leading-dot filename (dotfile, editor swap/backup file)
|
|
96
|
+
* is always rejected — an empty string is never a legal type, matching the
|
|
97
|
+
* `filename.startsWith('.')` guard `extractEntryTypeFromFilename` in
|
|
98
|
+
* `content-id-index.ts` already applies.
|
|
99
|
+
* @returns `{ type, slug, id }`, or `null` if `filename` doesn't match the
|
|
100
|
+
* `{type}.{slug}.{id}.{ext}` shape (too few segments, no extension, a
|
|
101
|
+
* leading dot, an invalid ID, or — when `entryTypes` is given — an
|
|
102
|
+
* unrecognized type). `id` is validated (`isValidId`) and safe to trust. **`slug` is
|
|
103
|
+
* not** — it is the raw dot-joined middle segment(s), lowercased, cast to the branded
|
|
104
|
+
* `Slug` type without running `parseSlug`'s validation. A filename with an
|
|
105
|
+
* unconventional slug segment (e.g. containing a space) still parses and still
|
|
106
|
+
* receives the `Slug` brand. Callers that need a validated slug must run the result
|
|
107
|
+
* through `parseSlug` themselves; this function's contract is "split the filename
|
|
108
|
+
* grammar apart," not "validate every part."
|
|
63
109
|
*/
|
|
64
110
|
export const parseTypedFilename = (filename, entryTypes) => {
|
|
111
|
+
// Reject dotfiles outright (matching extractEntryTypeFromFilename's guard in
|
|
112
|
+
// content-id-index.ts): a leading dot can never be a legal entry type, and this
|
|
113
|
+
// is exactly the shape of the files a structural (no-entryTypes) parse would
|
|
114
|
+
// otherwise misparse -- e.g. '.hidden.file.aB3cD4eF5gH6.md' -> potentialType ''.
|
|
115
|
+
if (filename.startsWith('.'))
|
|
116
|
+
return null;
|
|
65
117
|
// Remove extension
|
|
66
118
|
const lastDot = filename.lastIndexOf('.');
|
|
67
119
|
if (lastDot === -1)
|
|
@@ -69,23 +121,23 @@ export const parseTypedFilename = (filename, entryTypes) => {
|
|
|
69
121
|
const nameWithoutExt = filename.slice(0, lastDot);
|
|
70
122
|
// Parse: {type}.{slug}.{id}
|
|
71
123
|
const parts = nameWithoutExt.split('.');
|
|
72
|
-
if (parts.length
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return null;
|
|
80
|
-
const slug = parts.slice(1, -1).join('.').toLowerCase();
|
|
81
|
-
return {
|
|
82
|
-
type: potentialType,
|
|
83
|
-
slug: slug,
|
|
84
|
-
id: id,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
124
|
+
if (parts.length < 3)
|
|
125
|
+
return null;
|
|
126
|
+
const potentialType = parts[0];
|
|
127
|
+
// When a known-types list is supplied, the first segment must match one of
|
|
128
|
+
// them. Without it, any non-empty first segment is accepted as the type.
|
|
129
|
+
if (entryTypes && !entryTypes.some((e) => e.name === potentialType)) {
|
|
130
|
+
return null;
|
|
87
131
|
}
|
|
88
|
-
|
|
132
|
+
const id = parts[parts.length - 1];
|
|
133
|
+
if (!isValidId(id))
|
|
134
|
+
return null;
|
|
135
|
+
const slug = parts.slice(1, -1).join('.').toLowerCase();
|
|
136
|
+
return {
|
|
137
|
+
type: potentialType,
|
|
138
|
+
slug: slug,
|
|
139
|
+
id: id,
|
|
140
|
+
};
|
|
89
141
|
};
|
|
90
142
|
/**
|
|
91
143
|
* List all content entries as a flat array.
|
|
@@ -93,12 +145,30 @@ export const parseTypedFilename = (filename, entryTypes) => {
|
|
|
93
145
|
* Walks the schema to discover collections, reads entries from each,
|
|
94
146
|
* and returns a flat list suitable for generateStaticParams, search indexing, sitemaps, etc.
|
|
95
147
|
*
|
|
148
|
+
* Build-time-only failure: a file with a recognized content extension (`.md`/`.mdx`/`.json`/
|
|
149
|
+
* `.yaml`) sitting in a collection directory that *looks like an attempted entry* (see
|
|
150
|
+
* `looksLikeMalformedEntry` below) but doesn't match `{type}.{slug}.{id}.{ext}` is, by default,
|
|
151
|
+
* silently dropped (see `listCollectionEntries`'s debug-gated warning). That is exactly the
|
|
152
|
+
* silent-page-loss failure mode static generation must not have — a schema rename without a
|
|
153
|
+
* matching file rename, or an entry type declared in one collection but not another, would
|
|
154
|
+
* otherwise vanish a page with zero build output. So when `isBuildMode()` is true, any such file
|
|
155
|
+
* turns the listing into a thrown error instead (see `findInvalidEntries`/`assertBuildEntriesValid`
|
|
156
|
+
* in `static/index.ts` for the sibling schema-validity guard this mirrors). Outside build mode
|
|
157
|
+
* (admin UI, content tree, `next dev`) the file is still just skipped, since a fresh scaffold or
|
|
158
|
+
* mid-rename file legitimately exists there.
|
|
159
|
+
*
|
|
160
|
+
* A file that was never entry-shaped to begin with — a `README.md`, or a colocated sibling
|
|
161
|
+
* artifact named `{contentId}.suffix.ext` per the `entryTransforms`/`readSibling` convention
|
|
162
|
+
* documented in the README — is not this guard's failure mode and never throws, in or out of
|
|
163
|
+
* build mode. See `looksLikeMalformedEntry` for the exact shape test.
|
|
164
|
+
*
|
|
96
165
|
* @param branchRoot - Absolute path to the branch workspace root
|
|
97
166
|
* @param flatSchema - Flattened schema items (from flattenSchema)
|
|
98
167
|
* @param contentRootName - The content root name (e.g. "content")
|
|
99
168
|
* @param options - Listing options (extract, filter, rootPath, sort)
|
|
169
|
+
* @param visibility - Internal path-ACL predicate; see `ContentVisibilityOptions`
|
|
100
170
|
*/
|
|
101
|
-
export async function listEntries(branchRoot, flatSchema, contentRootName, options) {
|
|
171
|
+
export async function listEntries(branchRoot, flatSchema, contentRootName, options, visibility) {
|
|
102
172
|
const rootPath = options?.rootPath ?? contentRootName;
|
|
103
173
|
const extract = options?.extract;
|
|
104
174
|
const filter = options?.filter;
|
|
@@ -107,11 +177,33 @@ export async function listEntries(branchRoot, flatSchema, contentRootName, optio
|
|
|
107
177
|
const collections = flatSchema.filter((item) => item.type === 'collection' &&
|
|
108
178
|
item.entries !== undefined &&
|
|
109
179
|
(item.logicalPath === rootPath || item.logicalPath.startsWith(`${rootPath}/`)));
|
|
110
|
-
// List entries from all collections in parallel
|
|
180
|
+
// List entries from all collections in parallel.
|
|
181
|
+
// The visibility predicate is applied here, before the map below, so a denied entry's
|
|
182
|
+
// data never reaches `extract` (let alone the returned items).
|
|
183
|
+
const shouldInclude = visibility?.shouldInclude;
|
|
184
|
+
const skippedFiles = [];
|
|
111
185
|
const collectionResults = await Promise.all(collections.map(async (collection) => {
|
|
112
|
-
const entries = await listCollectionEntries(branchRoot, collection);
|
|
113
|
-
|
|
186
|
+
const entries = await listCollectionEntries(branchRoot, collection, (file) => skippedFiles.push(file));
|
|
187
|
+
const visible = shouldInclude ? entries.filter((e) => shouldInclude(e.physicalPath)) : entries;
|
|
188
|
+
return visible.map((entry) => ({ entry, collection }));
|
|
114
189
|
}));
|
|
190
|
+
// Build-time only: fail loudly rather than silently shipping a build with a page missing. See
|
|
191
|
+
// the build-time-only-failure note in this function's own doc comment above. Only files that
|
|
192
|
+
// structurally look like a malformed entry reach `skippedFiles` at all -- see
|
|
193
|
+
// `looksLikeMalformedEntry` and `listCollectionEntries`.
|
|
194
|
+
if (isBuildMode() && skippedFiles.length > 0) {
|
|
195
|
+
const lines = skippedFiles.map(({ filename, collectionPath }) => ` - ${collectionPath}/${filename}`);
|
|
196
|
+
throw new Error(`CanopyCMS static build: found ${skippedFiles.length} file(s) that look like malformed ` +
|
|
197
|
+
`content entries inside a content collection:\n${lines.join('\n')}\n` +
|
|
198
|
+
'Expected {type}.{slug}.{id}.{ext} with a known entry type (a name declared in that ' +
|
|
199
|
+
"collection's entries config) and a valid 12-char Base58 ID. This usually means a schema " +
|
|
200
|
+
'rename without a matching file rename, an entry type declared in one collection but not ' +
|
|
201
|
+
'another, or a stray file placed directly in a collection directory. If this is meant to ' +
|
|
202
|
+
"be a colocated sibling artifact (e.g. an entry's contentId-prefixed data file read via " +
|
|
203
|
+
'an entryTransforms readSibling call), keep its name to three or fewer dot-separated ' +
|
|
204
|
+
'segments (id.suffix.ext) so it is never mistaken for an entry attempt. Otherwise rename ' +
|
|
205
|
+
'or move the file, or fix the schema, then rebuild.');
|
|
206
|
+
}
|
|
115
207
|
// Flatten and map to ListEntriesItem
|
|
116
208
|
const contentPrefix = contentRootName ? `${contentRootName}/` : '';
|
|
117
209
|
const items = [];
|
|
@@ -144,6 +236,7 @@ export async function listEntries(branchRoot, flatSchema, contentRootName, optio
|
|
|
144
236
|
format: entry.format,
|
|
145
237
|
data,
|
|
146
238
|
schema: collection.entries?.find((e) => e.name === entry.entryType)?.schema,
|
|
239
|
+
updatedAt: entry.updatedAt,
|
|
147
240
|
};
|
|
148
241
|
if (filter && !filter(item))
|
|
149
242
|
continue;
|
|
@@ -187,11 +280,56 @@ export const sortByOrder = (items, order, fallbackKey) => {
|
|
|
187
280
|
return fallbackKey(a).localeCompare(fallbackKey(b));
|
|
188
281
|
});
|
|
189
282
|
};
|
|
283
|
+
/**
|
|
284
|
+
* True when a content-extension filename structurally resembles an attempted entry — as opposed
|
|
285
|
+
* to a file that was never entry-shaped to begin with.
|
|
286
|
+
*
|
|
287
|
+
* A successfully-parsed entry always has at least 4 dot-separated segments: `type` (1+),
|
|
288
|
+
* `slug` (1+, since `parseTypedFilename` always takes at least the one segment between type and
|
|
289
|
+
* id), `id` (1), `ext` (1). So a file with 4+ segments that still failed to parse is malformed
|
|
290
|
+
* on its face — a wrong-length or invalid-Base58 ID, most often (`post.hello-world.BADID.md`).
|
|
291
|
+
*
|
|
292
|
+
* That segment-count test alone missed the MORE common accident: losing the ID segment
|
|
293
|
+
* entirely. `post.hello-world.md` (3 segments) fails `parseTypedFilename` exactly like the
|
|
294
|
+
* 4-segment case does, but a bare 3-or-fewer-segment cutoff would treat it as never having been
|
|
295
|
+
* entry-shaped and drop it silently — the page just vanishes with a green build. So a 3-segment
|
|
296
|
+
* file whose FIRST segment matches a real entry type name in this collection is ALSO treated as
|
|
297
|
+
* malformed: `parseTypedFilename` requires type+slug+id (3 segments) after stripping the
|
|
298
|
+
* extension, so a 3-total-segment filename already has only 2 left over — it could only have
|
|
299
|
+
* been attempting `type.slug` with no id, or `type.id` with no slug, either way a lost segment,
|
|
300
|
+
* not a coincidence. This still leaves the two motivating "was never an entry" cases alone: a
|
|
301
|
+
* bare `README.md` (2 segments, and "README" is essentially never a configured entry type name)
|
|
302
|
+
* and an entry's colocated sibling artifact named `{contentId}.suffix.ext` per the
|
|
303
|
+
* `entryTransforms`/`readSibling` convention documented in the README (3 segments, e.g.
|
|
304
|
+
* `5NVkkrB1MJUv.profile.json` — a content ID is never itself an entry type name, so the same
|
|
305
|
+
* "first segment matches a known type" test correctly leaves it unflagged).
|
|
306
|
+
*
|
|
307
|
+
* Dot-prefixed (hidden files, editor swap/backup files) and underscore-prefixed (a common
|
|
308
|
+
* adopter convention for "not an entry") names are excluded outright regardless of segment
|
|
309
|
+
* count, matching `parseTypedFilename`'s own dotfile rejection.
|
|
310
|
+
*/
|
|
311
|
+
const looksLikeMalformedEntry = (filename, entryTypes) => {
|
|
312
|
+
if (filename.startsWith('.') || filename.startsWith('_'))
|
|
313
|
+
return false;
|
|
314
|
+
const segments = filename.split('.');
|
|
315
|
+
if (segments.length >= 4)
|
|
316
|
+
return true;
|
|
317
|
+
return segments.length === 3 && entryTypes.some((e) => e.name === segments[0]);
|
|
318
|
+
};
|
|
190
319
|
/**
|
|
191
320
|
* List all entries in a collection directory.
|
|
192
321
|
* Reads each entry's data (frontmatter or JSON).
|
|
322
|
+
*
|
|
323
|
+
* @param onSkip - Called for every file that has a recognized content extension, doesn't match
|
|
324
|
+
* the `{type}.{slug}.{id}.{ext}` grammar (see `parseTypedFilename`), AND structurally looks
|
|
325
|
+
* like an attempted entry (see `looksLikeMalformedEntry`). A file that was never entry-shaped
|
|
326
|
+
* (too few dot-separated segments to ever be a valid entry — a `README.md`, a colocated
|
|
327
|
+
* sibling artifact) is always silently dropped with a debug-gated `log.warn`, never passed to
|
|
328
|
+
* `onSkip`. Optional and purely a diagnostic hook — existing callers that omit it keep the
|
|
329
|
+
* exact prior behavior. `listEntries` below uses this to turn the skip into a hard build-time
|
|
330
|
+
* failure instead of a silent one.
|
|
193
331
|
*/
|
|
194
|
-
export const listCollectionEntries = async (root, collection) => {
|
|
332
|
+
export const listCollectionEntries = async (root, collection, onSkip) => {
|
|
195
333
|
if (collection.type !== 'collection' || !collection.entries) {
|
|
196
334
|
return [];
|
|
197
335
|
}
|
|
@@ -231,6 +369,9 @@ export const listCollectionEntries = async (root, collection) => {
|
|
|
231
369
|
const parsed = parseTypedFilename(file.name, entryTypes);
|
|
232
370
|
if (!parsed) {
|
|
233
371
|
log.warn('listCollectionEntries', `Skipping file with unrecognized filename format: ${file.name} (expected {type}.{slug}.{id}.{ext} with a known entry type and valid 12-char Base58 ID)`);
|
|
372
|
+
if (looksLikeMalformedEntry(file.name, entryTypes)) {
|
|
373
|
+
onSkip?.({ filename: file.name, collectionPath: collection.logicalPath });
|
|
374
|
+
}
|
|
234
375
|
return null;
|
|
235
376
|
}
|
|
236
377
|
const { type: entryTypeName, slug, id: contentId } = parsed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-listing.js","sourceRoot":"","sources":["../src/content-listing.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"content-listing.js","sourceRoot":"","sources":["../src/content-listing.ts"],"names":[],"mappings":"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"}
|
package/dist/content-reader.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type LogicalPath, type PhysicalPath, type Slug } from './paths';
|
|
1
|
+
import { type ContentId, type LogicalPath, type PhysicalPath, type Slug } from './paths';
|
|
2
2
|
import type { CanopyServices } from './services';
|
|
3
3
|
import type { BranchContext } from './types';
|
|
4
4
|
import type { CanopyUser } from './user';
|
|
@@ -22,13 +22,50 @@ export interface ReadContentInput {
|
|
|
22
22
|
/** Whether to resolve entry:ID links in body/markdown fields. Defaults to true. */
|
|
23
23
|
resolveEntryLinks?: boolean;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Structural metadata surfaced alongside a resolved content read. Shared by
|
|
27
|
+
* `ContentReader['read']` here and by `CanopyBuildContext`'s `read`/`readByUrlPath`
|
|
28
|
+
* (context.ts), which both wrap this same reader.
|
|
29
|
+
*/
|
|
30
|
+
export interface ContentReadMeta {
|
|
31
|
+
/**
|
|
32
|
+
* Absolute filesystem path to the resolved entry file. It is **server-only**
|
|
33
|
+
* -- do not serialize it to the client or embed it in public output, as it
|
|
34
|
+
* reveals the deployment's filesystem layout (home dir / EFS mount / branch
|
|
35
|
+
* name).
|
|
36
|
+
*/
|
|
37
|
+
physicalPath: PhysicalPath;
|
|
38
|
+
/**
|
|
39
|
+
* The resolved entry type name, read from the entry's own filename
|
|
40
|
+
* (`{type}.{slug}.{id}.{ext}`) -- immutable once the file is created, and
|
|
41
|
+
* NOT re-validated against the collection's current `entries` config on
|
|
42
|
+
* every read. It is therefore usually, but not guaranteed to be, a key in
|
|
43
|
+
* the collection's `entries` config: it can diverge if an entry type was
|
|
44
|
+
* renamed or removed from the schema after files using the old name were
|
|
45
|
+
* created, or if the file was hand-authored with an unrecognized type
|
|
46
|
+
* token.
|
|
47
|
+
*
|
|
48
|
+
* For a legacy entry file predating embedded-type filenames (`{slug}.{ext}`),
|
|
49
|
+
* there is no type recorded on disk at all -- `entryType` silently falls
|
|
50
|
+
* back to the collection's DEFAULT entry type, which may or may not be what
|
|
51
|
+
* the file actually is. `entryId` being `undefined` (below) is the signal
|
|
52
|
+
* that this happened: when `entryId` is `undefined`, `entryType` is
|
|
53
|
+
* inferred rather than read.
|
|
54
|
+
*/
|
|
55
|
+
entryType: string;
|
|
56
|
+
/**
|
|
57
|
+
* The entry's 12-char Base58 content ID, when the resolved file carries one.
|
|
58
|
+
* Undefined only for legacy entry files predating embedded-ID filenames
|
|
59
|
+
* (`{slug}.{ext}` rather than `{type}.{slug}.{id}.{ext}`) -- see the
|
|
60
|
+
* `entryType` caveat above for what that implies about it.
|
|
61
|
+
*/
|
|
62
|
+
entryId?: ContentId;
|
|
63
|
+
}
|
|
25
64
|
export interface ContentReader {
|
|
26
65
|
read: <T = unknown>(input: ReadContentInput, message?: string) => Promise<{
|
|
27
66
|
data: T;
|
|
28
67
|
path: string;
|
|
29
|
-
meta:
|
|
30
|
-
physicalPath: PhysicalPath;
|
|
31
|
-
};
|
|
68
|
+
meta: ContentReadMeta;
|
|
32
69
|
}>;
|
|
33
70
|
}
|
|
34
71
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-reader.d.ts","sourceRoot":"","sources":["../src/content-reader.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"content-reader.d.ts","sourceRoot":"","sources":["../src/content-reader.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,IAAI,EACV,MAAM,SAAS,CAAA;AAGhB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAKxC,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,cAAc,CAAA;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;CACrE;AAED,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,SAAS,EAAE,WAAW,CAAA;IACtB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,IAAI,EAAE,UAAU,CAAA;IAChB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,YAAY,EAAE,YAAY,CAAA;IAC1B;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,CAAC,CAAC,GAAG,OAAO,EAChB,KAAK,EAAE,gBAAgB,EACvB,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC;QACX,IAAI,EAAE,CAAC,CAAA;QACP,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,eAAe,CAAA;KACtB,CAAC,CAAA;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,oBAAoB,KAAG,aAgOnE,CAAA"}
|
package/dist/content-reader.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadBranchContext, loadOrCreateBranchContext } from './branch-workspace.js';
|
|
2
2
|
import { ContentStore, ContentStoreError } from './content-store.js';
|
|
3
|
-
import { resolveBranchPaths } from './paths/index.js';
|
|
3
|
+
import { resolveBranchPaths, } from './paths/index.js';
|
|
4
4
|
import { trimSlashes } from './paths/normalize.js';
|
|
5
5
|
import { isDeployedStatic, isBuildMode } from './build-mode.js';
|
|
6
6
|
import { isNotFoundError } from './utils/error.js';
|
|
@@ -108,10 +108,23 @@ export const createContentReader = (options) => {
|
|
|
108
108
|
// for server-side colocated-artifact reads (e.g. a sibling profile.json). Already
|
|
109
109
|
// computed here for permission checks; just carried through.
|
|
110
110
|
let physicalPath;
|
|
111
|
+
// Entry type + content ID are already resolved as part of path resolution
|
|
112
|
+
// (buildPaths() derives both from the schema item / filename) — surfaced on
|
|
113
|
+
// read() / readByUrlPath() so callers can route or key by them without a
|
|
114
|
+
// separate listEntries lookup or filename parse.
|
|
115
|
+
let entryType;
|
|
116
|
+
let entryId;
|
|
111
117
|
try {
|
|
112
118
|
const resolved = await store.resolveDocumentPath(entryPath, slug ?? '');
|
|
113
119
|
relativePath = resolved.relativePath;
|
|
114
120
|
physicalPath = resolved.absolutePath;
|
|
121
|
+
// resolveDocumentPath() always sets entryTypeName for a valid schema item
|
|
122
|
+
// (collection entries fall back to 'entry'; entry-type items delegate to
|
|
123
|
+
// their parent collection with their own name), so no further fallback
|
|
124
|
+
// is needed here — id is the one field that can be legitimately absent,
|
|
125
|
+
// for legacy entry files without an embedded ID (see ContentReadMeta).
|
|
126
|
+
entryType = resolved.entryTypeName;
|
|
127
|
+
entryId = resolved.id;
|
|
115
128
|
}
|
|
116
129
|
catch (err) {
|
|
117
130
|
const message = err instanceof ContentStoreError ? err.message : 'Invalid content request';
|
|
@@ -145,7 +158,7 @@ export const createContentReader = (options) => {
|
|
|
145
158
|
const doc = await store.read(entryPath, slug ?? '', {
|
|
146
159
|
resolveReferences: input.resolveReferences ?? true,
|
|
147
160
|
});
|
|
148
|
-
return { doc, store, physicalPath };
|
|
161
|
+
return { doc, store, physicalPath, entryType, entryId };
|
|
149
162
|
}
|
|
150
163
|
catch (err) {
|
|
151
164
|
if (isNotFoundError(err))
|
|
@@ -160,7 +173,7 @@ export const createContentReader = (options) => {
|
|
|
160
173
|
const defaultMessage = `Content not found for ${entryPath}${slug ? `/${slug}` : ''} on branch ${branchName}`;
|
|
161
174
|
throw new ContentStoreError(message ?? defaultMessage, 'NOT_FOUND');
|
|
162
175
|
}
|
|
163
|
-
const { doc, store, physicalPath } = result;
|
|
176
|
+
const { doc, store, physicalPath, entryType, entryId } = result;
|
|
164
177
|
// For md/mdx format, merge the body into the data so callers get a complete object.
|
|
165
178
|
// The field name comes from the schema's isBody flag (defaults to 'body').
|
|
166
179
|
const docRecord = doc;
|
|
@@ -179,7 +192,7 @@ export const createContentReader = (options) => {
|
|
|
179
192
|
slug,
|
|
180
193
|
branch: branchName,
|
|
181
194
|
});
|
|
182
|
-
return { data, path, meta: { physicalPath } };
|
|
195
|
+
return { data, path, meta: { physicalPath, entryType, entryId } };
|
|
183
196
|
};
|
|
184
197
|
return { read };
|
|
185
198
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-reader.js","sourceRoot":"","sources":["../src/content-reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAA;AACjF,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,
|
|
1
|
+
{"version":3,"file":"content-reader.js","sourceRoot":"","sources":["../src/content-reader.ts"],"names":[],"mappings":"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"}
|
package/dist/content-store.d.ts
CHANGED
|
@@ -28,15 +28,15 @@ export type WriteInput = {
|
|
|
28
28
|
format: 'md' | 'mdx';
|
|
29
29
|
data?: Record<string, unknown>;
|
|
30
30
|
body: string;
|
|
31
|
-
expectedVersion?: number;
|
|
31
|
+
expectedVersion?: number | null;
|
|
32
32
|
} | {
|
|
33
33
|
format: 'json';
|
|
34
34
|
data: Record<string, unknown>;
|
|
35
|
-
expectedVersion?: number;
|
|
35
|
+
expectedVersion?: number | null;
|
|
36
36
|
} | {
|
|
37
37
|
format: 'yaml';
|
|
38
38
|
data: Record<string, unknown>;
|
|
39
|
-
expectedVersion?: number;
|
|
39
|
+
expectedVersion?: number | null;
|
|
40
40
|
};
|
|
41
41
|
export type ContentStoreErrorCode = 'NOT_FOUND' | 'NO_SCHEMA_ITEM' | 'FORBIDDEN' | 'VALIDATION';
|
|
42
42
|
export declare class ContentStoreError extends Error {
|
|
@@ -48,7 +48,49 @@ export declare class ContentStoreError extends Error {
|
|
|
48
48
|
* Indicates a cross-process concurrent write — the caller should reload and retry.
|
|
49
49
|
*/
|
|
50
50
|
export declare class ContentConflictError extends Error {
|
|
51
|
-
constructor();
|
|
51
|
+
constructor(message?: string);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* [SYNC-C1] Thrown when a mutation could not take the branch's cross-host
|
|
55
|
+
* content-write lock within its bounded wait -- in practice, the worker is
|
|
56
|
+
* mid-rebase on this branch's working tree (utils/content-write-lock.ts).
|
|
57
|
+
*
|
|
58
|
+
* A `ContentConflictError` subclass so every existing 409 mapping keeps
|
|
59
|
+
* working unchanged; the distinct type exists so the API can surface THIS
|
|
60
|
+
* message ("the branch is busy, retry") instead of the generic "modified by
|
|
61
|
+
* another editor", which would be actively misleading. The default wording
|
|
62
|
+
* covers writer-vs-writer contention too, which this lock also produces --
|
|
63
|
+
* see ContentWriteLockBusyError.
|
|
64
|
+
*/
|
|
65
|
+
export declare class BranchSyncingError extends ContentConflictError {
|
|
66
|
+
constructor(message: string);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* [F1] Thrown when a save's content ID is carried by MORE THAN ONE file in
|
|
70
|
+
* the branch's content tree -- the duplicate-ID state `ContentIdIndex`
|
|
71
|
+
* quarantines (see its "Duplicate-ID quarantine" section).
|
|
72
|
+
*
|
|
73
|
+
* Why refuse rather than write: with two files sharing one ID, "this entry"
|
|
74
|
+
* is ambiguous, and every way of proceeding is worse than stopping.
|
|
75
|
+
* Following the index would mutate (and, via the slug-change cleanup, DELETE)
|
|
76
|
+
* a file the caller never addressed -- the data-loss bug this class exists to
|
|
77
|
+
* prevent. Writing only the addressed file would succeed silently into a file
|
|
78
|
+
* that is invisible to every ID-based lookup (reads-by-id, references,
|
|
79
|
+
* listings all resolve to the OTHER copy) and that the repair action later
|
|
80
|
+
* archives away, so the editor's work would appear to evaporate with no error
|
|
81
|
+
* anywhere. Refusing mutates nothing under any interleaving, and says what is
|
|
82
|
+
* wrong and who can fix it.
|
|
83
|
+
*
|
|
84
|
+
* A `ContentConflictError` subclass so every existing 409 mapping keeps
|
|
85
|
+
* working; the distinct type exists so the API can surface THIS message
|
|
86
|
+
* rather than the generic "modified by another editor", which would send the
|
|
87
|
+
* editor into a reload-and-retry loop that cannot succeed.
|
|
88
|
+
*/
|
|
89
|
+
export declare class DuplicateContentIdError extends ContentConflictError {
|
|
90
|
+
readonly contentId: string;
|
|
91
|
+
/** Every path known to carry `contentId`, repo-relative, sorted. */
|
|
92
|
+
readonly paths: readonly string[];
|
|
93
|
+
constructor(contentId: string, paths: readonly string[]);
|
|
52
94
|
}
|
|
53
95
|
/**
|
|
54
96
|
* Get the default entry type from a collection's entries array.
|
|
@@ -72,6 +114,13 @@ export interface ContentStoreOptions {
|
|
|
72
114
|
* path-based reads keep working. Defaults to 'content'.
|
|
73
115
|
*/
|
|
74
116
|
contentRootName?: string;
|
|
117
|
+
/**
|
|
118
|
+
* [SYNC-C1] Bounded wait (ms) for the branch's cross-host content-write lock
|
|
119
|
+
* before a mutation gives up with {@link BranchSyncingError}. See
|
|
120
|
+
* `utils/content-write-lock.ts` for why the default is short. Tests pass a
|
|
121
|
+
* small value to keep contention cases fast.
|
|
122
|
+
*/
|
|
123
|
+
contentWriteLockWaitMs?: number;
|
|
75
124
|
}
|
|
76
125
|
export declare class ContentStore {
|
|
77
126
|
private readonly root;
|
|
@@ -93,9 +142,29 @@ export declare class ContentStore {
|
|
|
93
142
|
private lastDiskProbeMs;
|
|
94
143
|
private lastForcedRefreshMs;
|
|
95
144
|
private readonly indexFreshnessIntervalMs;
|
|
145
|
+
/** See ContentStoreOptions.contentWriteLockWaitMs. */
|
|
146
|
+
private readonly contentWriteLockWaitMs;
|
|
96
147
|
/** In-flight index build, shared by concurrent idIndex() callers so scans never interleave. */
|
|
97
148
|
private indexBuild;
|
|
98
149
|
constructor(root: string, flatSchema: FlatSchemaItem[], options?: ContentStoreOptions);
|
|
150
|
+
/**
|
|
151
|
+
* [SYNC-C1] Run a working-tree mutation under the branch's cross-host
|
|
152
|
+
* content-write lock (utils/content-write-lock.ts), on top of the
|
|
153
|
+
* in-process locks the callee takes for itself.
|
|
154
|
+
*
|
|
155
|
+
* The in-process mutex serializes writers inside ONE process; it says
|
|
156
|
+
* nothing about the EC2 worker rebasing this same tree on shared EFS, which
|
|
157
|
+
* destroys an in-flight save (`checkout --theirs` overwrites it and the
|
|
158
|
+
* rebase then reports success; `rebase --abort` hard-resets it). This is the
|
|
159
|
+
* layer that actually excludes the two.
|
|
160
|
+
*
|
|
161
|
+
* Reads deliberately do NOT take it -- an extra EFS round-trip per read is
|
|
162
|
+
* not an acceptable cost, and reads cannot be destroyed by a rebase.
|
|
163
|
+
*
|
|
164
|
+
* Acquisition order is always content lock -> `withLock`, never the reverse,
|
|
165
|
+
* so the two cannot deadlock.
|
|
166
|
+
*/
|
|
167
|
+
private withContentWriteExclusion;
|
|
99
168
|
/**
|
|
100
169
|
* Mark the ID index stale so the next idIndex() access rebuilds it from disk.
|
|
101
170
|
*
|
|
@@ -146,10 +215,15 @@ export declare class ContentStore {
|
|
|
146
215
|
*/
|
|
147
216
|
private refreshIndexForSuspiciousLookup;
|
|
148
217
|
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
218
|
+
* Every file in `dir` whose filename embeds `id`, as root-relative paths
|
|
219
|
+
* (empty when there is no such file, or no such dir).
|
|
220
|
+
*
|
|
221
|
+
* [F1] Returns ALL matches, not the first: more than one match is a
|
|
222
|
+
* duplicate-ID pair, and callers must be able to tell that apart from a
|
|
223
|
+
* clean single hit rather than silently picking whichever one `readdir()`
|
|
224
|
+
* happened to yield first.
|
|
151
225
|
*/
|
|
152
|
-
private
|
|
226
|
+
private findEntryPathsById;
|
|
153
227
|
/**
|
|
154
228
|
* Get all schema items for iteration.
|
|
155
229
|
* Used internally by ReferenceResolver for path matching.
|
|
@@ -228,7 +302,16 @@ export declare class ContentStore {
|
|
|
228
302
|
absolutePath: string;
|
|
229
303
|
relativePath: PhysicalPath;
|
|
230
304
|
id?: string;
|
|
231
|
-
|
|
305
|
+
/**
|
|
306
|
+
* Always populated for a valid schema item: the collection branch below
|
|
307
|
+
* always resolves a name (falling back to `'entry'` when the collection
|
|
308
|
+
* has no matching/default entry type config), and the entry-type branch
|
|
309
|
+
* delegates to it with its own name set explicitly. Only non-collection,
|
|
310
|
+
* non-entry-type schema items (impossible via the public API, which only
|
|
311
|
+
* ever resolves to one of those two) skip both branches, hitting the
|
|
312
|
+
* throw below instead of returning at all.
|
|
313
|
+
*/
|
|
314
|
+
entryTypeName: string;
|
|
232
315
|
/**
|
|
233
316
|
* True if this slug already had a file on disk (a directory-scan finding,
|
|
234
317
|
* or `options.existingId` asserting one) -- i.e. this resolution is an
|