@c9up/ream 0.2.18 → 0.2.20

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 (50) hide show
  1. package/README.md +4 -0
  2. package/dist/Application.d.ts +15 -0
  3. package/dist/Application.d.ts.map +1 -1
  4. package/dist/Application.js +15 -0
  5. package/dist/Application.js.map +1 -1
  6. package/dist/Ignitor.d.ts +12 -1
  7. package/dist/Ignitor.d.ts.map +1 -1
  8. package/dist/Ignitor.js +63 -8
  9. package/dist/Ignitor.js.map +1 -1
  10. package/dist/Provider.d.ts +15 -0
  11. package/dist/Provider.d.ts.map +1 -1
  12. package/dist/Provider.js.map +1 -1
  13. package/dist/http/Request.d.ts +13 -3
  14. package/dist/http/Request.d.ts.map +1 -1
  15. package/dist/http/Request.js.map +1 -1
  16. package/dist/index.d.ts +3 -3
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +2 -2
  19. package/dist/index.js.map +1 -1
  20. package/dist/router/Router.d.ts +1 -1
  21. package/dist/router/Router.js +1 -1
  22. package/dist/security/CookieSigner.d.ts +3 -2
  23. package/dist/security/CookieSigner.d.ts.map +1 -1
  24. package/dist/security/CookieSigner.js +3 -2
  25. package/dist/security/CookieSigner.js.map +1 -1
  26. package/dist/storage/StaticMiddleware.d.ts +75 -7
  27. package/dist/storage/StaticMiddleware.d.ts.map +1 -1
  28. package/dist/storage/StaticMiddleware.js +257 -85
  29. package/dist/storage/StaticMiddleware.js.map +1 -1
  30. package/dist/storage/StaticProvider.d.ts.map +1 -1
  31. package/dist/storage/StaticProvider.js +12 -3
  32. package/dist/storage/StaticProvider.js.map +1 -1
  33. package/events.win32-x64-msvc.node +0 -0
  34. package/index.darwin-arm64.node +0 -0
  35. package/index.darwin-x64.node +0 -0
  36. package/index.linux-arm64-gnu.node +0 -0
  37. package/index.linux-x64-gnu.node +0 -0
  38. package/index.win32-x64-msvc.node +0 -0
  39. package/package.json +8 -8
  40. package/scheduler.win32-x64-msvc.node +0 -0
  41. package/scripts/copy-napi.mjs +11 -3
  42. package/src/Application.ts +15 -0
  43. package/src/Ignitor.ts +80 -9
  44. package/src/Provider.ts +15 -0
  45. package/src/http/Request.ts +13 -3
  46. package/src/index.ts +3 -3
  47. package/src/router/Router.ts +1 -1
  48. package/src/security/CookieSigner.ts +3 -2
  49. package/src/storage/StaticMiddleware.ts +338 -97
  50. package/src/storage/StaticProvider.ts +14 -3
@@ -1,10 +1,22 @@
1
1
  /**
2
2
  * Static file serving middleware.
3
3
  *
4
- * Serves files from a directory with cache headers and ETag support.
4
+ * The shape is `@adonisjs/static`'s, whose own work is done by `serve-static`:
5
+ * the same option names, the same defaults, the same response headers. Ream
6
+ * cannot delegate to `serve-static` itself —
7
+ *
8
+ * NAMED DEVIATION (NAPI): `serve-static` writes to a Node `ServerResponse`, and
9
+ * Ream's response crosses the NAPI boundary as a complete object; there is no
10
+ * such object to hand it. So the BEHAVIOUR is reproduced here rather than the
11
+ * code, and every deviation from it below is deliberate and marked.
12
+ *
13
+ * One deviation is a deliberate improvement, kept per the rule that we do not
14
+ * give up safety for parity: the file is opened with `O_NOFOLLOW` and its
15
+ * metadata read from the descriptor, so the bytes served are the ones that
16
+ * passed the containment checks. `serve-static` re-reads by path.
5
17
  *
6
18
  * Usage:
7
- * server.use(new StaticMiddleware({ root: 'public' }))
19
+ * server.use(new StaticMiddleware({ root: app.publicPath() }))
8
20
  *
9
21
  * @implements MISS-25
10
22
  */
