@zmdb/web 1.0.0-beta.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.
Files changed (179) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +49 -0
  3. package/dist/app/bridge.d.ts +12 -0
  4. package/dist/app/bridge.d.ts.map +1 -0
  5. package/dist/app/bridge.js +16 -0
  6. package/dist/app/bridge.js.map +1 -0
  7. package/dist/app/index.d.ts +23 -0
  8. package/dist/app/index.d.ts.map +1 -0
  9. package/dist/app/index.js +47 -0
  10. package/dist/app/index.js.map +1 -0
  11. package/dist/bench/index.d.ts +68 -0
  12. package/dist/bench/index.d.ts.map +1 -0
  13. package/dist/bench/index.js +250 -0
  14. package/dist/bench/index.js.map +1 -0
  15. package/dist/compression/index.d.ts +13 -0
  16. package/dist/compression/index.d.ts.map +1 -0
  17. package/dist/compression/index.js +211 -0
  18. package/dist/compression/index.js.map +1 -0
  19. package/dist/context/index.d.ts +74 -0
  20. package/dist/context/index.d.ts.map +1 -0
  21. package/dist/context/index.js +118 -0
  22. package/dist/context/index.js.map +1 -0
  23. package/dist/contract/__fixtures__/http-client.generated.d.ts +70 -0
  24. package/dist/contract/__fixtures__/http-client.generated.d.ts.map +1 -0
  25. package/dist/contract/__fixtures__/http-client.generated.js +86 -0
  26. package/dist/contract/__fixtures__/http-client.generated.js.map +1 -0
  27. package/dist/contract/__fixtures__/http-convergence.d.ts +396 -0
  28. package/dist/contract/__fixtures__/http-convergence.d.ts.map +1 -0
  29. package/dist/contract/__fixtures__/http-convergence.js +425 -0
  30. package/dist/contract/__fixtures__/http-convergence.js.map +1 -0
  31. package/dist/contract/compiler/client.d.ts +12 -0
  32. package/dist/contract/compiler/client.d.ts.map +1 -0
  33. package/dist/contract/compiler/client.js +1293 -0
  34. package/dist/contract/compiler/client.js.map +1 -0
  35. package/dist/contract/compiler/index.d.ts +18 -0
  36. package/dist/contract/compiler/index.d.ts.map +1 -0
  37. package/dist/contract/compiler/index.js +1058 -0
  38. package/dist/contract/compiler/index.js.map +1 -0
  39. package/dist/contract/index.d.ts +237 -0
  40. package/dist/contract/index.d.ts.map +1 -0
  41. package/dist/contract/index.js +22 -0
  42. package/dist/contract/index.js.map +1 -0
  43. package/dist/csrf/index.d.ts +15 -0
  44. package/dist/csrf/index.d.ts.map +1 -0
  45. package/dist/csrf/index.js +218 -0
  46. package/dist/csrf/index.js.map +1 -0
  47. package/dist/data/index.d.ts +35 -0
  48. package/dist/data/index.d.ts.map +1 -0
  49. package/dist/data/index.js +58 -0
  50. package/dist/data/index.js.map +1 -0
  51. package/dist/devtools/index.d.ts +74 -0
  52. package/dist/devtools/index.d.ts.map +1 -0
  53. package/dist/devtools/index.js +552 -0
  54. package/dist/devtools/index.js.map +1 -0
  55. package/dist/dto-pipes/index.d.ts +45 -0
  56. package/dist/dto-pipes/index.d.ts.map +1 -0
  57. package/dist/dto-pipes/index.js +78 -0
  58. package/dist/dto-pipes/index.js.map +1 -0
  59. package/dist/gateways/index.d.ts +31 -0
  60. package/dist/gateways/index.d.ts.map +1 -0
  61. package/dist/gateways/index.js +138 -0
  62. package/dist/gateways/index.js.map +1 -0
  63. package/dist/health/index.d.ts +20 -0
  64. package/dist/health/index.d.ts.map +1 -0
  65. package/dist/health/index.js +148 -0
  66. package/dist/health/index.js.map +1 -0
  67. package/dist/http-token.d.ts +2 -0
  68. package/dist/http-token.d.ts.map +1 -0
  69. package/dist/http-token.js +21 -0
  70. package/dist/http-token.js.map +1 -0
  71. package/dist/index.d.ts +18 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +40 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/integrations/index.d.ts +11 -0
  76. package/dist/integrations/index.d.ts.map +1 -0
  77. package/dist/integrations/index.js +39 -0
  78. package/dist/integrations/index.js.map +1 -0
  79. package/dist/middleware/errors.d.ts +14 -0
  80. package/dist/middleware/errors.d.ts.map +1 -0
  81. package/dist/middleware/errors.js +18 -0
  82. package/dist/middleware/errors.js.map +1 -0
  83. package/dist/middleware/index.d.ts +46 -0
  84. package/dist/middleware/index.d.ts.map +1 -0
  85. package/dist/middleware/index.js +64 -0
  86. package/dist/middleware/index.js.map +1 -0
  87. package/dist/modules/__fixtures__/large-graph.d.ts +239 -0
  88. package/dist/modules/__fixtures__/large-graph.d.ts.map +1 -0
  89. package/dist/modules/__fixtures__/large-graph.js +483 -0
  90. package/dist/modules/__fixtures__/large-graph.js.map +1 -0
  91. package/dist/openapi/__fixtures__/entities.d.ts +8 -0
  92. package/dist/openapi/__fixtures__/entities.d.ts.map +1 -0
  93. package/dist/openapi/__fixtures__/entities.js +4 -0
  94. package/dist/openapi/__fixtures__/entities.js.map +1 -0
  95. package/dist/openapi/__fixtures__/openapi-tools.fixture.d.ts +38 -0
  96. package/dist/openapi/__fixtures__/openapi-tools.fixture.d.ts.map +1 -0
  97. package/dist/openapi/__fixtures__/openapi-tools.fixture.js +172 -0
  98. package/dist/openapi/__fixtures__/openapi-tools.fixture.js.map +1 -0
  99. package/dist/openapi/__fixtures__/route-schemas.d.ts +2 -0
  100. package/dist/openapi/__fixtures__/route-schemas.d.ts.map +1 -0
  101. package/dist/openapi/__fixtures__/route-schemas.js +17 -0
  102. package/dist/openapi/__fixtures__/route-schemas.js.map +1 -0
  103. package/dist/openapi/index.d.ts +61 -0
  104. package/dist/openapi/index.d.ts.map +1 -0
  105. package/dist/openapi/index.js +314 -0
  106. package/dist/openapi/index.js.map +1 -0
  107. package/dist/pipeline/guards.d.ts +9 -0
  108. package/dist/pipeline/guards.d.ts.map +1 -0
  109. package/dist/pipeline/guards.js +11 -0
  110. package/dist/pipeline/guards.js.map +1 -0
  111. package/dist/pipeline/index.d.ts +141 -0
  112. package/dist/pipeline/index.d.ts.map +1 -0
  113. package/dist/pipeline/index.js +1624 -0
  114. package/dist/pipeline/index.js.map +1 -0
  115. package/dist/routing/index.d.ts +40 -0
  116. package/dist/routing/index.d.ts.map +1 -0
  117. package/dist/routing/index.js +162 -0
  118. package/dist/routing/index.js.map +1 -0
  119. package/dist/static/index.d.ts +14 -0
  120. package/dist/static/index.d.ts.map +1 -0
  121. package/dist/static/index.js +348 -0
  122. package/dist/static/index.js.map +1 -0
  123. package/dist/testing/index.d.ts +20 -0
  124. package/dist/testing/index.d.ts.map +1 -0
  125. package/dist/testing/index.js +32 -0
  126. package/dist/testing/index.js.map +1 -0
  127. package/dist/traced-router.d.ts +5 -0
  128. package/dist/traced-router.d.ts.map +1 -0
  129. package/dist/traced-router.js +6 -0
  130. package/dist/traced-router.js.map +1 -0
  131. package/dist/upload/index.d.ts +28 -0
  132. package/dist/upload/index.d.ts.map +1 -0
  133. package/dist/upload/index.js +410 -0
  134. package/dist/upload/index.js.map +1 -0
  135. package/dist/versioning/index.d.ts +35 -0
  136. package/dist/versioning/index.d.ts.map +1 -0
  137. package/dist/versioning/index.js +66 -0
  138. package/dist/versioning/index.js.map +1 -0
  139. package/dist/versioning/runtime.d.ts +5 -0
  140. package/dist/versioning/runtime.d.ts.map +1 -0
  141. package/dist/versioning/runtime.js +34 -0
  142. package/dist/versioning/runtime.js.map +1 -0
  143. package/package.json +143 -0
  144. package/src/app/bridge.ts +39 -0
  145. package/src/app/index.ts +76 -0
  146. package/src/bench/index.ts +329 -0
  147. package/src/compression/index.ts +255 -0
  148. package/src/context/index.ts +181 -0
  149. package/src/contract/__fixtures__/http-client.generated.ts +73 -0
  150. package/src/contract/__fixtures__/http-client.generated.ts.map +1 -0
  151. package/src/contract/__fixtures__/http-convergence.ts +564 -0
  152. package/src/contract/compiler/client.ts +1518 -0
  153. package/src/contract/compiler/index.ts +1457 -0
  154. package/src/contract/index.ts +266 -0
  155. package/src/csrf/index.ts +264 -0
  156. package/src/data/index.ts +65 -0
  157. package/src/devtools/index.ts +727 -0
  158. package/src/dto-pipes/index.ts +93 -0
  159. package/src/gateways/index.ts +180 -0
  160. package/src/health/index.ts +198 -0
  161. package/src/http-token.ts +22 -0
  162. package/src/index.ts +167 -0
  163. package/src/integrations/index.ts +50 -0
  164. package/src/middleware/errors.ts +17 -0
  165. package/src/middleware/index.ts +108 -0
  166. package/src/modules/__fixtures__/large-graph.ts +540 -0
  167. package/src/openapi/__fixtures__/entities.ts +19 -0
  168. package/src/openapi/__fixtures__/openapi-tools.fixture.ts +212 -0
  169. package/src/openapi/__fixtures__/route-schemas.ts +27 -0
  170. package/src/openapi/index.ts +483 -0
  171. package/src/pipeline/guards.ts +23 -0
  172. package/src/pipeline/index.ts +2041 -0
  173. package/src/routing/index.ts +201 -0
  174. package/src/static/index.ts +443 -0
  175. package/src/testing/index.ts +58 -0
  176. package/src/traced-router.ts +8 -0
  177. package/src/upload/index.ts +489 -0
  178. package/src/versioning/index.ts +106 -0
  179. package/src/versioning/runtime.ts +38 -0
