@pwfabric/cli 0.0.0-stage → 1.0.0-rc.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 (171) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +122 -2
  3. package/dist/args.d.ts +12 -0
  4. package/dist/args.d.ts.map +1 -0
  5. package/dist/args.js +43 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/bin.d.ts +3 -0
  8. package/dist/bin.d.ts.map +1 -0
  9. package/dist/bin.js +10 -0
  10. package/dist/bin.js.map +1 -0
  11. package/dist/commands/add.d.ts +4 -0
  12. package/dist/commands/add.d.ts.map +1 -0
  13. package/dist/commands/add.js +56 -0
  14. package/dist/commands/add.js.map +1 -0
  15. package/dist/commands/build.d.ts +4 -0
  16. package/dist/commands/build.d.ts.map +1 -0
  17. package/dist/commands/build.js +55 -0
  18. package/dist/commands/build.js.map +1 -0
  19. package/dist/commands/create.d.ts +10 -0
  20. package/dist/commands/create.d.ts.map +1 -0
  21. package/dist/commands/create.js +119 -0
  22. package/dist/commands/create.js.map +1 -0
  23. package/dist/commands/dev.d.ts +13 -0
  24. package/dist/commands/dev.d.ts.map +1 -0
  25. package/dist/commands/dev.js +107 -0
  26. package/dist/commands/dev.js.map +1 -0
  27. package/dist/commands/lib/flags.d.ts +11 -0
  28. package/dist/commands/lib/flags.d.ts.map +1 -0
  29. package/dist/commands/lib/flags.js +33 -0
  30. package/dist/commands/lib/flags.js.map +1 -0
  31. package/dist/commands/lib/identity.d.ts +39 -0
  32. package/dist/commands/lib/identity.d.ts.map +1 -0
  33. package/dist/commands/lib/identity.js +120 -0
  34. package/dist/commands/lib/identity.js.map +1 -0
  35. package/dist/commands/lib/project.d.ts +35 -0
  36. package/dist/commands/lib/project.d.ts.map +1 -0
  37. package/dist/commands/lib/project.js +78 -0
  38. package/dist/commands/lib/project.js.map +1 -0
  39. package/dist/commands/lib/report.d.ts +16 -0
  40. package/dist/commands/lib/report.d.ts.map +1 -0
  41. package/dist/commands/lib/report.js +75 -0
  42. package/dist/commands/lib/report.js.map +1 -0
  43. package/dist/commands/lib/starter.d.ts +42 -0
  44. package/dist/commands/lib/starter.d.ts.map +1 -0
  45. package/dist/commands/lib/starter.js +136 -0
  46. package/dist/commands/lib/starter.js.map +1 -0
  47. package/dist/commands/lib/static-server.d.ts +46 -0
  48. package/dist/commands/lib/static-server.d.ts.map +1 -0
  49. package/dist/commands/lib/static-server.js +173 -0
  50. package/dist/commands/lib/static-server.js.map +1 -0
  51. package/dist/commands/pack.d.ts +6 -0
  52. package/dist/commands/pack.d.ts.map +1 -0
  53. package/dist/commands/pack.js +56 -0
  54. package/dist/commands/pack.js.map +1 -0
  55. package/dist/commands/registry.d.ts +8 -0
  56. package/dist/commands/registry.d.ts.map +1 -0
  57. package/dist/commands/registry.js +16 -0
  58. package/dist/commands/registry.js.map +1 -0
  59. package/dist/commands/run.d.ts +15 -0
  60. package/dist/commands/run.d.ts.map +1 -0
  61. package/dist/commands/run.js +79 -0
  62. package/dist/commands/run.js.map +1 -0
  63. package/dist/commands/types.d.ts +35 -0
  64. package/dist/commands/types.d.ts.map +1 -0
  65. package/dist/commands/types.js +10 -0
  66. package/dist/commands/types.js.map +1 -0
  67. package/dist/commands/validate.d.ts +7 -0
  68. package/dist/commands/validate.d.ts.map +1 -0
  69. package/dist/commands/validate.js +33 -0
  70. package/dist/commands/validate.js.map +1 -0
  71. package/dist/dev/assemble.d.ts +48 -0
  72. package/dist/dev/assemble.d.ts.map +1 -0
  73. package/dist/dev/assemble.js +339 -0
  74. package/dist/dev/assemble.js.map +1 -0
  75. package/dist/dev/compile.d.ts +55 -0
  76. package/dist/dev/compile.d.ts.map +1 -0
  77. package/dist/dev/compile.js +215 -0
  78. package/dist/dev/compile.js.map +1 -0
  79. package/dist/dev/csp.d.ts +68 -0
  80. package/dist/dev/csp.d.ts.map +1 -0
  81. package/dist/dev/csp.js +260 -0
  82. package/dist/dev/csp.js.map +1 -0
  83. package/dist/dev/diagnostics.d.ts +22 -0
  84. package/dist/dev/diagnostics.d.ts.map +1 -0
  85. package/dist/dev/diagnostics.js +22 -0
  86. package/dist/dev/diagnostics.js.map +1 -0
  87. package/dist/dev/envelope.d.ts +93 -0
  88. package/dist/dev/envelope.d.ts.map +1 -0
  89. package/dist/dev/envelope.js +154 -0
  90. package/dist/dev/envelope.js.map +1 -0
  91. package/dist/dev/media.d.ts +54 -0
  92. package/dist/dev/media.d.ts.map +1 -0
  93. package/dist/dev/media.js +128 -0
  94. package/dist/dev/media.js.map +1 -0
  95. package/dist/dev/needs-host.d.ts +3 -0
  96. package/dist/dev/needs-host.d.ts.map +1 -0
  97. package/dist/dev/needs-host.js +32 -0
  98. package/dist/dev/needs-host.js.map +1 -0
  99. package/dist/dev/output.d.ts +10 -0
  100. package/dist/dev/output.d.ts.map +1 -0
  101. package/dist/dev/output.js +32 -0
  102. package/dist/dev/output.js.map +1 -0
  103. package/dist/dev/overlay.d.ts +22 -0
  104. package/dist/dev/overlay.d.ts.map +1 -0
  105. package/dist/dev/overlay.js +59 -0
  106. package/dist/dev/overlay.js.map +1 -0
  107. package/dist/dev/server.d.ts +28 -0
  108. package/dist/dev/server.d.ts.map +1 -0
  109. package/dist/dev/server.js +264 -0
  110. package/dist/dev/server.js.map +1 -0
  111. package/dist/dev/shell.d.ts +83 -0
  112. package/dist/dev/shell.d.ts.map +1 -0
  113. package/dist/dev/shell.js +244 -0
  114. package/dist/dev/shell.js.map +1 -0
  115. package/dist/dev/sources.d.ts +46 -0
  116. package/dist/dev/sources.d.ts.map +1 -0
  117. package/dist/dev/sources.js +165 -0
  118. package/dist/dev/sources.js.map +1 -0
  119. package/dist/dev/theme.d.ts +52 -0
  120. package/dist/dev/theme.d.ts.map +1 -0
  121. package/dist/dev/theme.js +185 -0
  122. package/dist/dev/theme.js.map +1 -0
  123. package/dist/dev/types.d.ts +41 -0
  124. package/dist/dev/types.d.ts.map +1 -0
  125. package/dist/dev/types.js +11 -0
  126. package/dist/dev/types.js.map +1 -0
  127. package/dist/dev/watcher.d.ts +30 -0
  128. package/dist/dev/watcher.d.ts.map +1 -0
  129. package/dist/dev/watcher.js +150 -0
  130. package/dist/dev/watcher.js.map +1 -0
  131. package/dist/host/definitions.d.ts +62 -0
  132. package/dist/host/definitions.d.ts.map +1 -0
  133. package/dist/host/definitions.js +136 -0
  134. package/dist/host/definitions.js.map +1 -0
  135. package/dist/host/http.d.ts +40 -0
  136. package/dist/host/http.d.ts.map +1 -0
  137. package/dist/host/http.js +156 -0
  138. package/dist/host/http.js.map +1 -0
  139. package/dist/host/local-host.d.ts +60 -0
  140. package/dist/host/local-host.d.ts.map +1 -0
  141. package/dist/host/local-host.js +420 -0
  142. package/dist/host/local-host.js.map +1 -0
  143. package/dist/host/oidc.d.ts +47 -0
  144. package/dist/host/oidc.d.ts.map +1 -0
  145. package/dist/host/oidc.js +192 -0
  146. package/dist/host/oidc.js.map +1 -0
  147. package/dist/host/query.d.ts +36 -0
  148. package/dist/host/query.d.ts.map +1 -0
  149. package/dist/host/query.js +158 -0
  150. package/dist/host/query.js.map +1 -0
  151. package/dist/host/receipts.d.ts +26 -0
  152. package/dist/host/receipts.d.ts.map +1 -0
  153. package/dist/host/receipts.js +72 -0
  154. package/dist/host/receipts.js.map +1 -0
  155. package/dist/host/records.d.ts +74 -0
  156. package/dist/host/records.d.ts.map +1 -0
  157. package/dist/host/records.js +229 -0
  158. package/dist/host/records.js.map +1 -0
  159. package/dist/host/tokens.d.ts +29 -0
  160. package/dist/host/tokens.d.ts.map +1 -0
  161. package/dist/host/tokens.js +52 -0
  162. package/dist/host/tokens.js.map +1 -0
  163. package/dist/host/types.d.ts +33 -0
  164. package/dist/host/types.d.ts.map +1 -0
  165. package/dist/host/types.js +11 -0
  166. package/dist/host/types.js.map +1 -0
  167. package/dist/index.d.ts +17 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +41 -0
  170. package/dist/index.js.map +1 -0
  171. package/package.json +65 -3
