@caretcms/core 0.1.2 → 0.3.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 +109 -13
- package/dist/contracts.d.ts +1 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +1 -0
- package/dist/contracts.js.map +1 -1
- package/dist/index.d.ts +31 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -30
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +17 -6
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +57 -14
- package/dist/loader.js.map +1 -1
- package/dist/markdown/block-context.d.ts +21 -0
- package/dist/markdown/block-context.d.ts.map +1 -0
- package/dist/markdown/block-context.js +27 -0
- package/dist/markdown/block-context.js.map +1 -0
- package/dist/markdown/canonical-body.d.ts +30 -0
- package/dist/markdown/canonical-body.d.ts.map +1 -0
- package/dist/markdown/canonical-body.js +54 -0
- package/dist/markdown/canonical-body.js.map +1 -0
- package/dist/markdown/contracts.d.ts +66 -0
- package/dist/markdown/contracts.d.ts.map +1 -0
- package/dist/markdown/contracts.js +102 -0
- package/dist/markdown/contracts.js.map +1 -0
- package/dist/markdown/html-to-snodes.d.ts +26 -0
- package/dist/markdown/html-to-snodes.d.ts.map +1 -0
- package/dist/markdown/html-to-snodes.js +118 -0
- package/dist/markdown/html-to-snodes.js.map +1 -0
- package/dist/markdown/remark.d.ts +35 -0
- package/dist/markdown/remark.d.ts.map +1 -0
- package/dist/markdown/remark.js +66 -0
- package/dist/markdown/remark.js.map +1 -0
- package/dist/markdown/satteri.d.ts +19 -0
- package/dist/markdown/satteri.d.ts.map +1 -0
- package/dist/markdown/satteri.js +144 -0
- package/dist/markdown/satteri.js.map +1 -0
- package/dist/markdown/serialize.d.ts +60 -0
- package/dist/markdown/serialize.d.ts.map +1 -0
- package/dist/markdown/serialize.js +264 -0
- package/dist/markdown/serialize.js.map +1 -0
- package/dist/markdown/splice.d.ts +32 -0
- package/dist/markdown/splice.d.ts.map +1 -0
- package/dist/markdown/splice.js +44 -0
- package/dist/markdown/splice.js.map +1 -0
- package/dist/markdown/stamp.d.ts +68 -0
- package/dist/markdown/stamp.d.ts.map +1 -0
- package/dist/markdown/stamp.js +131 -0
- package/dist/markdown/stamp.js.map +1 -0
- package/dist/runtime/auth/rate-limiter.d.ts.map +1 -1
- package/dist/runtime/auth/rate-limiter.js +5 -0
- package/dist/runtime/auth/rate-limiter.js.map +1 -1
- package/dist/runtime/auth/session.d.ts +3 -3
- package/dist/runtime/auth/session.d.ts.map +1 -1
- package/dist/runtime/auth/session.js +68 -21
- package/dist/runtime/auth/session.js.map +1 -1
- 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.d.ts.map +1 -1
- package/dist/runtime/content.js +4 -2
- package/dist/runtime/content.js.map +1 -1
- package/dist/runtime/i18n.d.ts +86 -0
- package/dist/runtime/i18n.d.ts.map +1 -0
- package/dist/runtime/i18n.js +168 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/middleware.d.ts.map +1 -1
- package/dist/runtime/middleware.js +61 -6
- package/dist/runtime/middleware.js.map +1 -1
- package/dist/runtime/mutations/contracts.d.ts +28 -1
- package/dist/runtime/mutations/contracts.d.ts.map +1 -1
- package/dist/runtime/mutations/contracts.js +76 -0
- package/dist/runtime/mutations/contracts.js.map +1 -1
- package/dist/runtime/mutations/engine.d.ts +6 -1
- package/dist/runtime/mutations/engine.d.ts.map +1 -1
- package/dist/runtime/mutations/engine.js +271 -51
- package/dist/runtime/mutations/engine.js.map +1 -1
- package/dist/runtime/providers.d.ts +2 -1
- package/dist/runtime/providers.d.ts.map +1 -1
- package/dist/runtime/providers.js +7 -1
- package/dist/runtime/providers.js.map +1 -1
- package/dist/runtime/publish.d.ts +13 -1
- package/dist/runtime/publish.d.ts.map +1 -1
- package/dist/runtime/publish.js +80 -4
- package/dist/runtime/publish.js.map +1 -1
- package/dist/runtime/request-context.d.ts +14 -2
- 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 +109 -3
- package/dist/runtime/rewrite.js.map +1 -1
- package/dist/runtime/rich-allowlist.d.ts.map +1 -1
- package/dist/runtime/rich-allowlist.js +5 -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 +114 -18
- 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 +33 -15
- 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 +4 -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 +64 -41
- package/dist/runtime/routes/collection-list.js.map +1 -1
- package/dist/runtime/routes/entries.d.ts.map +1 -1
- package/dist/runtime/routes/entries.js +16 -6
- 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 +50 -22
- 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 +40 -6
- 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 +5 -2
- 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 -3
- 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 +38 -19
- package/dist/runtime/routes/studio-home.js.map +1 -1
- package/dist/runtime/routes/theme-stylesheet.d.ts.map +1 -1
- package/dist/runtime/routes/theme-stylesheet.js +11 -1
- package/dist/runtime/routes/theme-stylesheet.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 +47 -3
- package/dist/runtime/schema-registry.js.map +1 -1
- package/dist/runtime/storage/atomic-write.d.ts.map +1 -1
- package/dist/runtime/storage/atomic-write.js +8 -3
- package/dist/runtime/storage/atomic-write.js.map +1 -1
- package/dist/runtime/storage/markdown-adapter.d.ts +19 -0
- package/dist/runtime/storage/markdown-adapter.d.ts.map +1 -1
- package/dist/runtime/storage/markdown-adapter.js +41 -0
- package/dist/runtime/storage/markdown-adapter.js.map +1 -1
- package/dist/runtime/storage/session-overlay-adapter.d.ts +8 -0
- package/dist/runtime/storage/session-overlay-adapter.d.ts.map +1 -1
- package/dist/runtime/storage/session-overlay-adapter.js +24 -2
- package/dist/runtime/storage/session-overlay-adapter.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 +10 -0
- package/dist/runtime/utils.d.ts.map +1 -1
- package/dist/runtime/utils.js +16 -0
- 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 +83 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/static/cms/admin-entry.css +135 -13
- package/static/cms/admin-entry.js +509 -86
- package/static/cms/editor/guards.js +1 -1
- package/static/cms/editor/image-edit.js +42 -11
- package/static/cms/editor/image.css +7 -1
- package/static/cms/editor/md-block-edit.js +176 -0
- package/static/cms/editor/md-serialize.js +301 -0
- package/static/cms/editor/panel.css +69 -25
- package/static/cms/editor/panel.js +58 -1
- package/static/cms/editor/rich-toolbar.js +4 -3
- package/static/cms/editor/sanitize.js +2 -1
- package/static/cms/editor/sync.js +277 -56
- package/static/cms/editor/text-edit.js +68 -17
- package/static/cms/editor/text-link-interactions.js +4 -4
- package/static/cms/editor/toast.css +114 -2
- package/static/cms/editor/toast.js +121 -22
- package/static/cms/editor/tokens-and-text.css +73 -3
- package/static/cms/editor/toolbar.css +19 -6
- package/static/cms/editor/toolbar.js +64 -23
- package/static/cms/editor.css +1 -1
- package/static/cms/editor.js +14 -3
- package/static/cms/studio-tokens.css +4 -4
- package/static/cms/studio.css +24 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared, pipeline-independent logic for stamping `data-caret-md` bindings.
|
|
3
|
+
*
|
|
4
|
+
* Two frontends drive this — a Sätteri mdast plugin (Astro 7) and a remark
|
|
5
|
+
* plugin (Astro 6) — walking their own trees but calling the SAME pure
|
|
6
|
+
* functions here so both emit byte-identical attributes (a parity test holds
|
|
7
|
+
* them together). Nothing in this module touches a tree or a pipeline type; it
|
|
8
|
+
* takes already-extracted node facts and returns attributes or `null`.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* mdast node types that make their subtree non-editable: their inner text is
|
|
12
|
+
* either structured (tables), reference plumbing (footnote definitions), or
|
|
13
|
+
* raw/JSX passthrough that markdown block editing can't safely round-trip.
|
|
14
|
+
*/
|
|
15
|
+
export declare const ISLAND_TYPES: ReadonlySet<string>;
|
|
16
|
+
export interface ResolvedEntry {
|
|
17
|
+
collection: string;
|
|
18
|
+
id: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolve a source file to its `{collection, id}` under the content root, or
|
|
22
|
+
* `null`. v1 scope: flat `<contentRoot>/<collection>/<id>.md` only — `.mdx`,
|
|
23
|
+
* nested slugs, and identifiers failing the id grammar are intentionally
|
|
24
|
+
* unmatched (and so never stamped).
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveEntry(fileURL: string | URL | undefined, contentRoot: string): ResolvedEntry | null;
|
|
27
|
+
export type ParagraphPlan = {
|
|
28
|
+
action: "skip";
|
|
29
|
+
} | {
|
|
30
|
+
action: "self";
|
|
31
|
+
nested: boolean;
|
|
32
|
+
} | {
|
|
33
|
+
action: "parent";
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Decide how a paragraph maps to a bound element. A list item renders its text
|
|
37
|
+
* on the `<li>` (a tight list drops the `<p>` entirely), so we bind the item —
|
|
38
|
+
* via its FIRST paragraph, using that paragraph's marker-free offsets. Other
|
|
39
|
+
* paragraphs bind themselves; `nested` marks those inside a container.
|
|
40
|
+
*/
|
|
41
|
+
export declare function planParagraph(parentType: string, indexInParent: number | undefined): ParagraphPlan;
|
|
42
|
+
export interface StampInput {
|
|
43
|
+
/** The exact source string the pipeline parsed (offsets are relative to it). */
|
|
44
|
+
source: string;
|
|
45
|
+
/** The file being rendered. */
|
|
46
|
+
fileURL: string | URL | undefined;
|
|
47
|
+
/** Absolute content root the markdown adapter reads from. */
|
|
48
|
+
contentRoot: string;
|
|
49
|
+
/** unist offsets of the block whose text the binding edits. */
|
|
50
|
+
start: number | undefined;
|
|
51
|
+
end: number | undefined;
|
|
52
|
+
/** Root-to-element child indexes identifying the bound element. */
|
|
53
|
+
blockPath: readonly number[];
|
|
54
|
+
/** Types of the bound node's ancestors (island detection). */
|
|
55
|
+
ancestorTypes: readonly string[];
|
|
56
|
+
/** True when the block sits inside a container (blockquote / list item). */
|
|
57
|
+
nested: boolean;
|
|
58
|
+
/** mdast node type of the bound block ("heading" | "paragraph" | "listItem"). */
|
|
59
|
+
blockType?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Compute the `{data-caret-md, data-caret-md-src}` attributes for one block, or
|
|
63
|
+
* `null` to leave it unstamped. Offsets are normalized to the canonical body
|
|
64
|
+
* base (frontmatter-stripped, trimmed) so a `.md` import, a content-collection
|
|
65
|
+
* entry, and Astro 6 remark all yield the same numbers.
|
|
66
|
+
*/
|
|
67
|
+
export declare function computeStamp(input: StampInput): Record<string, string> | null;
|
|
68
|
+
//# sourceMappingURL=stamp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamp.d.ts","sourceRoot":"","sources":["../../src/markdown/stamp.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAS3C,CAAC;AAEH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;CACZ;AAyBD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,EACjC,WAAW,EAAE,MAAM,GAClB,aAAa,GAAG,IAAI,CAetB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEzB;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,aAAa,CAKf;AAED,MAAM,WAAW,UAAU;IACzB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,OAAO,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC;IAClC,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,mEAAmE;IACnE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,8DAA8D;IAC9D,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,4EAA4E;IAC5E,MAAM,EAAE,OAAO,CAAC;IAChB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAmC7E"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared, pipeline-independent logic for stamping `data-caret-md` bindings.
|
|
3
|
+
*
|
|
4
|
+
* Two frontends drive this — a Sätteri mdast plugin (Astro 7) and a remark
|
|
5
|
+
* plugin (Astro 6) — walking their own trees but calling the SAME pure
|
|
6
|
+
* functions here so both emit byte-identical attributes (a parity test holds
|
|
7
|
+
* them together). Nothing in this module touches a tree or a pipeline type; it
|
|
8
|
+
* takes already-extracted node facts and returns attributes or `null`.
|
|
9
|
+
*/
|
|
10
|
+
import { COLLECTION_NAME_RE, ENTRY_ID_RE } from "../runtime/storage/id-contracts.js";
|
|
11
|
+
import { CARET_MD_ATTR, CARET_MD_SRC_ATTR, fnv1a32, formatBlockPath, formatMdBinding, formatMdSrc, } from "./contracts.js";
|
|
12
|
+
/**
|
|
13
|
+
* mdast node types that make their subtree non-editable: their inner text is
|
|
14
|
+
* either structured (tables), reference plumbing (footnote definitions), or
|
|
15
|
+
* raw/JSX passthrough that markdown block editing can't safely round-trip.
|
|
16
|
+
*/
|
|
17
|
+
export const ISLAND_TYPES = new Set([
|
|
18
|
+
"table",
|
|
19
|
+
"tableRow",
|
|
20
|
+
"tableCell",
|
|
21
|
+
"footnoteDefinition",
|
|
22
|
+
"html",
|
|
23
|
+
"mdxJsxFlowElement",
|
|
24
|
+
"mdxJsxTextElement",
|
|
25
|
+
"code",
|
|
26
|
+
]);
|
|
27
|
+
/** Normalize a file URL or path to a forward-slash filesystem path. */
|
|
28
|
+
function toPath(fileURL) {
|
|
29
|
+
if (fileURL == null)
|
|
30
|
+
return null;
|
|
31
|
+
let p = typeof fileURL === "string" ? fileURL : (fileURL.pathname ?? String(fileURL));
|
|
32
|
+
if (p.startsWith("file://")) {
|
|
33
|
+
try {
|
|
34
|
+
p = new URL(p).pathname;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
/* keep p */
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
p = decodeURIComponent(p);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
/* keep p */
|
|
45
|
+
}
|
|
46
|
+
return p.replace(/\\/g, "/");
|
|
47
|
+
}
|
|
48
|
+
function normalizeRoot(contentRoot) {
|
|
49
|
+
return contentRoot.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolve a source file to its `{collection, id}` under the content root, or
|
|
53
|
+
* `null`. v1 scope: flat `<contentRoot>/<collection>/<id>.md` only — `.mdx`,
|
|
54
|
+
* nested slugs, and identifiers failing the id grammar are intentionally
|
|
55
|
+
* unmatched (and so never stamped).
|
|
56
|
+
*/
|
|
57
|
+
export function resolveEntry(fileURL, contentRoot) {
|
|
58
|
+
const path = toPath(fileURL);
|
|
59
|
+
if (path === null)
|
|
60
|
+
return null;
|
|
61
|
+
const root = normalizeRoot(contentRoot);
|
|
62
|
+
if (!path.startsWith(`${root}/`))
|
|
63
|
+
return null;
|
|
64
|
+
const rel = path.slice(root.length + 1);
|
|
65
|
+
const segments = rel.split("/");
|
|
66
|
+
if (segments.length !== 2)
|
|
67
|
+
return null; // nested slugs are out of scope in v1
|
|
68
|
+
const [collection, filename] = segments;
|
|
69
|
+
if (!filename.endsWith(".md"))
|
|
70
|
+
return null; // .mdx stamped in a later version
|
|
71
|
+
const id = filename.slice(0, -".md".length);
|
|
72
|
+
if (!COLLECTION_NAME_RE.test(collection) || !ENTRY_ID_RE.test(id))
|
|
73
|
+
return null;
|
|
74
|
+
return { collection, id };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Decide how a paragraph maps to a bound element. A list item renders its text
|
|
78
|
+
* on the `<li>` (a tight list drops the `<p>` entirely), so we bind the item —
|
|
79
|
+
* via its FIRST paragraph, using that paragraph's marker-free offsets. Other
|
|
80
|
+
* paragraphs bind themselves; `nested` marks those inside a container.
|
|
81
|
+
*/
|
|
82
|
+
export function planParagraph(parentType, indexInParent) {
|
|
83
|
+
if (parentType === "listItem") {
|
|
84
|
+
return indexInParent === 0 ? { action: "parent" } : { action: "skip" };
|
|
85
|
+
}
|
|
86
|
+
return { action: "self", nested: parentType !== "root" };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Compute the `{data-caret-md, data-caret-md-src}` attributes for one block, or
|
|
90
|
+
* `null` to leave it unstamped. Offsets are normalized to the canonical body
|
|
91
|
+
* base (frontmatter-stripped, trimmed) so a `.md` import, a content-collection
|
|
92
|
+
* entry, and Astro 6 remark all yield the same numbers.
|
|
93
|
+
*/
|
|
94
|
+
export function computeStamp(input) {
|
|
95
|
+
const { source, start, end, blockPath, ancestorTypes, nested } = input;
|
|
96
|
+
if (start == null || end == null || start >= end || end > source.length)
|
|
97
|
+
return null;
|
|
98
|
+
const entry = resolveEntry(input.fileURL, input.contentRoot);
|
|
99
|
+
if (!entry)
|
|
100
|
+
return null;
|
|
101
|
+
if (ancestorTypes.some((t) => ISLAND_TYPES.has(t)))
|
|
102
|
+
return null;
|
|
103
|
+
const slice = source.slice(start, end);
|
|
104
|
+
// A container-nested block whose source spans lines embeds `> `/indent
|
|
105
|
+
// prefixes inside its range; splicing prefix-free text would corrupt it.
|
|
106
|
+
if (nested && slice.includes("\n"))
|
|
107
|
+
return null;
|
|
108
|
+
// Setext headings (`Title\n====`) are not editable in v1: the write path
|
|
109
|
+
// derives block context from the slice and only understands ATX markers, so
|
|
110
|
+
// an edit would silently demote the heading to a paragraph. Skip stamping.
|
|
111
|
+
if (input.blockType === "heading" && !slice.startsWith("#"))
|
|
112
|
+
return null;
|
|
113
|
+
const delta = source.length - source.trimStart().length;
|
|
114
|
+
const canonicalStart = start - delta;
|
|
115
|
+
const canonicalEnd = end - delta;
|
|
116
|
+
if (canonicalStart < 0)
|
|
117
|
+
return null;
|
|
118
|
+
return {
|
|
119
|
+
[CARET_MD_ATTR]: formatMdBinding({
|
|
120
|
+
collection: entry.collection,
|
|
121
|
+
id: entry.id,
|
|
122
|
+
blockPath: formatBlockPath(blockPath),
|
|
123
|
+
}),
|
|
124
|
+
[CARET_MD_SRC_ATTR]: formatMdSrc({
|
|
125
|
+
start: canonicalStart,
|
|
126
|
+
end: canonicalEnd,
|
|
127
|
+
hash: fnv1a32(slice),
|
|
128
|
+
}),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=stamp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamp.js","sourceRoot":"","sources":["../../src/markdown/stamp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GACtE,eAAe,CAcjB;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAChD,IAAI,CAWN;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,sCAAsC;AACtC,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GACtE,eAAe,CAcjB;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAChD,IAAI,CAWN;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,sCAAsC;AACtC,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAyB5D"}
|
|
@@ -54,6 +54,11 @@ export function extractRateLimitKey(request) {
|
|
|
54
54
|
// X-Forwarded-For per request to mint unlimited fresh buckets and bypass the
|
|
55
55
|
// brute-force limit entirely. When the proxy isn't trusted we fall back to a
|
|
56
56
|
// single shared "unknown" bucket — a coarser limit, but not spoofable.
|
|
57
|
+
//
|
|
58
|
+
// Tradeoff (C5): the shared bucket means one attacker's failed attempts also
|
|
59
|
+
// rate-limit legitimate logins during the window (a login DoS). Set
|
|
60
|
+
// CARET_TRUST_PROXY behind a proxy that sets a trustworthy client-IP header to
|
|
61
|
+
// get per-client buckets; leave it unset only when no such proxy exists.
|
|
57
62
|
if (isProxyTrusted()) {
|
|
58
63
|
const headers = request.headers;
|
|
59
64
|
const candidates = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../../src/runtime/auth/rate-limiter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../../src/runtime/auth/rate-limiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,10 +13,10 @@ type CookieBagLike = {
|
|
|
13
13
|
export declare function isEditorAuthenticated(context: CookieBagLike): boolean;
|
|
14
14
|
/**
|
|
15
15
|
* The per-editor id carried by the session cookie, used to key a draft overlay.
|
|
16
|
-
* Returns null when the request has no valid editor session
|
|
17
|
-
*
|
|
18
|
-
* are keyed by their own `sessionId`.
|
|
16
|
+
* Returns null when the request has no valid editor session. Does NOT consider
|
|
17
|
+
* demo sessions — those are keyed by their own `sessionId`.
|
|
19
18
|
*/
|
|
20
19
|
export declare function getEditorId(context: CookieBagLike): string | null;
|
|
20
|
+
export declare function getEditorIdentity(context: CookieBagLike): import("../../types.js").EditorIdentity | null;
|
|
21
21
|
export {};
|
|
22
22
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/session.ts"],"names":[],"mappings":"AAoFA,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAgID,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAWhE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,SAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAS9E;AAED,wBAAgB,wBAAwB,CAAC,IAAI,SAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAE9E;AAED,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED,KAAK,aAAa,GAAG;IACnB,OAAO,CAAC,EAAE;QACR,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC;KACtD,CAAC;CACH,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAerE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAOjE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,gBAAgB,EAAE,cAAc,GAAG,IAAI,CAKxG"}
|
|
@@ -1,12 +1,38 @@
|
|
|
1
1
|
import { createHmac, randomUUID, timingSafeEqual } from "crypto";
|
|
2
2
|
import { shouldUseSecureCookies } from "./cookie-utils.js";
|
|
3
3
|
import { getRequestContext } from "../request-context.js";
|
|
4
|
+
/**
|
|
5
|
+
* Read an env var from any available source. Node hosts populate `process.env`;
|
|
6
|
+
* Cloudflare Workers inject bindings via `context.locals.runtime.env`, which the
|
|
7
|
+
* middleware exposes on the request context. Process env wins when both are set.
|
|
8
|
+
*/
|
|
9
|
+
function readEnv(key) {
|
|
10
|
+
const fromProcess = typeof process !== "undefined" ? process.env?.[key] : undefined;
|
|
11
|
+
if (typeof fromProcess === "string" && fromProcess.length > 0)
|
|
12
|
+
return fromProcess;
|
|
13
|
+
const runtimeEnv = getRequestContext()?.runtimeEnv;
|
|
14
|
+
const fromRuntime = runtimeEnv?.[key];
|
|
15
|
+
return typeof fromRuntime === "string" ? fromRuntime : undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* True in a dev context, where the public fallback session secret is acceptable
|
|
19
|
+
* (zero-config `astro dev`). The build-time define is authoritative; when it is
|
|
20
|
+
* absent (unit tests, direct imports) we fall back to NODE_ENV, defaulting to
|
|
21
|
+
* dev unless it is explicitly "production". A production build bakes the define
|
|
22
|
+
* to `false`, so the fallback secret is refused regardless of NODE_ENV.
|
|
23
|
+
*/
|
|
24
|
+
function isDevContext() {
|
|
25
|
+
if (typeof __ASTRO_CARET_DEV__ === "boolean")
|
|
26
|
+
return __ASTRO_CARET_DEV__;
|
|
27
|
+
const nodeEnv = typeof process !== "undefined" ? process.env?.NODE_ENV : undefined;
|
|
28
|
+
return nodeEnv !== "production";
|
|
29
|
+
}
|
|
4
30
|
const SESSION_COOKIE_NAME = "caret_session";
|
|
5
31
|
const SESSION_TTL_SECONDS = 60 * 60 * 12;
|
|
6
32
|
const DEV_SECRET_FALLBACK = "caretcms-dev-secret";
|
|
7
33
|
let devSecretWarned = false;
|
|
8
34
|
function getConfiguredEditorPassword() {
|
|
9
|
-
const value =
|
|
35
|
+
const value = readEnv("CARET_EDIT_PASSWORD") ?? readEnv("EDIT_PASSWORD") ?? "";
|
|
10
36
|
return value.trim().length > 0 ? value : null;
|
|
11
37
|
}
|
|
12
38
|
// During `astro dev`, the integration generates a throwaway password and exposes
|
|
@@ -30,25 +56,30 @@ export function isDevEditorPasswordActive() {
|
|
|
30
56
|
return getConfiguredEditorPassword() === null && getDevFallbackPassword() !== null;
|
|
31
57
|
}
|
|
32
58
|
function getSessionSecret() {
|
|
33
|
-
const configured =
|
|
59
|
+
const configured = readEnv("CARET_SESSION_SECRET");
|
|
34
60
|
if (configured && configured.trim().length > 0)
|
|
35
61
|
return configured;
|
|
36
|
-
// No secret configured.
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
|
|
62
|
+
// No secret configured. The public fallback is a known constant, so any token
|
|
63
|
+
// signed with it is forgeable — it is ONLY safe in a dev context. A production
|
|
64
|
+
// build refuses it and fails closed, regardless of whether a password is set:
|
|
65
|
+
// - no password → the editor is meant to be locked; minting a session signed
|
|
66
|
+
// with a public secret would make that "locked" state fully writable (S1).
|
|
67
|
+
// - password set → the operator must supply a real secret.
|
|
68
|
+
// In both cases we throw here; `trySignPayload` catches it so verification just
|
|
69
|
+
// returns "not an editor" rather than 500-ing every request.
|
|
70
|
+
if (isDevContext()) {
|
|
71
|
+
// Warn only once, and only when a real password is configured — that's the
|
|
72
|
+
// "you set a password, now set a secret" nudge. Zero-config dev (no password)
|
|
73
|
+
// stays silent.
|
|
74
|
+
if (getConfiguredEditorPassword() !== null && !devSecretWarned) {
|
|
75
|
+
devSecretWarned = true;
|
|
76
|
+
console.warn("[caretcms] CARET_SESSION_SECRET is unset; using a public dev fallback. " +
|
|
77
|
+
"Set CARET_SESSION_SECRET before exposing this site to the network.");
|
|
78
|
+
}
|
|
41
79
|
return DEV_SECRET_FALLBACK;
|
|
42
|
-
if (process.env.NODE_ENV === "production") {
|
|
43
|
-
throw new Error("[caretcms] CARET_SESSION_SECRET is required in production when CARET_EDIT_PASSWORD is set. " +
|
|
44
|
-
"Generate one with `openssl rand -base64 32` and set it in your environment.");
|
|
45
|
-
}
|
|
46
|
-
if (!devSecretWarned) {
|
|
47
|
-
devSecretWarned = true;
|
|
48
|
-
console.warn("[caretcms] CARET_SESSION_SECRET is unset; using a public dev fallback. " +
|
|
49
|
-
"Set CARET_SESSION_SECRET before exposing this site to the network.");
|
|
50
80
|
}
|
|
51
|
-
|
|
81
|
+
throw new Error("[caretcms] CARET_SESSION_SECRET is required in production. " +
|
|
82
|
+
"Generate one with `openssl rand -base64 32` and set it in your environment.");
|
|
52
83
|
}
|
|
53
84
|
function signPayload(payloadB64) {
|
|
54
85
|
return createHmac("sha256", getSessionSecret()).update(payloadB64).digest("base64url");
|
|
@@ -126,8 +157,9 @@ function parseToken(token) {
|
|
|
126
157
|
return null;
|
|
127
158
|
if (payload.exp <= Date.now())
|
|
128
159
|
return null;
|
|
129
|
-
//
|
|
130
|
-
|
|
160
|
+
// Every editor session carries an id (keys the draft overlay). Reject a
|
|
161
|
+
// token that lacks a valid one — this also rejects any pre-editorId token.
|
|
162
|
+
if (typeof payload.editorId !== "string" || payload.editorId === "")
|
|
131
163
|
return null;
|
|
132
164
|
return payload;
|
|
133
165
|
}
|
|
@@ -169,6 +201,10 @@ export function isEditorAuthenticated(context) {
|
|
|
169
201
|
const ctx = getRequestContext();
|
|
170
202
|
if (ctx?.demoMode && ctx.sessionId && ctx.overlayActive)
|
|
171
203
|
return true;
|
|
204
|
+
if (ctx?.identity)
|
|
205
|
+
return true;
|
|
206
|
+
if (ctx?.identityAuthoritative)
|
|
207
|
+
return false;
|
|
172
208
|
const token = context.cookies?.get(SESSION_COOKIE_NAME)?.value;
|
|
173
209
|
if (!token)
|
|
174
210
|
return false;
|
|
@@ -176,14 +212,25 @@ export function isEditorAuthenticated(context) {
|
|
|
176
212
|
}
|
|
177
213
|
/**
|
|
178
214
|
* The per-editor id carried by the session cookie, used to key a draft overlay.
|
|
179
|
-
* Returns null when the request has no valid editor session
|
|
180
|
-
*
|
|
181
|
-
* are keyed by their own `sessionId`.
|
|
215
|
+
* Returns null when the request has no valid editor session. Does NOT consider
|
|
216
|
+
* demo sessions — those are keyed by their own `sessionId`.
|
|
182
217
|
*/
|
|
183
218
|
export function getEditorId(context) {
|
|
219
|
+
const externalId = getRequestContext()?.identity?.id;
|
|
220
|
+
if (externalId)
|
|
221
|
+
return externalId;
|
|
222
|
+
if (getRequestContext()?.identityAuthoritative)
|
|
223
|
+
return null;
|
|
184
224
|
const token = context.cookies?.get(SESSION_COOKIE_NAME)?.value;
|
|
185
225
|
if (!token)
|
|
186
226
|
return null;
|
|
187
227
|
return parseToken(token)?.editorId ?? null;
|
|
188
228
|
}
|
|
229
|
+
export function getEditorIdentity(context) {
|
|
230
|
+
const external = getRequestContext()?.identity;
|
|
231
|
+
if (external)
|
|
232
|
+
return external;
|
|
233
|
+
const editorId = getEditorId(context);
|
|
234
|
+
return editorId ? { id: editorId } : null;
|
|
235
|
+
}
|
|
189
236
|
//# sourceMappingURL=session.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/runtime/auth/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/runtime/auth/session.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CaretMode } from "../types.js";
|
|
2
|
+
import { type ResolvedStudioDictionary, type StudioLocale } from "./i18n.js";
|
|
2
3
|
export type CaretBrandConfig = {
|
|
3
4
|
name: string;
|
|
4
5
|
logo: string | null;
|
|
@@ -15,6 +16,8 @@ export type CaretRuntimeConfig = {
|
|
|
15
16
|
mode: CaretMode;
|
|
16
17
|
theme: CaretThemeConfig;
|
|
17
18
|
brand: CaretBrandConfig;
|
|
19
|
+
locale: StudioLocale;
|
|
20
|
+
messages: ResolvedStudioDictionary;
|
|
18
21
|
};
|
|
19
22
|
export declare function normalizePath(input: string | undefined, fallback: string): string;
|
|
20
23
|
export declare function getRuntimeConfig(): CaretRuntimeConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/runtime/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/runtime/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAA2B,KAAK,wBAAwB,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAWtG,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,gBAAgB,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,wBAAwB,CAAC;CACpC,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASjF;AAsBD,wBAAgB,gBAAgB,IAAI,kBAAkB,CAoBrD"}
|
package/dist/runtime/config.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveStudioDictionary } from "./i18n.js";
|
|
1
2
|
export function normalizePath(input, fallback) {
|
|
2
3
|
if (!input)
|
|
3
4
|
return fallback;
|
|
@@ -36,6 +37,8 @@ export function getRuntimeConfig() {
|
|
|
36
37
|
const mode = (__ASTRO_CARET_MODE__ ?? "embedded");
|
|
37
38
|
const theme = safeParse(__ASTRO_CARET_THEME_CONFIG__, DEFAULT_THEME);
|
|
38
39
|
const brand = safeParse(__ASTRO_CARET_BRAND_CONFIG__, DEFAULT_BRAND);
|
|
39
|
-
|
|
40
|
+
const locale = (__ASTRO_CARET_LOCALE__ === "es" ? "es" : "en");
|
|
41
|
+
const messages = safeParse(__ASTRO_CARET_DICTIONARY__, resolveStudioDictionary(locale));
|
|
42
|
+
return { mountPath, apiBasePath, editorHome, mode, theme, brand, locale, messages };
|
|
40
43
|
}
|
|
41
44
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/runtime/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/runtime/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAoD,MAAM,WAAW,CAAC;AAiCtG,MAAM,UAAU,aAAa,CAAC,KAAyB,EAAE,QAAgB;IACvE,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC;IAC3E,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,SAAS,SAAS,CAAI,GAAuB,EAAE,QAAW;IACxD,IAAI,CAAC,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,aAAa,GAAqB;IACtC,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF,MAAM,aAAa,GAAqB;IACtC,QAAQ,EAAE,IAAI;IACd,cAAc,EAAE,EAAE;CACnB,CAAC;AAEF,MAAM,UAAU,gBAAgB;IAC9B,MAAM,SAAS,GAAG,aAAa,CAAC,0BAA0B,EAAE,QAAQ,CAAC,CAAC;IACtE,MAAM,WAAW,GAAG,aAAa,CAAC,6BAA6B,EAAE,UAAU,CAAC,CAAC;IAC7E,MAAM,UAAU,GAAG,aAAa,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,CAAC,oBAAoB,IAAI,UAAU,CAAc,CAAC;IAC/D,MAAM,KAAK,GAAG,SAAS,CACrB,4BAA4B,EAC5B,aAAa,CACd,CAAC;IACF,MAAM,KAAK,GAAG,SAAS,CACrB,4BAA4B,EAC5B,aAAa,CACd,CAAC;IACF,MAAM,MAAM,GAAG,CAAC,sBAAsB,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAiB,CAAC;IAC/E,MAAM,QAAQ,GAAG,SAAS,CACxB,0BAA0B,EAC1B,uBAAuB,CAAC,MAAM,CAAC,CAChC,CAAC;IAEF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AACtF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/runtime/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/runtime/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAIzC;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAI7E;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAGzD"}
|
package/dist/runtime/content.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* const posts = await loadCollection('posts')
|
|
10
10
|
*/
|
|
11
11
|
import { requireRequestContext } from "./request-context.js";
|
|
12
|
+
import { stripBodyOverlay } from "./utils.js";
|
|
12
13
|
/**
|
|
13
14
|
* Load a single entry by collection and id.
|
|
14
15
|
* Returns the entry data, or null if not found.
|
|
@@ -16,7 +17,7 @@ import { requireRequestContext } from "./request-context.js";
|
|
|
16
17
|
export async function loadEntry(collection, id) {
|
|
17
18
|
const { adapter } = requireRequestContext();
|
|
18
19
|
const entry = await adapter.getEntry(collection, id);
|
|
19
|
-
return entry
|
|
20
|
+
return entry ? stripBodyOverlay(entry.data) : null;
|
|
20
21
|
}
|
|
21
22
|
/**
|
|
22
23
|
* Load all entries in a collection.
|
|
@@ -24,7 +25,8 @@ export async function loadEntry(collection, id) {
|
|
|
24
25
|
*/
|
|
25
26
|
export async function loadCollection(collection) {
|
|
26
27
|
const { adapter } = requireRequestContext();
|
|
27
|
-
|
|
28
|
+
const entries = await adapter.listEntries(collection);
|
|
29
|
+
return entries.map((entry) => ({ ...entry, data: stripBodyOverlay(entry.data) }));
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
30
32
|
* Discover all collection names.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/runtime/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/runtime/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAI9C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,UAAkB,EAClB,EAAU;IAEV,MAAM,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB;IACrD,MAAM,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACpF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAC5C,OAAO,OAAO,CAAC,mBAAmB,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export declare const EN_STUDIO_MESSAGES: {
|
|
2
|
+
readonly "nav.studio": "Studio";
|
|
3
|
+
readonly "nav.signOut": "Sign out";
|
|
4
|
+
readonly "home.title": "Content Studio";
|
|
5
|
+
readonly "home.intro": "Manage your collections and entries.";
|
|
6
|
+
readonly "home.empty": "No collections yet. Create one from Studio, edit any data-caret element on your site, or run npx @caretcms/caretize to make existing pages editable.";
|
|
7
|
+
readonly "count.entry": "entry";
|
|
8
|
+
readonly "count.entries": "entries";
|
|
9
|
+
readonly "common.error": "Error";
|
|
10
|
+
readonly "common.loading": "Loading…";
|
|
11
|
+
readonly "common.close": "Close";
|
|
12
|
+
readonly "common.cancel": "Cancel";
|
|
13
|
+
readonly "common.retry": "Retry";
|
|
14
|
+
readonly "common.saving": "Saving…";
|
|
15
|
+
readonly "collection.search": "Search";
|
|
16
|
+
readonly "collection.searchPlaceholder": "Search entries…";
|
|
17
|
+
readonly "collection.reorder": "Reorder";
|
|
18
|
+
readonly "collection.reordering": "Reordering…";
|
|
19
|
+
readonly "collection.new": "+ New";
|
|
20
|
+
readonly "collection.noEntries": "No entries yet.";
|
|
21
|
+
readonly "collection.createFirst": "Create First Entry";
|
|
22
|
+
readonly "collection.failed": "Failed to load entries.";
|
|
23
|
+
readonly "collection.saveOrder": "Save Order";
|
|
24
|
+
readonly "collection.newEntry": "New Entry";
|
|
25
|
+
readonly "collection.entryId": "Entry ID (slug)";
|
|
26
|
+
readonly "collection.entryIdPlaceholder": "e.g. my-first-entry";
|
|
27
|
+
readonly "collection.idHint": "Use a permanent internal address such as quiet-structures. Lowercase letters, numbers, and hyphens only.";
|
|
28
|
+
readonly "collection.publishHint": "You’ll add the content on the next screen. Collections with a Published switch remain hidden until you turn it on and Save.";
|
|
29
|
+
readonly "collection.create": "Create";
|
|
30
|
+
readonly "collection.untitled": "Untitled";
|
|
31
|
+
readonly "collection.published": "Published";
|
|
32
|
+
readonly "collection.unpublished": "Unpublished";
|
|
33
|
+
readonly "collection.invalid": "Invalid stored data — open to repair";
|
|
34
|
+
readonly "collection.invalidId": "Use lowercase letters, numbers, and hyphens only.";
|
|
35
|
+
readonly "collection.duplicateId": "An entry with this ID already exists.";
|
|
36
|
+
readonly "collection.createFailed": "Failed to create entry. Try again.";
|
|
37
|
+
readonly "entry.notFound": "Entry not found.";
|
|
38
|
+
readonly "entry.goBack": "Go back";
|
|
39
|
+
readonly "entry.savingLive": "Saving live";
|
|
40
|
+
readonly "entry.savingPreview": "Saving to private preview";
|
|
41
|
+
readonly "entry.preview": "Preview site ↗";
|
|
42
|
+
readonly "entry.history": "History";
|
|
43
|
+
readonly "entry.delete": "Delete";
|
|
44
|
+
readonly "entry.saveLive": "Save live";
|
|
45
|
+
readonly "entry.saveDraft": "Save draft";
|
|
46
|
+
readonly "entry.guideTitle": "How editing works";
|
|
47
|
+
readonly "entry.guideCopy": "Edit any field, add or remove repeatable rows, then choose Save. In the sidebar Studio, text and image edits preview on the page as you work; Save confirms them and refreshes the visual preview for structural changes. Click an image preview to replace it, or paste an image URL. The Published switch controls whether signed-out visitors can see an entry.";
|
|
48
|
+
readonly "entry.versionHistory": "Version History";
|
|
49
|
+
readonly "entry.deleteTitle": "Delete Entry";
|
|
50
|
+
readonly "entry.deleteCopy": "Permanently delete this entry? A snapshot will be saved to history for recovery.";
|
|
51
|
+
readonly "entry.allSaved": "All changes saved";
|
|
52
|
+
readonly "entry.unsaved": "Unsaved changes";
|
|
53
|
+
readonly "entry.savingChanges": "Saving changes…";
|
|
54
|
+
readonly "entry.saved": "Saved";
|
|
55
|
+
readonly "entry.liveConfirm": "Save these changes directly to the live site?";
|
|
56
|
+
readonly "entry.validationFailed": "Validation failed";
|
|
57
|
+
readonly "entry.changedElsewhere": "Changed elsewhere — Save again to overwrite";
|
|
58
|
+
readonly "entry.deleteFailed": "Delete failed";
|
|
59
|
+
readonly "entry.deleting": "Deleting…";
|
|
60
|
+
readonly "entry.newGuideTitle": "Entry created with safe defaults";
|
|
61
|
+
readonly "entry.newGuideCopy": "Fill in the fields below. Save becomes available after your first change. In the sidebar Studio, text and image edits preview on the page as you work; Save confirms them and refreshes the visual preview for structural changes. The Published switch controls whether signed-out visitors can see this entry.";
|
|
62
|
+
readonly "field.add": "Add";
|
|
63
|
+
readonly "field.remove": "Remove";
|
|
64
|
+
readonly "field.moveUp": "Move up";
|
|
65
|
+
readonly "field.moveDown": "Move down";
|
|
66
|
+
readonly "field.drag": "Drag to reorder";
|
|
67
|
+
readonly "field.replaceImage": "Replace image";
|
|
68
|
+
readonly "field.uploadOrReplaceImage": "Upload or replace image";
|
|
69
|
+
readonly "field.chooseImage": "Choose an image";
|
|
70
|
+
readonly "login.title": "Sign in";
|
|
71
|
+
readonly "login.password": "Password";
|
|
72
|
+
readonly "login.placeholder": "Enter editor password";
|
|
73
|
+
readonly "login.submit": "Sign in";
|
|
74
|
+
readonly "login.invalid": "Invalid password.";
|
|
75
|
+
readonly "login.status": "Sign in to manage content.";
|
|
76
|
+
readonly "login.noPassword": "Caret needs an editor password before you can sign in.";
|
|
77
|
+
readonly "login.devPassword": "Temporary dev password active — check your terminal to sign in.";
|
|
78
|
+
readonly "login.back": "← Back to site";
|
|
79
|
+
readonly "login.failed": "Login failed";
|
|
80
|
+
};
|
|
81
|
+
export type StudioMessageKey = keyof typeof EN_STUDIO_MESSAGES;
|
|
82
|
+
export type StudioLocale = "en" | "es";
|
|
83
|
+
export type StudioDictionary = Partial<Record<StudioMessageKey, string>>;
|
|
84
|
+
export type ResolvedStudioDictionary = Record<StudioMessageKey, string>;
|
|
85
|
+
export declare function resolveStudioDictionary(locale?: StudioLocale, overrides?: StudioDictionary): ResolvedStudioDictionary;
|
|
86
|
+
//# sourceMappingURL=i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/runtime/i18n.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+ErB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAC/D,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC;AACvC,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;AACzE,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AAmFxE,wBAAgB,uBAAuB,CACrC,MAAM,GAAE,YAAmB,EAC3B,SAAS,GAAE,gBAAqB,GAC/B,wBAAwB,CAM1B"}
|