@caretcms/core 0.2.0 → 0.4.0
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 +195 -12
- package/dist/index.d.ts +26 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +113 -12
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +35 -3
- package/dist/loader.js.map +1 -1
- package/dist/markdown/paragraphs.d.ts +14 -0
- package/dist/markdown/paragraphs.d.ts.map +1 -0
- package/dist/markdown/paragraphs.js +61 -0
- package/dist/markdown/paragraphs.js.map +1 -0
- package/dist/markdown/remark.d.ts.map +1 -1
- package/dist/markdown/remark.js +1 -0
- package/dist/markdown/remark.js.map +1 -1
- package/dist/markdown/satteri.d.ts.map +1 -1
- package/dist/markdown/satteri.js +35 -9
- package/dist/markdown/satteri.js.map +1 -1
- package/dist/markdown/stamp.d.ts +0 -9
- package/dist/markdown/stamp.d.ts.map +1 -1
- package/dist/markdown/stamp.js +6 -0
- package/dist/markdown/stamp.js.map +1 -1
- package/dist/providers/deployment/github.d.ts +27 -0
- package/dist/providers/deployment/github.d.ts.map +1 -0
- package/dist/providers/deployment/github.js +180 -0
- package/dist/providers/deployment/github.js.map +1 -0
- package/dist/providers/deployment/simulated.d.ts +10 -0
- package/dist/providers/deployment/simulated.d.ts.map +1 -0
- package/dist/providers/deployment/simulated.js +29 -0
- package/dist/providers/deployment/simulated.js.map +1 -0
- package/dist/runtime/auth/session.d.ts +1 -0
- package/dist/runtime/auth/session.d.ts.map +1 -1
- package/dist/runtime/auth/session.js +16 -0
- package/dist/runtime/auth/session.js.map +1 -1
- package/dist/runtime/authorization.d.ts +11 -0
- package/dist/runtime/authorization.d.ts.map +1 -0
- package/dist/runtime/authorization.js +29 -0
- package/dist/runtime/authorization.js.map +1 -0
- package/dist/runtime/collection-policy.d.ts +11 -0
- package/dist/runtime/collection-policy.d.ts.map +1 -0
- package/dist/runtime/collection-policy.js +44 -0
- package/dist/runtime/collection-policy.js.map +1 -0
- package/dist/runtime/config.d.ts +3 -0
- package/dist/runtime/config.d.ts.map +1 -1
- package/dist/runtime/config.js +4 -1
- package/dist/runtime/config.js.map +1 -1
- package/dist/runtime/content-errors.d.ts +9 -0
- package/dist/runtime/content-errors.d.ts.map +1 -0
- package/dist/runtime/content-errors.js +17 -0
- package/dist/runtime/content-errors.js.map +1 -0
- package/dist/runtime/content.d.ts.map +1 -1
- package/dist/runtime/content.js +13 -4
- package/dist/runtime/content.js.map +1 -1
- package/dist/runtime/deployment-status.d.ts +14 -0
- package/dist/runtime/deployment-status.d.ts.map +1 -0
- package/dist/runtime/deployment-status.js +57 -0
- package/dist/runtime/deployment-status.js.map +1 -0
- package/dist/runtime/draft-state.d.ts +16 -0
- package/dist/runtime/draft-state.d.ts.map +1 -0
- package/dist/runtime/draft-state.js +29 -0
- package/dist/runtime/draft-state.js.map +1 -0
- package/dist/runtime/i18n.d.ts +97 -0
- package/dist/runtime/i18n.d.ts.map +1 -0
- package/dist/runtime/i18n.js +190 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/middleware.d.ts.map +1 -1
- package/dist/runtime/middleware.js +61 -4
- package/dist/runtime/middleware.js.map +1 -1
- package/dist/runtime/mutations/contracts.d.ts +12 -0
- package/dist/runtime/mutations/contracts.d.ts.map +1 -1
- package/dist/runtime/mutations/contracts.js +54 -4
- package/dist/runtime/mutations/contracts.js.map +1 -1
- package/dist/runtime/mutations/engine.d.ts +2 -0
- package/dist/runtime/mutations/engine.d.ts.map +1 -1
- package/dist/runtime/mutations/engine.js +220 -57
- package/dist/runtime/mutations/engine.js.map +1 -1
- package/dist/runtime/providers.d.ts +4 -1
- package/dist/runtime/providers.d.ts.map +1 -1
- package/dist/runtime/providers.js +18 -1
- package/dist/runtime/providers.js.map +1 -1
- package/dist/runtime/publish-recovery.d.ts +32 -0
- package/dist/runtime/publish-recovery.d.ts.map +1 -0
- package/dist/runtime/publish-recovery.js +98 -0
- package/dist/runtime/publish-recovery.js.map +1 -0
- package/dist/runtime/publish.d.ts +10 -4
- package/dist/runtime/publish.d.ts.map +1 -1
- package/dist/runtime/publish.js +105 -63
- package/dist/runtime/publish.js.map +1 -1
- package/dist/runtime/rebuild-webhook.d.ts +4 -0
- package/dist/runtime/rebuild-webhook.d.ts.map +1 -1
- package/dist/runtime/rebuild-webhook.js +12 -2
- package/dist/runtime/rebuild-webhook.js.map +1 -1
- package/dist/runtime/request-context.d.ts +7 -1
- package/dist/runtime/request-context.d.ts.map +1 -1
- package/dist/runtime/request-context.js +7 -1
- package/dist/runtime/request-context.js.map +1 -1
- package/dist/runtime/rewrite.d.ts.map +1 -1
- package/dist/runtime/rewrite.js +28 -2
- package/dist/runtime/rewrite.js.map +1 -1
- package/dist/runtime/rich-allowlist.js +1 -1
- package/dist/runtime/rich-allowlist.js.map +1 -1
- package/dist/runtime/routes/admin-entry.d.ts.map +1 -1
- package/dist/runtime/routes/admin-entry.js +129 -21
- package/dist/runtime/routes/admin-entry.js.map +1 -1
- package/dist/runtime/routes/admin.d.ts.map +1 -1
- package/dist/runtime/routes/admin.js +28 -14
- package/dist/runtime/routes/admin.js.map +1 -1
- package/dist/runtime/routes/auth-login.d.ts.map +1 -1
- package/dist/runtime/routes/auth-login.js +4 -0
- package/dist/runtime/routes/auth-login.js.map +1 -1
- package/dist/runtime/routes/auth-logout.d.ts.map +1 -1
- package/dist/runtime/routes/auth-logout.js +7 -2
- package/dist/runtime/routes/auth-logout.js.map +1 -1
- package/dist/runtime/routes/auth-session.d.ts.map +1 -1
- package/dist/runtime/routes/auth-session.js +10 -2
- package/dist/runtime/routes/auth-session.js.map +1 -1
- package/dist/runtime/routes/collection-list.d.ts.map +1 -1
- package/dist/runtime/routes/collection-list.js +213 -66
- package/dist/runtime/routes/collection-list.js.map +1 -1
- package/dist/runtime/routes/deployment.d.ts +5 -0
- package/dist/runtime/routes/deployment.d.ts.map +1 -0
- package/dist/runtime/routes/deployment.js +38 -0
- package/dist/runtime/routes/deployment.js.map +1 -0
- package/dist/runtime/routes/draft.d.ts.map +1 -1
- package/dist/runtime/routes/draft.js +10 -3
- package/dist/runtime/routes/draft.js.map +1 -1
- package/dist/runtime/routes/entries.d.ts.map +1 -1
- package/dist/runtime/routes/entries.js +87 -43
- package/dist/runtime/routes/entries.js.map +1 -1
- package/dist/runtime/routes/history.d.ts.map +1 -1
- package/dist/runtime/routes/history.js +40 -21
- package/dist/runtime/routes/history.js.map +1 -1
- package/dist/runtime/routes/mutate.d.ts.map +1 -1
- package/dist/runtime/routes/mutate.js +4 -1
- package/dist/runtime/routes/mutate.js.map +1 -1
- package/dist/runtime/routes/publish.d.ts.map +1 -1
- package/dist/runtime/routes/publish.js +127 -33
- package/dist/runtime/routes/publish.js.map +1 -1
- package/dist/runtime/routes/schema.d.ts.map +1 -1
- package/dist/runtime/routes/schema.js +11 -2
- package/dist/runtime/routes/schema.js.map +1 -1
- package/dist/runtime/routes/studio-home.d.ts.map +1 -1
- package/dist/runtime/routes/studio-home.js +41 -20
- package/dist/runtime/routes/studio-home.js.map +1 -1
- package/dist/runtime/routes/upload.d.ts.map +1 -1
- package/dist/runtime/routes/upload.js +3 -0
- package/dist/runtime/routes/upload.js.map +1 -1
- package/dist/runtime/schema-registry.d.ts +8 -1
- package/dist/runtime/schema-registry.d.ts.map +1 -1
- package/dist/runtime/schema-registry.js +49 -3
- package/dist/runtime/schema-registry.js.map +1 -1
- package/dist/runtime/storage/entry-commit.d.ts +8 -0
- package/dist/runtime/storage/entry-commit.d.ts.map +1 -0
- package/dist/runtime/storage/entry-commit.js +45 -0
- package/dist/runtime/storage/entry-commit.js.map +1 -0
- package/dist/runtime/storage/filesystem-adapter.d.ts +5 -0
- package/dist/runtime/storage/filesystem-adapter.d.ts.map +1 -1
- package/dist/runtime/storage/filesystem-adapter.js +12 -3
- package/dist/runtime/storage/filesystem-adapter.js.map +1 -1
- package/dist/runtime/storage/frontmatter-codec.d.ts +5 -23
- package/dist/runtime/storage/frontmatter-codec.d.ts.map +1 -1
- package/dist/runtime/storage/frontmatter-codec.js +156 -13
- package/dist/runtime/storage/frontmatter-codec.js.map +1 -1
- package/dist/runtime/storage/in-memory-adapter.d.ts +7 -0
- package/dist/runtime/storage/in-memory-adapter.d.ts.map +1 -1
- package/dist/runtime/storage/in-memory-adapter.js +6 -0
- package/dist/runtime/storage/in-memory-adapter.js.map +1 -1
- package/dist/runtime/storage/markdown-adapter.d.ts.map +1 -1
- package/dist/runtime/storage/markdown-adapter.js +18 -20
- package/dist/runtime/storage/markdown-adapter.js.map +1 -1
- package/dist/runtime/storage/session-overlay-adapter.d.ts +12 -4
- package/dist/runtime/storage/session-overlay-adapter.d.ts.map +1 -1
- package/dist/runtime/storage/session-overlay-adapter.js +100 -13
- package/dist/runtime/storage/session-overlay-adapter.js.map +1 -1
- package/dist/runtime/storage/sidecar-meta-store.d.ts +5 -0
- package/dist/runtime/storage/sidecar-meta-store.d.ts.map +1 -1
- package/dist/runtime/storage/sidecar-meta-store.js +48 -5
- package/dist/runtime/storage/sidecar-meta-store.js.map +1 -1
- package/dist/runtime/themes/preset-tokens.js +4 -4
- package/dist/runtime/themes/preset-tokens.js.map +1 -1
- package/dist/runtime/utils.d.ts.map +1 -1
- package/dist/runtime/utils.js +3 -4
- package/dist/runtime/utils.js.map +1 -1
- package/dist/runtime/views/studio-layout.d.ts +3 -0
- package/dist/runtime/views/studio-layout.d.ts.map +1 -1
- package/dist/runtime/views/studio-layout.js +36 -13
- package/dist/runtime/views/studio-layout.js.map +1 -1
- package/dist/schema-utils.d.ts +7 -0
- package/dist/schema-utils.d.ts.map +1 -1
- package/dist/schema-utils.js +143 -0
- package/dist/schema-utils.js.map +1 -1
- package/dist/types.d.ts +165 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -3
- package/static/cms/admin-entry.css +144 -13
- package/static/cms/admin-entry.js +539 -586
- package/static/cms/dev-toolbar/app.js +78 -19
- package/static/cms/editor/config.js +35 -15
- package/static/cms/editor/content-map.css +8 -1
- package/static/cms/editor/content-map.js +62 -23
- package/static/cms/editor/deployment-status.js +66 -0
- package/static/cms/editor/draft-client.js +87 -0
- package/static/cms/editor/guards.js +20 -0
- package/static/cms/editor/helpers.js +30 -1
- package/static/cms/editor/highlight.js +1 -0
- package/static/cms/editor/image-edit.js +44 -1
- package/static/cms/editor/image-utils.js +23 -7
- package/static/cms/editor/link-follow.js +122 -41
- package/static/cms/editor/link-ui.css +10 -1
- package/static/cms/editor/linkify.js +2 -0
- package/static/cms/editor/md-block-edit.js +140 -37
- package/static/cms/editor/md-paragraphs.js +98 -0
- package/static/cms/editor/md-serialize.js +1 -1
- package/static/cms/editor/panel.js +53 -7
- package/static/cms/editor/preview-mode.js +44 -0
- package/static/cms/editor/publish-result.js +100 -0
- package/static/cms/editor/rich-toolbar.js +58 -15
- package/static/cms/editor/sanitize.js +6 -2
- package/static/cms/editor/save-queue.js +75 -17
- package/static/cms/editor/section-controls/activation.js +3 -0
- package/static/cms/editor/section-controls/api.js +25 -7
- package/static/cms/editor/section-controls/index.js +60 -8
- package/static/cms/editor/section-controls/model.js +39 -4
- package/static/cms/editor/section-controls/mutations.js +15 -0
- package/static/cms/editor/section-controls/page-context.js +9 -0
- package/static/cms/editor/section-controls/pickers.js +53 -2
- package/static/cms/editor/section-controls/reorder.js +23 -0
- package/static/cms/editor/section-controls/selection.js +6 -0
- package/static/cms/editor/section-controls/spacing-drag.js +16 -0
- package/static/cms/editor/section-controls/ui-elements.js +7 -0
- package/static/cms/editor/section-controls/utils.js +7 -0
- package/static/cms/editor/section-controls.css +18 -3
- package/static/cms/editor/security.js +13 -2
- package/static/cms/editor/stega-hydrate.js +17 -4
- package/static/cms/editor/sync.js +475 -56
- package/static/cms/editor/text-edit.js +37 -3
- package/static/cms/editor/text-link-interactions.js +59 -17
- package/static/cms/editor/toast.js +23 -9
- package/static/cms/editor/tokens-and-text.css +9 -0
- package/static/cms/editor/toolbar.css +5 -0
- package/static/cms/editor/toolbar.js +91 -101
- package/static/cms/editor.css +1 -1
- package/static/cms/editor.js +1 -0
- package/static/cms/studio/entry-loader.js +102 -0
- package/static/cms/studio/field-model.js +110 -0
- package/static/cms/studio/fields.js +319 -0
- package/static/cms/studio/history-client.js +74 -0
- package/static/cms/studio/mutation-client.js +74 -0
- package/static/cms/studio/sync-client.js +107 -0
- package/static/cms/studio/upload-client.js +109 -0
- package/static/cms/studio-tokens.css +4 -4
- package/static/cms/studio.css +24 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { PUBLISH_RECOVERY_KEY, sameContent } from "./draft-state.js";
|
|
2
|
+
import { rewriteFrontmatter } from "./storage/frontmatter-codec.js";
|
|
3
|
+
import { spliceBodyBlocks } from "../markdown/splice.js";
|
|
4
|
+
import { commitEntryChanges } from "./storage/entry-commit.js";
|
|
5
|
+
export class RecoveryConflict extends Error {
|
|
6
|
+
}
|
|
7
|
+
export function recoveryState(data) {
|
|
8
|
+
const raw = data[PUBLISH_RECOVERY_KEY];
|
|
9
|
+
if (raw === undefined)
|
|
10
|
+
return null;
|
|
11
|
+
const r = raw;
|
|
12
|
+
const recordOrNull = (value) => value === null ||
|
|
13
|
+
(typeof value === "object" && !Array.isArray(value));
|
|
14
|
+
if (!r || r.version !== 1 || !Number.isSafeInteger(r.beforeRevision) || r.beforeRevision < 0 ||
|
|
15
|
+
!recordOrNull(r.beforeData) || !recordOrNull(r.afterData) ||
|
|
16
|
+
!r.history || typeof r.history.operationId !== "string" || !Number.isFinite(r.history.ts) ||
|
|
17
|
+
(r.beforeSource !== undefined && typeof r.beforeSource !== "string") ||
|
|
18
|
+
(r.afterSource !== undefined && typeof r.afterSource !== "string")) {
|
|
19
|
+
throw new RecoveryConflict("Invalid publish recovery record");
|
|
20
|
+
}
|
|
21
|
+
return r;
|
|
22
|
+
}
|
|
23
|
+
/** Prepare the entire Markdown file before any source write, preserving untouched YAML. */
|
|
24
|
+
export function prepareSource(source, before, after, blocks) {
|
|
25
|
+
const spliced = spliceBodyBlocks(source, blocks);
|
|
26
|
+
if (!spliced.ok)
|
|
27
|
+
return null;
|
|
28
|
+
if (sameContent(before, after))
|
|
29
|
+
return spliced.content;
|
|
30
|
+
const rewritten = rewriteFrontmatter(spliced.content, after);
|
|
31
|
+
if (!rewritten.ok)
|
|
32
|
+
throw new Error("Cannot prepare source content");
|
|
33
|
+
return rewritten.content;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Forward recovery under the entry lock. The overlay's atomic write persists
|
|
37
|
+
* this plan before touching base content. Each subsequent step is checked so a
|
|
38
|
+
* lost acknowledgement/restart cannot apply the source edit or revision twice.
|
|
39
|
+
* This is recoverability, not atomic visibility or a distributed transaction.
|
|
40
|
+
*/
|
|
41
|
+
export async function resumePublish(base, overlay, collection, id, plan) {
|
|
42
|
+
const revision = await base.getRevision(collection, id);
|
|
43
|
+
const current = (await base.getEntry(collection, id))?.data ?? null;
|
|
44
|
+
const source = plan.beforeSource !== undefined && base.readBodySource
|
|
45
|
+
? await base.readBodySource(collection, id) : undefined;
|
|
46
|
+
const atBefore = sameContent(current, plan.beforeData) &&
|
|
47
|
+
(plan.beforeSource === undefined || source === plan.beforeSource);
|
|
48
|
+
const atAfter = sameContent(current, plan.afterData) &&
|
|
49
|
+
(plan.afterSource === undefined || source === plan.afterSource);
|
|
50
|
+
if ((!atBefore && !atAfter) || (revision !== plan.beforeRevision && revision !== plan.beforeRevision + 1) ||
|
|
51
|
+
(revision === plan.beforeRevision + 1 && !atAfter)) {
|
|
52
|
+
throw new RecoveryConflict("Published content changed during recovery");
|
|
53
|
+
}
|
|
54
|
+
let committedTransition = false;
|
|
55
|
+
if (!atAfter) {
|
|
56
|
+
if (plan.afterSource === undefined) {
|
|
57
|
+
const committed = await commitEntryChanges(base, [{
|
|
58
|
+
collection,
|
|
59
|
+
id,
|
|
60
|
+
expectedRevision: plan.beforeRevision,
|
|
61
|
+
expectedExists: plan.beforeData !== null,
|
|
62
|
+
data: plan.afterData,
|
|
63
|
+
history: plan.history,
|
|
64
|
+
}]);
|
|
65
|
+
if (!committed.ok)
|
|
66
|
+
throw new RecoveryConflict("Published content changed during recovery");
|
|
67
|
+
committedTransition = true;
|
|
68
|
+
}
|
|
69
|
+
else if (base.writeBodySource) {
|
|
70
|
+
await base.writeBodySource(collection, id, plan.afterSource);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
throw new RecoveryConflict("Source-backed publication is unavailable");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (!committedTransition && revision === plan.beforeRevision) {
|
|
77
|
+
const next = await base.bumpRevision(collection, id);
|
|
78
|
+
if (next !== plan.beforeRevision + 1)
|
|
79
|
+
throw new RecoveryConflict("Unexpected revision during recovery");
|
|
80
|
+
}
|
|
81
|
+
if (!committedTransition) {
|
|
82
|
+
const history = await base.getHistory(collection, id);
|
|
83
|
+
if (!history.some(entry => entry.operationId === plan.history.operationId)) {
|
|
84
|
+
await base.appendHistory(collection, id, plan.history);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const overlayRevision = await overlay.getRevision(collection, id);
|
|
88
|
+
const overlayEntry = await overlay.getEntry(collection, id);
|
|
89
|
+
if (overlayEntry) {
|
|
90
|
+
const cleared = await commitEntryChanges(overlay, [{
|
|
91
|
+
collection, id, expectedRevision: overlayRevision, expectedExists: true, data: null,
|
|
92
|
+
}]);
|
|
93
|
+
if (!cleared.ok)
|
|
94
|
+
throw new RecoveryConflict("Draft changed during publication cleanup");
|
|
95
|
+
}
|
|
96
|
+
return plan.afterData === null ? 0 : plan.beforeRevision + 1;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=publish-recovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-recovery.js","sourceRoot":"","sources":["../../src/runtime/publish-recovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,15 +22,21 @@ export interface PublishedEntry {
|
|
|
22
22
|
export interface PublishConflict {
|
|
23
23
|
collection: string;
|
|
24
24
|
id: string;
|
|
25
|
-
/**
|
|
26
|
-
*
|
|
27
|
-
|
|
28
|
-
reason: "stale_body" | "invalid_body";
|
|
25
|
+
/** Body hashes, structured baselines, or legacy drafts failed validation.
|
|
26
|
+
* The entry was not published and its draft is preserved. */
|
|
27
|
+
reason: "stale_body" | "invalid_body" | "stale_entry" | "legacy_draft";
|
|
29
28
|
}
|
|
30
29
|
export interface PublishOutcome {
|
|
31
30
|
published: PublishedEntry[];
|
|
32
31
|
conflicts: PublishConflict[];
|
|
32
|
+
failed: Array<{
|
|
33
|
+
collection: string;
|
|
34
|
+
id: string;
|
|
35
|
+
reason: "storage_error" | "recovery_conflict";
|
|
36
|
+
}>;
|
|
33
37
|
}
|
|
38
|
+
/** Preflight the entire batch before any source, revision, journal or hook write. */
|
|
39
|
+
export declare function canPublishOverlay(overlay: StorageAdapter, scope?: PublishScope): Promise<boolean>;
|
|
34
40
|
/**
|
|
35
41
|
* Flush the overlay into the base. A tombstoned draft entry deletes from the
|
|
36
42
|
* base; any other draft entry is written, the base revision bumped, and a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/runtime/publish.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/runtime/publish.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AASlD,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX;iEAC6D;IAC7D,MAAM,EAAE,YAAY,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,CAAC;CACxE;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,MAAM,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,eAAe,GAAG,mBAAmB,CAAA;KAAE,CAAC,CAAC;CAClG;AAoDD,qFAAqF;AACrF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,GAAE,YAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAW3G;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,cAAc,EACvB,KAAK,GAAE,YAAiB,GACvB,OAAO,CAAC,cAAc,CAAC,CA4EzB;AAED,+DAA+D;AAC/D,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,EACvB,KAAK,GAAE,YAAiB,GACvB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED;6CAC6C;AAC7C,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,KAAK,GAAE,YAAiB,GACvB,OAAO,CAAC,MAAM,CAAC,CAgBjB"}
|
package/dist/runtime/publish.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { canPerform, PermissionDenied } from "./authorization.js";
|
|
1
2
|
import { BODY_OVERLAY_KEY, parseMdSrc, formatMdSrc } from "../markdown/contracts.js";
|
|
2
3
|
import { withEntryLock } from "./mutations/engine.js";
|
|
3
4
|
import { TOMBSTONE_KEY } from "./storage/session-overlay-adapter.js";
|
|
5
|
+
import { DRAFT_STATE_KEY, PUBLISH_RECOVERY_KEY, readDraftState, sameContent } from "./draft-state.js";
|
|
6
|
+
import { prepareSource, recoveryState, resumePublish, RecoveryConflict } from "./publish-recovery.js";
|
|
7
|
+
import { getRequestContext } from "./request-context.js";
|
|
8
|
+
import { commitEntryChanges } from "./storage/entry-commit.js";
|
|
4
9
|
/** Extract + validate the body-draft map from draft data, or null when absent.
|
|
5
10
|
* `undefined` return = present but malformed (never publish through it). */
|
|
6
11
|
function extractBodyBlocks(data) {
|
|
@@ -47,6 +52,23 @@ async function overlayEntriesInScope(overlay, scope) {
|
|
|
47
52
|
}
|
|
48
53
|
return out;
|
|
49
54
|
}
|
|
55
|
+
/** Preflight the entire batch before any source, revision, journal or hook write. */
|
|
56
|
+
export async function canPublishOverlay(overlay, scope = {}) {
|
|
57
|
+
if (!getRequestContext()?.authorize)
|
|
58
|
+
return true;
|
|
59
|
+
const targets = await overlayEntriesInScope(overlay, scope);
|
|
60
|
+
if (!targets.length)
|
|
61
|
+
return canPerform("publish", scope.collection, scope.id);
|
|
62
|
+
for (const { collection, id } of targets) {
|
|
63
|
+
if (!(await canPerform("publish", collection, id)))
|
|
64
|
+
return false;
|
|
65
|
+
const draft = await overlay.getEntry(collection, id);
|
|
66
|
+
const plan = draft ? recoveryState(draft.data) : null;
|
|
67
|
+
if ((isTombstoneData(draft?.data) || plan?.afterData === null) && !(await canPerform("delete", collection, id)))
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
50
72
|
/**
|
|
51
73
|
* Flush the overlay into the base. A tombstoned draft entry deletes from the
|
|
52
74
|
* base; any other draft entry is written, the base revision bumped, and a
|
|
@@ -60,75 +82,83 @@ async function overlayEntriesInScope(overlay, scope) {
|
|
|
60
82
|
* surface "publish all" should report that list.
|
|
61
83
|
*/
|
|
62
84
|
export async function publishOverlay(base, overlay, scope = {}) {
|
|
85
|
+
if (!(await canPublishOverlay(overlay, scope)))
|
|
86
|
+
throw new PermissionDenied();
|
|
63
87
|
const targets = await overlayEntriesInScope(overlay, scope);
|
|
64
88
|
const published = [];
|
|
65
89
|
const conflicts = [];
|
|
90
|
+
const failed = [];
|
|
66
91
|
for (const { collection, id } of targets) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
92
|
+
try {
|
|
93
|
+
await withEntryLock(collection, id, async () => {
|
|
94
|
+
const draftRevision = await overlay.getRevision(collection, id);
|
|
95
|
+
const draft = await overlay.getEntry(collection, id);
|
|
96
|
+
if (!draft)
|
|
97
|
+
return;
|
|
98
|
+
let plan = recoveryState(draft.data);
|
|
99
|
+
if (!plan) {
|
|
100
|
+
const state = readDraftState(draft.data);
|
|
101
|
+
const { [BODY_OVERLAY_KEY]: _body, [DRAFT_STATE_KEY]: _state, [PUBLISH_RECOVERY_KEY]: _recovery, [TOMBSTONE_KEY]: _tombstone, ...fields } = draft.data;
|
|
102
|
+
const blocks = extractBodyBlocks(draft.data);
|
|
103
|
+
if (blocks === undefined) {
|
|
104
|
+
conflicts.push({ collection, id, reason: "invalid_body" });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const deleted = isTombstoneData(draft.data);
|
|
108
|
+
const structured = state?.structured ?? (deleted || Object.keys(fields).length > 0);
|
|
109
|
+
if (!state && structured) {
|
|
110
|
+
conflicts.push({ collection, id, reason: "legacy_draft" });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const before = (await base.getEntry(collection, id))?.data ?? null;
|
|
114
|
+
const beforeRevision = await base.getRevision(collection, id);
|
|
115
|
+
if (structured && state && (state.baseRevision !== beforeRevision || !sameContent(state.baseData, before))) {
|
|
116
|
+
conflicts.push({ collection, id, reason: "stale_entry" });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const after = deleted ? null : structured ? fields : { ...(before ?? {}), ...fields };
|
|
120
|
+
const source = base.readBodySource ? await base.readBodySource(collection, id) : null;
|
|
121
|
+
if (blocks?.length && (!source || !base.writeBodySource)) {
|
|
122
|
+
conflicts.push({ collection, id, reason: "invalid_body" });
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const afterSource = source !== null && after !== null && base.writeBodySource
|
|
126
|
+
? prepareSource(source, before, after, blocks ?? []) : undefined;
|
|
127
|
+
if (afterSource === null) {
|
|
128
|
+
conflicts.push({ collection, id, reason: "stale_body" });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const context = getRequestContext();
|
|
132
|
+
const editor = context?.identity ?? (context?.editorId ? { id: context.editorId } : null);
|
|
133
|
+
plan = {
|
|
134
|
+
version: 1, beforeRevision, beforeData: before, afterData: after,
|
|
135
|
+
...(source !== null ? { beforeSource: source } : {}),
|
|
136
|
+
...(afterSource !== undefined ? { afterSource } : {}),
|
|
137
|
+
history: { operationId: crypto.randomUUID(), ts: Date.now(), action: "publish", data: before,
|
|
138
|
+
...(source !== null ? { bodySource: source } : {}), ...(editor ? { editor } : {}) },
|
|
139
|
+
};
|
|
140
|
+
const persisted = await commitEntryChanges(overlay, [{
|
|
141
|
+
collection,
|
|
142
|
+
id,
|
|
143
|
+
expectedRevision: draftRevision,
|
|
144
|
+
expectedExists: true,
|
|
145
|
+
data: { ...draft.data, [PUBLISH_RECOVERY_KEY]: plan },
|
|
146
|
+
}]);
|
|
147
|
+
if (!persisted.ok) {
|
|
148
|
+
conflicts.push({ collection, id, reason: "stale_entry" });
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
99
151
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
// Merge the draft's frontmatter DELTAS onto the current base rather than
|
|
103
|
-
// replacing it. A body-only draft carries no frontmatter keys, so base
|
|
104
|
-
// fields edited after the draft was staged (e.g. a Studio field save,
|
|
105
|
-
// which writes straight to base in server delivery) survive instead of
|
|
106
|
-
// being clobbered by a stale snapshot. Skip the write entirely when the
|
|
107
|
-
// merge changes nothing — a body-only publish must not re-serialize
|
|
108
|
-
// untouched frontmatter (it re-quotes scalars and pollutes the diff).
|
|
109
|
-
// Same-shape objects come through the same parse path, so stringify
|
|
110
|
-
// comparison is order-stable here.
|
|
111
|
-
const mergedData = { ...(before?.data ?? {}), ...entryData };
|
|
112
|
-
if (JSON.stringify(before?.data ?? null) !== JSON.stringify(mergedData)) {
|
|
113
|
-
await base.writeEntry(collection, id, mergedData);
|
|
114
|
-
}
|
|
115
|
-
const revision = await base.bumpRevision(collection, id);
|
|
116
|
-
await base.appendHistory(collection, id, {
|
|
117
|
-
ts: Date.now(),
|
|
118
|
-
action: "publish",
|
|
119
|
-
data: before?.data ?? null,
|
|
120
|
-
// Pre-publish source file, so a restore can put the prose back.
|
|
121
|
-
...(bodySource !== undefined ? { bodySource } : {}),
|
|
152
|
+
const revision = await resumePublish(base, overlay, collection, id, plan);
|
|
153
|
+
published.push({ collection, id, revision, deleted: plan.afterData === null });
|
|
122
154
|
});
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
else if (result)
|
|
129
|
-
published.push(result);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
console.error("[caretcms] Publish requires recovery:", error);
|
|
158
|
+
failed.push({ collection, id, reason: error instanceof RecoveryConflict ? "recovery_conflict" : "storage_error" });
|
|
159
|
+
}
|
|
130
160
|
}
|
|
131
|
-
return { published, conflicts };
|
|
161
|
+
return { published, conflicts, failed };
|
|
132
162
|
}
|
|
133
163
|
/** Count draft entries currently held in an editor overlay. */
|
|
134
164
|
export async function countOverlayDrafts(overlay, scope = {}) {
|
|
@@ -139,7 +169,19 @@ export async function countOverlayDrafts(overlay, scope = {}) {
|
|
|
139
169
|
export async function discardOverlay(overlay, scope = {}) {
|
|
140
170
|
const targets = await overlayEntriesInScope(overlay, scope);
|
|
141
171
|
for (const { collection, id } of targets) {
|
|
142
|
-
await withEntryLock(collection, id, () =>
|
|
172
|
+
await withEntryLock(collection, id, async () => {
|
|
173
|
+
const revision = await overlay.getRevision(collection, id);
|
|
174
|
+
const draft = await overlay.getEntry(collection, id);
|
|
175
|
+
if (draft?.data[PUBLISH_RECOVERY_KEY])
|
|
176
|
+
throw new Error("Finish pending publication before discarding drafts");
|
|
177
|
+
if (draft) {
|
|
178
|
+
const discarded = await commitEntryChanges(overlay, [{
|
|
179
|
+
collection, id, expectedRevision: revision, expectedExists: true, data: null,
|
|
180
|
+
}]);
|
|
181
|
+
if (!discarded.ok)
|
|
182
|
+
throw new Error("Draft changed while it was being discarded");
|
|
183
|
+
}
|
|
184
|
+
});
|
|
143
185
|
}
|
|
144
186
|
return targets.length;
|
|
145
187
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/runtime/publish.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/runtime/publish.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,8 @@ export interface RebuildWebhookConfig {
|
|
|
2
2
|
webhookUrl: string | null;
|
|
3
3
|
method?: "POST" | "PUT";
|
|
4
4
|
headers?: Record<string, string>;
|
|
5
|
+
/** Defaults to 5 seconds, bounded to 30 seconds. */
|
|
6
|
+
timeoutMs?: number;
|
|
5
7
|
}
|
|
6
8
|
export interface RebuildWebhookPayload {
|
|
7
9
|
published: Array<{
|
|
@@ -11,6 +13,8 @@ export interface RebuildWebhookPayload {
|
|
|
11
13
|
deleted: boolean;
|
|
12
14
|
}>;
|
|
13
15
|
commit: string | null;
|
|
16
|
+
/** Correlates this request with deployment status provider results. */
|
|
17
|
+
deploymentId?: string;
|
|
14
18
|
}
|
|
15
19
|
export type RebuildWebhookResult = {
|
|
16
20
|
triggered: false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rebuild-webhook.d.ts","sourceRoot":"","sources":["../../src/runtime/rebuild-webhook.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"rebuild-webhook.d.ts","sourceRoot":"","sources":["../../src/runtime/rebuild-webhook.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACzF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GAC9B;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CA4C/B"}
|
|
@@ -2,8 +2,12 @@ export async function triggerRebuildWebhook(config, payload) {
|
|
|
2
2
|
const webhookUrl = config.webhookUrl?.trim();
|
|
3
3
|
if (!webhookUrl)
|
|
4
4
|
return { triggered: false, ok: true };
|
|
5
|
+
const controller = new AbortController();
|
|
6
|
+
const timeout = Number.isFinite(config.timeoutMs) ? Math.max(1, Math.min(config.timeoutMs, 30_000)) : 5_000;
|
|
7
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
5
8
|
try {
|
|
6
9
|
const response = await fetch(webhookUrl, {
|
|
10
|
+
signal: controller.signal,
|
|
7
11
|
method: config.method ?? "POST",
|
|
8
12
|
headers: {
|
|
9
13
|
"content-type": "application/json",
|
|
@@ -14,8 +18,11 @@ export async function triggerRebuildWebhook(config, payload) {
|
|
|
14
18
|
event: "publish",
|
|
15
19
|
published: payload.published,
|
|
16
20
|
commit: payload.commit,
|
|
21
|
+
...(payload.deploymentId ? { deploymentId: payload.deploymentId } : {}),
|
|
17
22
|
}),
|
|
18
23
|
});
|
|
24
|
+
// Only acknowledgement headers matter; don't leave a streaming response open.
|
|
25
|
+
void response.body?.cancel().catch(() => { });
|
|
19
26
|
if (!response.ok) {
|
|
20
27
|
return {
|
|
21
28
|
triggered: true,
|
|
@@ -26,12 +33,15 @@ export async function triggerRebuildWebhook(config, payload) {
|
|
|
26
33
|
}
|
|
27
34
|
return { triggered: true, ok: true, status: response.status };
|
|
28
35
|
}
|
|
29
|
-
catch
|
|
36
|
+
catch {
|
|
30
37
|
return {
|
|
31
38
|
triggered: true,
|
|
32
39
|
ok: false,
|
|
33
|
-
error:
|
|
40
|
+
error: controller.signal.aborted ? "Rebuild webhook timed out" : "Could not reach rebuild webhook",
|
|
34
41
|
};
|
|
35
42
|
}
|
|
43
|
+
finally {
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
}
|
|
36
46
|
}
|
|
37
47
|
//# sourceMappingURL=rebuild-webhook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rebuild-webhook.js","sourceRoot":"","sources":["../../src/runtime/rebuild-webhook.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rebuild-webhook.js","sourceRoot":"","sources":["../../src/runtime/rebuild-webhook.ts"],"names":[],"mappings":"AAoBA,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAA4B,EAC5B,OAA8B;IAE9B,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAEvD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7G,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;YACvC,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,MAAM;YAC/B,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;aAC1B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACxE,CAAC;SACH,CAAC,CAAC;QAEH,8EAA8E;QAC9E,KAAK,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAE7C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO;gBACL,SAAS,EAAE,IAAI;gBACf,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,KAAK,EAAE,sCAAsC,QAAQ,CAAC,MAAM,EAAE;aAC/D,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,SAAS,EAAE,IAAI;YACf,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,iCAAiC;SACnG,CAAC;IACJ,CAAC;YAAS,CAAC;QAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC;AACpC,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type { StorageAdapter, UploadHandler } from "../types.js";
|
|
1
|
+
import type { AuthorizationAction, EditorIdentity, StorageAdapter, UploadHandler } from "../types.js";
|
|
2
2
|
export interface CaretRequestContext {
|
|
3
3
|
adapter: StorageAdapter;
|
|
4
|
+
/** A request-bound, fail-closed policy. Omitted in legacy full-access mode. */
|
|
5
|
+
authorize?: (action: AuthorizationAction, collection?: string, id?: string) => Promise<boolean>;
|
|
4
6
|
uploadHandler: UploadHandler;
|
|
5
7
|
sessionId: string | null;
|
|
6
8
|
demoMode: boolean;
|
|
@@ -17,6 +19,10 @@ export interface CaretRequestContext {
|
|
|
17
19
|
* their overlay by `sessionId` instead.
|
|
18
20
|
*/
|
|
19
21
|
editorId?: string | null;
|
|
22
|
+
/** Named identity supplied by an optional authoritative identity adapter. */
|
|
23
|
+
identity?: EditorIdentity | null;
|
|
24
|
+
/** True when an external identity adapter is configured and authoritative. */
|
|
25
|
+
identityAuthoritative?: boolean;
|
|
20
26
|
/**
|
|
21
27
|
* True only when a per-session storage overlay was actually installed for
|
|
22
28
|
* this demo request, guaranteeing writes are isolated from the shared base
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/runtime/request-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/runtime/request-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtG,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChG,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACjC,8EAA8E;IAC9E,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC7C;AAUD,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,mBAAmB,EAC5B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED,wBAAgB,iBAAiB,IAAI,mBAAmB,GAAG,SAAS,CAEnE;AAED,wBAAgB,qBAAqB,IAAI,mBAAmB,CAQ3D"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
-
|
|
2
|
+
// Vite may evaluate more than one copy of @caretcms/core during Astro dev
|
|
3
|
+
// dependency optimization. Keep the request scope on the process global so the
|
|
4
|
+
// middleware and live loader still share one AsyncLocalStorage instance.
|
|
5
|
+
const requestContextKey = Symbol.for("@caretcms/core/request-context");
|
|
6
|
+
const globalSlots = globalThis;
|
|
7
|
+
const storage = (globalSlots[requestContextKey] ??=
|
|
8
|
+
new AsyncLocalStorage());
|
|
3
9
|
export function runWithRequestContext(context, fn) {
|
|
4
10
|
return storage.run(context, fn);
|
|
5
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/runtime/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/runtime/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AA2CrD,0EAA0E;AAC1E,+EAA+E;AAC/E,yEAAyE;AACzE,MAAM,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AACvE,MAAM,WAAW,GAAG,UAAyD,CAAC;AAC9E,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,iBAAiB,CAAC;IAC7C,IAAI,iBAAiB,EAAuB,CAA2C,CAAC;AAE1F,MAAM,UAAU,qBAAqB,CACnC,OAA4B,EAC5B,EAAoB;IAEpB,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,kIAAkI,CACnI,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewrite.d.ts","sourceRoot":"","sources":["../../src/runtime/rewrite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,aAAa,CAAC;AAqB7D,KAAK,UAAU,GAAG;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AASF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,uMAKvB,CAAC;AAkJX;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,UAAU,GAAG,IAAI,GACvB;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAY1D;AA2CD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAA;CAAE,GAC/D,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"rewrite.d.ts","sourceRoot":"","sources":["../../src/runtime/rewrite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,aAAa,CAAC;AAqB7D,KAAK,UAAU,GAAG;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AASF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,uMAKvB,CAAC;AAkJX;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,UAAU,GAAG,IAAI,GACvB;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAY1D;AA2CD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAA;CAAE,GAC/D,OAAO,CAAC,MAAM,CAAC,CA4MjB"}
|
package/dist/runtime/rewrite.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* v1 scope: text-only leaf nodes + <img> src swaps.
|
|
9
9
|
* Elements with nested child markup are skipped (editor warns at runtime).
|
|
10
10
|
*/
|
|
11
|
-
import { BODY_OVERLAY_KEY, parseMdBinding } from "../markdown/contracts.js";
|
|
11
|
+
import { BODY_OVERLAY_KEY, parseMdBinding, formatMdSrc, BLOCK_PATH_RE } from "../markdown/contracts.js";
|
|
12
12
|
import { sanitizeHtml } from "./sanitize-html.js";
|
|
13
13
|
import { getNestedValue } from "./utils.js";
|
|
14
14
|
// --- Patterns ---
|
|
@@ -279,9 +279,35 @@ export async function rewriteCaretAttributes(html, adapter, options) {
|
|
|
279
279
|
const drafts = entry.data[BODY_OVERLAY_KEY];
|
|
280
280
|
if (drafts === null || typeof drafts !== "object")
|
|
281
281
|
continue;
|
|
282
|
+
// Structural drafts own several original stamps but splice one verified
|
|
283
|
+
// contiguous range. Only their first stamp renders the editable group.
|
|
284
|
+
let consumed = false;
|
|
285
|
+
for (const [path, value] of Object.entries(drafts)) {
|
|
286
|
+
if (path === binding.mdBlockPath || !value || typeof value !== "object")
|
|
287
|
+
continue;
|
|
288
|
+
const sources = value.sources;
|
|
289
|
+
if (Array.isArray(sources) && sources.some(source => source?.blockPath === binding.mdBlockPath))
|
|
290
|
+
consumed = true;
|
|
291
|
+
}
|
|
292
|
+
if (consumed) {
|
|
293
|
+
result = result.slice(0, binding.contentStart) + result.slice(binding.contentEnd);
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
282
296
|
const block = drafts[binding.mdBlockPath];
|
|
283
297
|
if (block === null || typeof block !== "object")
|
|
284
298
|
continue;
|
|
299
|
+
const group = block;
|
|
300
|
+
if (Array.isArray(group.paragraphs) && group.paragraphs.every(p => typeof p === "string") &&
|
|
301
|
+
Array.isArray(group.sources) && group.sources.length > 0 && group.sources.length <= 128 &&
|
|
302
|
+
group.sources.every(source => source && typeof source.blockPath === "string" && BLOCK_PATH_RE.test(source.blockPath) && source.src && typeof source.html === "string")) {
|
|
303
|
+
const sources = group.sources.map(source => ({ blockPath: source.blockPath,
|
|
304
|
+
src: formatMdSrc(source.src), html: source.html }));
|
|
305
|
+
const bindingValue = `${binding.collection}::${binding.id}::body::${binding.mdBlockPath}`;
|
|
306
|
+
const paragraphs = group.paragraphs.map(p => `<p>${sanitizeHtml(p, { allowedClasses: options?.allowedClasses }) || "<br>"}</p>`).join("");
|
|
307
|
+
const rendered = `<div data-caret-md="${escapeAttr(bindingValue)}" data-caret-md-src="${escapeAttr(sources[0].src)}" data-caret-md-sources="${escapeAttr(JSON.stringify(sources))}" data-caret-md-draft>${paragraphs || "<p><br></p>"}</div>`;
|
|
308
|
+
result = result.slice(0, binding.contentStart) + rendered + result.slice(binding.contentEnd);
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
285
311
|
const draftHtml = block.html;
|
|
286
312
|
if (typeof draftHtml !== "string")
|
|
287
313
|
continue;
|
|
@@ -295,7 +321,7 @@ export async function rewriteCaretAttributes(html, adapter, options) {
|
|
|
295
321
|
const openTag = binding.fullMatch.slice(0, openTagEnd);
|
|
296
322
|
const before = openTag.includes("data-caret-md-draft")
|
|
297
323
|
? openTag
|
|
298
|
-
: `${openTag.slice(0, -1)} data-caret-md-draft>`;
|
|
324
|
+
: `${openTag.slice(0, -1)}${openTag.includes('data-caret-md-paragraph="true"') ? ` data-caret-md-original="${escapeAttr(binding.fullMatch.slice(openTagEnd, closeTagStart))}"` : ""} data-caret-md-draft>`;
|
|
299
325
|
const after = binding.fullMatch.slice(closeTagStart);
|
|
300
326
|
const injected = sanitizeHtml(draftHtml, { allowedClasses: options?.allowedClasses });
|
|
301
327
|
result =
|