@@ -0,0 +1,260 @@
1
+ /**
2
+ * The app's Content Security Policy, derived from what the app declares.
3
+ *
4
+ * A pwapp is static files; what it may load and reach is known at build time
5
+ * from its own declarations, so `pwf build` writes a policy that allows that
6
+ * and nothing else (pwapp-format §2.1):
7
+ *
8
+ * default-src 'none'
9
+ * script-src 'self' blob: 'sha256-<import map>'
10
+ * Blocks and compiled engines are verified and then imported
11
+ * from `blob:` URLs. The import map is the shell's only inline
12
+ * script (an import map cannot be an external file), so its
13
+ * hash is listed; the renderer seeding and the boot call are
14
+ * files (`assets/seed.js`, `assets/boot.js`).
15
+ * style-src 'self' 'unsafe-inline' [+ the webfont stylesheet origin]
16
+ * The renderer draws `<style>` elements at run time (the
17
+ * surface base, visibility, state, responsive and dark-theme
18
+ * rules, computed per page), and blocks set `style`
19
+ * attributes. Neither can be hashed ahead of time.
20
+ * img-src 'self' data: blob: [+ media origins]
21
+ * media-src 'self' data: blob: [+ media origins]
22
+ * frame-src [media origins] — only when there are any
23
+ * font-src 'self' [+ the webfont file origin]
24
+ * connect-src 'self' [+ every origin the app's data and sign-in reach]
25
+ * base-uri 'self' — a host that serves the app under a sub-path
26
+ * injects `<base href>` (pwapp-format §2); 'none' would make
27
+ * the browser ignore it and break path routing.
28
+ * object-src 'none'
29
+ * frame-ancestors 'none' — header only: browsers ignore it in a `<meta>`.
30
+ *
31
+ * Origins come from: absolute `rest` endpoints in the receipts; declared
32
+ * engines' `host` templates filled from `connections.json` config;
33
+ * the envelope `auth.json` addresses and an external issuer; `publish.json`
34
+ * media and absolute media URLs in receipt props. A template that cannot be
35
+ * resolved at build time, and a compiled engine (whose code may reach any
36
+ * origin), is listed in `unresolved` instead of being guessed.
37
+ *
38
+ * @module @pwfabric/cli/dev/csp
39
+ */
40
+ import { createHash } from 'node:crypto';
41
+ import { isRecord } from './sources.js';
42
+ /** Directives a `<meta http-equiv="Content-Security-Policy">` cannot carry (CSP3 §3.3). */
43
+ const HEADER_ONLY = new Set(['frame-ancestors', 'report-uri', 'report-to', 'sandbox']);
44
+ /** The CSP source for an inline script: `'sha256-<base64>'` of its exact text. */
45
+ export function scriptHash(text) {
46
+ return `'sha256-${createHash('sha256').update(text, 'utf8').digest('base64')}'`;
47
+ }
48
+ const LOOPBACK = /^(?:localhost|127\.0\.0\.1|\[::1\]|[^/:]+\.localhost)(?::\d+)?$/i;
49
+ /**
50
+ * The origin of an absolute http(s) URL, or null. Expressions (`{{…}}`) or
51
+ * templates (`{…}`) in the scheme or host make it unresolvable (`undefined`).
52
+ */
53
+ export function originOf(value) {
54
+ const m = /^(https?):\/\/([^/?#]*)/i.exec(value.trim());
55
+ if (!m)
56
+ return null;
57
+ const host = m[2];
58
+ if (!host || /[{}]/.test(host))
59
+ return undefined;
60
+ try {
61
+ return new URL(`${m[1].toLowerCase()}://${host}`).origin;
62
+ }
63
+ catch {
64
+ return undefined;
65
+ }
66
+ }
67
+ /**
68
+ * The origin a declared engine's `host` reaches (connector-manifest §3.1):
69
+ * `{name}` filled from the connection's string config, the scheme dropped and
70
+ * `https://` prepended, except an explicit `http://` on a loopback host.
71
+ * `undefined` when a placeholder stays unfilled.
72
+ */
73
+ export function engineHostOrigin(host, config) {
74
+ const filled = host.replace(/\{([A-Za-z0-9_.-]+)\}/g, (whole, name) => {
75
+ const v = config?.[name];
76
+ return typeof v === 'string' ? v : whole;
77
+ });
78
+ if (/[{}]/.test(filled))
79
+ return undefined;
80
+ const explicitHttp = /^http:\/\//i.test(filled.trim());
81
+ const bare = filled.trim().replace(/^[a-z][a-z0-9+.-]*:\/\//i, '');
82
+ const hostPart = bare.split(/[/?#]/)[0] ?? '';
83
+ if (!hostPart)
84
+ return undefined;
85
+ const scheme = explicitHttp && LOOPBACK.test(hostPart) ? 'http' : 'https';
86
+ try {
87
+ return new URL(`${scheme}://${hostPart}`).origin;
88
+ }
89
+ catch {
90
+ return undefined;
91
+ }
92
+ }
93
+ /** A prop that names where a link goes (navigation is not governed by CSP). */
94
+ const LINK_PROP = /^(?:href|to|link|url|.*Href|.*Link)$/;
95
+ /** Every absolute URL a receipt's block props carry, except links. */
96
+ function mediaUrlsOf(blocks, out) {
97
+ if (!Array.isArray(blocks))
98
+ return;
99
+ for (const block of blocks) {
100
+ if (!isRecord(block))
101
+ continue;
102
+ const props = block['props'];
103
+ if (isRecord(props))
104
+ collectUrls(props, out);
105
+ mediaUrlsOf(block['children'], out);
106
+ }
107
+ }
108
+ function collectUrls(value, out) {
109
+ const entries = Array.isArray(value) ? value.map((v, i) => [String(i), v]) : Object.entries(value);
110
+ for (const [key, v] of entries) {
111
+ if (typeof v === 'string') {
112
+ if (!LINK_PROP.test(key) && /^https?:\/\//i.test(v.trim()))
113
+ out.push(v.trim());
114
+ }
115
+ else if (Array.isArray(v) || isRecord(v)) {
116
+ collectUrls(v, out);
117
+ }
118
+ }
119
+ }
120
+ /** `rest` data sources of a receipt's persistence capability. */
121
+ function restEndpointsOf(receipt) {
122
+ if (!isRecord(receipt) || !Array.isArray(receipt['capabilities']))
123
+ return [];
124
+ const out = [];
125
+ for (const cap of receipt['capabilities']) {
126
+ if (!isRecord(cap) || !isRecord(cap['config']))
127
+ continue;
128
+ const sources = cap['config']['dataSources'];
129
+ if (!Array.isArray(sources))
130
+ continue;
131
+ for (const s of sources) {
132
+ if (isRecord(s) && s['kind'] === 'rest' && typeof s['endpoint'] === 'string')
133
+ out.push(s['endpoint']);
134
+ }
135
+ }
136
+ return out;
137
+ }
138
+ const AUTH_ADDRESS_KEYS = ['loginUrl', 'registerUrl', 'logoutUrl', 'sessionUrl', 'tokenUrl', 'issuer', 'startUrl', 'gatewaySessionUrl', 'gatewayLogoutUrl'];
139
+ /** Writes the directives as a policy string. */
140
+ export function serializeCsp(directives, options = {}) {
141
+ return Object.entries(directives)
142
+ .filter(([name, values]) => values.length > 0 && !(options.meta && HEADER_ONLY.has(name)))
143
+ .map(([name, values]) => `${name} ${values.join(' ')}`)
144
+ .join('; ');
145
+ }
146
+ /** Derives the app's policy from what it declares. */
147
+ export function deriveCsp(input) {
148
+ const unresolved = [];
149
+ const connect = new Set();
150
+ const media = new Set();
151
+ const style = new Set();
152
+ const font = new Set();
153
+ const addConnect = (value, source) => {
154
+ const o = originOf(value);
155
+ if (o === undefined)
156
+ unresolved.push({ source, value, reason: 'the address is a template or expression; its origin is known only at run time' });
157
+ else if (o)
158
+ connect.add(o);
159
+ };
160
+ // Data: absolute `rest` endpoints in the receipts. Relative ones are 'self'.
161
+ for (const [key, receipt] of input.receipts) {
162
+ for (const endpoint of restEndpointsOf(receipt))
163
+ addConnect(endpoint, `page:${key}`);
164
+ const urls = [];
165
+ if (isRecord(receipt))
166
+ mediaUrlsOf(receipt['blocks'], urls);
167
+ for (const url of urls) {
168
+ const o = originOf(url);
169
+ if (o)
170
+ media.add(o);
171
+ else if (o === undefined)
172
+ unresolved.push({ source: `page:${key}`, value: url, reason: 'a media address with an expression in its origin' });
173
+ }
174
+ }
175
+ // Connections: declared engines resolve their host; compiled ones cannot be read.
176
+ const configOf = new Map();
177
+ for (const c of input.connections?.connections ?? []) {
178
+ if (typeof c['name'] === 'string')
179
+ configOf.set(c['name'], isRecord(c['config']) ? c['config'] : {});
180
+ }
181
+ for (const e of input.engines) {
182
+ const host = isRecord(e.engine) && typeof e.engine['host'] === 'string' ? e.engine['host'] : undefined;
183
+ if (host !== undefined) {
184
+ const o = engineHostOrigin(host, configOf.get(e.connection));
185
+ if (o)
186
+ connect.add(o);
187
+ else
188
+ unresolved.push({ source: `connection:${e.connection}`, value: host, reason: 'the engine host names config the connection does not provide' });
189
+ }
190
+ else if (e.moduleUrl) {
191
+ unresolved.push({
192
+ source: `engine:${e.atomId}`,
193
+ value: e.moduleUrl,
194
+ reason: `compiled engine for connection "${e.connection}"; the origins its code reaches are not declared`,
195
+ });
196
+ }
197
+ }
198
+ // Sign-in: the envelope's addresses, and an external issuer's.
199
+ if (isRecord(input.envelopeAuth)) {
200
+ for (const k of AUTH_ADDRESS_KEYS) {
201
+ const v = input.envelopeAuth[k];
202
+ if (typeof v === 'string')
203
+ addConnect(v, 'auth');
204
+ }
205
+ }
206
+ const issuer = isRecord(input.authDefinition) && isRecord(input.authDefinition['issuer']) ? input.authDefinition['issuer'] : undefined;
207
+ if (issuer) {
208
+ for (const k of ['issuer', 'tokenUrl']) {
209
+ const v = issuer[k];
210
+ if (typeof v === 'string')
211
+ addConnect(v, 'auth');
212
+ }
213
+ if (typeof issuer['tokenUrl'] !== 'string' && typeof issuer['issuer'] === 'string') {
214
+ unresolved.push({
215
+ source: 'auth',
216
+ value: issuer['issuer'],
217
+ reason: "the token endpoint is discovered at run time; the policy allows the issuer's own origin only",
218
+ });
219
+ }
220
+ }
221
+ // Media the app declares.
222
+ for (const m of input.media) {
223
+ const o = originOf(m.url);
224
+ if (o)
225
+ media.add(o);
226
+ }
227
+ // Webfonts: the stylesheet and the files it points at.
228
+ if (input.webfontHref) {
229
+ const o = originOf(input.webfontHref);
230
+ if (o)
231
+ style.add(o);
232
+ if (o === 'https://fonts.googleapis.com')
233
+ font.add('https://fonts.gstatic.com');
234
+ }
235
+ const sorted = (s) => [...s].sort();
236
+ const directives = {
237
+ 'default-src': ["'none'"],
238
+ 'script-src': ["'self'", 'blob:', scriptHash(input.importMapText)],
239
+ 'style-src': ["'self'", "'unsafe-inline'", ...sorted(style)],
240
+ 'img-src': ["'self'", 'data:', 'blob:', ...sorted(media)],
241
+ 'media-src': ["'self'", 'data:', 'blob:', ...sorted(media)],
242
+ ...(media.size > 0 ? { 'frame-src': sorted(media) } : {}),
243
+ 'font-src': ["'self'", ...sorted(font)],
244
+ 'connect-src': ["'self'", ...sorted(connect)],
245
+ 'base-uri': ["'self'"],
246
+ 'object-src': ["'none'"],
247
+ 'frame-ancestors': ["'none'"],
248
+ };
249
+ return {
250
+ directives,
251
+ header: serializeCsp(directives),
252
+ meta: serializeCsp(directives, { meta: true }),
253
+ unresolved,
254
+ };
255
+ }
256
+ /** The static-host `_headers` file (`/*` and the policy). */
257
+ export function headersFile(policy) {
258
+ return `/*\n Content-Security-Policy: ${policy}\n`;
259
+ }
260
+ //# sourceMappingURL=csp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csp.js","sourceRoot":"","sources":["../../src/dev/csp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * What an assembly says about the folder it read: one shape for compiler
3
+ * output, validation findings and the assembler's own checks, so the terminal
4
+ * and the overlay page print the same list.
5
+ */
6
+ export type AssembleSeverity = 'error' | 'warning' | 'info';
7
+ export interface AssembleDiagnostic {
8
+ readonly severity: AssembleSeverity;
9
+ /** Machine-readable reason, e.g. `PACK_NOT_CACHED` or a compiler code. */
10
+ readonly code: string;
11
+ readonly message: string;
12
+ /** The file the finding is about, relative to the app folder when it can be. */
13
+ readonly path?: string;
14
+ readonly line?: number;
15
+ readonly column?: number;
16
+ }
17
+ /** `error app/surfaces/home.receipt.json:3:7 UNKNOWN_BLOCK_TYPE …` */
18
+ export declare function formatDiagnostic(d: AssembleDiagnostic): string;
19
+ export declare function hasErrors(diagnostics: readonly AssembleDiagnostic[]): boolean;
20
+ /** Errors first, then warnings, then info; stable within a severity. */
21
+ export declare function sortDiagnostics(diagnostics: readonly AssembleDiagnostic[]): AssembleDiagnostic[];
22
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/dev/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAE3D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAG9D;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,GAAG,OAAO,CAE7E;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,GAAG,kBAAkB,EAAE,CAMhG"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * What an assembly says about the folder it read: one shape for compiler
3
+ * output, validation findings and the assembler's own checks, so the terminal
4
+ * and the overlay page print the same list.
5
+ */
6
+ /** `error app/surfaces/home.receipt.json:3:7 UNKNOWN_BLOCK_TYPE …` */
7
+ export function formatDiagnostic(d) {
8
+ const where = d.path ? `${d.path}${d.line !== undefined ? `:${d.line}${d.column !== undefined ? `:${d.column}` : ''}` : ''} ` : '';
9
+ return `${d.severity.padEnd(7)} ${where}${d.code} ${d.message}`;
10
+ }
11
+ export function hasErrors(diagnostics) {
12
+ return diagnostics.some((d) => d.severity === 'error');
13
+ }
14
+ /** Errors first, then warnings, then info; stable within a severity. */
15
+ export function sortDiagnostics(diagnostics) {
16
+ const rank = { error: 0, warning: 1, info: 2 };
17
+ return diagnostics
18
+ .map((d, i) => [d, i])
19
+ .sort((a, b) => rank[a[0].severity] - rank[b[0].severity] || a[1] - b[1])
20
+ .map(([d]) => d);
21
+ }
22
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/dev/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,CAAqB;IACpD,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;IACnI,OAAO,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAA;AAClE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,WAA0C;IAClE,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAA;AACxD,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,eAAe,CAAC,WAA0C;IACxE,MAAM,IAAI,GAAqC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;IAChF,OAAO,WAAW;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAU,CAAC;SAC9B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;SACxE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;AACpB,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * The envelope documents a runner reads (`pwpack/project.json`,
3
+ * `navigation.json`, `connections.json`, the two module manifests), built
4
+ * from the app folder's declaration.
5
+ */
6
+ import type { AssembleDiagnostic } from './diagnostics.js';
7
+ /** One page of the app: its key, its receipt and what the receipt says. */
8
+ export interface Page {
9
+ readonly key: string;
10
+ /** Path of the receipt in the app folder. */
11
+ readonly path: string;
12
+ readonly bytes: Uint8Array;
13
+ readonly receipt: Record<string, unknown>;
14
+ }
15
+ /** The block types a receipt places, walking `blocks` and every `children`. */
16
+ export declare function blockTypesOf(receipt: unknown): string[];
17
+ /** The page's display name: the receipt's title, else the key. */
18
+ export declare function pageLabel(page: Page): string;
19
+ /** Navigation derived from the route table when the app declares none. */
20
+ export declare function deriveNavigation(pages: readonly Page[], entry: string): {
21
+ navbar: {
22
+ links: {
23
+ label: string;
24
+ href: string;
25
+ }[];
26
+ };
27
+ };
28
+ /** What the app declares about who may enter (`app/definitions/auth.json`), as `project.json` carries it. */
29
+ export declare function identityOf(auth: unknown): {
30
+ required: boolean;
31
+ topology: 'app' | 'external';
32
+ methods?: string[];
33
+ } | undefined;
34
+ export interface ProjectJsonInput {
35
+ readonly id: string;
36
+ readonly title: string;
37
+ readonly entry: string;
38
+ readonly pages: readonly Page[];
39
+ readonly auth?: unknown;
40
+ }
41
+ /** `pwpack/project.json`. */
42
+ export declare function buildProjectJson(input: ProjectJsonInput): Record<string, unknown>;
43
+ /** Config keys that smell of a credential. Such a key never reaches a published app. */
44
+ export declare const CREDENTIAL_KEY_RE: RegExp;
45
+ /**
46
+ * `pwpack/connections.json`: the declaration with every credential-like
47
+ * config key removed (each removal is reported). A bare string entry is read
48
+ * as `{ name }`.
49
+ */
50
+ export declare function buildConnections(doc: unknown, diagnostics: AssembleDiagnostic[], path?: string): {
51
+ connections: Record<string, unknown>[];
52
+ } | undefined;
53
+ /** One entry of `blocks/manifest.json`. */
54
+ export interface BlockManifestEntry {
55
+ readonly blockType: string;
56
+ readonly moduleUrl: string;
57
+ readonly integrity: string;
58
+ readonly publisher: string;
59
+ readonly publisherVerified: boolean;
60
+ readonly definition: {
61
+ readonly name: string;
62
+ };
63
+ }
64
+ /** One entry of `engines/manifest.json`. */
65
+ export interface EngineManifestEntry {
66
+ readonly connection: string;
67
+ readonly atomId: string;
68
+ readonly kind: 'connector' | 'provider';
69
+ readonly moduleUrl?: string;
70
+ readonly integrity?: string;
71
+ readonly engine?: unknown;
72
+ }
73
+ /** A file name for a module: `<name>.<first 8 hex of its hash>.mjs`, with anything unsafe replaced. */
74
+ export declare function moduleFileName(name: string, hexHash: string): string;
75
+ /** The publisher an atom is attributed to: the pack id's publisher segment, or the id itself. */
76
+ export declare function publisherOf(packId: string): string;
77
+ /**
78
+ * Whether a local host may write `name` into the envelope: a relative path of
79
+ * `/`-separated segments ending in `.json` (`auth.json`,
80
+ * `surfaces/home.receipt.json`), each segment starting with a letter, digit,
81
+ * `_` or `-` — so no `.`/`..` segment, no hidden file, no absolute path.
82
+ */
83
+ export declare function isEnvelopeFileName(name: string): boolean;
84
+ /**
85
+ * Merges what a local host adds to the envelope. Each key is a file name
86
+ * relative to `pwpack/` (`auth.json`, `surfaces/<key>.receipt.json`) and each
87
+ * value the document; a value for `project.json` is merged into it member by
88
+ * member. Called after the static envelope is laid out, so what the host
89
+ * offers WINS: its receipts (entity sources rewritten to its record
90
+ * endpoints) replace the folder's copies.
91
+ */
92
+ export declare function mergeEnvelopeEntries(files: Map<string, Uint8Array>, entries: Readonly<Record<string, unknown>> | undefined, diagnostics: AssembleDiagnostic[]): void;
93
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/dev/envelope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,154 @@
1
+ import { isRecord } from './sources.js';
2
+ /** The block types a receipt places, walking `blocks` and every `children`. */
3
+ export function blockTypesOf(receipt) {
4
+ const types = new Set();
5
+ const walk = (node) => {
6
+ if (Array.isArray(node)) {
7
+ node.forEach(walk);
8
+ return;
9
+ }
10
+ if (!isRecord(node))
11
+ return;
12
+ if (typeof node['type'] === 'string' && node['type'])
13
+ types.add(node['type']);
14
+ if (Array.isArray(node['children']))
15
+ node['children'].forEach(walk);
16
+ };
17
+ if (isRecord(receipt))
18
+ walk(receipt['blocks']);
19
+ return [...types];
20
+ }
21
+ /** The page's display name: the receipt's title, else the key. */
22
+ export function pageLabel(page) {
23
+ const title = page.receipt['title'];
24
+ return typeof title === 'string' && title.trim() ? title.trim() : page.key;
25
+ }
26
+ /** Navigation derived from the route table when the app declares none. */
27
+ export function deriveNavigation(pages, entry) {
28
+ return {
29
+ navbar: { links: pages.map((p) => ({ label: pageLabel(p), href: p.key === entry ? '/' : `/${p.key}` })) },
30
+ };
31
+ }
32
+ /** What the app declares about who may enter (`app/definitions/auth.json`), as `project.json` carries it. */
33
+ export function identityOf(auth) {
34
+ if (!isRecord(auth))
35
+ return undefined;
36
+ const topology = auth['topology'] === 'external' ? 'external' : 'app';
37
+ const methods = Array.isArray(auth['methods']) ? auth['methods'].filter((m) => typeof m === 'string') : [];
38
+ return {
39
+ required: auth['required'] === true,
40
+ topology,
41
+ ...(topology === 'app' ? { methods } : {}),
42
+ };
43
+ }
44
+ /** `pwpack/project.json`. */
45
+ export function buildProjectJson(input) {
46
+ const surfaceReceiptFiles = {};
47
+ for (const p of input.pages)
48
+ surfaceReceiptFiles[p.key] = `surfaces/${p.key}.receipt.json`;
49
+ const identity = identityOf(input.auth);
50
+ return {
51
+ schemaVersion: '1.0.0',
52
+ id: input.id,
53
+ title: input.title,
54
+ entrySurfaceId: input.entry,
55
+ surfaceOrder: input.pages.map((p) => p.key),
56
+ surfaceReceiptFiles,
57
+ ...(identity ? { identity } : {}),
58
+ };
59
+ }
60
+ /** Config keys that smell of a credential. Such a key never reaches a published app. */
61
+ export const CREDENTIAL_KEY_RE = /(auth|header|credential|secret|token|password|passwd|apikey|api_key|clientsecret|client_secret|bearer|cookie|signature)/i;
62
+ function stripCredentials(value, path, dropped) {
63
+ if (Array.isArray(value))
64
+ return value.map((v, i) => stripCredentials(v, `${path}[${i}]`, dropped));
65
+ if (!isRecord(value))
66
+ return value;
67
+ const out = {};
68
+ for (const [k, v] of Object.entries(value)) {
69
+ if (CREDENTIAL_KEY_RE.test(k)) {
70
+ dropped.push(`${path}.${k}`);
71
+ continue;
72
+ }
73
+ out[k] = stripCredentials(v, `${path}.${k}`, dropped);
74
+ }
75
+ return out;
76
+ }
77
+ /**
78
+ * `pwpack/connections.json`: the declaration with every credential-like
79
+ * config key removed (each removal is reported). A bare string entry is read
80
+ * as `{ name }`.
81
+ */
82
+ export function buildConnections(doc, diagnostics, path = 'app/definitions/connections.json') {
83
+ if (!isRecord(doc))
84
+ return undefined;
85
+ const list = Array.isArray(doc['connections']) ? doc['connections'] : [];
86
+ const connections = [];
87
+ for (const raw of list) {
88
+ const entry = typeof raw === 'string' ? { name: raw } : isRecord(raw) ? raw : null;
89
+ if (!entry || typeof entry['name'] !== 'string') {
90
+ diagnostics.push({ severity: 'warning', code: 'CONNECTION_INVALID', message: 'a connection without a name is skipped', path });
91
+ continue;
92
+ }
93
+ const dropped = [];
94
+ const out = { ...entry };
95
+ if (entry['config'] !== undefined)
96
+ out['config'] = stripCredentials(entry['config'], 'config', dropped);
97
+ for (const d of dropped) {
98
+ diagnostics.push({
99
+ severity: 'warning',
100
+ code: 'CREDENTIAL_DROPPED',
101
+ message: `connection "${entry['name']}": ${d} looks like a credential and is not published`,
102
+ path,
103
+ });
104
+ }
105
+ connections.push(out);
106
+ }
107
+ return { connections };
108
+ }
109
+ /** A file name for a module: `<name>.<first 8 hex of its hash>.mjs`, with anything unsafe replaced. */
110
+ export function moduleFileName(name, hexHash) {
111
+ const safe = name.replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^\.+/, '_') || 'module';
112
+ return `${safe}.${hexHash.slice(0, 8)}.mjs`;
113
+ }
114
+ /** The publisher an atom is attributed to: the pack id's publisher segment, or the id itself. */
115
+ export function publisherOf(packId) {
116
+ const m = /^@pwpack\/([^/]+)\//.exec(packId);
117
+ return m?.[1] ?? packId;
118
+ }
119
+ /**
120
+ * Whether a local host may write `name` into the envelope: a relative path of
121
+ * `/`-separated segments ending in `.json` (`auth.json`,
122
+ * `surfaces/home.receipt.json`), each segment starting with a letter, digit,
123
+ * `_` or `-` — so no `.`/`..` segment, no hidden file, no absolute path.
124
+ */
125
+ export function isEnvelopeFileName(name) {
126
+ return /^(?:[A-Za-z0-9_-][A-Za-z0-9_.-]*\/)*[A-Za-z0-9_-][A-Za-z0-9_.-]*\.json$/.test(name);
127
+ }
128
+ /**
129
+ * Merges what a local host adds to the envelope. Each key is a file name
130
+ * relative to `pwpack/` (`auth.json`, `surfaces/<key>.receipt.json`) and each
131
+ * value the document; a value for `project.json` is merged into it member by
132
+ * member. Called after the static envelope is laid out, so what the host
133
+ * offers WINS: its receipts (entity sources rewritten to its record
134
+ * endpoints) replace the folder's copies.
135
+ */
136
+ export function mergeEnvelopeEntries(files, entries, diagnostics) {
137
+ if (!entries)
138
+ return;
139
+ const enc = new TextEncoder();
140
+ for (const [name, value] of Object.entries(entries)) {
141
+ if (!isEnvelopeFileName(name)) {
142
+ diagnostics.push({ severity: 'warning', code: 'HOST_ENTRY_IGNORED', message: `the local host offered "${name}", which is not an envelope file name` });
143
+ continue;
144
+ }
145
+ const path = `pwpack/${name}`;
146
+ if (name === 'project.json' && isRecord(value)) {
147
+ const current = JSON.parse(new TextDecoder().decode(files.get(path)));
148
+ files.set(path, enc.encode(JSON.stringify({ ...current, ...value })));
149
+ continue;
150
+ }
151
+ files.set(path, enc.encode(JSON.stringify(value)));
152
+ }
153
+ }
154
+ //# sourceMappingURL=envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/dev/envelope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Media: the app's declared images and files, copied into the pwapp.
3
+ *
4
+ * pwpack-format §1.3: `app/media/<key>.json` declares one image or file
5
+ * (`{ purpose, kind, origin, slots, status, url?, decorative?, file? }`) and
6
+ * carries no bytes; the bytes are `media/<file>`, each recorded in
7
+ * `media/provenance.json`. The pack library's `mediaDeclarations` reads
8
+ * that layout (its findings reach the diagnostics through `validatePack`).
9
+ * pwapp-format §1 puts the bytes the app serves at `pwpack/media/<file>`,
10
+ * and §4 records each declaration's resolved address in `publish.json`
11
+ * `media[]`.
12
+ *
13
+ * For each declaration the bytes are looked up, in order:
14
+ *
15
+ * 1. the declaration's `file` (a pack path, `media/<name>`);
16
+ * 2. `media/<path>` — a `url` that is itself a `media/…` path;
17
+ * 3. `media/<key>.<ext>` — the one media file named after the key.
18
+ *
19
+ * Found bytes are served at `pwpack/media/…` and the declaration resolves to
20
+ * that address. A declaration without bytes but with an absolute `url` keeps
21
+ * the url. Every other one is reported (info) and left alone.
22
+ *
23
+ * Slots: a declared slot (`{ surfaceKey, blockId, prop }`) whose prop is
24
+ * empty in the served receipt gets the resolved address. A value already in
25
+ * the prop is never replaced (plan.md §2 rule 1). The app's own files are
26
+ * never rewritten; only the served copy of the receipt is.
27
+ */
28
+ import { type PackFolder } from '@pwfabric/pack';
29
+ import type { AssembleDiagnostic } from './diagnostics.js';
30
+ /** One slot a resolved address is written into. */
31
+ export interface MediaSlot {
32
+ readonly blockId: string;
33
+ readonly prop: string;
34
+ readonly url: string;
35
+ }
36
+ export interface CollectedMedia {
37
+ /** Files to serve, relative to `pwpack/` (`media/hero.webp`). */
38
+ readonly files: Map<string, Uint8Array>;
39
+ /** `publish.json` `media[]`, in key order. */
40
+ readonly records: {
41
+ key: string;
42
+ url: string;
43
+ }[];
44
+ /** Slots to fill, by page key. */
45
+ readonly slots: Map<string, MediaSlot[]>;
46
+ }
47
+ /** Reads the app's media declarations and bytes. */
48
+ export declare function collectMedia(folder: PackFolder, diagnostics: AssembleDiagnostic[]): CollectedMedia;
49
+ /**
50
+ * The served receipt with its empty media slots filled, or `undefined` when
51
+ * nothing changed (the bytes are then served exactly as written).
52
+ */
53
+ export declare function fillMediaSlots(receiptBytes: Uint8Array, slots: readonly MediaSlot[] | undefined): Uint8Array | undefined;
54
+ //# sourceMappingURL=media.d.ts.map