@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.
Files changed (174) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/LICENSE +21 -0
  3. package/README.md +475 -2
  4. package/lib/src/archive-writers.d.ts +31 -0
  5. package/lib/src/archive-writers.js +197 -0
  6. package/lib/src/attest.d.ts +126 -0
  7. package/lib/src/attest.js +220 -0
  8. package/lib/src/bake.d.ts +74 -0
  9. package/lib/src/bake.js +372 -0
  10. package/lib/src/base-image.d.ts +76 -0
  11. package/lib/src/base-image.js +138 -0
  12. package/lib/src/build-args.d.ts +26 -0
  13. package/lib/src/build-args.js +164 -0
  14. package/lib/src/cache-limit.d.ts +54 -0
  15. package/lib/src/cache-limit.js +239 -0
  16. package/lib/src/casefold-data.d.ts +2 -0
  17. package/lib/src/casefold-data.js +217 -0
  18. package/lib/src/cbor.d.ts +39 -0
  19. package/lib/src/cbor.js +174 -0
  20. package/lib/src/checklinks.d.ts +42 -0
  21. package/lib/src/checklinks.js +118 -0
  22. package/lib/src/cli/bake.d.ts +2 -0
  23. package/lib/src/cli/bake.js +179 -0
  24. package/lib/src/cli/build-image.d.ts +21 -0
  25. package/lib/src/cli/build-image.js +42 -0
  26. package/lib/src/cli/cache.d.ts +8 -0
  27. package/lib/src/cli/cache.js +109 -0
  28. package/lib/src/cli/common.d.ts +29 -0
  29. package/lib/src/cli/common.js +100 -0
  30. package/lib/src/cli/git-context.d.ts +18 -0
  31. package/lib/src/cli/git-context.js +48 -0
  32. package/lib/src/cli/images.d.ts +6 -0
  33. package/lib/src/cli/images.js +285 -0
  34. package/lib/src/cli/index.d.ts +10 -0
  35. package/lib/src/cli/index.js +95 -0
  36. package/lib/src/cli/outdated.d.ts +5 -0
  37. package/lib/src/cli/outdated.js +94 -0
  38. package/lib/src/cli/registry.d.ts +2 -0
  39. package/lib/src/cli/registry.js +122 -0
  40. package/lib/src/cli/serve-worker.d.ts +2 -0
  41. package/lib/src/cli/serve-worker.js +42 -0
  42. package/lib/src/cli/servers.d.ts +15 -0
  43. package/lib/src/cli/servers.js +451 -0
  44. package/lib/src/cli/vendor.d.ts +2 -0
  45. package/lib/src/cli/vendor.js +92 -0
  46. package/lib/src/cli/watch.d.ts +26 -0
  47. package/lib/src/cli/watch.js +81 -0
  48. package/lib/src/cli.d.ts +12 -0
  49. package/lib/src/cli.js +486 -0
  50. package/lib/src/csv.d.ts +27 -0
  51. package/lib/src/csv.js +117 -0
  52. package/lib/src/deflate.d.ts +76 -0
  53. package/lib/src/deflate.js +604 -0
  54. package/lib/src/digest.d.ts +3 -0
  55. package/lib/src/digest.js +7 -0
  56. package/lib/src/errors.d.ts +34 -0
  57. package/lib/src/errors.js +20 -0
  58. package/lib/src/executor.d.ts +386 -0
  59. package/lib/src/executor.js +2193 -0
  60. package/lib/src/explain.d.ts +64 -0
  61. package/lib/src/explain.js +445 -0
  62. package/lib/src/export-formats.d.ts +16 -0
  63. package/lib/src/export-formats.js +52 -0
  64. package/lib/src/exporter.d.ts +103 -0
  65. package/lib/src/exporter.js +676 -0
  66. package/lib/src/fingerprint.d.ts +40 -0
  67. package/lib/src/fingerprint.js +168 -0
  68. package/lib/src/frontmatter.d.ts +22 -0
  69. package/lib/src/frontmatter.js +45 -0
  70. package/lib/src/index.d.ts +12 -0
  71. package/lib/src/index.js +12 -0
  72. package/lib/src/language/ast.d.ts +353 -0
  73. package/lib/src/language/ast.js +57 -0
  74. package/lib/src/language/parser.d.ts +3 -0
  75. package/lib/src/language/parser.js +612 -0
  76. package/lib/src/language/scanner.d.ts +110 -0
  77. package/lib/src/language/scanner.js +449 -0
  78. package/lib/src/language/validate.d.ts +13 -0
  79. package/lib/src/language/validate.js +367 -0
  80. package/lib/src/links.d.ts +79 -0
  81. package/lib/src/links.js +583 -0
  82. package/lib/src/lint.d.ts +10 -0
  83. package/lib/src/lint.js +223 -0
  84. package/lib/src/markdown.d.ts +29 -0
  85. package/lib/src/markdown.js +612 -0
  86. package/lib/src/media.d.ts +82 -0
  87. package/lib/src/media.js +650 -0
  88. package/lib/src/memo.d.ts +57 -0
  89. package/lib/src/memo.js +93 -0
  90. package/lib/src/oci.d.ts +178 -0
  91. package/lib/src/oci.js +380 -0
  92. package/lib/src/outdated.d.ts +46 -0
  93. package/lib/src/outdated.js +195 -0
  94. package/lib/src/pages.d.ts +10 -0
  95. package/lib/src/pages.js +54 -0
  96. package/lib/src/paths.d.ts +39 -0
  97. package/lib/src/paths.js +101 -0
  98. package/lib/src/planner.d.ts +297 -0
  99. package/lib/src/planner.js +410 -0
  100. package/lib/src/plugins/cache.d.ts +70 -0
  101. package/lib/src/plugins/cache.js +226 -0
  102. package/lib/src/plugins/exec.d.ts +51 -0
  103. package/lib/src/plugins/exec.js +144 -0
  104. package/lib/src/plugins/host.d.ts +75 -0
  105. package/lib/src/plugins/host.js +277 -0
  106. package/lib/src/plugins/wasm.d.ts +23 -0
  107. package/lib/src/plugins/wasm.js +249 -0
  108. package/lib/src/profile.d.ts +42 -0
  109. package/lib/src/profile.js +68 -0
  110. package/lib/src/ref.d.ts +40 -0
  111. package/lib/src/ref.js +79 -0
  112. package/lib/src/registry-auth.d.ts +32 -0
  113. package/lib/src/registry-auth.js +151 -0
  114. package/lib/src/registry-cache.d.ts +71 -0
  115. package/lib/src/registry-cache.js +333 -0
  116. package/lib/src/registry-ops.d.ts +51 -0
  117. package/lib/src/registry-ops.js +248 -0
  118. package/lib/src/registry.d.ts +109 -0
  119. package/lib/src/registry.js +505 -0
  120. package/lib/src/render.d.ts +134 -0
  121. package/lib/src/render.js +576 -0
  122. package/lib/src/resources/archive.d.ts +11 -0
  123. package/lib/src/resources/archive.js +306 -0
  124. package/lib/src/resources/bundle-data.d.ts +16 -0
  125. package/lib/src/resources/bundle-data.js +50 -0
  126. package/lib/src/resources/convert.d.ts +12 -0
  127. package/lib/src/resources/convert.js +63 -0
  128. package/lib/src/resources/documents.d.ts +35 -0
  129. package/lib/src/resources/documents.js +122 -0
  130. package/lib/src/resources/git.d.ts +103 -0
  131. package/lib/src/resources/git.js +720 -0
  132. package/lib/src/resources/https.d.ts +40 -0
  133. package/lib/src/resources/https.js +256 -0
  134. package/lib/src/resources/ignore.d.ts +33 -0
  135. package/lib/src/resources/ignore.js +119 -0
  136. package/lib/src/resources/local.d.ts +64 -0
  137. package/lib/src/resources/local.js +248 -0
  138. package/lib/src/resources/lockfile.d.ts +52 -0
  139. package/lib/src/resources/lockfile.js +172 -0
  140. package/lib/src/resources/netpolicy.d.ts +6 -0
  141. package/lib/src/resources/netpolicy.js +82 -0
  142. package/lib/src/resources/types.d.ts +63 -0
  143. package/lib/src/resources/types.js +13 -0
  144. package/lib/src/resources/vendor.d.ts +94 -0
  145. package/lib/src/resources/vendor.js +296 -0
  146. package/lib/src/resources/wbn-reader.d.ts +44 -0
  147. package/lib/src/resources/wbn-reader.js +302 -0
  148. package/lib/src/schema.d.ts +25 -0
  149. package/lib/src/schema.js +169 -0
  150. package/lib/src/secrets.d.ts +21 -0
  151. package/lib/src/secrets.js +103 -0
  152. package/lib/src/serve-rules.d.ts +29 -0
  153. package/lib/src/serve-rules.js +122 -0
  154. package/lib/src/server.d.ts +45 -0
  155. package/lib/src/server.js +246 -0
  156. package/lib/src/servers.d.ts +71 -0
  157. package/lib/src/servers.js +139 -0
  158. package/lib/src/site.d.ts +60 -0
  159. package/lib/src/site.js +169 -0
  160. package/lib/src/store.d.ts +151 -0
  161. package/lib/src/store.js +596 -0
  162. package/lib/src/tree.d.ts +50 -0
  163. package/lib/src/tree.js +134 -0
  164. package/lib/src/values.d.ts +7 -0
  165. package/lib/src/values.js +37 -0
  166. package/lib/src/vendor.d.ts +19 -0
  167. package/lib/src/vendor.js +145 -0
  168. package/lib/src/watch.d.ts +44 -0
  169. package/lib/src/watch.js +137 -0
  170. package/lib/src/wbn.d.ts +5 -0
  171. package/lib/src/wbn.js +147 -0
  172. package/lib/src/yaml.d.ts +34 -0
  173. package/lib/src/yaml.js +562 -0
  174. package/package.json +58 -4