@@ -0,0 +1,348 @@
1
+ // @zmdb/web — confined static-file responses (epic #564, issue #568).
2
+ //
3
+ // Paths are decoded once, refused before filesystem access, opened once, and
4
+ // streamed from that descriptor. Every refusal is the same empty 404; details
5
+ // go only to the required onError sink.
6
+ import { respond, stream } from '../pipeline/index.js';
7
+ const DEFAULT_CACHE_CONTROL = 'public, max-age=0, must-revalidate';
8
+ const NOSNIFF = Object.freeze({ 'x-content-type-options': 'nosniff' });
9
+ const DEFAULT_CONTENT_TYPES = Object.freeze({
10
+ '.css': 'text/css',
11
+ '.csv': 'text/csv',
12
+ '.gif': 'image/gif',
13
+ '.htm': 'text/html; charset=utf-8',
14
+ '.html': 'text/html; charset=utf-8',
15
+ '.ico': 'image/x-icon',
16
+ '.jpeg': 'image/jpeg',
17
+ '.jpg': 'image/jpeg',
18
+ '.js': 'application/javascript',
19
+ '.json': 'application/json',
20
+ '.mjs': 'application/javascript',
21
+ '.png': 'image/png',
22
+ '.svg': 'image/svg+xml',
23
+ '.txt': 'text/plain; charset=utf-8',
24
+ '.webp': 'image/webp',
25
+ '.woff': 'font/woff',
26
+ '.woff2': 'font/woff2',
27
+ '.xml': 'application/xml',
28
+ });
29
+ /** Build a handler whose root is resolved and validated exactly once. */
30
+ export async function createStaticHandler(options) {
31
+ // Keep @zmdb/web and @zmdb/web/static loadable on Fetch-only runtimes. The
32
+ // Node filesystem is required only when an application constructs this
33
+ // filesystem-backed handler.
34
+ const [fsModule, fsPromises, pathModule] = await Promise.all([
35
+ import('node:fs'),
36
+ import('node:fs/promises'),
37
+ import('node:path'),
38
+ ]);
39
+ const filesystem = {
40
+ open: (path, flags) => fsPromises.open(path, flags),
41
+ realpath: path => fsPromises.realpath(path),
42
+ stat: path => fsPromises.stat(path),
43
+ readFlags: fsModule.constants.O_RDONLY | fsModule.constants.O_NONBLOCK,
44
+ };
45
+ const paths = {
46
+ extname: pathModule.extname,
47
+ isAbsolute: pathModule.isAbsolute,
48
+ resolve: pathModule.resolve,
49
+ sep: pathModule.sep,
50
+ };
51
+ const root = await filesystem.realpath(options.root);
52
+ const rootStat = await filesystem.stat(root);
53
+ if (!rootStat.isDirectory()) {
54
+ throw new Error('static root must be a directory');
55
+ }
56
+ const cacheControl = options.cacheControl ?? DEFAULT_CACHE_CONTROL;
57
+ const contentTypes = normalizedContentTypes(options.contentTypes);
58
+ return {
59
+ serve(pathname, headers) {
60
+ return serveFromRoot(filesystem, paths, root, pathname, headers, cacheControl, contentTypes, options);
61
+ },
62
+ };
63
+ }
64
+ async function serveFromRoot(filesystem, paths, root, pathname, requestHeaders, cacheControl, contentTypes, options) {
65
+ const relative = confinedPath(pathname, options.index, paths);
66
+ if (relative.kind === 'missing') {
67
+ return notFound();
68
+ }
69
+ if (relative.kind === 'refused') {
70
+ report(options, relative.error);
71
+ return notFound();
72
+ }
73
+ const resolved = paths.resolve(root, relative.value);
74
+ if (!contains(root, resolved, paths.sep)) {
75
+ report(options, new Error('static path escaped its root'));
76
+ return notFound();
77
+ }
78
+ let handle;
79
+ try {
80
+ // O_NONBLOCK is load-bearing for FIFOs: opening one only to discover its
81
+ // inode type must not wait forever for a writer.
82
+ handle = await filesystem.open(resolved, filesystem.readFlags);
83
+ }
84
+ catch (error) {
85
+ if (!isOrdinaryMiss(error)) {
86
+ report(options, error);
87
+ }
88
+ return notFound();
89
+ }
90
+ try {
91
+ const descriptorStat = await handle.stat();
92
+ if (!descriptorStat.isFile()) {
93
+ report(options, new Error('static path is not a regular file'));
94
+ await closeQuietly(handle);
95
+ return notFound();
96
+ }
97
+ const target = await openedRealpath(filesystem, handle, resolved, descriptorStat);
98
+ if (!contains(root, target, paths.sep)) {
99
+ report(options, new Error('static symlink escaped its root'));
100
+ await closeQuietly(handle);
101
+ return notFound();
102
+ }
103
+ const validators = validatorHeaders(descriptorStat, cacheControl);
104
+ if (notModified(requestHeaders, descriptorStat, validators.etag)) {
105
+ await closeQuietly(handle);
106
+ return respond({ status: 304, headers: validators });
107
+ }
108
+ const requestedRange = header(requestHeaders, 'if-range') === undefined
109
+ ? parseRange(header(requestHeaders, 'range'), descriptorStat.size)
110
+ : { kind: 'full' };
111
+ if (requestedRange.kind === 'unsatisfiable') {
112
+ await closeQuietly(handle);
113
+ return respond({
114
+ status: 416,
115
+ headers: { ...validators, 'content-range': `bytes */${String(descriptorStat.size)}` },
116
+ });
117
+ }
118
+ const extension = paths.extname(relative.value).toLowerCase();
119
+ const contentType = contentTypes[extension] ?? 'application/octet-stream';
120
+ const start = requestedRange.kind === 'full' ? 0 : requestedRange.start;
121
+ const end = requestedRange.kind === 'full' ? Math.max(0, descriptorStat.size - 1) : requestedRange.end;
122
+ const length = requestedRange.kind === 'full' ? descriptorStat.size : end - start + 1;
123
+ const responseHeaders = {
124
+ ...validators,
125
+ 'accept-ranges': 'bytes',
126
+ 'content-length': String(length),
127
+ 'content-type': contentType,
128
+ };
129
+ if (requestedRange.kind !== 'full') {
130
+ responseHeaders['content-range'] = `bytes ${String(start)}-${String(end)}/${String(descriptorStat.size)}`;
131
+ }
132
+ return stream(fileWindow(handle, start, length), {
133
+ status: requestedRange.kind === 'full' ? 200 : 206,
134
+ headers: responseHeaders,
135
+ length,
136
+ onError: options.onError,
137
+ });
138
+ }
139
+ catch (error) {
140
+ await closeQuietly(handle);
141
+ report(options, error);
142
+ return notFound();
143
+ }
144
+ }
145
+ function confinedPath(pathname, index, paths) {
146
+ if (pathname.length === 0 && index === undefined) {
147
+ return { kind: 'missing' };
148
+ }
149
+ let decoded;
150
+ try {
151
+ decoded = decodeURIComponent(pathname.length === 0 ? (index ?? '') : pathname);
152
+ }
153
+ catch {
154
+ return { kind: 'refused', error: new Error('static path is not valid percent-encoded UTF-8') };
155
+ }
156
+ if (decoded.length === 0 ||
157
+ decoded.includes('%') ||
158
+ decoded.includes('\0') ||
159
+ decoded.includes('\\') ||
160
+ decoded.startsWith('/') ||
161
+ decoded.startsWith('//') ||
162
+ /^[A-Za-z]:/.test(decoded) ||
163
+ paths.isAbsolute(decoded)) {
164
+ return { kind: 'refused', error: new Error('static path contains a refused form') };
165
+ }
166
+ const segments = decoded.split('/');
167
+ if (segments.some(segment => segment.length === 0 || segment === '..' || segment.startsWith('.'))) {
168
+ return { kind: 'refused', error: new Error('static path contains a refused segment') };
169
+ }
170
+ return { kind: 'path', value: decoded };
171
+ }
172
+ function contains(root, candidate, separator) {
173
+ const prefix = root.endsWith(separator) ? root : `${root}${separator}`;
174
+ return candidate === root || candidate.startsWith(prefix);
175
+ }
176
+ function normalizedContentTypes(overrides) {
177
+ if (overrides === undefined) {
178
+ return DEFAULT_CONTENT_TYPES;
179
+ }
180
+ const result = { ...DEFAULT_CONTENT_TYPES };
181
+ for (const key of Object.keys(overrides)) {
182
+ result[key.toLowerCase()] = overrides[key] ?? 'application/octet-stream';
183
+ }
184
+ return result;
185
+ }
186
+ async function openedRealpath(filesystem, handle, originalPath, descriptorStat) {
187
+ try {
188
+ // Linux exposes the canonical target of the descriptor itself. The frozen
189
+ // tests already require /proc for descriptor accounting, and this form
190
+ // closes the path-swap gap between open() and the symlink containment check.
191
+ return await filesystem.realpath(`/proc/self/fd/${String(handle.fd)}`);
192
+ }
193
+ catch {
194
+ // Other supported Node platforms have no portable fd-to-path API. The
195
+ // opened descriptor still owns response metadata and bytes. Bind the
196
+ // path-based real target back to that descriptor by filesystem identity so
197
+ // a swap between open() and realpath() is refused.
198
+ const target = await filesystem.realpath(originalPath);
199
+ const targetStat = await filesystem.stat(target);
200
+ if (!sameFile(descriptorStat, targetStat)) {
201
+ throw new Error('static path changed while it was being opened');
202
+ }
203
+ return target;
204
+ }
205
+ }
206
+ function sameFile(left, right) {
207
+ return left.dev === right.dev && left.ino === right.ino;
208
+ }
209
+ function validatorHeaders(statValue, cacheControl) {
210
+ return {
211
+ 'cache-control': cacheControl,
212
+ etag: `W/"${String(statValue.size)}-${String(statValue.mtimeMs)}"`,
213
+ 'last-modified': statValue.mtime.toUTCString(),
214
+ 'x-content-type-options': 'nosniff',
215
+ };
216
+ }
217
+ function notModified(headers, statValue, etag) {
218
+ const ifNoneMatch = header(headers, 'if-none-match');
219
+ if (ifNoneMatch !== undefined) {
220
+ return ifNoneMatch
221
+ .split(',')
222
+ .map(value => value.trim())
223
+ .some(value => value === '*' || weakTag(value) === weakTag(etag));
224
+ }
225
+ const ifModifiedSince = header(headers, 'if-modified-since');
226
+ if (ifModifiedSince === undefined) {
227
+ return false;
228
+ }
229
+ const since = Date.parse(ifModifiedSince);
230
+ return Number.isFinite(since) && Math.floor(statValue.mtimeMs / 1000) * 1000 <= since;
231
+ }
232
+ function weakTag(value) {
233
+ const trimmed = value.trim();
234
+ return trimmed.startsWith('W/') ? trimmed.slice(2) : trimmed;
235
+ }
236
+ function parseRange(value, size) {
237
+ if (value === undefined || value.includes(',')) {
238
+ return { kind: 'full' };
239
+ }
240
+ const match = /^bytes=(\d*)-(\d*)$/i.exec(value.trim());
241
+ if (match === null) {
242
+ return { kind: 'full' };
243
+ }
244
+ const first = match[1] ?? '';
245
+ const second = match[2] ?? '';
246
+ if (first.length === 0 && second.length === 0) {
247
+ return { kind: 'full' };
248
+ }
249
+ if (first.length === 0) {
250
+ const suffix = safeInteger(second);
251
+ if (suffix === undefined || suffix <= 0 || size === 0) {
252
+ return { kind: 'full' };
253
+ }
254
+ return { kind: 'range', start: Math.max(0, size - suffix), end: size - 1 };
255
+ }
256
+ const start = safeInteger(first);
257
+ if (start === undefined) {
258
+ return { kind: 'full' };
259
+ }
260
+ if (start >= size) {
261
+ return { kind: 'unsatisfiable' };
262
+ }
263
+ if (second.length === 0) {
264
+ return { kind: 'range', start, end: size - 1 };
265
+ }
266
+ const requestedEnd = safeInteger(second);
267
+ if (requestedEnd === undefined || requestedEnd < start) {
268
+ return { kind: 'full' };
269
+ }
270
+ return { kind: 'range', start, end: Math.min(requestedEnd, size - 1) };
271
+ }
272
+ function safeInteger(value) {
273
+ if (!/^\d+$/.test(value)) {
274
+ return undefined;
275
+ }
276
+ const parsed = Number(value);
277
+ return Number.isSafeInteger(parsed) ? parsed : undefined;
278
+ }
279
+ function header(headers, wanted) {
280
+ for (const name of Object.keys(headers)) {
281
+ if (name.toLowerCase() === wanted) {
282
+ return headers[name];
283
+ }
284
+ }
285
+ return undefined;
286
+ }
287
+ function fileWindow(handle, start, length) {
288
+ let position = start;
289
+ let remaining = length;
290
+ let closed = false;
291
+ const close = async () => {
292
+ if (!closed) {
293
+ closed = true;
294
+ await handle.close();
295
+ }
296
+ };
297
+ return new ReadableStream({
298
+ async pull(controller) {
299
+ try {
300
+ if (remaining === 0) {
301
+ await close();
302
+ controller.close();
303
+ return;
304
+ }
305
+ const wanted = Math.min(64 * 1024, remaining);
306
+ const chunk = new Uint8Array(wanted);
307
+ const result = await handle.read(chunk, 0, wanted, position);
308
+ if (result.bytesRead === 0) {
309
+ throw new Error('static file ended before its measured length');
310
+ }
311
+ position += result.bytesRead;
312
+ remaining -= result.bytesRead;
313
+ controller.enqueue(chunk.slice(0, result.bytesRead));
314
+ }
315
+ catch (error) {
316
+ await close().catch(() => undefined);
317
+ controller.error(error);
318
+ }
319
+ },
320
+ cancel: close,
321
+ });
322
+ }
323
+ function notFound() {
324
+ return respond({ status: 404, headers: NOSNIFF });
325
+ }
326
+ function isOrdinaryMiss(error) {
327
+ const code = errorCode(error);
328
+ return code === 'ENOENT' || code === 'ENOTDIR';
329
+ }
330
+ function errorCode(error) {
331
+ if (typeof error !== 'object' || error === null || !('code' in error)) {
332
+ return undefined;
333
+ }
334
+ const code = Reflect.get(error, 'code');
335
+ return typeof code === 'string' ? code : undefined;
336
+ }
337
+ function report(options, error) {
338
+ try {
339
+ options.onError(error);
340
+ }
341
+ catch {
342
+ // A diagnostic sink cannot turn a uniform 404 into a rejected request.
343
+ }
344
+ }
345
+ async function closeQuietly(handle) {
346
+ await handle.close().catch(() => undefined);
347
+ }
348
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/static/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type ModuleClass, type ProviderDef, type Token } from '@zmdb/app';
2
+ import type { Observability } from '@zmdb/app/observability';
3
+ import { type WebRequest, type WebResponse } from '../pipeline/index.js';
4
+ /** Options for `createTestApp`. */
5
+ export interface TestAppOptions {
6
+ readonly overrides?: readonly ProviderDef[];
7
+ readonly observability?: Observability;
8
+ }
9
+ /** A test application: drive requests in-process and resolve providers. */
10
+ export interface TestApp extends AsyncDisposable {
11
+ request(req: WebRequest): Promise<WebResponse>;
12
+ get<T>(token: Token<T>): T;
13
+ init(): Promise<void>;
14
+ }
15
+ /**
16
+ * Compile one overridden graph, hand that exact graph to createApplication,
17
+ * and drive its controllers through the production HTTP router.
18
+ */
19
+ export declare function createTestApp(rootModule: ModuleClass, options?: TestAppOptions): TestApp;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,KAAK,EACX,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,EAA6B,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEpG,mCAAmC;AACnC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;CACxC;AAED,2EAA2E;AAC3E,MAAM,WAAW,OAAQ,SAAQ,eAAe;IAC9C,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAoB5F"}
@@ -0,0 +1,32 @@
1
+ // @zmdb/web — in-process HTTP testing over the app-owned graph and lifecycle.
2
+ import { compileModule, createApplication, } from '@zmdb/app';
3
+ import { applicationControllersOf, withCompiledApplication } from '../app/bridge.js';
4
+ import { createRouter } from '../pipeline/index.js';
5
+ /**
6
+ * Compile one overridden graph, hand that exact graph to createApplication,
7
+ * and drive its controllers through the production HTTP router.
8
+ */
9
+ export function createTestApp(rootModule, options = {}) {
10
+ const compiled = compileModule(rootModule, options.overrides ?? []);
11
+ const applicationOptions = options.observability === undefined ? {} : { observability: options.observability };
12
+ const application = createApplication(rootModule, withCompiledApplication(applicationOptions, compiled));
13
+ const router = createRouter(options.observability);
14
+ for (const binding of applicationControllersOf(application)) {
15
+ if (binding.kind === 'eager') {
16
+ router.register(binding.controller);
17
+ }
18
+ else {
19
+ router.registerDeferred(binding.controller, binding.instance);
20
+ }
21
+ }
22
+ return {
23
+ request: req => router.handle(req),
24
+ get: (token) => resolveFrom(application.container, token),
25
+ init: application.init,
26
+ [Symbol.asyncDispose]: application[Symbol.asyncDispose],
27
+ };
28
+ }
29
+ function resolveFrom(container, token) {
30
+ return container.resolve(token);
31
+ }
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,EACL,aAAa,EACb,iBAAiB,GAMlB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAkD,MAAM,sBAAsB,CAAC;AAepG;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,UAAuB,EAAE,OAAO,GAAmB,EAAE;IACjF,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,kBAAkB,GACtB,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;IACtF,MAAM,WAAW,GAAG,iBAAiB,CAAC,UAAU,EAAE,uBAAuB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC,CAAC;IACzG,MAAM,MAAM,GAAW,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3D,KAAK,MAAM,OAAO,IAAI,wBAAwB,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5D,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC7B,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;QAClC,GAAG,EAAE,CAAI,KAAe,EAAK,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC;QACzE,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAI,SAAoB,EAAE,KAAe;IAC3D,OAAO,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Observability } from '@zmdb/app/observability';
2
+ import { type Router } from './pipeline/index.js';
3
+ /** Build the HTTP router with the app-owned observability ports. */
4
+ export declare function createTracedRouter(observability?: Observability): Router;
5
+ //# sourceMappingURL=traced-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traced-router.d.ts","sourceRoot":"","sources":["../src/traced-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAEhE,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,aAAa,GAAE,aAAkB,GAAG,MAAM,CAE5E"}
@@ -0,0 +1,6 @@
1
+ import { createRouter } from './pipeline/index.js';
2
+ /** Build the HTTP router with the app-owned observability ports. */
3
+ export function createTracedRouter(observability = {}) {
4
+ return createRouter(observability);
5
+ }
6
+ //# sourceMappingURL=traced-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traced-router.js","sourceRoot":"","sources":["../src/traced-router.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAe,MAAM,qBAAqB,CAAC;AAEhE,oEAAoE;AACpE,MAAM,UAAU,kBAAkB,CAAC,aAAa,GAAkB,EAAE;IAClE,OAAO,YAAY,CAAC,aAAa,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,28 @@
1
+ export interface UploadLimits {
2
+ readonly maxParts: number;
3
+ readonly maxPartBytes: number;
4
+ readonly maxTotalBytes: number;
5
+ readonly maxFieldNameBytes: number;
6
+ readonly maxFilenameBytes: number;
7
+ readonly maxPartHeaderBytes: number;
8
+ }
9
+ export declare const UPLOAD_DEFAULTS: UploadLimits;
10
+ export interface UploadPart {
11
+ readonly name: string;
12
+ readonly filename: string | undefined;
13
+ readonly declaredType: string | undefined;
14
+ readonly bytes: Uint8Array<ArrayBuffer>;
15
+ }
16
+ export interface Multipart {
17
+ readonly fields: Readonly<Record<string, string>>;
18
+ readonly files: readonly UploadPart[];
19
+ }
20
+ /**
21
+ * Parse one bounded `multipart/form-data` body without decoding file contents.
22
+ *
23
+ * The adapter's `maxBodyBytes` is the transfer-time limit. This function checks
24
+ * `maxTotalBytes` before scanning and then stops each bounded scan at the first
25
+ * exceeded part/header limit, before decoding or returning that region.
26
+ */
27
+ export declare function parseMultipart(rawBody: unknown, contentType: string, overrides?: Partial<UploadLimits>): Multipart;
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upload/index.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,eAAO,MAAM,eAAe,EAAE,YAO5B,CAAC;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;CACvC;AAkXD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,OAAO,CAAC,YAAY,CAAM,GACpC,SAAS,CAsEX"}