@johnhenry/sitefile 0.0.0-stage → 0.0.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/CHANGELOG.md +48 -0
- package/LICENSE +21 -0
- package/README.md +475 -2
- package/lib/src/archive-writers.d.ts +31 -0
- package/lib/src/archive-writers.js +197 -0
- package/lib/src/attest.d.ts +126 -0
- package/lib/src/attest.js +220 -0
- package/lib/src/bake.d.ts +74 -0
- package/lib/src/bake.js +372 -0
- package/lib/src/base-image.d.ts +76 -0
- package/lib/src/base-image.js +138 -0
- package/lib/src/build-args.d.ts +26 -0
- package/lib/src/build-args.js +164 -0
- package/lib/src/cache-limit.d.ts +54 -0
- package/lib/src/cache-limit.js +239 -0
- package/lib/src/casefold-data.d.ts +2 -0
- package/lib/src/casefold-data.js +217 -0
- package/lib/src/cbor.d.ts +39 -0
- package/lib/src/cbor.js +174 -0
- package/lib/src/checklinks.d.ts +42 -0
- package/lib/src/checklinks.js +118 -0
- package/lib/src/cli/bake.d.ts +2 -0
- package/lib/src/cli/bake.js +179 -0
- package/lib/src/cli/build-image.d.ts +21 -0
- package/lib/src/cli/build-image.js +42 -0
- package/lib/src/cli/cache.d.ts +8 -0
- package/lib/src/cli/cache.js +109 -0
- package/lib/src/cli/common.d.ts +29 -0
- package/lib/src/cli/common.js +100 -0
- package/lib/src/cli/git-context.d.ts +18 -0
- package/lib/src/cli/git-context.js +48 -0
- package/lib/src/cli/images.d.ts +6 -0
- package/lib/src/cli/images.js +285 -0
- package/lib/src/cli/index.d.ts +10 -0
- package/lib/src/cli/index.js +95 -0
- package/lib/src/cli/outdated.d.ts +5 -0
- package/lib/src/cli/outdated.js +94 -0
- package/lib/src/cli/registry.d.ts +2 -0
- package/lib/src/cli/registry.js +122 -0
- package/lib/src/cli/serve-worker.d.ts +2 -0
- package/lib/src/cli/serve-worker.js +42 -0
- package/lib/src/cli/servers.d.ts +15 -0
- package/lib/src/cli/servers.js +451 -0
- package/lib/src/cli/vendor.d.ts +2 -0
- package/lib/src/cli/vendor.js +92 -0
- package/lib/src/cli/watch.d.ts +26 -0
- package/lib/src/cli/watch.js +81 -0
- package/lib/src/cli.d.ts +12 -0
- package/lib/src/cli.js +486 -0
- package/lib/src/csv.d.ts +27 -0
- package/lib/src/csv.js +117 -0
- package/lib/src/deflate.d.ts +76 -0
- package/lib/src/deflate.js +604 -0
- package/lib/src/digest.d.ts +3 -0
- package/lib/src/digest.js +7 -0
- package/lib/src/errors.d.ts +34 -0
- package/lib/src/errors.js +20 -0
- package/lib/src/executor.d.ts +386 -0
- package/lib/src/executor.js +2193 -0
- package/lib/src/explain.d.ts +64 -0
- package/lib/src/explain.js +445 -0
- package/lib/src/export-formats.d.ts +16 -0
- package/lib/src/export-formats.js +52 -0
- package/lib/src/exporter.d.ts +103 -0
- package/lib/src/exporter.js +676 -0
- package/lib/src/fingerprint.d.ts +40 -0
- package/lib/src/fingerprint.js +168 -0
- package/lib/src/frontmatter.d.ts +22 -0
- package/lib/src/frontmatter.js +45 -0
- package/lib/src/index.d.ts +12 -0
- package/lib/src/index.js +12 -0
- package/lib/src/language/ast.d.ts +353 -0
- package/lib/src/language/ast.js +57 -0
- package/lib/src/language/parser.d.ts +3 -0
- package/lib/src/language/parser.js +612 -0
- package/lib/src/language/scanner.d.ts +110 -0
- package/lib/src/language/scanner.js +449 -0
- package/lib/src/language/validate.d.ts +13 -0
- package/lib/src/language/validate.js +367 -0
- package/lib/src/links.d.ts +79 -0
- package/lib/src/links.js +583 -0
- package/lib/src/lint.d.ts +10 -0
- package/lib/src/lint.js +223 -0
- package/lib/src/markdown.d.ts +29 -0
- package/lib/src/markdown.js +612 -0
- package/lib/src/media.d.ts +82 -0
- package/lib/src/media.js +650 -0
- package/lib/src/memo.d.ts +57 -0
- package/lib/src/memo.js +93 -0
- package/lib/src/oci.d.ts +178 -0
- package/lib/src/oci.js +380 -0
- package/lib/src/outdated.d.ts +46 -0
- package/lib/src/outdated.js +195 -0
- package/lib/src/pages.d.ts +10 -0
- package/lib/src/pages.js +54 -0
- package/lib/src/paths.d.ts +39 -0
- package/lib/src/paths.js +101 -0
- package/lib/src/planner.d.ts +297 -0
- package/lib/src/planner.js +410 -0
- package/lib/src/plugins/cache.d.ts +70 -0
- package/lib/src/plugins/cache.js +226 -0
- package/lib/src/plugins/exec.d.ts +51 -0
- package/lib/src/plugins/exec.js +144 -0
- package/lib/src/plugins/host.d.ts +75 -0
- package/lib/src/plugins/host.js +277 -0
- package/lib/src/plugins/wasm.d.ts +23 -0
- package/lib/src/plugins/wasm.js +249 -0
- package/lib/src/profile.d.ts +42 -0
- package/lib/src/profile.js +68 -0
- package/lib/src/ref.d.ts +40 -0
- package/lib/src/ref.js +79 -0
- package/lib/src/registry-auth.d.ts +32 -0
- package/lib/src/registry-auth.js +151 -0
- package/lib/src/registry-cache.d.ts +71 -0
- package/lib/src/registry-cache.js +333 -0
- package/lib/src/registry-ops.d.ts +51 -0
- package/lib/src/registry-ops.js +248 -0
- package/lib/src/registry.d.ts +109 -0
- package/lib/src/registry.js +505 -0
- package/lib/src/render.d.ts +134 -0
- package/lib/src/render.js +576 -0
- package/lib/src/resources/archive.d.ts +11 -0
- package/lib/src/resources/archive.js +306 -0
- package/lib/src/resources/bundle-data.d.ts +16 -0
- package/lib/src/resources/bundle-data.js +50 -0
- package/lib/src/resources/convert.d.ts +12 -0
- package/lib/src/resources/convert.js +63 -0
- package/lib/src/resources/documents.d.ts +35 -0
- package/lib/src/resources/documents.js +122 -0
- package/lib/src/resources/git.d.ts +103 -0
- package/lib/src/resources/git.js +720 -0
- package/lib/src/resources/https.d.ts +40 -0
- package/lib/src/resources/https.js +256 -0
- package/lib/src/resources/ignore.d.ts +33 -0
- package/lib/src/resources/ignore.js +119 -0
- package/lib/src/resources/local.d.ts +64 -0
- package/lib/src/resources/local.js +248 -0
- package/lib/src/resources/lockfile.d.ts +52 -0
- package/lib/src/resources/lockfile.js +172 -0
- package/lib/src/resources/netpolicy.d.ts +6 -0
- package/lib/src/resources/netpolicy.js +82 -0
- package/lib/src/resources/types.d.ts +63 -0
- package/lib/src/resources/types.js +13 -0
- package/lib/src/resources/vendor.d.ts +94 -0
- package/lib/src/resources/vendor.js +296 -0
- package/lib/src/resources/wbn-reader.d.ts +44 -0
- package/lib/src/resources/wbn-reader.js +302 -0
- package/lib/src/schema.d.ts +25 -0
- package/lib/src/schema.js +169 -0
- package/lib/src/secrets.d.ts +21 -0
- package/lib/src/secrets.js +103 -0
- package/lib/src/serve-rules.d.ts +29 -0
- package/lib/src/serve-rules.js +122 -0
- package/lib/src/server.d.ts +45 -0
- package/lib/src/server.js +246 -0
- package/lib/src/servers.d.ts +71 -0
- package/lib/src/servers.js +139 -0
- package/lib/src/site.d.ts +60 -0
- package/lib/src/site.js +169 -0
- package/lib/src/store.d.ts +151 -0
- package/lib/src/store.js +596 -0
- package/lib/src/tree.d.ts +50 -0
- package/lib/src/tree.js +134 -0
- package/lib/src/values.d.ts +7 -0
- package/lib/src/values.js +37 -0
- package/lib/src/vendor.d.ts +19 -0
- package/lib/src/vendor.js +145 -0
- package/lib/src/watch.d.ts +44 -0
- package/lib/src/watch.js +137 -0
- package/lib/src/wbn.d.ts +5 -0
- package/lib/src/wbn.js +147 -0
- package/lib/src/yaml.d.ts +34 -0
- package/lib/src/yaml.js +562 -0
- package/package.json +58 -4
package/lib/src/pages.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// What a `RENDER … FOR x IN list [BY key] [PAGE n [FIRST <dest>]]` loop renders (docs/LANGUAGE.md, "Tag pages,
|
|
2
|
+
// pagination and drafts"):
|
|
3
|
+
//
|
|
4
|
+
// - BY key: one element per distinct value of `key` (a list field gives one per element), `{ key, count, items }`,
|
|
5
|
+
// keys in SORT BY order (numeric strings numerically, otherwise UTF-16 order); items keep the list's order.
|
|
6
|
+
// - PAGE n: the list (or each group) cut into pages of n items: `{ [key,] count, items, number, total }`; the
|
|
7
|
+
// executor adds `url`, `prev` and `next` once it knows each page's destination. An empty list (without BY) is
|
|
8
|
+
// one page with no items, so an index always exists.
|
|
9
|
+
import { SitefileError } from './errors.js';
|
|
10
|
+
import { compareValues } from './resources/documents.js';
|
|
11
|
+
const isObject = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);
|
|
12
|
+
/** Group documents by a field; `what` prefixes messages (`FOR tag IN posts BY tags`). */
|
|
13
|
+
export function groupBy(items, key, what, span) {
|
|
14
|
+
const groups = new Map();
|
|
15
|
+
items.forEach((item, i) => {
|
|
16
|
+
if (!isObject(item))
|
|
17
|
+
throw new SitefileError('E_TYPE', `${what}: element ${i + 1} is not a document (an object with a '${key}' field)`, span);
|
|
18
|
+
const v = item[key];
|
|
19
|
+
const name = typeof item['path'] === 'string' ? item['path'] : `#${i + 1}`;
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
for (const x of Array.isArray(v) ? v : [v]) {
|
|
22
|
+
if (x === undefined || x === null || x === '')
|
|
23
|
+
continue;
|
|
24
|
+
if (typeof x !== 'string' && typeof x !== 'number' && typeof x !== 'boolean') {
|
|
25
|
+
throw new SitefileError('E_TYPE', `${what}: '${key}' of document '${name}' is not text or a list of text`, span);
|
|
26
|
+
}
|
|
27
|
+
const k = String(x);
|
|
28
|
+
if (seen.has(k))
|
|
29
|
+
continue;
|
|
30
|
+
seen.add(k);
|
|
31
|
+
const g = groups.get(k);
|
|
32
|
+
if (g)
|
|
33
|
+
g.push(item);
|
|
34
|
+
else
|
|
35
|
+
groups.set(k, [item]);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
const keys = [...groups.keys()].sort((a, b) => compareValues(a, b));
|
|
39
|
+
return keys.map((k) => ({ key: k, count: groups.get(k).length, items: groups.get(k) }));
|
|
40
|
+
}
|
|
41
|
+
/** Cut each group (or the whole list, as one group without a key) into pages of `size` items. */
|
|
42
|
+
export function paginate(groups, size) {
|
|
43
|
+
return groups.map((g) => {
|
|
44
|
+
const total = Math.max(1, Math.ceil(g.items.length / size));
|
|
45
|
+
return Array.from({ length: total }, (_, i) => ({
|
|
46
|
+
...(g.key !== undefined ? { key: g.key } : {}),
|
|
47
|
+
count: g.items.length,
|
|
48
|
+
items: g.items.slice(i * size, (i + 1) * size),
|
|
49
|
+
number: i + 1,
|
|
50
|
+
total,
|
|
51
|
+
}));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=pages.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type SourceSpan } from './errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Unicode NFC. Every virtual path (Sitefile operands, names read from the
|
|
4
|
+
* context, archive entries, plugin outputs) is stored in NFC, so NFC and NFD
|
|
5
|
+
* spellings of a name are the same path on every OS.
|
|
6
|
+
*/
|
|
7
|
+
export declare function nfc(s: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Unicode simple case folding (CaseFolding.txt status C and S, one code
|
|
10
|
+
* point to one code point; no full or Turkic mappings), applied code point
|
|
11
|
+
* by code point. Two paths with the same fold differ only in case.
|
|
12
|
+
* `rust/src/paths.rs` uses the same generated table.
|
|
13
|
+
*/
|
|
14
|
+
export declare function foldCase(s: string): string;
|
|
15
|
+
export interface VirtualPath {
|
|
16
|
+
/** Normalized absolute POSIX path inside the artifact, `/` for the root. */
|
|
17
|
+
readonly path: string;
|
|
18
|
+
/** The original ended with `/` (or was the root). */
|
|
19
|
+
readonly trailingSlash: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Normalize an artifact (virtual) path. Must be absolute; `.` and repeated
|
|
23
|
+
* slashes collapse; any `..` segment is rejected outright; the result is NFC.
|
|
24
|
+
*/
|
|
25
|
+
export declare function normalizeVirtual(raw: string, span?: SourceSpan, what?: string): VirtualPath;
|
|
26
|
+
/**
|
|
27
|
+
* Normalize a host path relative to the build context. Returns a relative
|
|
28
|
+
* POSIX path (`''` for the context root). Rejects absolute paths and anything
|
|
29
|
+
* that escapes the context with `..`. The result is NFC; LocalContext finds
|
|
30
|
+
* the file whatever normalization its on-disk name uses.
|
|
31
|
+
*/
|
|
32
|
+
export declare function normalizeLocal(raw: string, span?: SourceSpan): {
|
|
33
|
+
path: string;
|
|
34
|
+
trailingSlash: boolean;
|
|
35
|
+
};
|
|
36
|
+
export declare function joinVirtual(dir: string, name: string): string;
|
|
37
|
+
export declare function basenameVirtual(p: string): string;
|
|
38
|
+
/** Ancestors of a virtual path, excluding the root and the path itself. */
|
|
39
|
+
export declare function ancestorsVirtual(p: string): string[];
|
package/lib/src/paths.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { posix } from 'node:path';
|
|
2
|
+
import { SitefileError } from './errors.js';
|
|
3
|
+
import { CASEFOLD_RUNS } from './casefold-data.js';
|
|
4
|
+
const ASCII = /^[\x00-\x7f]*$/;
|
|
5
|
+
/**
|
|
6
|
+
* Unicode NFC. Every virtual path (Sitefile operands, names read from the
|
|
7
|
+
* context, archive entries, plugin outputs) is stored in NFC, so NFC and NFD
|
|
8
|
+
* spellings of a name are the same path on every OS.
|
|
9
|
+
*/
|
|
10
|
+
export function nfc(s) {
|
|
11
|
+
return ASCII.test(s) ? s : s.normalize('NFC');
|
|
12
|
+
}
|
|
13
|
+
function foldCodePoint(c) {
|
|
14
|
+
let lo = 0;
|
|
15
|
+
let hi = CASEFOLD_RUNS.length - 1;
|
|
16
|
+
while (lo <= hi) {
|
|
17
|
+
const mid = (lo + hi) >> 1;
|
|
18
|
+
const [start, end, delta, step] = CASEFOLD_RUNS[mid];
|
|
19
|
+
if (c < start)
|
|
20
|
+
hi = mid - 1;
|
|
21
|
+
else if (c > end)
|
|
22
|
+
lo = mid + 1;
|
|
23
|
+
else
|
|
24
|
+
return (c - start) % step === 0 ? c + delta : c;
|
|
25
|
+
}
|
|
26
|
+
return c;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Unicode simple case folding (CaseFolding.txt status C and S, one code
|
|
30
|
+
* point to one code point; no full or Turkic mappings), applied code point
|
|
31
|
+
* by code point. Two paths with the same fold differ only in case.
|
|
32
|
+
* `rust/src/paths.rs` uses the same generated table.
|
|
33
|
+
*/
|
|
34
|
+
export function foldCase(s) {
|
|
35
|
+
if (ASCII.test(s))
|
|
36
|
+
return s.toLowerCase();
|
|
37
|
+
let out = '';
|
|
38
|
+
for (const ch of s)
|
|
39
|
+
out += String.fromCodePoint(foldCodePoint(ch.codePointAt(0)));
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Normalize an artifact (virtual) path. Must be absolute; `.` and repeated
|
|
44
|
+
* slashes collapse; any `..` segment is rejected outright; the result is NFC.
|
|
45
|
+
*/
|
|
46
|
+
export function normalizeVirtual(raw, span, what = 'path') {
|
|
47
|
+
raw = nfc(raw);
|
|
48
|
+
if (raw.includes('\0'))
|
|
49
|
+
throw new SitefileError('E_PATH', `${what} contains a NUL byte`, span);
|
|
50
|
+
if (!raw.startsWith('/')) {
|
|
51
|
+
throw new SitefileError('E_PATH', `${what} '${raw}' must be an absolute artifact path (start with '/')`, span);
|
|
52
|
+
}
|
|
53
|
+
const segments = [];
|
|
54
|
+
for (const seg of raw.split('/')) {
|
|
55
|
+
if (seg === '' || seg === '.')
|
|
56
|
+
continue;
|
|
57
|
+
if (seg === '..')
|
|
58
|
+
throw new SitefileError('E_PATH', `${what} '${raw}' must not contain '..'`, span);
|
|
59
|
+
segments.push(seg);
|
|
60
|
+
}
|
|
61
|
+
const path = '/' + segments.join('/');
|
|
62
|
+
return { path, trailingSlash: raw.endsWith('/') || path === '/' };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Normalize a host path relative to the build context. Returns a relative
|
|
66
|
+
* POSIX path (`''` for the context root). Rejects absolute paths and anything
|
|
67
|
+
* that escapes the context with `..`. The result is NFC; LocalContext finds
|
|
68
|
+
* the file whatever normalization its on-disk name uses.
|
|
69
|
+
*/
|
|
70
|
+
export function normalizeLocal(raw, span) {
|
|
71
|
+
raw = nfc(raw);
|
|
72
|
+
if (raw.includes('\0'))
|
|
73
|
+
throw new SitefileError('E_PATH', 'path contains a NUL byte', span);
|
|
74
|
+
if (raw.startsWith('/') || /^[A-Za-z]:[\\/]/.test(raw) || raw.startsWith('\\')) {
|
|
75
|
+
throw new SitefileError('E_PATH_ESCAPE', `local path '${raw}' must be relative to the build context`, span);
|
|
76
|
+
}
|
|
77
|
+
const norm = posix.normalize(raw === '' ? '.' : raw);
|
|
78
|
+
if (norm === '..' || norm.startsWith('../')) {
|
|
79
|
+
throw new SitefileError('E_PATH_ESCAPE', `local path '${raw}' escapes the build context`, span);
|
|
80
|
+
}
|
|
81
|
+
const path = norm === '.' || norm === './' ? '' : norm.replace(/\/+$/, '');
|
|
82
|
+
return { path, trailingSlash: raw.endsWith('/') };
|
|
83
|
+
}
|
|
84
|
+
export function joinVirtual(dir, name) {
|
|
85
|
+
name = nfc(name);
|
|
86
|
+
return dir === '/' ? `/${name}` : `${dir}/${name}`;
|
|
87
|
+
}
|
|
88
|
+
export function basenameVirtual(p) {
|
|
89
|
+
return posix.basename(p);
|
|
90
|
+
}
|
|
91
|
+
/** Ancestors of a virtual path, excluding the root and the path itself. */
|
|
92
|
+
export function ancestorsVirtual(p) {
|
|
93
|
+
const out = [];
|
|
94
|
+
let i = p.indexOf('/', 1);
|
|
95
|
+
while (i !== -1) {
|
|
96
|
+
out.push(p.slice(0, i));
|
|
97
|
+
i = p.indexOf('/', i + 1);
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { type SourceSpan } from './errors.js';
|
|
2
|
+
import { type EscapeMode, type RedirectStatus, type ExportFormat, type ImportKind, type OciCompression, type Operand, type Program } from './language/ast.js';
|
|
3
|
+
import { type Scalar } from './values.js';
|
|
4
|
+
import { type GitLocation } from './resources/git.js';
|
|
5
|
+
import type { TemplateNode } from './render.js';
|
|
6
|
+
/** An html LET: its template, parsed, evaluated where a RENDER uses it. */
|
|
7
|
+
export interface FragmentSpec {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
/** The template as written (memo keys). */
|
|
10
|
+
readonly text: string;
|
|
11
|
+
readonly nodes: readonly TemplateNode[];
|
|
12
|
+
readonly span: SourceSpan;
|
|
13
|
+
}
|
|
14
|
+
/** Where a COPY/RENDER reads from. */
|
|
15
|
+
export type SourceRef =
|
|
16
|
+
/** Content written in the Sitefile itself (heredoc); `bodyLine` is its first Sitefile line. */
|
|
17
|
+
{
|
|
18
|
+
readonly kind: 'inline';
|
|
19
|
+
readonly text: string;
|
|
20
|
+
readonly delimiter: string;
|
|
21
|
+
readonly bodyLine: number;
|
|
22
|
+
readonly span: SourceSpan;
|
|
23
|
+
}
|
|
24
|
+
/** `path` is a normalized virtual path inside an earlier stage's final tree (`--from=name`). */
|
|
25
|
+
| {
|
|
26
|
+
readonly kind: 'stage';
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly path: string;
|
|
29
|
+
readonly span: SourceSpan;
|
|
30
|
+
} | {
|
|
31
|
+
readonly kind: 'local';
|
|
32
|
+
readonly path: string;
|
|
33
|
+
readonly span: SourceSpan;
|
|
34
|
+
}
|
|
35
|
+
/** `path` is a normalized virtual path inside the import, `/` for the whole import. */
|
|
36
|
+
| {
|
|
37
|
+
readonly kind: 'import';
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly path: string;
|
|
40
|
+
readonly span: SourceSpan;
|
|
41
|
+
};
|
|
42
|
+
export interface ImportSpec {
|
|
43
|
+
readonly name: string;
|
|
44
|
+
/** Interpolated URI as written. */
|
|
45
|
+
readonly uri: string;
|
|
46
|
+
readonly location: {
|
|
47
|
+
readonly kind: 'local';
|
|
48
|
+
readonly path: string;
|
|
49
|
+
} | {
|
|
50
|
+
readonly kind: 'remote';
|
|
51
|
+
readonly url: string;
|
|
52
|
+
} | ({
|
|
53
|
+
readonly kind: 'git';
|
|
54
|
+
} & GitLocation);
|
|
55
|
+
readonly as?: ImportKind;
|
|
56
|
+
readonly integrity?: string;
|
|
57
|
+
readonly sort?: {
|
|
58
|
+
readonly key: string;
|
|
59
|
+
readonly descending: boolean;
|
|
60
|
+
};
|
|
61
|
+
/** `SCHEMA <path>`: `uri` as written (for messages), `path` context-relative. */
|
|
62
|
+
readonly schema?: {
|
|
63
|
+
readonly uri: string;
|
|
64
|
+
readonly path: string;
|
|
65
|
+
readonly span: SourceSpan;
|
|
66
|
+
};
|
|
67
|
+
/** `DRAFTS true|false`: false leaves out the elements whose `draft` is true. */
|
|
68
|
+
readonly drafts?: boolean;
|
|
69
|
+
/** Build secrets sent as request headers (ids and header names only; values come from --secret). */
|
|
70
|
+
readonly secrets?: readonly {
|
|
71
|
+
readonly id: string;
|
|
72
|
+
readonly header: string;
|
|
73
|
+
readonly bearer: boolean;
|
|
74
|
+
}[];
|
|
75
|
+
/** `AS sitefile`: the `ARG NAME=value` clauses, evaluated (build args of the imported Sitefile). */
|
|
76
|
+
readonly args?: readonly {
|
|
77
|
+
readonly name: string;
|
|
78
|
+
readonly value: string;
|
|
79
|
+
readonly span: SourceSpan;
|
|
80
|
+
}[];
|
|
81
|
+
readonly span: SourceSpan;
|
|
82
|
+
}
|
|
83
|
+
/** A declared renderer plugin: a local `.mjs` file in its own folder, or a `.wasm` module. */
|
|
84
|
+
export interface PluginSpec {
|
|
85
|
+
readonly name: string;
|
|
86
|
+
/** Context-relative path of the module. */
|
|
87
|
+
readonly path: string;
|
|
88
|
+
readonly integrity?: string;
|
|
89
|
+
readonly span: SourceSpan;
|
|
90
|
+
}
|
|
91
|
+
/** A declared external program; it runs only when the CLI allows it (`--allow-exec`). */
|
|
92
|
+
export interface ToolSpec {
|
|
93
|
+
readonly name: string;
|
|
94
|
+
readonly span: SourceSpan;
|
|
95
|
+
}
|
|
96
|
+
/** A REDIRECT, evaluated; written to `/_redirects` at EXPORT. */
|
|
97
|
+
export interface RedirectSpec {
|
|
98
|
+
readonly from: string;
|
|
99
|
+
readonly to: string;
|
|
100
|
+
readonly status: RedirectStatus;
|
|
101
|
+
readonly overwrite: boolean;
|
|
102
|
+
readonly span: SourceSpan;
|
|
103
|
+
}
|
|
104
|
+
/** A HEADER, evaluated; written to `/_headers` at EXPORT. */
|
|
105
|
+
export interface HeaderSpec {
|
|
106
|
+
readonly pattern: string;
|
|
107
|
+
readonly name: string;
|
|
108
|
+
readonly value: string;
|
|
109
|
+
readonly overwrite: boolean;
|
|
110
|
+
readonly span: SourceSpan;
|
|
111
|
+
}
|
|
112
|
+
export type Operation = {
|
|
113
|
+
/** Report the references in the tree's HTML and CSS files that point at nothing. */
|
|
114
|
+
readonly kind: 'CHECKLINKS';
|
|
115
|
+
readonly warn: boolean;
|
|
116
|
+
readonly external: boolean;
|
|
117
|
+
/** The EXPORT path: absolute references resolve below it. */
|
|
118
|
+
readonly root: string;
|
|
119
|
+
/** Every REDIRECT source in the Sitefile: links to them are not broken. */
|
|
120
|
+
readonly redirects: readonly string[];
|
|
121
|
+
readonly span: SourceSpan;
|
|
122
|
+
} | {
|
|
123
|
+
/** Rename the files matching `patterns` to `name.<hash>.ext` and rewrite the HTML and CSS that reference them. */
|
|
124
|
+
readonly kind: 'FINGERPRINT';
|
|
125
|
+
/** Checked absolute patterns, NFC; a trailing `/` became `/**`. */
|
|
126
|
+
readonly patterns: readonly string[];
|
|
127
|
+
/** `MANIFEST <dest>`: the JSON map of old to new paths. */
|
|
128
|
+
readonly manifest?: string;
|
|
129
|
+
/** The EXPORT path: absolute references (`/img/a.png`) in HTML and CSS name files below it. */
|
|
130
|
+
readonly root: string;
|
|
131
|
+
readonly overwrite: boolean;
|
|
132
|
+
readonly span: SourceSpan;
|
|
133
|
+
} | {
|
|
134
|
+
/** sitemaps.org XML of the `.html` files in the tree at this point. */
|
|
135
|
+
readonly kind: 'SITEMAP';
|
|
136
|
+
/** Checked base URL without trailing slashes. */
|
|
137
|
+
readonly base: string;
|
|
138
|
+
readonly dest: string;
|
|
139
|
+
readonly overwrite: boolean;
|
|
140
|
+
readonly span: SourceSpan;
|
|
141
|
+
} | {
|
|
142
|
+
/** An Atom feed of a list import; `link` is interpolated per element (`${item…}`). */
|
|
143
|
+
readonly kind: 'FEED';
|
|
144
|
+
readonly list: string;
|
|
145
|
+
readonly base: string;
|
|
146
|
+
readonly link: Operand;
|
|
147
|
+
readonly dest: string;
|
|
148
|
+
readonly title: string;
|
|
149
|
+
readonly overwrite: boolean;
|
|
150
|
+
readonly span: SourceSpan;
|
|
151
|
+
} | {
|
|
152
|
+
/** Run a plugin; `dest` and option values are interpolated per FOR element at execution. */
|
|
153
|
+
readonly kind: 'TRANSFORM';
|
|
154
|
+
readonly source?: SourceRef;
|
|
155
|
+
readonly plugin: string;
|
|
156
|
+
readonly dest: Operand;
|
|
157
|
+
readonly options: ReadonlyArray<{
|
|
158
|
+
readonly key: string;
|
|
159
|
+
readonly value: Operand;
|
|
160
|
+
}>;
|
|
161
|
+
readonly each?: {
|
|
162
|
+
readonly as: string;
|
|
163
|
+
readonly list: string;
|
|
164
|
+
};
|
|
165
|
+
/** argv template when `plugin` names a TOOL. */
|
|
166
|
+
readonly args?: readonly Operand[];
|
|
167
|
+
/** A directory source's files to keep / leave out (`.sitefileignore` patterns, relative to it). */
|
|
168
|
+
readonly include?: readonly string[];
|
|
169
|
+
readonly exclude?: readonly string[];
|
|
170
|
+
readonly overwrite: boolean;
|
|
171
|
+
readonly span: SourceSpan;
|
|
172
|
+
} | {
|
|
173
|
+
readonly kind: 'COPY';
|
|
174
|
+
readonly source: SourceRef;
|
|
175
|
+
readonly dest: string;
|
|
176
|
+
readonly destIsDir: boolean;
|
|
177
|
+
readonly overwrite: boolean;
|
|
178
|
+
/** `--exclude` patterns (`.sitefileignore` syntax, relative to the source directory). */
|
|
179
|
+
readonly exclude?: readonly string[];
|
|
180
|
+
/** `--chmod`: 0o644 or 0o755 for every copied file. */
|
|
181
|
+
readonly chmod?: number;
|
|
182
|
+
/** `--parents`: the source's path is kept under `dest`. */
|
|
183
|
+
readonly parents?: true;
|
|
184
|
+
readonly span: SourceSpan;
|
|
185
|
+
} | {
|
|
186
|
+
readonly kind: 'RENDER';
|
|
187
|
+
readonly template: SourceRef;
|
|
188
|
+
/** Normalized destination; '' when `each` is set (computed per element). */
|
|
189
|
+
readonly dest: string;
|
|
190
|
+
/**
|
|
191
|
+
* `FOR as IN list [BY key] [PAGE size [FIRST <dest>]]`: render once per element (or group, or page); `dest`
|
|
192
|
+
* (and `first`, for the first page) is interpolated per element.
|
|
193
|
+
*/
|
|
194
|
+
readonly each?: {
|
|
195
|
+
readonly as: string;
|
|
196
|
+
readonly list: string;
|
|
197
|
+
readonly dest: Operand;
|
|
198
|
+
readonly by?: string;
|
|
199
|
+
readonly page?: {
|
|
200
|
+
readonly size: number;
|
|
201
|
+
readonly first?: Operand;
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
readonly escape: EscapeMode;
|
|
205
|
+
readonly overwrite: boolean;
|
|
206
|
+
/** `--inline-svg`: `${file … | svg}` may paste SVG markup. */
|
|
207
|
+
readonly inlineSvg?: true;
|
|
208
|
+
readonly span: SourceSpan;
|
|
209
|
+
};
|
|
210
|
+
/** What a stage's tree starts as. */
|
|
211
|
+
export type StageBase = {
|
|
212
|
+
readonly kind: 'scratch';
|
|
213
|
+
}
|
|
214
|
+
/** `path` is context-relative (`''` for the context root). */
|
|
215
|
+
| {
|
|
216
|
+
readonly kind: 'local';
|
|
217
|
+
readonly path: string;
|
|
218
|
+
}
|
|
219
|
+
/** A copy of an earlier stage's final tree. */
|
|
220
|
+
| {
|
|
221
|
+
readonly kind: 'stage';
|
|
222
|
+
readonly name: string;
|
|
223
|
+
}
|
|
224
|
+
/** `FROM image <ref> [AT <dir>]`: the files of an OCI site image. */
|
|
225
|
+
| ImageStageBase;
|
|
226
|
+
export interface ImageStageBase {
|
|
227
|
+
readonly kind: 'image';
|
|
228
|
+
/** The evaluated reference, as written (validated). */
|
|
229
|
+
readonly ref: string;
|
|
230
|
+
/** No registry host: an image in the local store, never fetched. */
|
|
231
|
+
readonly local: boolean;
|
|
232
|
+
/** `AT`: normalized absolute directory inside the image (default: the image's root label). */
|
|
233
|
+
readonly at?: string;
|
|
234
|
+
/** `FROM` or `STAGE <name> FROM`, for messages. */
|
|
235
|
+
readonly lead: string;
|
|
236
|
+
readonly span: SourceSpan;
|
|
237
|
+
}
|
|
238
|
+
/** One FROM and the operations that follow it. */
|
|
239
|
+
export interface Stage {
|
|
240
|
+
readonly name?: string;
|
|
241
|
+
readonly base: StageBase;
|
|
242
|
+
readonly operations: Operation[];
|
|
243
|
+
readonly span: SourceSpan;
|
|
244
|
+
}
|
|
245
|
+
/** A fully evaluated build: no variables left, no IO done yet. */
|
|
246
|
+
export interface Plan {
|
|
247
|
+
readonly file: string;
|
|
248
|
+
/** In source order; EXPORT reads the last one. */
|
|
249
|
+
readonly stages: readonly Stage[];
|
|
250
|
+
readonly vars: ReadonlyMap<string, Scalar>;
|
|
251
|
+
/** html LETs by name, in source order (not in `vars`: they are not evaluated here). */
|
|
252
|
+
readonly fragments: ReadonlyMap<string, FragmentSpec>;
|
|
253
|
+
readonly imports: readonly ImportSpec[];
|
|
254
|
+
readonly plugins: readonly PluginSpec[];
|
|
255
|
+
readonly tools: readonly ToolSpec[];
|
|
256
|
+
readonly exportPath: string;
|
|
257
|
+
readonly exportFormat: ExportFormat;
|
|
258
|
+
/** Evaluated `BASE` clause of EXPORT, if any (raw string; validated when the export is written). */
|
|
259
|
+
readonly exportBase: string | undefined;
|
|
260
|
+
/** Evaluated `AT` clause of EXPORT ... AS oci: the root directory inside the image layer. */
|
|
261
|
+
readonly exportRoot: string | undefined;
|
|
262
|
+
/** `COMPRESSION` clause of EXPORT ... AS oci (undefined: gzip). */
|
|
263
|
+
readonly exportCompression: OciCompression | undefined;
|
|
264
|
+
/** REDIRECT lines in source order (any stage); EXPORT writes them to `/_redirects`. */
|
|
265
|
+
readonly redirects: readonly RedirectSpec[];
|
|
266
|
+
/** HEADER lines in source order (any stage); EXPORT writes them to `/_headers`. */
|
|
267
|
+
readonly headers: readonly HeaderSpec[];
|
|
268
|
+
readonly warnings: readonly string[];
|
|
269
|
+
/**
|
|
270
|
+
* `--target <stage>`: the build stops after this stage and exports its whole tree (see {@link targetPlan}).
|
|
271
|
+
* Undefined for a normal build.
|
|
272
|
+
*/
|
|
273
|
+
readonly target?: string;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Evaluate a program. `argSource` names where a build arg came from in messages (`--build-arg NAME` for the
|
|
277
|
+
* CLI's; an imported Sitefile's come from the `ARG` clauses of its IMPORT).
|
|
278
|
+
*/
|
|
279
|
+
export declare function plan(program: Program, buildArgs?: Readonly<Record<string, string>>, argSource?: (name: string) => string): Plan;
|
|
280
|
+
/**
|
|
281
|
+
* `--target <name>`: keep the stages up to and including the named one, and export that stage's whole tree
|
|
282
|
+
* (`/`) instead of the EXPORT path. The EXPORT's format and its options (AS, BASE, AT, COMPRESSION) still apply;
|
|
283
|
+
* the `/_redirects` and `/_headers` files EXPORT writes are not (they belong to the EXPORT path). An unknown
|
|
284
|
+
* name is a usage error that lists the named stages.
|
|
285
|
+
*/
|
|
286
|
+
export declare function targetPlan(p: Plan, name: string): Plan;
|
|
287
|
+
/** A reference to a stage of an imported Sitefile (`FROM theme+assets`, `COPY --from=theme+assets …`). */
|
|
288
|
+
export interface ImportedStageRef {
|
|
289
|
+
/** `theme+assets` */
|
|
290
|
+
readonly name: string;
|
|
291
|
+
readonly import: string;
|
|
292
|
+
readonly stage: string;
|
|
293
|
+
/** The instruction that names it. */
|
|
294
|
+
readonly span: SourceSpan;
|
|
295
|
+
}
|
|
296
|
+
/** Every reference to a stage of an imported Sitefile, in source order (stage bases, then `--from` sources, per stage). */
|
|
297
|
+
export declare function importedStageRefs(stages: readonly Stage[]): ImportedStageRef[];
|