package/lib/src/wbn.js ADDED
@@ -0,0 +1,147 @@
1
+ import { SitefileError } from './errors.js';
2
+ import { cborArray, cborBytes, cborMap, cborText, cborUint } from './cbor.js';
3
+ /**
4
+ * Unsigned Web Bundle, format version "b2"
5
+ * (draft-ietf-wpack-bundled-responses). Layout, as one CBOR array:
6
+ *
7
+ * [ magic h'F09F8C90F09F93A6' ("🌐📦"), version h'62320000' ("b2\0\0"),
8
+ * section-lengths (bstr holding a CBOR array of name, length, ...),
9
+ * sections (array: index, [primary,] responses),
10
+ * length (8-byte big-endian bstr: size of the whole bundle) ]
11
+ *
12
+ * (b1 had six items with the primary URL in the header and variants in the
13
+ * index; b2 has five, so the header starts 0x85.) Verified against the WICG
14
+ * reference reader `dump-bundle` (see test/export-formats.test.ts).
15
+ *
16
+ * index = { url => [ offset, length ] }; offset/length
17
+ * locate the response inside the responses section, counted from
18
+ * the first byte of that section's CBOR encoding.
19
+ * responses = [ [ headers (bstr holding { h':status' => h'200', h'content-type' => ... }), payload bstr ] ... ]
20
+ *
21
+ * primary = text URL, present only when /index.html exists. No signatures.
22
+ */
23
+ const MAGIC = Buffer.from('f09f8c90f09f93a6', 'hex');
24
+ const VERSION = Buffer.from([0x62, 0x32, 0x00, 0x00]);
25
+ const TEXT_CHARSET = '; charset=utf-8';
26
+ const MIME = {
27
+ html: 'text/html' + TEXT_CHARSET,
28
+ htm: 'text/html' + TEXT_CHARSET,
29
+ css: 'text/css' + TEXT_CHARSET,
30
+ js: 'text/javascript' + TEXT_CHARSET,
31
+ mjs: 'text/javascript' + TEXT_CHARSET,
32
+ json: 'application/json' + TEXT_CHARSET,
33
+ svg: 'image/svg+xml' + TEXT_CHARSET,
34
+ txt: 'text/plain' + TEXT_CHARSET,
35
+ xml: 'application/xml' + TEXT_CHARSET,
36
+ webmanifest: 'application/manifest+json' + TEXT_CHARSET,
37
+ png: 'image/png',
38
+ jpg: 'image/jpeg',
39
+ jpeg: 'image/jpeg',
40
+ gif: 'image/gif',
41
+ webp: 'image/webp',
42
+ avif: 'image/avif',
43
+ ico: 'image/x-icon',
44
+ wasm: 'application/wasm',
45
+ woff: 'font/woff',
46
+ woff2: 'font/woff2',
47
+ pdf: 'application/pdf',
48
+ mp4: 'video/mp4',
49
+ webm: 'video/webm',
50
+ mp3: 'audio/mpeg',
51
+ };
52
+ export function mimeTypeFor(path) {
53
+ const base = path.slice(path.lastIndexOf('/') + 1);
54
+ const dot = base.lastIndexOf('.');
55
+ const ext = dot < 0 ? '' : base.slice(dot + 1).toLowerCase();
56
+ return MIME[ext] ?? 'application/octet-stream';
57
+ }
58
+ /** An absolute https URL ending in `/`, without credentials, query or fragment. Returns its normalized form. */
59
+ export function validateBaseUrl(raw) {
60
+ if (raw === undefined || raw === '') {
61
+ throw new SitefileError('E_VALIDATION', "wbn export needs a base URL: use 'EXPORT <path> AS wbn BASE https://example.com/' or --base-url");
62
+ }
63
+ let u;
64
+ try {
65
+ u = new URL(raw);
66
+ }
67
+ catch {
68
+ throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': not an absolute URL`);
69
+ }
70
+ if (u.protocol !== 'https:')
71
+ throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': must be https`);
72
+ if (u.username || u.password)
73
+ throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': must not contain credentials`);
74
+ if (u.search || u.hash || raw.includes('?') || raw.includes('#')) {
75
+ throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': must not have a query or fragment`);
76
+ }
77
+ if (!raw.endsWith('/'))
78
+ throw new SitefileError('E_VALIDATION', `invalid base URL '${raw}': must end with '/'`);
79
+ return u.href;
80
+ }
81
+ function encodePath(p) {
82
+ return p
83
+ .slice(1)
84
+ .split('/')
85
+ .map((seg) => encodeURIComponent(seg))
86
+ .join('/');
87
+ }
88
+ const enc = new TextEncoder();
89
+ const bstr = (s) => cborBytes(enc.encode(s));
90
+ export function writeWebBundle(tree, baseUrl) {
91
+ const base = validateBaseUrl(baseUrl);
92
+ const entries = tree.entries();
93
+ const responses = [];
94
+ const index = [];
95
+ // Offset of the first response = size of the responses array head.
96
+ let offset = headSize(entries.length);
97
+ for (const [p, node] of entries) {
98
+ const headers = cborMap([
99
+ [bstr(':status'), bstr('200')],
100
+ [bstr('content-type'), bstr(mimeTypeFor(p))],
101
+ ]);
102
+ const response = cborArray([cborBytes(headers), cborBytes(node.bytes)]);
103
+ // b2 index entries are [offset, length]; b1's leading variants value is gone.
104
+ const loc = [cborUint(offset), cborUint(response.length)];
105
+ const urls = [base + encodePath(p)];
106
+ if (p === '/index.html' || p.endsWith('/index.html'))
107
+ urls.push(base + encodePath(p.slice(0, -'index.html'.length)));
108
+ for (const url of urls)
109
+ index.push([cborText(url), cborArray(loc)]);
110
+ responses.push(response);
111
+ offset += response.length;
112
+ }
113
+ const responsesSection = cborArray(responses);
114
+ const indexSection = cborMap(index);
115
+ // b2 moves the primary URL out of the header into an optional "primary"
116
+ // section; sections are ordered index, primary, responses (always last).
117
+ const sections = [['index', indexSection]];
118
+ if (tree.isFile('/index.html'))
119
+ sections.push(['primary', cborText(base)]);
120
+ sections.push(['responses', responsesSection]);
121
+ const sectionLengths = cborArray(sections.flatMap(([name, bytes]) => [cborText(name), cborUint(bytes.length)]));
122
+ // The trailing length field is fixed-size, so the total is computable first.
123
+ const parts = [
124
+ Buffer.from([0x85]), // b2: array(5) = magic, version, section-lengths, sections, length
125
+ cborBytes(MAGIC),
126
+ cborBytes(VERSION),
127
+ cborBytes(sectionLengths),
128
+ cborArray(sections.map(([, bytes]) => bytes)),
129
+ ];
130
+ const lenField = 1 + 8; // bstr(8) head + 8 bytes
131
+ const total = parts.reduce((n, b) => n + b.length, 0) + lenField;
132
+ const len = Buffer.alloc(8);
133
+ len.writeBigUInt64BE(BigInt(total));
134
+ return Buffer.concat([...parts, cborBytes(len)]);
135
+ }
136
+ function headSize(n) {
137
+ if (n < 24)
138
+ return 1;
139
+ if (n < 0x100)
140
+ return 2;
141
+ if (n < 0x10000)
142
+ return 3;
143
+ if (n < 0x100000000)
144
+ return 5;
145
+ return 9;
146
+ }
147
+ //# 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;