pagiera 0.2.0-alpha.33
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 +528 -0
- package/dist/adapters.d.ts +89 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +2 -0
- package/dist/adapters.js.map +1 -0
- package/dist/client.d.ts +22 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +33 -0
- package/dist/client.js.map +1 -0
- package/dist/data.js +210 -0
- package/dist/data.js.map +7 -0
- package/dist/document.d.ts +63 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +25 -0
- package/dist/document.js.map +1 -0
- package/dist/editor.d.ts +14 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +59 -0
- package/dist/editor.js.map +1 -0
- package/dist/full-editor.d.ts +53 -0
- package/dist/full-editor.js +11117 -0
- package/dist/full-editor.js.map +7 -0
- package/dist/full.css +3498 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/app/api/ai-design/route.d.ts +3 -0
- package/dist/internal/app/api/ai-design/route.d.ts.map +1 -0
- package/dist/internal/app/api/ai-design/route.js +165 -0
- package/dist/internal/app/api/ai-design/route.js.map +1 -0
- package/dist/internal/app/p/editor/ai-panel.d.ts +27 -0
- package/dist/internal/app/p/editor/ai-panel.d.ts.map +1 -0
- package/dist/internal/app/p/editor/ai-panel.js +77 -0
- package/dist/internal/app/p/editor/ai-panel.js.map +1 -0
- package/dist/internal/app/p/editor/data-modal.d.ts +26 -0
- package/dist/internal/app/p/editor/data-modal.d.ts.map +1 -0
- package/dist/internal/app/p/editor/data-modal.js +94 -0
- package/dist/internal/app/p/editor/data-modal.js.map +1 -0
- package/dist/internal/app/p/editor/data-panel.d.ts +18 -0
- package/dist/internal/app/p/editor/data-panel.d.ts.map +1 -0
- package/dist/internal/app/p/editor/data-panel.js +45 -0
- package/dist/internal/app/p/editor/data-panel.js.map +1 -0
- package/dist/internal/app/p/editor/editor.d.ts +51 -0
- package/dist/internal/app/p/editor/editor.d.ts.map +1 -0
- package/dist/internal/app/p/editor/editor.js +1551 -0
- package/dist/internal/app/p/editor/editor.js.map +1 -0
- package/dist/internal/app/p/editor/fields.d.ts +111 -0
- package/dist/internal/app/p/editor/fields.d.ts.map +1 -0
- package/dist/internal/app/p/editor/fields.js +141 -0
- package/dist/internal/app/p/editor/fields.js.map +1 -0
- package/dist/internal/app/p/editor/inspector.d.ts +38 -0
- package/dist/internal/app/p/editor/inspector.d.ts.map +1 -0
- package/dist/internal/app/p/editor/inspector.js +336 -0
- package/dist/internal/app/p/editor/inspector.js.map +1 -0
- package/dist/internal/app/p/editor/library.d.ts +18 -0
- package/dist/internal/app/p/editor/library.d.ts.map +1 -0
- package/dist/internal/app/p/editor/library.js +61 -0
- package/dist/internal/app/p/editor/library.js.map +1 -0
- package/dist/internal/app/p/editor/parts.d.ts +75 -0
- package/dist/internal/app/p/editor/parts.d.ts.map +1 -0
- package/dist/internal/app/p/editor/parts.js +261 -0
- package/dist/internal/app/p/editor/parts.js.map +1 -0
- package/dist/internal/app/p/editor/templates-panel.d.ts +6 -0
- package/dist/internal/app/p/editor/templates-panel.d.ts.map +1 -0
- package/dist/internal/app/p/editor/templates-panel.js +12 -0
- package/dist/internal/app/p/editor/templates-panel.js.map +1 -0
- package/dist/internal/app/p/editor/use-canvas-view.d.ts +24 -0
- package/dist/internal/app/p/editor/use-canvas-view.d.ts.map +1 -0
- package/dist/internal/app/p/editor/use-canvas-view.js +242 -0
- package/dist/internal/app/p/editor/use-canvas-view.js.map +1 -0
- package/dist/internal/app/p/editor/use-editor.d.ts +48 -0
- package/dist/internal/app/p/editor/use-editor.d.ts.map +1 -0
- package/dist/internal/app/p/editor/use-editor.js +224 -0
- package/dist/internal/app/p/editor/use-editor.js.map +1 -0
- package/dist/internal/app/p/editor/variables-panel.d.ts +8 -0
- package/dist/internal/app/p/editor/variables-panel.d.ts.map +1 -0
- package/dist/internal/app/p/editor/variables-panel.js +52 -0
- package/dist/internal/app/p/editor/variables-panel.js.map +1 -0
- package/dist/internal/components/ui/select.d.ts +12 -0
- package/dist/internal/components/ui/select.d.ts.map +1 -0
- package/dist/internal/components/ui/select.js +32 -0
- package/dist/internal/components/ui/select.js.map +1 -0
- package/dist/internal/drizzle/index.d.ts +6 -0
- package/dist/internal/drizzle/index.d.ts.map +1 -0
- package/dist/internal/drizzle/index.js +20 -0
- package/dist/internal/drizzle/index.js.map +1 -0
- package/dist/internal/drizzle/schema.d.ts +405 -0
- package/dist/internal/drizzle/schema.d.ts.map +1 -0
- package/dist/internal/drizzle/schema.js +70 -0
- package/dist/internal/drizzle/schema.js.map +1 -0
- package/dist/internal/lib/data/context.d.ts +8 -0
- package/dist/internal/lib/data/context.d.ts.map +1 -0
- package/dist/internal/lib/data/context.js +17 -0
- package/dist/internal/lib/data/context.js.map +1 -0
- package/dist/internal/lib/data/source.d.ts +54 -0
- package/dist/internal/lib/data/source.d.ts.map +1 -0
- package/dist/internal/lib/data/source.js +229 -0
- package/dist/internal/lib/data/source.js.map +1 -0
- package/dist/internal/lib/editor/ai-types.d.ts +44 -0
- package/dist/internal/lib/editor/ai-types.d.ts.map +1 -0
- package/dist/internal/lib/editor/ai-types.js +2 -0
- package/dist/internal/lib/editor/ai-types.js.map +1 -0
- package/dist/internal/lib/editor/arrange.d.ts +12 -0
- package/dist/internal/lib/editor/arrange.d.ts.map +1 -0
- package/dist/internal/lib/editor/arrange.js +72 -0
- package/dist/internal/lib/editor/arrange.js.map +1 -0
- package/dist/internal/lib/editor/cascade.d.ts +39 -0
- package/dist/internal/lib/editor/cascade.d.ts.map +1 -0
- package/dist/internal/lib/editor/cascade.js +86 -0
- package/dist/internal/lib/editor/cascade.js.map +1 -0
- package/dist/internal/lib/editor/icon.d.ts +6 -0
- package/dist/internal/lib/editor/icon.d.ts.map +1 -0
- package/dist/internal/lib/editor/icon.js +13 -0
- package/dist/internal/lib/editor/icon.js.map +1 -0
- package/dist/internal/lib/editor/presets.d.ts +10 -0
- package/dist/internal/lib/editor/presets.d.ts.map +1 -0
- package/dist/internal/lib/editor/presets.js +83 -0
- package/dist/internal/lib/editor/presets.js.map +1 -0
- package/dist/internal/lib/editor/showcase.d.ts +14 -0
- package/dist/internal/lib/editor/showcase.d.ts.map +1 -0
- package/dist/internal/lib/editor/showcase.js +219 -0
- package/dist/internal/lib/editor/showcase.js.map +1 -0
- package/dist/internal/lib/editor/site-templates.d.ts +4 -0
- package/dist/internal/lib/editor/site-templates.d.ts.map +1 -0
- package/dist/internal/lib/editor/site-templates.js +156 -0
- package/dist/internal/lib/editor/site-templates.js.map +1 -0
- package/dist/internal/lib/editor/snap.d.ts +34 -0
- package/dist/internal/lib/editor/snap.d.ts.map +1 -0
- package/dist/internal/lib/editor/snap.js +70 -0
- package/dist/internal/lib/editor/snap.js.map +1 -0
- package/dist/internal/lib/editor/style.d.ts +53 -0
- package/dist/internal/lib/editor/style.d.ts.map +1 -0
- package/dist/internal/lib/editor/style.js +313 -0
- package/dist/internal/lib/editor/style.js.map +1 -0
- package/dist/internal/lib/editor/tree.d.ts +72 -0
- package/dist/internal/lib/editor/tree.d.ts.map +1 -0
- package/dist/internal/lib/editor/tree.js +301 -0
- package/dist/internal/lib/editor/tree.js.map +1 -0
- package/dist/internal/lib/editor/types.d.ts +273 -0
- package/dist/internal/lib/editor/types.d.ts.map +1 -0
- package/dist/internal/lib/editor/types.js +411 -0
- package/dist/internal/lib/editor/types.js.map +1 -0
- package/dist/internal/lib/editor/validate.d.ts +20 -0
- package/dist/internal/lib/editor/validate.d.ts.map +1 -0
- package/dist/internal/lib/editor/validate.js +467 -0
- package/dist/internal/lib/editor/validate.js.map +1 -0
- package/dist/internal/lib/pages.d.ts +83 -0
- package/dist/internal/lib/pages.d.ts.map +1 -0
- package/dist/internal/lib/pages.js +294 -0
- package/dist/internal/lib/pages.js.map +1 -0
- package/dist/internal/lib/render/bind.d.ts +18 -0
- package/dist/internal/lib/render/bind.d.ts.map +1 -0
- package/dist/internal/lib/render/bind.js +28 -0
- package/dist/internal/lib/render/bind.js.map +1 -0
- package/dist/internal/lib/render/css.d.ts +31 -0
- package/dist/internal/lib/render/css.d.ts.map +1 -0
- package/dist/internal/lib/render/css.js +239 -0
- package/dist/internal/lib/render/css.js.map +1 -0
- package/dist/internal/lib/render/load-data.d.ts +15 -0
- package/dist/internal/lib/render/load-data.d.ts.map +1 -0
- package/dist/internal/lib/render/load-data.js +39 -0
- package/dist/internal/lib/render/load-data.js.map +1 -0
- package/dist/internal/lib/render/page-render.d.ts +17 -0
- package/dist/internal/lib/render/page-render.d.ts.map +1 -0
- package/dist/internal/lib/render/page-render.js +117 -0
- package/dist/internal/lib/render/page-render.js.map +1 -0
- package/dist/internal/lib/utils.d.ts +3 -0
- package/dist/internal/lib/utils.d.ts.map +1 -0
- package/dist/internal/lib/utils.js +6 -0
- package/dist/internal/lib/utils.js.map +1 -0
- package/dist/manrope-data.d.ts +3 -0
- package/dist/manrope-data.d.ts.map +1 -0
- package/dist/manrope-data.js +3 -0
- package/dist/manrope-data.js.map +1 -0
- package/dist/page.d.ts +9 -0
- package/dist/page.d.ts.map +1 -0
- package/dist/page.js +148 -0
- package/dist/page.js.map +1 -0
- package/dist/provider.d.ts +14 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +45 -0
- package/dist/provider.js.map +1 -0
- package/dist/runtime.d.ts +8 -0
- package/dist/runtime.js +717 -0
- package/dist/runtime.js.map +7 -0
- package/dist/server.d.ts +31 -0
- package/dist/server.js +2267 -0
- package/dist/server.js.map +7 -0
- package/dist/styles.css +300 -0
- package/package.json +94 -0
- package/thumbnail.png +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type DataSource, type RequestContext } from "@/lib/editor/types";
|
|
2
|
+
export declare const MAX_ROWS = 200;
|
|
3
|
+
export declare class DataSourceError extends Error {
|
|
4
|
+
readonly status?: number | undefined;
|
|
5
|
+
constructor(message: string, status?: number | undefined);
|
|
6
|
+
}
|
|
7
|
+
export declare function assertFetchableUrl(raw: string): URL;
|
|
8
|
+
/**
|
|
9
|
+
* Walks a dotted path such as `data.items` or `results.0.tags`. An empty path
|
|
10
|
+
* returns the payload itself, which is what a bare JSON array needs.
|
|
11
|
+
*/
|
|
12
|
+
export declare function selectPath(payload: unknown, path: string): unknown;
|
|
13
|
+
export type SourceResult = {
|
|
14
|
+
rows: Array<Record<string, unknown>>;
|
|
15
|
+
keys: string[];
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Requests a source and normalizes it to rows. A root object becomes one row
|
|
19
|
+
* for Request; an array stays multiple rows for Repeat.
|
|
20
|
+
*/
|
|
21
|
+
export type LoadOptions = {
|
|
22
|
+
/**
|
|
23
|
+
* Seconds to cache the response for. `false` bypasses the cache — only for
|
|
24
|
+
* the editor's Test button; on a rendered route it would force an
|
|
25
|
+
* otherwise-static page to become dynamic on every request.
|
|
26
|
+
*/
|
|
27
|
+
revalidate?: number | false;
|
|
28
|
+
/** Supplies `{{query.…}}` / `{{page.…}}` values for this request. */
|
|
29
|
+
context?: RequestContext;
|
|
30
|
+
};
|
|
31
|
+
export declare const DEFAULT_REVALIDATE = 60;
|
|
32
|
+
export declare function loadSource(source: DataSource, { revalidate, context }?: LoadOptions): Promise<SourceResult>;
|
|
33
|
+
/** Reads one binding path off a row and flattens it to something renderable. */
|
|
34
|
+
export declare function readBinding(row: Record<string, unknown>, path: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Resolves `{{query.id}}`, `{{params.slug}}` and `{{page.slug}}`.
|
|
37
|
+
*
|
|
38
|
+
* Only these two namespaces exist: an unknown token becomes an empty string
|
|
39
|
+
* rather than being left in the URL, so a typo cannot send a literal `{{…}}`
|
|
40
|
+
* to the API or accidentally expose something else.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveTokens(value: string, context: RequestContext): string;
|
|
43
|
+
/**
|
|
44
|
+
* Builds the final URL: tokens resolved, params appended and percent-encoded
|
|
45
|
+
* by `URLSearchParams` so a value can never break out into the query grammar.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildRequest(source: DataSource, context: RequestContext): {
|
|
48
|
+
url: URL;
|
|
49
|
+
headers: Record<string, string>;
|
|
50
|
+
method: "POST" | "PATCH" | "DELETE" | "GET" | "PUT";
|
|
51
|
+
body: string | undefined;
|
|
52
|
+
};
|
|
53
|
+
export declare const EMPTY_CONTEXT: RequestContext;
|
|
54
|
+
//# sourceMappingURL=source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../../src/internal/lib/data/source.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,UAAU,EAEf,KAAK,cAAc,EAGtB,MAAM,oBAAoB,CAAC;AAyB5B,eAAO,MAAM,QAAQ,MAAM,CAAC;AAK5B,qBAAa,eAAgB,SAAQ,KAAK;aACO,MAAM,CAAC,EAAE,MAAM;gBAAhD,OAAO,EAAE,MAAM,EAAkB,MAAM,CAAC,EAAE,MAAM,YAAA;CAI/D;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAyBnD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQlE;AA6BD,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,qEAAqE;IACrE,OAAO,CAAC,EAAE,cAAc,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,wBAAsB,UAAU,CAC5B,MAAM,EAAE,UAAU,EAClB,EAAE,UAA+B,EAAE,OAAuB,EAAE,GAAE,WAAgB,GAC/E,OAAO,CAAC,YAAY,CAAC,CAkEvB;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK9E;AAID;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAS5E;AAWD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc;;;;;EAgCvE;AAED,eAAO,MAAM,aAAa,EAAE,cAA8D,CAAC"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { sendsBody, } from "@/lib/editor/types";
|
|
2
|
+
/**
|
|
3
|
+
* Fetching an author-supplied URL from our server is a server-side request
|
|
4
|
+
* forgery vector: without checks it can reach cloud metadata endpoints, admin
|
|
5
|
+
* services on localhost, or anything else inside the network perimeter. Every
|
|
6
|
+
* hop is validated against this list, and redirects are followed by hand so a
|
|
7
|
+
* public URL cannot bounce into private space.
|
|
8
|
+
*/
|
|
9
|
+
const BLOCKED_HOSTS = new Set([
|
|
10
|
+
"localhost",
|
|
11
|
+
"127.0.0.1",
|
|
12
|
+
"0.0.0.0",
|
|
13
|
+
"::1",
|
|
14
|
+
"[::1]",
|
|
15
|
+
"metadata.google.internal",
|
|
16
|
+
"metadata.goog",
|
|
17
|
+
]);
|
|
18
|
+
const PRIVATE_IPV4 = /^(10\.|127\.|0\.|169\.254\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.)/;
|
|
19
|
+
/** Hostnames that only resolve inside a private network. */
|
|
20
|
+
const PRIVATE_SUFFIXES = [".local", ".internal", ".localdomain", ".home.arpa"];
|
|
21
|
+
export const MAX_ROWS = 200;
|
|
22
|
+
const MAX_BYTES = 2000000;
|
|
23
|
+
const TIMEOUT_MS = 8000;
|
|
24
|
+
const MAX_REDIRECTS = 3;
|
|
25
|
+
export class DataSourceError extends Error {
|
|
26
|
+
constructor(message, status) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.status = status;
|
|
29
|
+
this.name = "DataSourceError";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function assertFetchableUrl(raw) {
|
|
33
|
+
let url;
|
|
34
|
+
try {
|
|
35
|
+
url = new URL(raw);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
throw new DataSourceError("That is not a valid URL.");
|
|
39
|
+
}
|
|
40
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
41
|
+
throw new DataSourceError("Only http and https URLs can be requested.");
|
|
42
|
+
}
|
|
43
|
+
const host = url.hostname.toLowerCase();
|
|
44
|
+
if (BLOCKED_HOSTS.has(host) || PRIVATE_IPV4.test(host)) {
|
|
45
|
+
throw new DataSourceError(`Requests to ${host} are not allowed.`);
|
|
46
|
+
}
|
|
47
|
+
if (PRIVATE_SUFFIXES.some((suffix) => host.endsWith(suffix))) {
|
|
48
|
+
throw new DataSourceError(`Requests to ${host} are not allowed.`);
|
|
49
|
+
}
|
|
50
|
+
// Bracketed IPv6 literals: anything link-local or unique-local.
|
|
51
|
+
if (host.startsWith("[") && /^\[(fe80|fc|fd)/i.test(host)) {
|
|
52
|
+
throw new DataSourceError("Requests to private addresses are not allowed.");
|
|
53
|
+
}
|
|
54
|
+
return url;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Walks a dotted path such as `data.items` or `results.0.tags`. An empty path
|
|
58
|
+
* returns the payload itself, which is what a bare JSON array needs.
|
|
59
|
+
*/
|
|
60
|
+
export function selectPath(payload, path) {
|
|
61
|
+
const steps = path.split(".").map((s) => s.trim()).filter(Boolean);
|
|
62
|
+
let cursor = payload;
|
|
63
|
+
for (const step of steps) {
|
|
64
|
+
if (cursor === null || typeof cursor !== "object")
|
|
65
|
+
return undefined;
|
|
66
|
+
cursor = cursor[step];
|
|
67
|
+
}
|
|
68
|
+
return cursor;
|
|
69
|
+
}
|
|
70
|
+
/** Reads a body with a hard cap so a huge response cannot exhaust memory. */
|
|
71
|
+
async function readCapped(response) {
|
|
72
|
+
const reader = response.body?.getReader();
|
|
73
|
+
if (!reader)
|
|
74
|
+
return "";
|
|
75
|
+
const chunks = [];
|
|
76
|
+
let total = 0;
|
|
77
|
+
while (true) {
|
|
78
|
+
const { done, value } = await reader.read();
|
|
79
|
+
if (done)
|
|
80
|
+
break;
|
|
81
|
+
total += value.byteLength;
|
|
82
|
+
if (total > MAX_BYTES) {
|
|
83
|
+
await reader.cancel();
|
|
84
|
+
throw new DataSourceError("That response is too large (over 2 MB).");
|
|
85
|
+
}
|
|
86
|
+
chunks.push(value);
|
|
87
|
+
}
|
|
88
|
+
return new TextDecoder().decode(chunks.reduce((acc, chunk) => {
|
|
89
|
+
const merged = new Uint8Array(acc.length + chunk.length);
|
|
90
|
+
merged.set(acc);
|
|
91
|
+
merged.set(chunk, acc.length);
|
|
92
|
+
return merged;
|
|
93
|
+
}, new Uint8Array()));
|
|
94
|
+
}
|
|
95
|
+
export const DEFAULT_REVALIDATE = 60;
|
|
96
|
+
export async function loadSource(source, { revalidate = DEFAULT_REVALIDATE, context = EMPTY_CONTEXT } = {}) {
|
|
97
|
+
const request = buildRequest(source, context);
|
|
98
|
+
let target = request.url;
|
|
99
|
+
let response;
|
|
100
|
+
for (let hop = 0; hop <= MAX_REDIRECTS; hop++) {
|
|
101
|
+
response = await fetch(target, {
|
|
102
|
+
// Redirects are followed by hand so each hop is validated too.
|
|
103
|
+
redirect: "manual",
|
|
104
|
+
method: request.method,
|
|
105
|
+
headers: request.headers,
|
|
106
|
+
body: request.body,
|
|
107
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
108
|
+
// Only GET responses are cacheable; anything with side effects is
|
|
109
|
+
// fetched fresh every time.
|
|
110
|
+
...(revalidate === false || request.method !== "GET"
|
|
111
|
+
? { cache: "no-store" }
|
|
112
|
+
: { next: { revalidate } }),
|
|
113
|
+
});
|
|
114
|
+
if (response.status < 300 || response.status >= 400)
|
|
115
|
+
break;
|
|
116
|
+
const location = response.headers.get("location");
|
|
117
|
+
if (!location)
|
|
118
|
+
break;
|
|
119
|
+
target = assertFetchableUrl(new URL(location, target).toString());
|
|
120
|
+
response = undefined;
|
|
121
|
+
}
|
|
122
|
+
if (!response)
|
|
123
|
+
throw new DataSourceError("Too many redirects.");
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
throw new DataSourceError(`The API replied ${response.status}.`, response.status);
|
|
126
|
+
}
|
|
127
|
+
const text = await readCapped(response);
|
|
128
|
+
let payload;
|
|
129
|
+
try {
|
|
130
|
+
payload = JSON.parse(text);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
throw new DataSourceError("The response was not JSON.");
|
|
134
|
+
}
|
|
135
|
+
const selected = selectPath(payload, source.path);
|
|
136
|
+
const selectedRows = Array.isArray(selected)
|
|
137
|
+
? selected
|
|
138
|
+
: selected !== null && typeof selected === "object"
|
|
139
|
+
? [selected]
|
|
140
|
+
: undefined;
|
|
141
|
+
if (!selectedRows) {
|
|
142
|
+
throw new DataSourceError(source.path
|
|
143
|
+
? `"${source.path}" is not a list in that response.`
|
|
144
|
+
: "That response is neither an object nor a list.");
|
|
145
|
+
}
|
|
146
|
+
const rows = selectedRows
|
|
147
|
+
.slice(0, MAX_ROWS)
|
|
148
|
+
.map((row) => row !== null && typeof row === "object" && !Array.isArray(row)
|
|
149
|
+
? row
|
|
150
|
+
: { value: row });
|
|
151
|
+
// Union of the keys across the sample, so binding menus list everything.
|
|
152
|
+
const keys = [...new Set(rows.flatMap((row) => Object.keys(row)))].sort();
|
|
153
|
+
return { rows, keys };
|
|
154
|
+
}
|
|
155
|
+
/** Reads one binding path off a row and flattens it to something renderable. */
|
|
156
|
+
export function readBinding(row, path) {
|
|
157
|
+
const value = selectPath(row, path);
|
|
158
|
+
if (value === null || value === undefined)
|
|
159
|
+
return "";
|
|
160
|
+
if (typeof value === "object")
|
|
161
|
+
return "";
|
|
162
|
+
return String(value);
|
|
163
|
+
}
|
|
164
|
+
/* ------------------------------------------------------------------ tokens */
|
|
165
|
+
/**
|
|
166
|
+
* Resolves `{{query.id}}`, `{{params.slug}}` and `{{page.slug}}`.
|
|
167
|
+
*
|
|
168
|
+
* Only these two namespaces exist: an unknown token becomes an empty string
|
|
169
|
+
* rather than being left in the URL, so a typo cannot send a literal `{{…}}`
|
|
170
|
+
* to the API or accidentally expose something else.
|
|
171
|
+
*/
|
|
172
|
+
export function resolveTokens(value, context) {
|
|
173
|
+
return value.replace(/\{\{\s*([a-zA-Z0-9_.]+)\s*\}\}/g, (_, token) => {
|
|
174
|
+
const [namespace, ...rest] = token.split(".");
|
|
175
|
+
const key = rest.join(".");
|
|
176
|
+
if (namespace === "query")
|
|
177
|
+
return context.query[key] ?? "";
|
|
178
|
+
if (namespace === "params")
|
|
179
|
+
return context.params[key] ?? "";
|
|
180
|
+
if (namespace === "page" && key === "slug")
|
|
181
|
+
return context.page.slug;
|
|
182
|
+
return "";
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/** Header names and values must not be able to inject extra headers. */
|
|
186
|
+
function safeHeader(pair, context) {
|
|
187
|
+
const name = pair.key.trim();
|
|
188
|
+
if (!/^[A-Za-z0-9!#$%&'*+.^_`|~-]+$/.test(name))
|
|
189
|
+
return null;
|
|
190
|
+
// Strip anything that could terminate the header line.
|
|
191
|
+
const value = resolveTokens(pair.value, context).replace(/[\r\n\0]/g, "").trim();
|
|
192
|
+
return value ? [name, value] : null;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Builds the final URL: tokens resolved, params appended and percent-encoded
|
|
196
|
+
* by `URLSearchParams` so a value can never break out into the query grammar.
|
|
197
|
+
*/
|
|
198
|
+
export function buildRequest(source, context) {
|
|
199
|
+
const url = assertFetchableUrl(resolveTokens(source.url, context));
|
|
200
|
+
for (const pair of source.params ?? []) {
|
|
201
|
+
const key = pair.key.trim();
|
|
202
|
+
if (!key)
|
|
203
|
+
continue;
|
|
204
|
+
const value = resolveTokens(pair.value, context);
|
|
205
|
+
// An empty optional filter is dropped rather than sent as `key=`.
|
|
206
|
+
if (value === "")
|
|
207
|
+
continue;
|
|
208
|
+
url.searchParams.set(key, value);
|
|
209
|
+
}
|
|
210
|
+
const method = source.method ?? "GET";
|
|
211
|
+
const headers = {
|
|
212
|
+
accept: "application/json,text/plain;q=0.9,*/*;q=0.8",
|
|
213
|
+
};
|
|
214
|
+
let body;
|
|
215
|
+
if (sendsBody(method) && source.body?.trim()) {
|
|
216
|
+
body = resolveTokens(source.body, context);
|
|
217
|
+
headers["content-type"] = "application/json";
|
|
218
|
+
}
|
|
219
|
+
// Author headers last, so they can override the defaults above.
|
|
220
|
+
for (const pair of source.headers ?? []) {
|
|
221
|
+
const safe = safeHeader(pair, context);
|
|
222
|
+
if (safe)
|
|
223
|
+
headers[safe[0]] = safe[1];
|
|
224
|
+
}
|
|
225
|
+
// Re-check after tokens: a token could have rewritten the host.
|
|
226
|
+
return { url: assertFetchableUrl(url.toString()), headers, method, body };
|
|
227
|
+
}
|
|
228
|
+
export const EMPTY_CONTEXT = { query: {}, params: {}, page: { slug: "" } };
|
|
229
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../../../src/internal/lib/data/source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { CanvasElement, ElementStyle, ElementType, RootStyle, StyleKey } from "./types";
|
|
2
|
+
type AiElementExtras = {
|
|
3
|
+
styleBindings?: Partial<Record<StyleKey, string>>;
|
|
4
|
+
interaction?: CanvasElement["interaction"];
|
|
5
|
+
pressStyle?: Partial<ElementStyle>;
|
|
6
|
+
loop?: CanvasElement["loop"];
|
|
7
|
+
draggable?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type AiDesignOperation = {
|
|
10
|
+
kind: "add";
|
|
11
|
+
ref: string;
|
|
12
|
+
type: ElementType;
|
|
13
|
+
parentId?: string | null;
|
|
14
|
+
content?: string;
|
|
15
|
+
src?: string;
|
|
16
|
+
href?: string;
|
|
17
|
+
style?: Partial<ElementStyle>;
|
|
18
|
+
tabletStyle?: Partial<ElementStyle>;
|
|
19
|
+
mobileStyle?: Partial<ElementStyle>;
|
|
20
|
+
hoverStyle?: Partial<ElementStyle>;
|
|
21
|
+
} & AiElementExtras | {
|
|
22
|
+
kind: "update";
|
|
23
|
+
id: string;
|
|
24
|
+
content?: string;
|
|
25
|
+
src?: string;
|
|
26
|
+
href?: string;
|
|
27
|
+
style?: Partial<ElementStyle>;
|
|
28
|
+
tabletStyle?: Partial<ElementStyle>;
|
|
29
|
+
mobileStyle?: Partial<ElementStyle>;
|
|
30
|
+
hoverStyle?: Partial<ElementStyle>;
|
|
31
|
+
} & AiElementExtras | {
|
|
32
|
+
kind: "remove";
|
|
33
|
+
id: string;
|
|
34
|
+
} | {
|
|
35
|
+
kind: "page";
|
|
36
|
+
style: Partial<RootStyle>;
|
|
37
|
+
};
|
|
38
|
+
export type AiDesignPlan = {
|
|
39
|
+
message: string;
|
|
40
|
+
steps: string[];
|
|
41
|
+
operations: AiDesignOperation[];
|
|
42
|
+
};
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=ai-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-types.d.ts","sourceRoot":"","sources":["../../../../src/internal/lib/editor/ai-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE7F,KAAK,eAAe,GAAG;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,WAAW,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAC3C,UAAU,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACvB;IACI,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CACtC,GAAG,eAAe,GACnB;IACI,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CACtC,GAAG,eAAe,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,iBAAiB,EAAE,CAAC;CACnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-types.js","sourceRoot":"","sources":["../../../../src/internal/lib/editor/ai-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Breakpoint, CanvasElement } from "./types";
|
|
2
|
+
export type AlignAction = "left" | "center-x" | "right" | "top" | "center-y" | "bottom";
|
|
3
|
+
export type DistributeAction = "horizontal" | "vertical";
|
|
4
|
+
/**
|
|
5
|
+
* Aligns the selection against its own bounding box. Only meaningful for
|
|
6
|
+
* elements positioned by x/y, so callers should restrict it to siblings inside
|
|
7
|
+
* an absolute parent.
|
|
8
|
+
*/
|
|
9
|
+
export declare function alignElements(elements: CanvasElement[], ids: string[], action: AlignAction, breakpoint: Breakpoint): CanvasElement[];
|
|
10
|
+
/** Evens out the gaps between the outermost two elements of the selection. */
|
|
11
|
+
export declare function distributeElements(elements: CanvasElement[], ids: string[], action: DistributeAction, breakpoint: Breakpoint): CanvasElement[];
|
|
12
|
+
//# sourceMappingURL=arrange.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrange.d.ts","sourceRoot":"","sources":["../../../../src/internal/lib/editor/arrange.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEzD,MAAM,MAAM,WAAW,GACjB,MAAM,GACN,UAAU,GACV,OAAO,GACP,KAAK,GACL,UAAU,GACV,QAAQ,CAAC;AAEf,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,UAAU,CAAC;AAiBzD;;;;GAIG;AACH,wBAAgB,aAAa,CACzB,QAAQ,EAAE,aAAa,EAAE,EACzB,GAAG,EAAE,MAAM,EAAE,EACb,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,UAAU,GACvB,aAAa,EAAE,CAiCjB;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAC9B,QAAQ,EAAE,aAAa,EAAE,EACzB,GAAG,EAAE,MAAM,EAAE,EACb,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,UAAU,GACvB,aAAa,EAAE,CA4BjB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { applyStyle, resolveStyle } from "./style";
|
|
2
|
+
function boxesOf(elements, ids, breakpoint) {
|
|
3
|
+
return elements
|
|
4
|
+
.filter((el) => ids.includes(el.id))
|
|
5
|
+
.map((el) => {
|
|
6
|
+
const style = resolveStyle(el, breakpoint);
|
|
7
|
+
return { id: el.id, x: style.x, y: style.y, w: style.w, h: style.h };
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Aligns the selection against its own bounding box. Only meaningful for
|
|
12
|
+
* elements positioned by x/y, so callers should restrict it to siblings inside
|
|
13
|
+
* an absolute parent.
|
|
14
|
+
*/
|
|
15
|
+
export function alignElements(elements, ids, action, breakpoint) {
|
|
16
|
+
const boxes = boxesOf(elements, ids, breakpoint);
|
|
17
|
+
if (boxes.length < 2)
|
|
18
|
+
return elements;
|
|
19
|
+
const minX = Math.min(...boxes.map((b) => b.x));
|
|
20
|
+
const maxX = Math.max(...boxes.map((b) => b.x + b.w));
|
|
21
|
+
const minY = Math.min(...boxes.map((b) => b.y));
|
|
22
|
+
const maxY = Math.max(...boxes.map((b) => b.y + b.h));
|
|
23
|
+
const midX = (minX + maxX) / 2;
|
|
24
|
+
const midY = (minY + maxY) / 2;
|
|
25
|
+
const patchFor = (box) => {
|
|
26
|
+
switch (action) {
|
|
27
|
+
case "left":
|
|
28
|
+
return { x: minX };
|
|
29
|
+
case "right":
|
|
30
|
+
return { x: maxX - box.w };
|
|
31
|
+
case "center-x":
|
|
32
|
+
return { x: midX - box.w / 2 };
|
|
33
|
+
case "top":
|
|
34
|
+
return { y: minY };
|
|
35
|
+
case "bottom":
|
|
36
|
+
return { y: maxY - box.h };
|
|
37
|
+
case "center-y":
|
|
38
|
+
return { y: midY - box.h / 2 };
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const byId = new Map(boxes.map((b) => [b.id, b]));
|
|
42
|
+
return elements.map((el) => {
|
|
43
|
+
const box = byId.get(el.id);
|
|
44
|
+
return box ? applyStyle(el, breakpoint, patchFor(box)) : el;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/** Evens out the gaps between the outermost two elements of the selection. */
|
|
48
|
+
export function distributeElements(elements, ids, action, breakpoint) {
|
|
49
|
+
const boxes = boxesOf(elements, ids, breakpoint);
|
|
50
|
+
if (boxes.length < 3)
|
|
51
|
+
return elements;
|
|
52
|
+
const horizontal = action === "horizontal";
|
|
53
|
+
const sorted = [...boxes].sort((a, b) => horizontal ? a.x - b.x : a.y - b.y);
|
|
54
|
+
const first = sorted[0];
|
|
55
|
+
const last = sorted[sorted.length - 1];
|
|
56
|
+
const span = horizontal
|
|
57
|
+
? last.x + last.w - first.x
|
|
58
|
+
: last.y + last.h - first.y;
|
|
59
|
+
const used = sorted.reduce((sum, b) => sum + (horizontal ? b.w : b.h), 0);
|
|
60
|
+
const gap = (span - used) / (sorted.length - 1);
|
|
61
|
+
const patches = new Map();
|
|
62
|
+
let cursor = horizontal ? first.x : first.y;
|
|
63
|
+
for (const box of sorted) {
|
|
64
|
+
patches.set(box.id, horizontal ? { x: cursor } : { y: cursor });
|
|
65
|
+
cursor += (horizontal ? box.w : box.h) + gap;
|
|
66
|
+
}
|
|
67
|
+
return elements.map((el) => {
|
|
68
|
+
const patch = patches.get(el.id);
|
|
69
|
+
return patch ? applyStyle(el, breakpoint, patch) : el;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=arrange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrange.js","sourceRoot":"","sources":["../../../../src/internal/lib/editor/arrange.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type BreakpointDefinition } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* The breakpoint layout of a page: which artboards exist and which one holds
|
|
4
|
+
* the shared values.
|
|
5
|
+
*
|
|
6
|
+
* Styles live in two places — `element.base` carries the base breakpoint's
|
|
7
|
+
* values, and `element.overrides[id]` carries the deltas for every other one.
|
|
8
|
+
* Which overrides apply to a given artboard depends entirely on where it sits
|
|
9
|
+
* relative to the base, so that ordering is computed here rather than being
|
|
10
|
+
* hard-coded to desktop → tablet → mobile.
|
|
11
|
+
*/
|
|
12
|
+
export type Cascade = {
|
|
13
|
+
breakpoints: BreakpointDefinition[];
|
|
14
|
+
/** Whose values live in `element.base`. */
|
|
15
|
+
baseId: string;
|
|
16
|
+
};
|
|
17
|
+
export declare const DEFAULT_CASCADE: Cascade;
|
|
18
|
+
/** Builds a cascade from whatever the page has stored, filling the gaps. */
|
|
19
|
+
export declare function cascadeOf(breakpoints: BreakpointDefinition[] | undefined, baseId: string | undefined): Cascade;
|
|
20
|
+
export declare function baseOf(cascade: Cascade): BreakpointDefinition;
|
|
21
|
+
/**
|
|
22
|
+
* The overrides to apply, in order, to reach `targetId` from the base.
|
|
23
|
+
*
|
|
24
|
+
* Narrower artboards inherit downward from the base and wider ones inherit
|
|
25
|
+
* upward, so a value set on the base reaches both directions until something
|
|
26
|
+
* closer to the target overrides it.
|
|
27
|
+
*/
|
|
28
|
+
export declare function overrideChain(cascade: Cascade, targetId: string): string[];
|
|
29
|
+
/**
|
|
30
|
+
* Media queries for the published page, in the order they must appear so that
|
|
31
|
+
* later rules win. Narrower artboards become `max-width`, wider ones
|
|
32
|
+
* `min-width`; the base itself needs no query.
|
|
33
|
+
*/
|
|
34
|
+
export declare function mediaPlan(cascade: Cascade): Array<{
|
|
35
|
+
id: string;
|
|
36
|
+
query: string;
|
|
37
|
+
}>;
|
|
38
|
+
export declare function chainFor(cascade: Cascade, targetId: string): string[];
|
|
39
|
+
//# sourceMappingURL=cascade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cascade.d.ts","sourceRoot":"","sources":["../../../../src/internal/lib/editor/cascade.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,oBAAoB,EAE5B,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;GASG;AACH,MAAM,MAAM,OAAO,GAAG;IAClB,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,OAG7B,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,SAAS,CACrB,WAAW,EAAE,oBAAoB,EAAE,GAAG,SAAS,EAC/C,MAAM,EAAE,MAAM,GAAG,SAAS,GAC3B,OAAO,CAIT;AAMD,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAK7D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAoB1E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACrB,OAAO,EAAE,OAAO,GACjB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAyBtC;AAKD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAYrE"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DEFAULT_BREAKPOINTS, } from "./types";
|
|
2
|
+
export const DEFAULT_CASCADE = {
|
|
3
|
+
breakpoints: DEFAULT_BREAKPOINTS,
|
|
4
|
+
baseId: "desktop",
|
|
5
|
+
};
|
|
6
|
+
/** Builds a cascade from whatever the page has stored, filling the gaps. */
|
|
7
|
+
export function cascadeOf(breakpoints, baseId) {
|
|
8
|
+
const list = breakpoints?.length ? breakpoints : DEFAULT_BREAKPOINTS;
|
|
9
|
+
const base = list.find((item) => item.id === baseId) ?? widest(list);
|
|
10
|
+
return { breakpoints: list, baseId: base.id };
|
|
11
|
+
}
|
|
12
|
+
function widest(list) {
|
|
13
|
+
return list.reduce((a, b) => (b.width > a.width ? b : a), list[0]);
|
|
14
|
+
}
|
|
15
|
+
export function baseOf(cascade) {
|
|
16
|
+
return (cascade.breakpoints.find((item) => item.id === cascade.baseId) ??
|
|
17
|
+
widest(cascade.breakpoints));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The overrides to apply, in order, to reach `targetId` from the base.
|
|
21
|
+
*
|
|
22
|
+
* Narrower artboards inherit downward from the base and wider ones inherit
|
|
23
|
+
* upward, so a value set on the base reaches both directions until something
|
|
24
|
+
* closer to the target overrides it.
|
|
25
|
+
*/
|
|
26
|
+
export function overrideChain(cascade, targetId) {
|
|
27
|
+
const base = baseOf(cascade);
|
|
28
|
+
if (targetId === base.id)
|
|
29
|
+
return [];
|
|
30
|
+
const target = cascade.breakpoints.find((item) => item.id === targetId);
|
|
31
|
+
if (!target)
|
|
32
|
+
return [];
|
|
33
|
+
const goingNarrower = target.width < base.width;
|
|
34
|
+
const between = cascade.breakpoints.filter((item) => {
|
|
35
|
+
if (item.id === base.id)
|
|
36
|
+
return false;
|
|
37
|
+
return goingNarrower
|
|
38
|
+
? item.width < base.width && item.width >= target.width
|
|
39
|
+
: item.width > base.width && item.width <= target.width;
|
|
40
|
+
});
|
|
41
|
+
// Apply from the artboard nearest the base outward, so the one closest to
|
|
42
|
+
// the target has the last word.
|
|
43
|
+
between.sort((a, b) => (goingNarrower ? b.width - a.width : a.width - b.width));
|
|
44
|
+
return between.map((item) => item.id);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Media queries for the published page, in the order they must appear so that
|
|
48
|
+
* later rules win. Narrower artboards become `max-width`, wider ones
|
|
49
|
+
* `min-width`; the base itself needs no query.
|
|
50
|
+
*/
|
|
51
|
+
export function mediaPlan(cascade) {
|
|
52
|
+
const base = baseOf(cascade);
|
|
53
|
+
// An artboard governs from its own width up to just below the next wider
|
|
54
|
+
// one — the same reading the canvas gives, where a 1000px window falls to
|
|
55
|
+
// the nearest artboard at or below it.
|
|
56
|
+
const narrower = cascade.breakpoints
|
|
57
|
+
.filter((item) => item.id !== base.id && item.width < base.width)
|
|
58
|
+
.sort((a, b) => b.width - a.width)
|
|
59
|
+
.map((item) => {
|
|
60
|
+
const ceiling = cascade.breakpoints
|
|
61
|
+
.filter((other) => other.width > item.width)
|
|
62
|
+
.reduce((lowest, other) => Math.min(lowest, other.width), Number.POSITIVE_INFINITY);
|
|
63
|
+
return { id: item.id, query: `(max-width: ${ceiling - 1}px)` };
|
|
64
|
+
});
|
|
65
|
+
const wider = cascade.breakpoints
|
|
66
|
+
.filter((item) => item.id !== base.id && item.width > base.width)
|
|
67
|
+
.sort((a, b) => a.width - b.width)
|
|
68
|
+
.map((item) => ({ id: item.id, query: `(min-width: ${item.width}px)` }));
|
|
69
|
+
return [...narrower, ...wider];
|
|
70
|
+
}
|
|
71
|
+
/** Memoised chains — resolution runs per element, the chain does not. */
|
|
72
|
+
const chainCache = new WeakMap();
|
|
73
|
+
export function chainFor(cascade, targetId) {
|
|
74
|
+
let byTarget = chainCache.get(cascade);
|
|
75
|
+
if (!byTarget) {
|
|
76
|
+
byTarget = new Map();
|
|
77
|
+
chainCache.set(cascade, byTarget);
|
|
78
|
+
}
|
|
79
|
+
const cached = byTarget.get(targetId);
|
|
80
|
+
if (cached)
|
|
81
|
+
return cached;
|
|
82
|
+
const chain = overrideChain(cascade, targetId);
|
|
83
|
+
byTarget.set(targetId, chain);
|
|
84
|
+
return chain;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=cascade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cascade.js","sourceRoot":"","sources":["../../../../src/internal/lib/editor/cascade.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../../src/internal/lib/editor/icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAW7C,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,aAAa,CAAA;CAAE,qBAEhE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const paths = {
|
|
3
|
+
star: _jsx("path", { d: "m12 2.8 2.8 5.7 6.2.9-4.5 4.4 1.1 6.2-5.6-2.9L6.4 20l1.1-6.2L3 9.4l6.2-.9L12 2.8Z" }),
|
|
4
|
+
heart: _jsx("path", { d: "M20.8 5.8c-2.2-2.2-5.7-2.2-7.9 0L12 6.7l-.9-.9a5.6 5.6 0 0 0-7.9 7.9L12 22l8.8-8.3a5.6 5.6 0 0 0 0-7.9Z" }),
|
|
5
|
+
"arrow-right": _jsxs(_Fragment, { children: [_jsx("path", { d: "M5 12h14" }), _jsx("path", { d: "m14 7 5 5-5 5" })] }),
|
|
6
|
+
check: _jsx("path", { d: "m5 12 4 4L19 6" }),
|
|
7
|
+
menu: _jsxs(_Fragment, { children: [_jsx("path", { d: "M4 7h16" }), _jsx("path", { d: "M4 12h16" }), _jsx("path", { d: "M4 17h16" })] }),
|
|
8
|
+
search: _jsxs(_Fragment, { children: [_jsx("circle", { cx: "11", cy: "11", r: "7" }), _jsx("path", { d: "m20 20-4-4" })] }),
|
|
9
|
+
};
|
|
10
|
+
export function IconGlyph({ element }) {
|
|
11
|
+
return _jsx("svg", { viewBox: "0 0 24 24", width: "100%", height: "100%", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: paths[element.iconName ?? "star"] });
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=icon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon.js","sourceRoot":"","sources":["../../../../src/internal/lib/editor/icon.tsx"],"names":[],"mappings":";AAGA,MAAM,KAAK,GAAoE;IAC3E,IAAI,EAAE,eAAM,CAAC,EAAC,mFAAmF,GAAG;IACpG,KAAK,EAAE,eAAM,CAAC,EAAC,yGAAyG,GAAG;IAC3H,aAAa,EAAE,8BAAE,eAAM,CAAC,EAAC,UAAU,GAAG,EAAA,eAAM,CAAC,EAAC,eAAe,GAAG,IAAG;IACnE,KAAK,EAAE,eAAM,CAAC,EAAC,gBAAgB,GAAG;IAClC,IAAI,EAAE,8BAAE,eAAM,CAAC,EAAC,SAAS,GAAG,EAAA,eAAM,CAAC,EAAC,UAAU,GAAG,EAAA,eAAM,CAAC,EAAC,UAAU,GAAG,IAAG;IACzE,MAAM,EAAE,8BAAE,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,GAAG,GAAG,EAAA,eAAM,CAAC,EAAC,YAAY,GAAG,IAAG;CACvE,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,EAAE,OAAO,EAA8B;IAC7D,OAAO,cAAK,OAAO,EAAC,WAAW,EAAC,KAAK,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,iBAAa,MAAM,YAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC,GAAO,CAAC;AAC3N,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CanvasElement } from "./types";
|
|
2
|
+
export type ComponentPreset = {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
category: "Navigation" | "Hero" | "Footer";
|
|
6
|
+
description: string;
|
|
7
|
+
create: () => CanvasElement[];
|
|
8
|
+
};
|
|
9
|
+
export declare const COMPONENT_PRESETS: ComponentPreset[];
|
|
10
|
+
//# sourceMappingURL=presets.d.ts.map
|