@@ -13,122 +25,273 @@ import * as fsp from 'node:fs/promises';
13
25
  import * as path from 'node:path';
14
26
  import { matchesIfNoneMatch, statTag } from '../http/etag.js';
15
27
  import { contentType } from '../http/mime.js';
16
- const DEFAULT_EXTENSIONS = [
17
- '.html',
18
- '.css',
19
- '.js',
20
- '.json',
21
- '.xml',
22
- '.txt',
23
- '.png',
24
- '.jpg',
25
- '.jpeg',
26
- '.gif',
27
- '.svg',
28
- '.ico',
29
- '.webp',
30
- '.woff',
31
- '.woff2',
32
- '.ttf',
33
- '.eot',
34
- '.mp4',
35
- '.webm',
36
- '.mp3',
37
- '.ogg',
38
- '.pdf',
39
- '.zip',
40
- ];
41
28
  export class StaticMiddleware {
42
29
  #root;
43
- #prefix;
44
- #maxAge;
30
+ #enabled;
31
+ #acceptRanges;
32
+ #cacheControl;
33
+ #dotFiles;
34
+ #etag;
45
35
  #extensions;
36
+ #immutable;
37
+ #index;
38
+ #lastModified;
39
+ #maxAge;
40
+ #headers;
41
+ #prefix;
46
42
  constructor(config) {
47
43
  this.#root = path.resolve(config.root);
48
- this.#prefix = config.prefix ?? '/static';
49
- this.#maxAge = config.maxAge ?? 86400;
50
- this.#extensions = new Set(config.extensions ?? DEFAULT_EXTENSIONS);
44
+ this.#enabled = config.enabled ?? true;
45
+ this.#acceptRanges = config.acceptRanges ?? true;
46
+ this.#cacheControl = config.cacheControl ?? true;
47
+ this.#dotFiles = config.dotFiles ?? 'ignore';
48
+ this.#etag = config.etag ?? true;
49
+ this.#extensions = config.extensions === false ? [] : (config.extensions ?? []);
50
+ this.#immutable = config.immutable ?? false;
51
+ this.#index =
52
+ config.index === false
53
+ ? []
54
+ : typeof config.index === 'string'
55
+ ? [config.index]
56
+ : (config.index ?? ['index.html']);
57
+ this.#lastModified = config.lastModified ?? true;
58
+ this.#maxAge = config.maxAge ?? 0;
59
+ this.#headers = config.headers;
60
+ this.#prefix = config.prefix ?? '';
51
61
  }
52
62
  async handle(ctx, next) {
53
- if (ctx.request.method() !== 'GET' && ctx.request.method() !== 'HEAD') {
63
+ if (!this.#enabled)
54
64
  return next();
65
+ const method = ctx.request.method();
66
+ if (method !== 'GET' && method !== 'HEAD')
67
+ return next();
68
+ const reqPath = ctx.request.path();
69
+ // A dotfile under `deny` is answered, not passed on: falling through would
70
+ // leak its existence through whatever the router answers next.
71
+ if (this.#dotFiles === 'deny' && this.#hasDotSegment(reqPath)) {
72
+ ctx.response.status(403).send('Forbidden');
73
+ return;
55
74
  }
56
- const resolved = await this.#openServableFile(ctx.request.path());
75
+ const resolved = await this.#openServableFile(reqPath);
57
76
  if (!resolved)
58
77
  return next();
59
- const { handle, ext, stat } = resolved;
60
- // The handle is ours until the read stream takes it; every path that does
61
- // not hand it over closes it, or the process leaks a descriptor per 304.
78
+ const { handle, filePath, stat } = resolved;
79
+ // The handle is ours until a read stream takes it; every path that does not
80
+ // hand it over closes it, or the process leaks a descriptor per 304.
62
81
  let owned = true;
63
82
  try {
64
- const etag = statTag(stat);
65
- if (matchesIfNoneMatch(ctx.request.header('if-none-match'), etag)) {
83
+ const etag = this.#etag ? statTag(stat) : undefined;
84
+ const lastModified = this.#lastModified ? stat.mtime.toUTCString() : undefined;
85
+ // One table for the whole package (`src/http/mime.ts`), generated from
86
+ // mime-db. A second hand-written one here is how `.js` came to be served
87
+ // as `application/javascript` from one path and `text/javascript` from
88
+ // the other.
89
+ ctx.response.header('Content-Type', contentType(path.extname(filePath).toLowerCase()) || 'application/octet-stream');
90
+ if (etag)
91
+ ctx.response.header('ETag', etag);
92
+ if (lastModified)
93
+ ctx.response.header('Last-Modified', lastModified);
94
+ if (this.#cacheControl)
95
+ ctx.response.header('Cache-Control', this.#cacheControlValue());
96
+ if (this.#acceptRanges)
97
+ ctx.response.header('Accept-Ranges', 'bytes');
98
+ if (this.#headers) {
99
+ for (const [name, value] of Object.entries(this.#headers(filePath, stat))) {
100
+ ctx.response.header(name, value);
101
+ }
102
+ }
103
+ if (this.#isFresh(ctx, etag, stat)) {
104
+ // A 304 carries no body and no Content-Length: the client reuses the
105
+ // copy it already has.
66
106
  ctx.response.status(304);
67
107
  return;
68
108
  }
69
- // One table for the whole package (`src/http/mime.ts`), generated from
70
- // mime-db. A second hand-written one here is how `.js` came to be
71
- // served as `application/javascript` from one code path and
72
- // `text/javascript` from the other.
73
- ctx.response.header('Content-Type', contentType(ext) || 'application/octet-stream');
74
- ctx.response.header('Content-Length', String(stat.size));
75
- ctx.response.header('Cache-Control', `public, max-age=${this.#maxAge}`);
76
- ctx.response.header('ETag', etag);
77
- if (ctx.request.method() === 'HEAD') {
78
- ctx.response.status(200);
109
+ const range = this.#acceptRanges ? this.#resolveRange(ctx, stat, etag) : undefined;
110
+ if (range === 'unsatisfiable') {
111
+ ctx.response.header('Content-Range', `bytes */${stat.size}`);
112
+ ctx.response.status(416).send('');
113
+ return;
114
+ }
115
+ const length = range ? range.end - range.start + 1 : stat.size;
116
+ ctx.response.header('Content-Length', String(length));
117
+ if (range) {
118
+ ctx.response.header('Content-Range', `bytes ${range.start}-${range.end}/${stat.size}`);
119
+ }
120
+ if (method === 'HEAD') {
121
+ // HEAD carries the headers a GET would, and no body.
122
+ ctx.response.status(range ? 206 : 200);
79
123
  return;
80
124
  }
81
- // Streamed, not read whole.
82
- //
83
- // `readFileSync` stalled the event loop for EVERY concurrent request
84
- // while one client asked for a file, and the allowed extensions include
85
- // `.mp4`, `.zip` and `.pdf` — so one large asset became every other
86
- // request's latency, and each request allocated the file again. The
87
- // stream applies backpressure and holds one chunk at a time.
88
- //
89
- // The read stream owns the handle from here and closes it at end.
90
- ctx.response.status(200);
125
+ // Streamed, not read whole. `readFileSync` stalled the event loop for
126
+ // every concurrent request while one client asked for a file, and one
127
+ // large asset became every other request's latency. The read stream owns
128
+ // the handle from here and closes it at end.
129
+ ctx.response.status(range ? 206 : 200);
91
130
  owned = false;
92
- await ctx.response.stream(handle.createReadStream());
131
+ await ctx.response.stream(range
132
+ ? handle.createReadStream({ start: range.start, end: range.end })
133
+ : handle.createReadStream());
93
134
  }
94
135
  finally {
95
136
  if (owned)
96
137
  await handle.close().catch(() => { });
97
138
  }
98
139
  }
140
+ /** `Cache-Control`, built the way `send` builds it. */
141
+ #cacheControlValue() {
142
+ const seconds = Math.floor(this.#maxAge / 1000);
143
+ let value = `public, max-age=${seconds}`;
144
+ // Upstream only honours `immutable` alongside a max-age: `immutable` on a
145
+ // response that expires immediately tells a cache two opposite things.
146
+ if (this.#immutable && seconds > 0)
147
+ value += ', immutable';
148
+ return value;
149
+ }
150
+ /**
151
+ * Is the client's copy still good? `If-None-Match` wins outright when
152
+ * present, and `If-Modified-Since` is only consulted in its absence — the
153
+ * order RFC 9110 §13.1.3 requires, and the reason a weak ETag plus a
154
+ * second-resolution mtime do not contradict each other.
155
+ */
156
+ #isFresh(ctx, etag, stat) {
157
+ const ifNoneMatch = ctx.request.header('if-none-match');
158
+ if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
159
+ return etag !== undefined && matchesIfNoneMatch(ifNoneMatch, etag);
160
+ }
161
+ if (!this.#lastModified)
162
+ return false;
163
+ const since = ctx.request.header('if-modified-since');
164
+ if (since === undefined || since === null)
165
+ return false;
166
+ const sinceMs = Date.parse(Array.isArray(since) ? since[0] : String(since));
167
+ if (Number.isNaN(sinceMs))
168
+ return false;
169
+ // HTTP dates have one-second resolution; the file's mtime does not. Compare
170
+ // at the coarser one, or a file written mid-second looks modified forever.
171
+ return Math.floor(stat.mtimeMs / 1000) * 1000 <= sinceMs;
172
+ }
173
+ /**
174
+ * The range to serve, `undefined` for the whole file, or `'unsatisfiable'`
175
+ * for a 416.
176
+ *
177
+ * Only a single range is honoured. Multiple ranges require a
178
+ * `multipart/byteranges` body, which upstream supports and this does not —
179
+ * a request for several is served whole, which is a response every client
180
+ * accepts.
181
+ */
182
+ #resolveRange(ctx, stat, etag) {
183
+ const raw = ctx.request.header('range');
184
+ if (raw === undefined || raw === null)
185
+ return undefined;
186
+ const header = Array.isArray(raw) ? raw[0] : String(raw);
187
+ // `If-Range` guards against a resumed download stitching bytes from two
188
+ // different versions of the file: if the validator does not match, the
189
+ // whole current file is the honest answer.
190
+ const ifRange = ctx.request.header('if-range');
191
+ if (ifRange !== undefined && ifRange !== null) {
192
+ const value = Array.isArray(ifRange) ? ifRange[0] : String(ifRange);
193
+ const matchesEtag = etag !== undefined && value.trim() === etag;
194
+ const asDate = Date.parse(value);
195
+ const matchesDate = !Number.isNaN(asDate) && Math.floor(stat.mtimeMs / 1000) * 1000 <= asDate;
196
+ if (!matchesEtag && !matchesDate)
197
+ return undefined;
198
+ }
199
+ const match = /^bytes=(\d*)-(\d*)$/.exec(header.trim());
200
+ if (!match)
201
+ return undefined; // not a form we serve: send the whole file
202
+ const [, rawStart, rawEnd] = match;
203
+ if (rawStart === '' && rawEnd === '')
204
+ return undefined;
205
+ let start;
206
+ let end;
207
+ if (rawStart === '') {
208
+ // `bytes=-500`: the LAST 500 bytes, not the first.
209
+ const suffix = Number(rawEnd);
210
+ if (suffix === 0)
211
+ return 'unsatisfiable';
212
+ start = Math.max(stat.size - suffix, 0);
213
+ end = stat.size - 1;
214
+ }
215
+ else {
216
+ start = Number(rawStart);
217
+ end = rawEnd === '' ? stat.size - 1 : Math.min(Number(rawEnd), stat.size - 1);
218
+ }
219
+ if (!Number.isFinite(start) || !Number.isFinite(end) || start > end || start >= stat.size) {
220
+ return 'unsatisfiable';
221
+ }
222
+ return { start, end };
223
+ }
224
+ #hasDotSegment(reqPath) {
225
+ return reqPath.split('/').some((segment) => segment.length > 1 && segment.startsWith('.'));
226
+ }
99
227
  /**
100
- * Open a request path as a real, in-root, regular file, or answer `null`
101
- * when it is not servable (wrong prefix/extension, outside the root,
102
- * missing, or a symlink escaping the root). `null` tells `handle` to call
103
- * `next()`.
228
+ * Open a request path as a real, in-root, regular file, or answer `null` when
229
+ * it is not servable. `null` tells `handle` to call `next()`.
104
230
  *
105
231
  * The file is OPENED here rather than merely checked, and its metadata read
106
- * from the descriptor: what gets served is then the same file that passed
107
- * the checks, which a path re-read after the fact cannot promise.
232
+ * from the descriptor: what gets served is then the same file that passed the
233
+ * checks, which a path re-read after the fact cannot promise.
108
234
  */
109
235
  async #openServableFile(reqPath) {
110
- // Match only when the prefix is followed by `/` or end-of-path —
111
- // otherwise `/staticx/foo.js` would be intercepted when the configured
112
- // prefix is `/static`, hijacking unrelated routes.
113
- if (!(reqPath === this.#prefix || reqPath.startsWith(`${this.#prefix}/`))) {
236
+ if (this.#prefix !== '') {
237
+ // Match only when the prefix is followed by `/` or end-of-path —
238
+ // otherwise `/staticx/foo.js` would be intercepted when the configured
239
+ // prefix is `/static`, hijacking unrelated routes.
240
+ if (!(reqPath === this.#prefix || reqPath.startsWith(`${this.#prefix}/`)))
241
+ return null;
242
+ reqPath = reqPath.slice(this.#prefix.length) || '/';
243
+ }
244
+ if (this.#dotFiles === 'ignore' && this.#hasDotSegment(reqPath))
245
+ return null;
246
+ // The candidates, in upstream's order: the path itself, then the path with
247
+ // each fallback extension, then the index files for a directory request.
248
+ //
249
+ // Percent-decoding happens BEFORE resolution on purpose: `%2e%2e%2f` is
250
+ // `../` and has to be normalised away by `path.resolve` like any other
251
+ // traversal, not carried through as an opaque segment. `decodeURIComponent`
252
+ // THROWS on a malformed sequence (a lone `%`), which would otherwise become
253
+ // a 500 on a request anyone can send.
254
+ let decoded;
255
+ try {
256
+ decoded = decodeURIComponent(reqPath);
257
+ }
258
+ catch {
114
259
  return null;
115
260
  }
116
- // Strip prefix and resolve file path
117
- const relativePath = reqPath.slice(this.#prefix.length) || '/index.html';
118
- const ext = path.extname(relativePath).toLowerCase();
119
- if (!this.#extensions.has(ext))
261
+ // A NUL truncates the path in the syscall layer of some runtimes; Node
262
+ // rejects it, but refusing here keeps the decision in one place.
263
+ if (decoded.includes('\0'))
120
264
  return null;
121
- const filePath = path.resolve(this.#root, relativePath.replace(/^\//, ''));
265
+ const relative = decoded.replace(/^\/+/, '');
266
+ const candidates = [];
267
+ if (relative !== '') {
268
+ candidates.push(relative);
269
+ for (const ext of this.#extensions) {
270
+ candidates.push(`${relative}.${ext.replace(/^\./, '')}`);
271
+ }
272
+ }
273
+ for (const index of this.#index) {
274
+ candidates.push(relative === '' ? index : `${relative}/${index}`);
275
+ }
276
+ for (const candidate of candidates) {
277
+ const opened = await this.#openInRoot(candidate);
278
+ if (opened)
279
+ return opened;
280
+ }
281
+ return null;
282
+ }
283
+ /** One candidate, fully contained and opened, or `null`. */
284
+ async #openInRoot(relative) {
285
+ const filePath = path.resolve(this.#root, relative);
122
286
  // Two containment checks. The first uses `path.sep` to reject sibling
123
- // directories with a shared prefix (`/var/www-static-secret` slipping
124
- // past a guard for `/var/www-static`). The second resolves symlinks
125
- // via realpath so a symlink planted inside the root cannot point
126
- // outside it. We do realpath AFTER the lexical check so a non-existent
127
- // path returns `next()` rather than throwing.
287
+ // directories with a shared prefix (`/var/www-static-secret` slipping past
288
+ // a guard for `/var/www-static`). The second resolves symlinks via realpath
289
+ // so a symlink planted inside the root cannot point outside it. Realpath
290
+ // runs AFTER the lexical check so a non-existent path returns null rather
291
+ // than throwing.
128
292
  const rootWithSep = this.#root.endsWith(path.sep) ? this.#root : this.#root + path.sep;
129
- if (filePath !== this.#root && !filePath.startsWith(rootWithSep)) {
293
+ if (filePath !== this.#root && !filePath.startsWith(rootWithSep))
130
294
  return null;
131
- }
132
295
  let realFilePath;
133
296
  let realRoot;
134
297
  try {
@@ -139,9 +302,8 @@ export class StaticMiddleware {
139
302
  return null;
140
303
  }
141
304
  const realRootWithSep = realRoot.endsWith(path.sep) ? realRoot : realRoot + path.sep;
142
- if (realFilePath !== realRoot && !realFilePath.startsWith(realRootWithSep)) {
305
+ if (realFilePath !== realRoot && !realFilePath.startsWith(realRootWithSep))
143
306
  return null;
144
- }
145
307
  // O_NOFOLLOW closes the window the checks above leave open: between
146
308
  // `realpath` and the read, the last path component can be replaced by a
147
309
  // symlink pointing anywhere, and a read by name follows it. Refusing to
@@ -161,7 +323,7 @@ export class StaticMiddleware {
161
323
  await handle.close();
162
324
  return null;
163
325
  }
164
- return { handle, ext, stat };
326
+ return { handle, filePath: realFilePath, stat };
165
327
  }
166
328
  catch {
167
329
  await handle.close().catch(() => { });
@@ -169,4 +331,14 @@ export class StaticMiddleware {
169
331
  }
170
332
  }
171
333
  }
334
+ /**
335
+ * Static config with the defaults filled in — `@adonisjs/static`'s
336
+ * `defineConfig`, value for value.
337
+ *
338
+ * // config/static.ts
339
+ * export default defineStaticConfig({ maxAge: 86_400_000 })
340
+ */
341
+ export function defineStaticConfig(config = {}) {
342
+ return { enabled: true, dotFiles: 'ignore', etag: true, lastModified: true, ...config };
343
+ }
172
344
  //# sourceMappingURL=StaticMiddleware.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StaticMiddleware.js","sourceRoot":"","sources":["../../src/storage/StaticMiddleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"StaticMiddleware.js","sourceRoot":"","sources":["../../src/storage/StaticMiddleware.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"StaticProvider.d.ts","sourceRoot":"","sources":["../../src/storage/StaticProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAqB,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE3E,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B;AAED,qBAAa,cAAe,SAAQ,QAAQ;;gBAG9B,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,qBAA0B;IAKhE;;;;;;;;;OASG;IACY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAOtC;AAGD,eAAe,cAAc,CAAA"}
1
+ {"version":3,"file":"StaticProvider.d.ts","sourceRoot":"","sources":["../../src/storage/StaticProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAqB,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE3E,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B;AAED,qBAAa,cAAe,SAAQ,QAAQ;;gBAG9B,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,qBAA0B;IAKhE;;;;;;;;;OASG;IACY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAkBtC;AAGD,eAAe,cAAc,CAAA"}
@@ -30,10 +30,19 @@ export class StaticProvider extends Provider {
30
30
  * the app that meant to override it.
31
31
  */
32
32
  async start() {
33
- const config = this.app.config.get('static');
34
- const middleware = this.#override ?? (config?.root ? new StaticMiddleware(config) : undefined);
33
+ // `?? {}` rather than a default argument: a host may supply its own
34
+ // ConfigReader, and not every implementation honours the second parameter.
35
+ const config = this.app.config.get('static') ?? {};
36
+ // Registering the provider is the whole opt-in, as it is upstream: there,
37
+ // `node ace configure @adonisjs/static` adds the provider AND the
38
+ // middleware, and the middleware serves `public/` with no `root` named
39
+ // anywhere. Requiring a `root` before doing anything meant a provider
40
+ // could be registered and silently serve nothing.
41
+ const root = config.root ?? this.app.publicPath?.() ?? 'public';
42
+ const middleware = this.#override ??
43
+ (config.enabled === false ? undefined : new StaticMiddleware({ ...config, root }));
35
44
  if (!middleware)
36
- return; // not configured — opt-out
45
+ return;
37
46
  const server = await this.app.container.make('server');
38
47
  server.use([(ctx, next) => middleware.handle(ctx, next)]);
39
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"StaticProvider.js","sourceRoot":"","sources":["../../src/storage/StaticProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAqB,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO3E,MAAM,OAAO,cAAe,SAAQ,QAAQ;IACjC,SAAS,CAAmB;IAErC,YAAY,GAAe,EAAE,UAAiC,EAAE;QAC9D,KAAK,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAA;IACrC,CAAC;IAED;;;;;;;;;OASG;IACM,KAAK,CAAC,KAAK;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAe,QAAQ,CAAC,CAAA;QAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAC9F,IAAI,CAAC,UAAU;YAAE,OAAM,CAAC,2BAA2B;QACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAS,QAAQ,CAAC,CAAA;QAC9D,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IAC3D,CAAC;CACF;AAED,yKAAyK;AACzK,eAAe,cAAc,CAAA"}
1
+ {"version":3,"file":"StaticProvider.js","sourceRoot":"","sources":["../../src/storage/StaticProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAqB,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO3E,MAAM,OAAO,cAAe,SAAQ,QAAQ;IACjC,SAAS,CAAmB;IAErC,YAAY,GAAe,EAAE,UAAiC,EAAE;QAC9D,KAAK,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAA;IACrC,CAAC;IAED;;;;;;;;;OASG;IACM,KAAK,CAAC,KAAK;QAClB,oEAAoE;QACpE,2EAA2E;QAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAe,QAAQ,CAAC,IAAK,EAAmB,CAAA;QAElF,0EAA0E;QAC1E,kEAAkE;QAClE,uEAAuE;QACvE,sEAAsE;QACtE,kDAAkD;QAClD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,IAAI,QAAQ,CAAA;QAC/D,MAAM,UAAU,GACd,IAAI,CAAC,SAAS;YACd,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACpF,IAAI,CAAC,UAAU;YAAE,OAAM;QACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAS,QAAQ,CAAC,CAAA;QAC9D,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IAC3D,CAAC;CACF;AAED,yKAAyK;AACzK,eAAe,cAAc,CAAA"}
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/ream",
3
- "version": "0.2.18",
3
+ "version": "0.2.20",
4
4
  "description": "Ream — Rust-powered Node.js application framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -228,12 +228,12 @@
228
228
  "tsconfig.client.json"
229
229
  ],
230
230
  "dependencies": {
231
- "file-type": "^22.0.1",
232
- "reflect-metadata": "^0.2"
231
+ "file-type": "^22.0.2",
232
+ "reflect-metadata": "^0.2.2"
233
233
  },
234
234
  "peerDependencies": {
235
235
  "@c9up/comet": "^0.1.0",
236
- "@c9up/quasar": "^0.1.0",
236
+ "@c9up/quasar": "^0.1.0 || ^0.2.0",
237
237
  "hot-hook": "^1.0.0"
238
238
  },
239
239
  "peerDependenciesMeta": {
@@ -250,12 +250,12 @@
250
250
  "devDependencies": {
251
251
  "@biomejs/biome": "2.5.12",
252
252
  "@c9up/comet": "^0.1.0",
253
- "@types/node": "^22.19.15",
254
- "@vitest/coverage-v8": "^4.1.6",
253
+ "@types/node": "^22.20.1",
254
+ "@vitest/coverage-v8": "4.1.11",
255
255
  "mime-db": "^1.54.0",
256
256
  "mime-types": "^3.0.2",
257
- "typescript": "^6.0.2",
258
- "vitest": "^4.1.6"
257
+ "typescript": "^6.0.3",
258
+ "vitest": "4.1.11"
259
259
  },
260
260
  "engines": {
261
261
  "node": ">=22.0.0"
Binary file
@@ -21,7 +21,7 @@
21
21
  // crate listed in `NAPI_CRATES` ships in the tarball.
22
22
 
23
23
  import { copyFileSync, existsSync } from 'node:fs'
24
- import { dirname, join } from 'node:path'
24
+ import { dirname, join, resolve } from 'node:path'
25
25
  import { arch, env, platform } from 'node:process'
26
26
  import { fileURLToPath } from 'node:url'
27
27
 
@@ -48,6 +48,14 @@ const HOST_SUFFIX_MAP = {
48
48
  'win32-x64': 'win32-x64-msvc',
49
49
  }
50
50
 
51
+ // Cargo writes its artifacts under CARGO_TARGET_DIR when that is set — a
52
+ // shared cache, a CI mount — so they are not under this package's `target/` at
53
+ // all. A relative value is resolved against the directory cargo ran in, which
54
+ // is this package root.
55
+ const targetDir = env.CARGO_TARGET_DIR
56
+ ? resolve(root, env.CARGO_TARGET_DIR)
57
+ : join(root, 'target')
58
+
51
59
  const triple = env.CARGO_BUILD_TARGET ?? ''
52
60
  let suffix
53
61
  let os
@@ -59,11 +67,11 @@ if (triple) {
59
67
  }
60
68
  suffix = entry.suffix
61
69
  os = entry.os
62
- releaseDir = join(root, 'target', triple, 'release')
70
+ releaseDir = join(targetDir, triple, 'release')
63
71
  } else {
64
72
  suffix = HOST_SUFFIX_MAP[`${platform}-${arch}`]
65
73
  os = platform
66
- releaseDir = join(root, 'target', 'release')
74
+ releaseDir = join(targetDir, 'release')
67
75
  if (!suffix) {
68
76
  throw new Error(`[ream:napi] unsupported platform/arch: ${platform}-${arch}`)
69
77
  }
@@ -73,6 +73,21 @@ export interface ReamrcContents {
73
73
  export class Application implements AppContext {
74
74
  readonly container: Container
75
75
  readonly config: ConfigStore
76
+ /**
77
+ * Whether the inker template engine is installed (AdonisJS `usingEdgeJS`).
78
+ *
79
+ * Set by `InkerProvider`'s CONSTRUCTOR, so it is already true by the time any
80
+ * other provider boots. A package that wants to contribute to templates —
81
+ * rosetta pushing its `t()` global, say — reads this before importing
82
+ * `@c9up/inker`, and stays installable without it when the answer is no.
83
+ *
84
+ * A flag rather than a container lookup, and that is the whole point: the
85
+ * engine is a module singleton, so asking the container would mean resolving
86
+ * a binding whose lifecycle has to have reached the right phase. This answers
87
+ * the only question the caller actually has — is the package there — without
88
+ * one.
89
+ */
90
+ usingInker = false
76
91
  #appRoot?: URL
77
92
  #directories: DirectoriesNode = { ...defaultDirectories }
78
93
  #rcFile: ReamrcContents = {}