@levo-so/site-runtime 0.2.0 → 0.2.2
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/CollectionInput-5QMoXahu.js +147 -0
- package/DateTimeWidget-CARoq7bQ.js +254 -0
- package/PhoneWidget-vtDO9CFq.js +99 -0
- package/Popover-B76-bN-a.js +57 -0
- package/RichTextWidget-CafZBEKI.js +912 -0
- package/ThemeProvider-Cm2jJC7a.js +381 -0
- package/Tooltip-Bx-BfR7T.js +78 -0
- package/VerifyButton-D1Mwk04d.js +299 -0
- package/index.d.ts +687 -0
- package/index.js +5782 -0
- package/package.json +63 -31
- package/styles.css +2 -0
- package/README.md +0 -93
- package/dist/LevoSiteProvider.d.ts +0 -25
- package/dist/LevoSiteProvider.js +0 -23
- package/dist/client.d.ts +0 -26
- package/dist/client.js +0 -14
- package/dist/data/index.d.ts +0 -105
- package/dist/data/index.js +0 -81
- package/dist/index.d.ts +0 -28
- package/dist/index.js +0 -7
- package/dist/inspector/dom.d.ts +0 -56
- package/dist/inspector/dom.js +0 -224
- package/dist/inspector/editorChannel.d.ts +0 -7
- package/dist/inspector/editorChannel.js +0 -19
- package/dist/inspector/historyWatcher.d.ts +0 -8
- package/dist/inspector/historyWatcher.js +0 -24
- package/dist/inspector/index.d.ts +0 -2
- package/dist/inspector/index.js +0 -191
- package/dist/inspector/messageRouter.d.ts +0 -38
- package/dist/inspector/messageRouter.js +0 -134
- package/dist/inspector/originalsStash.d.ts +0 -12
- package/dist/inspector/originalsStash.js +0 -24
- package/dist/inspector/protocol.d.ts +0 -180
- package/dist/inspector/stagedOverrides.d.ts +0 -28
- package/dist/inspector/stagedOverrides.js +0 -60
- package/dist/inspector/textEditController.d.ts +0 -24
- package/dist/inspector/textEditController.js +0 -62
- package/dist/pageHead.d.ts +0 -77
- package/dist/pageHead.js +0 -105
- package/dist/scaffold.d.ts +0 -110
- package/dist/scaffold.js +0 -64
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { IEditorChannel } from './editorChannel';
|
|
2
|
-
import { IOriginalsStash } from './originalsStash';
|
|
3
|
-
export type ITextEditController = ReturnType<typeof createTextEditController>;
|
|
4
|
-
export declare const createTextEditController: (deps: {
|
|
5
|
-
channel: IEditorChannel;
|
|
6
|
-
originals: IOriginalsStash;
|
|
7
|
-
/**
|
|
8
|
-
* Drop the text-mode hover affordance (outline + tracked hover target). Cursor is NOT
|
|
9
|
-
* reset here — the pointer tracker owns it (hovering the edited node clears it there).
|
|
10
|
-
*/
|
|
11
|
-
clearTextHover: () => void;
|
|
12
|
-
}) => {
|
|
13
|
-
startEdit: (el: Element, caretAtEnd?: boolean) => void;
|
|
14
|
-
/** The node currently in contenteditable, or null — read by hover/click/staged logic. */
|
|
15
|
-
editingNode: () => Element | null;
|
|
16
|
-
/** Commit any in-flight edit (mode exit, defensive re-entry). No-op when idle. */
|
|
17
|
-
commitIfEditing: () => void;
|
|
18
|
-
/**
|
|
19
|
-
* Teardown for unmount: end any in-flight edit WITHOUT committing (no report on
|
|
20
|
-
* teardown — matches the original closure's cleanup, which called endEdit directly).
|
|
21
|
-
*/
|
|
22
|
-
teardown: () => void;
|
|
23
|
-
};
|
|
24
|
-
//# sourceMappingURL=textEditController.d.ts.map
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { COLOR as e, nodesForSource as t, sourceIndex as n, sourceOf as r } from "./dom.js";
|
|
2
|
-
//#region src/inspector/textEditController.ts
|
|
3
|
-
var i = (i) => {
|
|
4
|
-
let { channel: a, originals: o, clearTextHover: s } = i, c = null, l = "", u = 0, d = (() => {
|
|
5
|
-
try {
|
|
6
|
-
let e = document.createElement("div");
|
|
7
|
-
return e.setAttribute("contenteditable", "plaintext-only"), e.contentEditable === "plaintext-only";
|
|
8
|
-
} catch {
|
|
9
|
-
return !1;
|
|
10
|
-
}
|
|
11
|
-
})(), f = () => {
|
|
12
|
-
c && _(c);
|
|
13
|
-
}, p = (e) => {
|
|
14
|
-
e.key === "Enter" ? (e.preventDefault(), c && _(c)) : e.key === "Escape" && (e.preventDefault(), c && v(c));
|
|
15
|
-
}, m = (e) => {
|
|
16
|
-
let t = window.getSelection();
|
|
17
|
-
if (!t) return;
|
|
18
|
-
let n = document.createRange();
|
|
19
|
-
n.selectNodeContents(e), n.collapse(!1), t.removeAllRanges(), t.addRange(n);
|
|
20
|
-
}, h = (t, i = !1) => {
|
|
21
|
-
if (c === t) return;
|
|
22
|
-
c && _(c), c = t, l = r(t) || "", u = n(t, l), s(), o.capture(`${l}#${u}`, t.textContent ?? ""), t.setAttribute("contenteditable", d ? "plaintext-only" : "true");
|
|
23
|
-
let a = t;
|
|
24
|
-
a.style.outline = `2px solid ${e.hover}`, a.style.outlineOffset = "3px", a.style.borderRadius = "3px", a.focus(), i && m(t), a.addEventListener("blur", f, !0), a.addEventListener("keydown", p, !0);
|
|
25
|
-
}, g = (e) => {
|
|
26
|
-
e.removeAttribute("contenteditable");
|
|
27
|
-
let t = e;
|
|
28
|
-
t.style.outline = "", t.style.outlineOffset = "", t.style.borderRadius = "", t.removeEventListener("blur", f, !0), t.removeEventListener("keydown", p, !0), c = null;
|
|
29
|
-
}, _ = (e) => {
|
|
30
|
-
let n = r(e), i = u, s = o.get(`${l}#${u}`);
|
|
31
|
-
g(e);
|
|
32
|
-
let c = (e.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
33
|
-
a.send({
|
|
34
|
-
type: "element-text-changed",
|
|
35
|
-
element: {
|
|
36
|
-
source: n,
|
|
37
|
-
index: i,
|
|
38
|
-
tag: e.tagName.toLowerCase(),
|
|
39
|
-
value: c,
|
|
40
|
-
previous: s,
|
|
41
|
-
occurrences: n ? t(n).length : 1
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
}, v = (e) => {
|
|
45
|
-
let t = `${l}#${u}`;
|
|
46
|
-
g(e);
|
|
47
|
-
let n = o.restore(t);
|
|
48
|
-
n != null && (e.textContent = n);
|
|
49
|
-
};
|
|
50
|
-
return {
|
|
51
|
-
startEdit: h,
|
|
52
|
-
editingNode: () => c,
|
|
53
|
-
commitIfEditing: () => {
|
|
54
|
-
c && _(c);
|
|
55
|
-
},
|
|
56
|
-
teardown: () => {
|
|
57
|
-
c && g(c);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
|
-
//#endregion
|
|
62
|
-
export { i as createTextEditController };
|
package/dist/pageHead.d.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/** One page's head metadata. Every field optional — site defaults fill gaps per-field. */
|
|
2
|
-
export interface IPageMeta {
|
|
3
|
-
title?: string;
|
|
4
|
-
description?: string;
|
|
5
|
-
/** Absolute URL. Rendered as `<link rel="canonical">`. */
|
|
6
|
-
canonical?: string;
|
|
7
|
-
/** e.g. "index,follow" / "noindex,nofollow". */
|
|
8
|
-
robots?: string;
|
|
9
|
-
og?: {
|
|
10
|
-
title?: string;
|
|
11
|
-
description?: string;
|
|
12
|
-
image?: string;
|
|
13
|
-
/** Absolute share URL. Falls back to `canonical` when unset. */
|
|
14
|
-
url?: string;
|
|
15
|
-
/** Defaults to "website" when any og field is present. */
|
|
16
|
-
type?: string;
|
|
17
|
-
};
|
|
18
|
-
twitter?: {
|
|
19
|
-
/** Defaults to "summary_large_image" when any twitter field is present. */
|
|
20
|
-
card?: string;
|
|
21
|
-
title?: string;
|
|
22
|
-
description?: string;
|
|
23
|
-
image?: string;
|
|
24
|
-
};
|
|
25
|
-
/** JSON-LD object(s) — each becomes a `<script type="application/ld+json">`. */
|
|
26
|
-
ldJson?: Record<string, unknown> | Array<Record<string, unknown>>;
|
|
27
|
-
/**
|
|
28
|
-
* Raw head snippet for THIS page. v1 supports `<script>`, `<meta>` and `<link>` tags
|
|
29
|
-
* only (the analytics / verification / preload cases) — anything else is dropped by
|
|
30
|
-
* `parseRawHead`, since arbitrary markup can't be expressed as document metadata.
|
|
31
|
-
*/
|
|
32
|
-
customHead?: string;
|
|
33
|
-
}
|
|
34
|
-
/** Site-wide defaults + site-wide raw head, from `src/pages/_site.meta.ts`. */
|
|
35
|
-
export interface ISiteMeta extends IPageMeta {
|
|
36
|
-
/** "%s · Acme" — %s is the page title. Applied only when the page provides a title. */
|
|
37
|
-
titleTemplate?: string;
|
|
38
|
-
}
|
|
39
|
-
interface IHeadEntry {
|
|
40
|
-
[attr: string]: string | undefined;
|
|
41
|
-
}
|
|
42
|
-
export interface IComposedHead {
|
|
43
|
-
meta: IHeadEntry[];
|
|
44
|
-
links: IHeadEntry[];
|
|
45
|
-
scripts: IHeadEntry[];
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Tolerant extraction of `<script>` / `<meta>` / `<link>` tags from a raw head snippet.
|
|
49
|
-
* Unsupported tags are DROPPED (documented v1 limitation) — silently at runtime; the
|
|
50
|
-
* editor warns at save time.
|
|
51
|
-
*/
|
|
52
|
-
export declare const parseRawHead: (raw: string) => IComposedHead;
|
|
53
|
-
/**
|
|
54
|
-
* Compose one page's document metadata from its sidecar + the site defaults. Page
|
|
55
|
-
* values win per-FIELD (an empty page og.title still inherits the site og.title).
|
|
56
|
-
* The object shape doubles as a TanStack Start route `head()` result for when the
|
|
57
|
-
* scaffold wires routes directly.
|
|
58
|
-
*/
|
|
59
|
-
export declare const pageHead: (meta?: IPageMeta, site?: ISiteMeta) => IComposedHead;
|
|
60
|
-
/**
|
|
61
|
-
* Renders a page's metadata as document tags. Pages include it anywhere in their JSX —
|
|
62
|
-
* React 19 hoists <title>/<meta>/<link> into <head> (SSR too); scripts render in place
|
|
63
|
-
* (see the file header caveat). The studio wires this automatically on a page's first
|
|
64
|
-
* meta save:
|
|
65
|
-
*
|
|
66
|
-
* import meta from "./about.meta";
|
|
67
|
-
* import siteMeta from "./_site.meta";
|
|
68
|
-
* import { PageHead } from "../lib/pageHead";
|
|
69
|
-
* …
|
|
70
|
-
* <PageHead meta={meta} site={siteMeta} />
|
|
71
|
-
*/
|
|
72
|
-
export declare function PageHead({ meta, site }: {
|
|
73
|
-
meta?: IPageMeta;
|
|
74
|
-
site?: ISiteMeta;
|
|
75
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
76
|
-
export {};
|
|
77
|
-
//# sourceMappingURL=pageHead.d.ts.map
|
package/dist/pageHead.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { Fragment as e, jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
2
|
-
//#region src/pageHead.tsx
|
|
3
|
-
var r = (e) => JSON.stringify(e).replace(/<\//g, "<\\/"), i = (e) => {
|
|
4
|
-
let t = {}, n = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*("([^"]*)"|'([^']*)'|[^\s"'>]+))?/g;
|
|
5
|
-
for (let r = n.exec(e); r; r = n.exec(e)) {
|
|
6
|
-
let e = r[1];
|
|
7
|
-
!e || /^on/i.test(e) || (t[e] = r[3] ?? r[4] ?? (r[2] ? r[2] : ""));
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
}, a = (e) => {
|
|
11
|
-
let t = {
|
|
12
|
-
meta: [],
|
|
13
|
-
links: [],
|
|
14
|
-
scripts: []
|
|
15
|
-
};
|
|
16
|
-
if (!e?.trim()) return t;
|
|
17
|
-
let n = e.replace(/<script\b([^>]*)>([\s\S]*?)<\/script\s*>/gi, (e, n, r) => {
|
|
18
|
-
let a = i(n), o = r.trim();
|
|
19
|
-
return o && (a.children = o), t.scripts.push(a), "";
|
|
20
|
-
});
|
|
21
|
-
return n = n.replace(/<(meta|link)\b([^>]*?)\/?>/gi, (e, n, r) => ((n.toLowerCase() === "meta" ? t.meta : t.links).push(i(r)), "")), t;
|
|
22
|
-
}, o = (e = {}, t = {}) => {
|
|
23
|
-
let n = {
|
|
24
|
-
meta: [],
|
|
25
|
-
links: [],
|
|
26
|
-
scripts: []
|
|
27
|
-
}, i = e.title?.trim(), o = t.title?.trim(), s = t.titleTemplate?.includes("%s") ? t.titleTemplate : void 0, c = i ? s ? s.replace("%s", i) : i : o;
|
|
28
|
-
c && n.meta.push({ title: c });
|
|
29
|
-
let l = e.description ?? t.description;
|
|
30
|
-
l && n.meta.push({
|
|
31
|
-
name: "description",
|
|
32
|
-
content: l
|
|
33
|
-
});
|
|
34
|
-
let u = e.robots ?? t.robots;
|
|
35
|
-
u && n.meta.push({
|
|
36
|
-
name: "robots",
|
|
37
|
-
content: u
|
|
38
|
-
});
|
|
39
|
-
let d = e.canonical ?? t.canonical;
|
|
40
|
-
d && n.links.push({
|
|
41
|
-
rel: "canonical",
|
|
42
|
-
href: d
|
|
43
|
-
});
|
|
44
|
-
let f = {
|
|
45
|
-
...t.og,
|
|
46
|
-
...e.og
|
|
47
|
-
}, p = f.title ?? i ?? o, m = f.description ?? l, h = !!(p || m || f.image), g = f.url ?? d;
|
|
48
|
-
h && (n.meta.push({
|
|
49
|
-
property: "og:type",
|
|
50
|
-
content: f.type ?? "website"
|
|
51
|
-
}), p && n.meta.push({
|
|
52
|
-
property: "og:title",
|
|
53
|
-
content: p
|
|
54
|
-
}), m && n.meta.push({
|
|
55
|
-
property: "og:description",
|
|
56
|
-
content: m
|
|
57
|
-
}), f.image && n.meta.push({
|
|
58
|
-
property: "og:image",
|
|
59
|
-
content: f.image
|
|
60
|
-
}), g && n.meta.push({
|
|
61
|
-
property: "og:url",
|
|
62
|
-
content: g
|
|
63
|
-
}));
|
|
64
|
-
let _ = {
|
|
65
|
-
...t.twitter,
|
|
66
|
-
...e.twitter
|
|
67
|
-
}, v = _.title ?? p, y = _.description ?? m, b = _.image ?? f.image;
|
|
68
|
-
(v || y || b) && (n.meta.push({
|
|
69
|
-
name: "twitter:card",
|
|
70
|
-
content: _.card ?? "summary_large_image"
|
|
71
|
-
}), v && n.meta.push({
|
|
72
|
-
name: "twitter:title",
|
|
73
|
-
content: v
|
|
74
|
-
}), y && n.meta.push({
|
|
75
|
-
name: "twitter:description",
|
|
76
|
-
content: y
|
|
77
|
-
}), b && n.meta.push({
|
|
78
|
-
name: "twitter:image",
|
|
79
|
-
content: b
|
|
80
|
-
}));
|
|
81
|
-
let x = e.ldJson ? Array.isArray(e.ldJson) ? e.ldJson : [e.ldJson] : [];
|
|
82
|
-
for (let e of x) n.scripts.push({
|
|
83
|
-
type: "application/ld+json",
|
|
84
|
-
children: r(e)
|
|
85
|
-
});
|
|
86
|
-
for (let r of [t.customHead, e.customHead]) {
|
|
87
|
-
if (!r) continue;
|
|
88
|
-
let e = a(r);
|
|
89
|
-
n.meta.push(...e.meta), n.links.push(...e.links), n.scripts.push(...e.scripts);
|
|
90
|
-
}
|
|
91
|
-
return n;
|
|
92
|
-
};
|
|
93
|
-
function s({ meta: r, site: i }) {
|
|
94
|
-
let a = o(r, i);
|
|
95
|
-
return /* @__PURE__ */ n(e, { children: [
|
|
96
|
-
a.meta.map((e, n) => e.title === void 0 ? /* @__PURE__ */ t("meta", { ...e }, `m${n}`) : /* @__PURE__ */ t("title", { children: e.title }, `t${n}`)),
|
|
97
|
-
a.links.map((e, n) => /* @__PURE__ */ t("link", { ...e }, `l${n}`)),
|
|
98
|
-
a.scripts.map(({ children: e, ...n }, r) => e === void 0 ? /* @__PURE__ */ t("script", { ...n }, `s${r}`) : /* @__PURE__ */ t("script", {
|
|
99
|
-
...n,
|
|
100
|
-
dangerouslySetInnerHTML: { __html: e }
|
|
101
|
-
}, `s${r}`))
|
|
102
|
-
] });
|
|
103
|
-
}
|
|
104
|
-
//#endregion
|
|
105
|
-
export { s as PageHead, o as pageHead, a as parseRawHead };
|
package/dist/scaffold.d.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { ILevoSiteConfig } from './client';
|
|
2
|
-
import { ILevoDataSources, IQueryClientLike } from './data';
|
|
3
|
-
import { IComposedHead } from './pageHead';
|
|
4
|
-
/** The platform's per-page SEO object — the `meta` key of `meta/<route>.json`. */
|
|
5
|
-
export interface IPlatformPageMeta {
|
|
6
|
-
meta_title?: string;
|
|
7
|
-
meta_description?: string;
|
|
8
|
-
keywords?: string;
|
|
9
|
-
og_title?: string;
|
|
10
|
-
og_description?: string;
|
|
11
|
-
/** Plain URL string, or the platform media object (older rows) — `.location` is read. */
|
|
12
|
-
og_image?: string | {
|
|
13
|
-
location?: string;
|
|
14
|
-
} | null;
|
|
15
|
-
og_url?: string;
|
|
16
|
-
canonical?: string;
|
|
17
|
-
twitter_card?: string;
|
|
18
|
-
/** JSON-LD structured data — rendered as an `application/ld+json` script tag. */
|
|
19
|
-
ld_json?: Record<string, unknown> | Array<Record<string, unknown>>;
|
|
20
|
-
/** Page-scoped raw head snippet — script/meta/link tags only. */
|
|
21
|
-
head_code?: string;
|
|
22
|
-
disable_indexing?: boolean;
|
|
23
|
-
robots?: string;
|
|
24
|
-
}
|
|
25
|
-
/** The full `meta/<route>.json` shape: page identity (platform-owned) + the SEO object. */
|
|
26
|
-
export interface IPlatformMetaFile {
|
|
27
|
-
title?: string;
|
|
28
|
-
description?: string;
|
|
29
|
-
meta?: IPlatformPageMeta;
|
|
30
|
-
}
|
|
31
|
-
/** The slice of the project's root `site.json` the runtime reads. */
|
|
32
|
-
export interface ISiteJson {
|
|
33
|
-
id?: string;
|
|
34
|
-
workspace_id?: string;
|
|
35
|
-
name?: string;
|
|
36
|
-
description?: string;
|
|
37
|
-
/** The site's live URL host (with or without protocol) — feeds auto-canonicals. */
|
|
38
|
-
domain?: string;
|
|
39
|
-
settings?: {
|
|
40
|
-
head_code?: string;
|
|
41
|
-
};
|
|
42
|
-
levo?: {
|
|
43
|
-
api_url?: string;
|
|
44
|
-
insights_url?: string | null;
|
|
45
|
-
app_mode?: string;
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Per-record head config for a dynamic (`$slug`) route — `levoHead`'s optional second
|
|
50
|
-
* argument. A static literal (AI/editor-written, next to the route's meta import); each
|
|
51
|
-
* field names a FIELD on the loaded record (the `dataSources` entry named by `source`).
|
|
52
|
-
* At request time the record's values override the static meta file per-field, so every
|
|
53
|
-
* slug ships its own title, description, and share image.
|
|
54
|
-
*/
|
|
55
|
-
export interface ILevoDynamicHead {
|
|
56
|
-
/** Key in the page's `dataSources` whose loaded record feeds the head. */
|
|
57
|
-
source: string;
|
|
58
|
-
/** Record field holding the page title (the site name is appended automatically). */
|
|
59
|
-
title?: string;
|
|
60
|
-
/** Record field holding the description. */
|
|
61
|
-
description?: string;
|
|
62
|
-
/** Record field holding the share image (platform image object or URL). */
|
|
63
|
-
image?: string;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* The slice of the router's head-fn context we read. Structural on purpose (like
|
|
67
|
-
* IQueryClientLike) so the package never depends on the router's types: `loaderData` is
|
|
68
|
-
* the loader's return value — `prefetchLevoSources`' source-keyed map — and
|
|
69
|
-
* `match.pathname` is the request path. Both read defensively; absent = skipped.
|
|
70
|
-
*/
|
|
71
|
-
interface IHeadCtx {
|
|
72
|
-
loaderData?: unknown;
|
|
73
|
-
match?: {
|
|
74
|
-
pathname?: string;
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* The site's Levo client config from its `site.json`. The platform stamps that file at
|
|
79
|
-
* provision and re-syncs it on settings saves; the `?.` on `levo` is load-bearing — a
|
|
80
|
-
* site provisioned before the block shipped degrades to an inert client, never a crash.
|
|
81
|
-
*/
|
|
82
|
-
export declare const siteConfigFromJson: (site: ISiteJson) => ILevoSiteConfig;
|
|
83
|
-
/**
|
|
84
|
-
* Build the site's `levoHead` from its `site.json`. Each route passes its OWN imported
|
|
85
|
-
* meta file (`head: levoHead(meta)`) — no path matching anywhere; the import IS the
|
|
86
|
-
* pairing. The argument default lets a meta-less route render pure site defaults.
|
|
87
|
-
*
|
|
88
|
-
* Dynamic (`$slug`) routes pass a second argument naming the record fields that feed the
|
|
89
|
-
* head (`head: levoHead(meta, { source: "post", title: "title", … })`), so every slug
|
|
90
|
-
* gets its own title/description/share image instead of the route's shared static meta.
|
|
91
|
-
* Pages that set no `canonical` get a self-referencing one derived from the site domain
|
|
92
|
-
* + request path (og:url follows it in pageHead) — per-slug correct on dynamic routes.
|
|
93
|
-
*/
|
|
94
|
-
export declare const createLevoHead: (site: ISiteJson) => (meta?: IPlatformMetaFile, dynamic?: ILevoDynamicHead) => (ctx?: IHeadCtx) => IComposedHead;
|
|
95
|
-
/**
|
|
96
|
-
* Build the one-line route loader (`loader: levoLoader(dataSources)`): prefetch the
|
|
97
|
-
* page's declared data sources on the server so SSR ships fully-rendered HTML, and
|
|
98
|
-
* return them keyed by source key — that map is the route's `loaderData`, which
|
|
99
|
-
* `levoHead`'s dynamic config reads for per-record heads. An empty `dataSources` ({})
|
|
100
|
-
* resolves to an empty map. Context is typed structurally (just `queryClient`) so the
|
|
101
|
-
* scaffold's router types never enter the package.
|
|
102
|
-
*/
|
|
103
|
-
export declare const createLevoLoader: (config: ILevoSiteConfig) => (sources: ILevoDataSources) => ({ context, params, }: {
|
|
104
|
-
context: {
|
|
105
|
-
queryClient: IQueryClientLike;
|
|
106
|
-
};
|
|
107
|
-
params?: Record<string, string>;
|
|
108
|
-
}) => Promise<Record<string, unknown>>;
|
|
109
|
-
export {};
|
|
110
|
-
//# sourceMappingURL=scaffold.d.ts.map
|
package/dist/scaffold.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { prefetchLevoSources as e } from "./data/index.js";
|
|
2
|
-
import { pageHead as t } from "./pageHead.js";
|
|
3
|
-
//#region src/scaffold.ts
|
|
4
|
-
var n = (e) => typeof e == "string" && e.trim() ? e : void 0, r = (e) => ({
|
|
5
|
-
apiUrl: e.levo?.api_url || "",
|
|
6
|
-
workspace: e.workspace_id || "",
|
|
7
|
-
siteId: e.id || "",
|
|
8
|
-
insightsUrl: e.levo?.insights_url || null,
|
|
9
|
-
appMode: e.levo?.app_mode || "production"
|
|
10
|
-
}), i = (e) => typeof e == "string" ? e : e?.location ?? void 0, a = (e, t) => {
|
|
11
|
-
let n = e.meta ?? {}, r = e.title && t ? `${e.title} | ${t}` : e.title || t || void 0;
|
|
12
|
-
return {
|
|
13
|
-
title: n.meta_title || r,
|
|
14
|
-
description: n.meta_description || void 0,
|
|
15
|
-
canonical: n.canonical || void 0,
|
|
16
|
-
robots: n.disable_indexing ? "noindex,nofollow" : n.robots || void 0,
|
|
17
|
-
og: {
|
|
18
|
-
title: n.og_title || void 0,
|
|
19
|
-
description: n.og_description || void 0,
|
|
20
|
-
image: i(n.og_image),
|
|
21
|
-
url: n.og_url || void 0
|
|
22
|
-
},
|
|
23
|
-
twitter: { card: n.twitter_card || void 0 },
|
|
24
|
-
ldJson: n.ld_json || void 0,
|
|
25
|
-
customHead: n.head_code || void 0
|
|
26
|
-
};
|
|
27
|
-
}, o = (e) => ({
|
|
28
|
-
description: e.description || void 0,
|
|
29
|
-
customHead: e.settings?.head_code || void 0
|
|
30
|
-
}), s = (e) => (r = {}, s) => (c) => {
|
|
31
|
-
let l = a(r, e.name);
|
|
32
|
-
if (s) {
|
|
33
|
-
let t = c?.loaderData?.[s.source];
|
|
34
|
-
if (t) {
|
|
35
|
-
let r = s.title ? n(t[s.title]) : void 0;
|
|
36
|
-
r && (l.title = e.name ? `${r} | ${e.name}` : r, l.og = {
|
|
37
|
-
...l.og,
|
|
38
|
-
title: r
|
|
39
|
-
});
|
|
40
|
-
let a = s.description ? n(t[s.description]) : void 0;
|
|
41
|
-
a && (l.description = a, l.og = {
|
|
42
|
-
...l.og,
|
|
43
|
-
description: a
|
|
44
|
-
});
|
|
45
|
-
let o = s.image ? i(t[s.image]) : void 0;
|
|
46
|
-
o && (l.og = {
|
|
47
|
-
...l.og,
|
|
48
|
-
image: o
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
if (!l.canonical) {
|
|
53
|
-
let t = c?.match?.pathname, n = (e.domain || "").trim();
|
|
54
|
-
n && t?.startsWith("/") && (l.canonical = (/^https?:\/\//.test(n) ? n : `https://${n}`).replace(/\/+$/, "") + t);
|
|
55
|
-
}
|
|
56
|
-
return t(l, o(e));
|
|
57
|
-
}, c = (t) => (n) => ({ context: r, params: i }) => e({
|
|
58
|
-
queryClient: r.queryClient,
|
|
59
|
-
config: t,
|
|
60
|
-
sources: n,
|
|
61
|
-
params: i
|
|
62
|
-
});
|
|
63
|
-
//#endregion
|
|
64
|
-
export { s as createLevoHead, c as createLevoLoader, r as siteConfigFromJson };
|