@johnhenry/sitefile 0.0.0-stage → 0.0.1
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 +152 -0
- package/LICENSE +21 -0
- package/README.md +513 -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 +120 -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 +119 -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/network.d.ts +34 -0
- package/lib/src/cli/network.js +56 -0
- package/lib/src/cli/outdated.d.ts +5 -0
- package/lib/src/cli/outdated.js +99 -0
- package/lib/src/cli/registry.d.ts +2 -0
- package/lib/src/cli/registry.js +127 -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 +467 -0
- package/lib/src/cli/vendor.d.ts +2 -0
- package/lib/src/cli/vendor.js +97 -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 +522 -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 +56 -0
- package/lib/src/errors.js +29 -0
- package/lib/src/executor.d.ts +393 -0
- package/lib/src/executor.js +2201 -0
- package/lib/src/explain.d.ts +64 -0
- package/lib/src/explain.js +445 -0
- package/lib/src/export-formats.d.ts +23 -0
- package/lib/src/export-formats.js +63 -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 +13 -0
- package/lib/src/index.js +13 -0
- package/lib/src/language/ast.d.ts +360 -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 +96 -0
- package/lib/src/plugins/cache.js +325 -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 +115 -0
- package/lib/src/registry.js +524 -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 +74 -0
- package/lib/src/resources/https.js +413 -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/network.d.ts +70 -0
- package/lib/src/resources/network.js +304 -0
- package/lib/src/resources/types.d.ts +69 -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 +123 -0
- package/lib/src/server.d.ts +45 -0
- package/lib/src/server.js +246 -0
- package/lib/src/servers.d.ts +85 -0
- package/lib/src/servers.js +225 -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 +26 -0
- package/lib/src/wbn.js +241 -0
- package/lib/src/yaml.d.ts +34 -0
- package/lib/src/yaml.js +562 -0
- package/package.json +59 -4
package/lib/src/wbn.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { SitefileError } from './errors.js';
|
|
2
|
+
import { cborArray, cborBytes, cborMap, cborText, cborUint } from './cbor.js';
|
|
3
|
+
import { headersFor, matchRedirect, parseHeaderRules, parseRedirectRules } from './serve-rules.js';
|
|
4
|
+
/**
|
|
5
|
+
* Unsigned Web Bundle, format version "b2"
|
|
6
|
+
* (draft-ietf-wpack-bundled-responses). Layout, as one CBOR array:
|
|
7
|
+
*
|
|
8
|
+
* [ magic h'F09F8C90F09F93A6' ("🌐📦"), version h'62320000' ("b2\0\0"),
|
|
9
|
+
* section-lengths (bstr holding a CBOR array of name, length, ...),
|
|
10
|
+
* sections (array: index, [primary,] responses),
|
|
11
|
+
* length (8-byte big-endian bstr: size of the whole bundle) ]
|
|
12
|
+
*
|
|
13
|
+
* (b1 had six items with the primary URL in the header and variants in the
|
|
14
|
+
* index; b2 has five, so the header starts 0x85.) Verified against the WICG
|
|
15
|
+
* reference reader `dump-bundle` (see test/export-formats.test.ts).
|
|
16
|
+
*
|
|
17
|
+
* index = { url => [ offset, length ] }; offset/length
|
|
18
|
+
* locate the response inside the responses section, counted from
|
|
19
|
+
* the first byte of that section's CBOR encoding.
|
|
20
|
+
* responses = [ [ headers (bstr holding { h':status' => h'200', h'content-type' => ... }), payload bstr ] ... ]
|
|
21
|
+
*
|
|
22
|
+
* primary = text URL, present only when /index.html exists. No signatures.
|
|
23
|
+
*
|
|
24
|
+
* The tree's own `/_headers` and `/_redirects` (what HEADER and REDIRECT
|
|
25
|
+
* write) are applied the way `sitefile serve` applies them (serve-rules.ts):
|
|
26
|
+
* see {@link bundleResponses}.
|
|
27
|
+
*/
|
|
28
|
+
const MAGIC = Buffer.from('f09f8c90f09f93a6', 'hex');
|
|
29
|
+
const VERSION = Buffer.from([0x62, 0x32, 0x00, 0x00]);
|
|
30
|
+
const TEXT_CHARSET = '; charset=utf-8';
|
|
31
|
+
const MIME = {
|
|
32
|
+
html: 'text/html' + TEXT_CHARSET,
|
|
33
|
+
htm: 'text/html' + TEXT_CHARSET,
|
|
34
|
+
css: 'text/css' + TEXT_CHARSET,
|
|
35
|
+
js: 'text/javascript' + TEXT_CHARSET,
|
|
36
|
+
mjs: 'text/javascript' + TEXT_CHARSET,
|
|
37
|
+
json: 'application/json' + TEXT_CHARSET,
|
|
38
|
+
svg: 'image/svg+xml' + TEXT_CHARSET,
|
|
39
|
+
txt: 'text/plain' + TEXT_CHARSET,
|
|
40
|
+
xml: 'application/xml' + TEXT_CHARSET,
|
|
41
|
+
webmanifest: 'application/manifest+json' + TEXT_CHARSET,
|
|
42
|
+
png: 'image/png',
|
|
43
|
+
jpg: 'image/jpeg',
|
|
44
|
+
jpeg: 'image/jpeg',
|
|
45
|
+
gif: 'image/gif',
|
|
46
|
+
webp: 'image/webp',
|
|
47
|
+
avif: 'image/avif',
|
|
48
|
+
ico: 'image/x-icon',
|
|
49
|
+
wasm: 'application/wasm',
|
|
50
|
+
woff: 'font/woff',
|
|
51
|
+
woff2: 'font/woff2',
|
|
52
|
+
pdf: 'application/pdf',
|
|
53
|
+
mp4: 'video/mp4',
|
|
54
|
+
webm: 'video/webm',
|
|
55
|
+
mp3: 'audio/mpeg',
|
|
56
|
+
};
|
|
57
|
+
export function mimeTypeFor(path) {
|
|
58
|
+
const base = path.slice(path.lastIndexOf('/') + 1);
|
|
59
|
+
const dot = base.lastIndexOf('.');
|
|
60
|
+
const ext = dot < 0 ? '' : base.slice(dot + 1).toLowerCase();
|
|
61
|
+
return MIME[ext] ?? 'application/octet-stream';
|
|
62
|
+
}
|
|
63
|
+
/** An absolute https URL ending in `/`, without credentials, query or fragment. Returns its normalized form. */
|
|
64
|
+
export function validateBaseUrl(raw) {
|
|
65
|
+
if (raw === undefined || raw === '') {
|
|
66
|
+
throw new SitefileError('E_VALIDATION', "wbn export needs a base URL: use 'EXPORT <path> AS wbn BASE https://example.com/' or --base-url");
|
|
67
|
+
}
|
|
68
|
+
let u;
|
|
69
|
+
try {
|
|
70
|
+
u = new URL(raw);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': not an absolute URL`);
|
|
74
|
+
}
|
|
75
|
+
if (u.protocol !== 'https:')
|
|
76
|
+
throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': must be https`);
|
|
77
|
+
if (u.username || u.password)
|
|
78
|
+
throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': must not contain credentials`);
|
|
79
|
+
if (u.search || u.hash || raw.includes('?') || raw.includes('#')) {
|
|
80
|
+
throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': must not have a query or fragment`);
|
|
81
|
+
}
|
|
82
|
+
if (!raw.endsWith('/'))
|
|
83
|
+
throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': must end with '/'`);
|
|
84
|
+
return u.href;
|
|
85
|
+
}
|
|
86
|
+
function encodePath(p) {
|
|
87
|
+
return p
|
|
88
|
+
.slice(1)
|
|
89
|
+
.split('/')
|
|
90
|
+
.map((seg) => encodeURIComponent(seg))
|
|
91
|
+
.join('/');
|
|
92
|
+
}
|
|
93
|
+
const enc = new TextEncoder();
|
|
94
|
+
const bstr = (s) => cborBytes(enc.encode(s));
|
|
95
|
+
export function writeWebBundle(tree, baseUrl) {
|
|
96
|
+
const base = validateBaseUrl(baseUrl);
|
|
97
|
+
const { responses, urls } = bundleResponses(tree);
|
|
98
|
+
const index = [];
|
|
99
|
+
// Offset of the first response = size of the responses array head.
|
|
100
|
+
const offsets = [];
|
|
101
|
+
let offset = headSize(responses.length);
|
|
102
|
+
for (const r of responses) {
|
|
103
|
+
offsets.push(offset);
|
|
104
|
+
offset += r.length;
|
|
105
|
+
}
|
|
106
|
+
for (const [path, i] of urls) {
|
|
107
|
+
// b2 index entries are [offset, length]; b1's leading variants value is gone.
|
|
108
|
+
index.push([cborText(base + encodePath(path)), cborArray([cborUint(offsets[i]), cborUint(responses[i].length)])]);
|
|
109
|
+
}
|
|
110
|
+
const responsesSection = cborArray(responses);
|
|
111
|
+
const indexSection = cborMap(index);
|
|
112
|
+
// b2 moves the primary URL out of the header into an optional "primary"
|
|
113
|
+
// section; sections are ordered index, primary, responses (always last).
|
|
114
|
+
const sections = [['index', indexSection]];
|
|
115
|
+
if (tree.isFile('/index.html'))
|
|
116
|
+
sections.push(['primary', cborText(base)]);
|
|
117
|
+
sections.push(['responses', responsesSection]);
|
|
118
|
+
const sectionLengths = cborArray(sections.flatMap(([name, bytes]) => [cborText(name), cborUint(bytes.length)]));
|
|
119
|
+
// The trailing length field is fixed-size, so the total is computable first.
|
|
120
|
+
const parts = [
|
|
121
|
+
Buffer.from([0x85]), // b2: array(5) = magic, version, section-lengths, sections, length
|
|
122
|
+
cborBytes(MAGIC),
|
|
123
|
+
cborBytes(VERSION),
|
|
124
|
+
cborBytes(sectionLengths),
|
|
125
|
+
cborArray(sections.map(([, bytes]) => bytes)),
|
|
126
|
+
];
|
|
127
|
+
const lenField = 1 + 8; // bstr(8) head + 8 bytes
|
|
128
|
+
const total = parts.reduce((n, b) => n + b.length, 0) + lenField;
|
|
129
|
+
const len = Buffer.alloc(8);
|
|
130
|
+
len.writeBigUInt64BE(BigInt(total));
|
|
131
|
+
return Buffer.concat([...parts, cborBytes(len)]);
|
|
132
|
+
}
|
|
133
|
+
/** One encoded response: `[headers bstr, payload bstr]`, header names in CBOR map (bytewise) order. */
|
|
134
|
+
function encodeResponse(status, headers, body) {
|
|
135
|
+
const map = cborMap([[bstr(':status'), bstr(String(status))], ...[...headers].map(([k, v]) => [bstr(k), bstr(v)])]);
|
|
136
|
+
return cborArray([cborBytes(map), cborBytes(body)]);
|
|
137
|
+
}
|
|
138
|
+
const isRedirectStatus = (s) => s >= 301 && s <= 308;
|
|
139
|
+
/** The rule `serve` would apply first in one pass (forced or not), when it is an exact-path 3xx redirect. */
|
|
140
|
+
function exactRedirect(rules, forced, path) {
|
|
141
|
+
const i = rules.findIndex((r) => r.force === forced && matchRedirect(r, path) !== undefined);
|
|
142
|
+
return i >= 0 && !rules[i].splat && isRedirectStatus(rules[i].status) ? i : undefined;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The responses section and its URLs (tree paths, percent-encoded by the caller), as `sitefile
|
|
146
|
+
* serve` would answer them:
|
|
147
|
+
*
|
|
148
|
+
* - Each file is a 200 with `content-type` and the `/_headers` blocks whose pattern matches its
|
|
149
|
+
* URL path (`headersFor`; a `content-type` there replaces the inferred one). A directory URL
|
|
150
|
+
* (`/docs/` for `/docs/index.html`) matches with its trailing slash, so it gets its own
|
|
151
|
+
* response when its headers differ from the file URL's.
|
|
152
|
+
* - An exact-path `/_redirects` rule with a 3xx status becomes a response with that `:status`, a
|
|
153
|
+
* `location` of the rule's target as written, and an empty body: at its path when no file
|
|
154
|
+
* would be served there, and over the file when forced (`301!`). Like `serve`, the first rule
|
|
155
|
+
* matching the path decides; when that is a splat or a 200/404 rewrite, the bundle leaves the
|
|
156
|
+
* path to `/_redirects`. Splat rules and rewrites are not baked in.
|
|
157
|
+
*
|
|
158
|
+
* `/_headers` and `/_redirects` stay in the bundle as files. Responses are deduplicated (both URLs
|
|
159
|
+
* of an index page share one when their headers agree; identical redirects share one).
|
|
160
|
+
*/
|
|
161
|
+
export function bundleResponses(tree) {
|
|
162
|
+
const text = (p) => {
|
|
163
|
+
const f = tree.get(p);
|
|
164
|
+
return f ? new TextDecoder().decode(f.bytes) : '';
|
|
165
|
+
};
|
|
166
|
+
const redirects = parseRedirectRules(text('/_redirects'));
|
|
167
|
+
const headerRules = parseHeaderRules(text('/_headers'));
|
|
168
|
+
const responses = [];
|
|
169
|
+
const urls = [];
|
|
170
|
+
const taken = new Set();
|
|
171
|
+
const redirectResponse = new Map();
|
|
172
|
+
const redirectTo = (rule) => {
|
|
173
|
+
const r = redirects[rule];
|
|
174
|
+
const key = `${r.status} ${r.to}`;
|
|
175
|
+
let i = redirectResponse.get(key);
|
|
176
|
+
if (i === undefined) {
|
|
177
|
+
i = responses.push(encodeResponse(r.status, [['location', r.to]], new Uint8Array(0))) - 1;
|
|
178
|
+
redirectResponse.set(key, i);
|
|
179
|
+
}
|
|
180
|
+
return i;
|
|
181
|
+
};
|
|
182
|
+
const fileResponse = (p, bytes, urlPath) => {
|
|
183
|
+
const headers = new Map([['content-type', mimeTypeFor(p)]]);
|
|
184
|
+
for (const [k, v] of Object.entries(headersFor(headerRules, urlPath)))
|
|
185
|
+
headers.set(k, v);
|
|
186
|
+
return encodeResponse(200, headers, bytes);
|
|
187
|
+
};
|
|
188
|
+
for (const [p, node] of tree.entries()) {
|
|
189
|
+
// [URL path, the path `serve` matches redirects against (no trailing slash)]
|
|
190
|
+
const targets = [[p, p]];
|
|
191
|
+
if (p === '/index.html' || p.endsWith('/index.html')) {
|
|
192
|
+
const dir = p.slice(0, -'index.html'.length);
|
|
193
|
+
targets.push([dir, dir === '/' ? '/' : dir.slice(0, -1)]);
|
|
194
|
+
}
|
|
195
|
+
let last;
|
|
196
|
+
for (const [urlPath, matchPath] of targets) {
|
|
197
|
+
taken.add(urlPath);
|
|
198
|
+
const forced = exactRedirect(redirects, true, matchPath);
|
|
199
|
+
if (forced !== undefined) {
|
|
200
|
+
urls.push([urlPath, redirectTo(forced)]);
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const r = fileResponse(p, node.bytes, urlPath);
|
|
204
|
+
if (last === undefined || !Buffer.from(last.bytes).equals(r))
|
|
205
|
+
last = { bytes: r, i: responses.push(r) - 1 };
|
|
206
|
+
urls.push([urlPath, last.i]);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Redirects at paths without a file: `serve` applies a forced rule first, then (when nothing
|
|
210
|
+
// is served there: no file, no `<path>.html`, no directory) the first other matching rule.
|
|
211
|
+
const servable = (p) => tree.isFile(p) && p !== '/_redirects' && p !== '/_headers';
|
|
212
|
+
for (const r of redirects) {
|
|
213
|
+
if (r.splat || !isRedirectStatus(r.status) || taken.has(r.from))
|
|
214
|
+
continue;
|
|
215
|
+
const path = r.from;
|
|
216
|
+
taken.add(path);
|
|
217
|
+
let rule = exactRedirect(redirects, true, path);
|
|
218
|
+
if (rule === undefined) {
|
|
219
|
+
const firstForced = redirects.some((x) => x.force && matchRedirect(x, path) !== undefined);
|
|
220
|
+
const served = path === '/' ? servable('/index.html') : servable(path) || servable(`${path}.html`) || tree.isDirectory(path);
|
|
221
|
+
if (firstForced || served)
|
|
222
|
+
continue;
|
|
223
|
+
rule = exactRedirect(redirects, false, path);
|
|
224
|
+
}
|
|
225
|
+
if (rule !== undefined)
|
|
226
|
+
urls.push([path, redirectTo(rule)]);
|
|
227
|
+
}
|
|
228
|
+
return { responses, urls };
|
|
229
|
+
}
|
|
230
|
+
function headSize(n) {
|
|
231
|
+
if (n < 24)
|
|
232
|
+
return 1;
|
|
233
|
+
if (n < 0x100)
|
|
234
|
+
return 2;
|
|
235
|
+
if (n < 0x10000)
|
|
236
|
+
return 3;
|
|
237
|
+
if (n < 0x100000000)
|
|
238
|
+
return 5;
|
|
239
|
+
return 9;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=wbn.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A small, safe YAML subset parser (no dependencies, no code execution).
|
|
3
|
+
*
|
|
4
|
+
* Supported:
|
|
5
|
+
* - Block style by indentation (spaces only; a tab in indentation is an error).
|
|
6
|
+
* - Mappings `key: value`, nested mappings, sequences `- item`, sequences of
|
|
7
|
+
* mappings (`- name: a` / ` url: /a`), mappings of sequences (including
|
|
8
|
+
* the indentless form), arbitrary nesting up to 64 levels.
|
|
9
|
+
* - Scalars: "double" quoted (escapes \" \\ \n \t), 'single' quoted ('' escape),
|
|
10
|
+
* plain strings (trimmed; ` #` begins a comment), `true`/`false`, integers
|
|
11
|
+
* and decimals (numbers), `null` / `~` / empty (null). Dates such as
|
|
12
|
+
* 2026-01-02 stay strings.
|
|
13
|
+
* - Flow collections on a single line: `[a, b, {x: 1}]`, `{a: 1, b: [2, 3]}`.
|
|
14
|
+
* - Block scalars `|` (literal) and `>` (folded) with optional `-` / `+`
|
|
15
|
+
* chomping; the indentation comes from the first content line.
|
|
16
|
+
* - Comments, blank lines, an optional leading `---` and a trailing `...`.
|
|
17
|
+
* - Keys are plain or quoted scalars and are always strings. Duplicate keys
|
|
18
|
+
* are an error. A `__proto__` key is stored as ordinary own data.
|
|
19
|
+
* - An empty document is `null`.
|
|
20
|
+
*
|
|
21
|
+
* Not supported (E_DATA at the offending line and column): anchors and aliases
|
|
22
|
+
* (`&` `*`), tags (`!`), multiple documents, complex keys (`? `), merge keys
|
|
23
|
+
* (`<<`), multi-line flow collections, multi-line plain or quoted scalars,
|
|
24
|
+
* block scalar indentation indicators, tabs for indentation.
|
|
25
|
+
*
|
|
26
|
+
* `firstLine` is the 1-based file line of the first line of `text`, so errors
|
|
27
|
+
* point at the right place when the YAML is embedded in another file.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseYaml(text: string, file: string, firstLine?: number): unknown;
|
|
30
|
+
/**
|
|
31
|
+
* Like parseYaml; with `rootMapping` the document must be a mapping (or empty)
|
|
32
|
+
* and indented content at the top is rejected. Used by frontmatter.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseYamlDocument(text: string, file: string, firstLine: number, rootMapping: boolean): unknown;
|