@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
package/src/Ignitor.ts CHANGED
@@ -93,7 +93,18 @@ export interface ReamrcConfig {
93
93
  modules?: {
94
94
  /** Path to the modules directory (relative to app root). Default: './app/modules' */
95
95
  path?: string
96
- /** Auto-loaded files in each module directory. Default: ['routes'] */
96
+ /**
97
+ * What to load from each module directory. Default `['routes', 'events']`.
98
+ *
99
+ * An entry names either a file (`routes` → `routes.ts`) or a DIRECTORY
100
+ * (`services` → every module file under `services/`, recursively). The
101
+ * directory form is what makes decorator-registered code — `@Schedule()`,
102
+ * and anything else that registers by being imported — discoverable
103
+ * without a hand-written preload.
104
+ *
105
+ * An entry that matches nothing in any module is reported at boot: the
106
+ * failure it otherwise produces is silence.
107
+ */
97
108
  autoload?: string[]
98
109
  }
99
110
  /** Test suites and runner settings — the `tests` block of adonisrc.ts. */
@@ -973,7 +984,6 @@ export class Ignitor {
973
984
  const { readdirSync, existsSync } = await import('node:fs')
974
985
  const { join, resolve } = await import('node:path')
975
986
  const { fileURLToPath } = await import('node:url')
976
- const { pathToFileURL } = await import('node:url')
977
987
 
978
988
  // Resolve modules path relative to app root or cwd
979
989
  const basePath = this.#appRoot
@@ -988,16 +998,77 @@ export class Ignitor {
988
998
  .map((d) => d.name)
989
999
  .sort()
990
1000
 
1001
+ // Entries that matched nothing in ANY module. A single module without a
1002
+ // `routes.ts` is normal; an entry that matches nowhere is a name that does
1003
+ // not exist, and the cost of getting it wrong is silence — a decorator
1004
+ // nobody imported is never registered, and nothing says so.
1005
+ const matched = new Set<string>()
1006
+
991
1007
  for (const moduleDir of moduleDirs) {
992
- for (const fileName of autoloadFiles) {
993
- const tsPath = join(basePath, moduleDir, `${fileName}.ts`)
994
- const jsPath = join(basePath, moduleDir, `${fileName}.js`)
995
- const filePath = existsSync(tsPath) ? tsPath : existsSync(jsPath) ? jsPath : null
996
- if (filePath) {
997
- await import(pathToFileURL(filePath).href)
998
- }
1008
+ for (const entry of autoloadFiles) {
1009
+ const loaded = await this.#autoloadEntry(join(basePath, moduleDir, entry))
1010
+ if (loaded) matched.add(entry)
1011
+ }
1012
+ }
1013
+
1014
+ const missing = autoloadFiles.filter((entry) => !matched.has(entry))
1015
+ if (missing.length > 0) {
1016
+ // eslint-disable-next-line no-console -- the logger is bound by a provider, and this runs before them
1017
+ console.warn(
1018
+ `[ream] reamrc modules.autoload: ${missing.map((m) => `"${m}"`).join(', ')} matched nothing under ` +
1019
+ `${modulesConfig.path}/*/. Expected a file (\`${missing[0]}.ts\`) or a directory ` +
1020
+ `(\`${missing[0]}/\`) in at least one module.`,
1021
+ )
1022
+ }
1023
+ }
1024
+
1025
+ /**
1026
+ * Load one autoload entry: a module file, or every module file in a directory.
1027
+ *
1028
+ * Directories are supported because that is what an entry like `services`
1029
+ * reads as, and naming one used to load NOTHING — a configuration no-op with
1030
+ * no error, which is the worst shape a missing import can take. A
1031
+ * `@Schedule()` in a file nobody imports is simply never discovered, and the
1032
+ * application starts perfectly.
1033
+ *
1034
+ * Answers whether anything was loaded, so a name that matches nowhere can be
1035
+ * reported rather than ignored.
1036
+ */
1037
+ async #autoloadEntry(entryPath: string): Promise<boolean> {
1038
+ const { existsSync, readdirSync, statSync } = await import('node:fs')
1039
+ const { join } = await import('node:path')
1040
+ const { pathToFileURL } = await import('node:url')
1041
+
1042
+ for (const ext of ['.ts', '.js']) {
1043
+ const filePath = `${entryPath}${ext}`
1044
+ if (existsSync(filePath)) {
1045
+ await import(pathToFileURL(filePath).href)
1046
+ return true
1047
+ }
1048
+ }
1049
+
1050
+ if (!existsSync(entryPath) || !statSync(entryPath).isDirectory()) return false
1051
+
1052
+ // Sorted, so a module that depends on load order behaves the same
1053
+ // everywhere rather than on whatever the filesystem returns.
1054
+ const entries = readdirSync(entryPath, { withFileTypes: true }).sort((a, b) =>
1055
+ a.name.localeCompare(b.name),
1056
+ )
1057
+ let loaded = false
1058
+ for (const entry of entries) {
1059
+ const child = join(entryPath, entry.name)
1060
+ if (entry.isDirectory()) {
1061
+ if (await this.#autoloadEntry(child)) loaded = true
1062
+ continue
999
1063
  }
1064
+ // `.d.ts` declares types and executes nothing; importing it is a parse
1065
+ // error under a runtime that does not strip types.
1066
+ if (entry.name.endsWith('.d.ts')) continue
1067
+ if (!entry.name.endsWith('.ts') && !entry.name.endsWith('.js')) continue
1068
+ await import(pathToFileURL(child).href)
1069
+ loaded = true
1000
1070
  }
1071
+ return loaded
1001
1072
  }
1002
1073
 
1003
1074
  /**
package/src/Provider.ts CHANGED
@@ -32,6 +32,21 @@ export interface ConfigReader {
32
32
  export interface AppContext {
33
33
  container: Container
34
34
  config: ConfigReader
35
+ /**
36
+ * Whether the inker template engine is installed — see
37
+ * `Application#usingInker`. Optional here because a host that is not ream
38
+ * satisfies this contract structurally and has no such flag; a provider
39
+ * reading it treats `undefined` as "no engine".
40
+ */
41
+ usingInker?: boolean
42
+ /**
43
+ * Absolute path to the application's `public/` directory — see
44
+ * `Application#publicPath`. Optional for the same reason as the flag above:
45
+ * a host that is not ream satisfies this contract structurally and has no
46
+ * directory layout. A provider that needs it falls back to a relative
47
+ * `'public'`, resolved against the working directory.
48
+ */
49
+ publicPath?(...paths: string[]): string
35
50
  }
36
51
 
37
52
  /**
@@ -384,9 +384,19 @@ export class Request extends Macroable {
384
384
  * `defaultValue` (or null) when absent OR when the signature is invalid
385
385
  * (tampered / not signed).
386
386
  *
387
- * NAMED DEVIATION — the fallback is `??`, where AdonisJS writes `||`. A
388
- * cookie legitimately holding `0`, `false` or `""` is a value, not an
389
- * absence, and upstream hands back the default for all three. Kept.
387
+ * NAMED DEVIATION — the fallback is `??`, where upstream writes `||`
388
+ * (`@adonisjs/http-server@9.3.0`: `return this.#cookieParser.unsign(key) ||
389
+ * defaultValue`).
390
+ *
391
+ * The case that matters is the EMPTY STRING. A signed cookie carries a
392
+ * string — {@link Response.cookie} takes `value: string` — so `""` is the one
393
+ * falsy value this accessor can actually hold, and it is a value someone
394
+ * wrote, not an absence. `||` hands back the default for it; `??` does not.
395
+ *
396
+ * Upstream's own doc-comment on that line says the default is returned "when
397
+ * actual value is undefined" — which is what `??` does and `||` does not. So
398
+ * this follows the contract upstream documents, and differs only from what it
399
+ * happens to execute. Kept.
390
400
  */
391
401
  cookie(name: string): string | null
392
402
  cookie(name: string, defaultValue: string): string
package/src/index.ts CHANGED
@@ -148,8 +148,8 @@ export { ApiResource } from './resources/ApiResource.js'
148
148
 
149
149
  // ─── Static Files ───────────────────────────────────────────
150
150
 
151
- export type { StaticConfig } from './storage/StaticMiddleware.js'
152
- export { StaticMiddleware } from './storage/StaticMiddleware.js'
151
+ export type { DotFilesPolicy, StaticConfig } from './storage/StaticMiddleware.js'
152
+ export { defineStaticConfig, StaticMiddleware } from './storage/StaticMiddleware.js'
153
153
  export type { StaticProviderOptions } from './storage/StaticProvider.js'
154
154
  export { StaticProvider } from './storage/StaticProvider.js'
155
155
 
@@ -385,4 +385,4 @@ export {
385
385
  StatsTracker,
386
386
  } from './scheduler/index.js'
387
387
 
388
- export const VERSION = '0.2.18'
388
+ export const VERSION = '0.2.20'
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Fluent Router — AdonisJS v6 compatible routing with controllers, resources, and groups.
2
+ * Fluent Router — AdonisJS-compatible routing with controllers, resources, and groups.
3
3
  *
4
4
  * @implements FR24, FR25, FR26, FR27, FR28
5
5
  */
@@ -159,8 +159,9 @@ export class CookieSigner {
159
159
  /**
160
160
  * The cipher in use (AdonisJS `Encryption.algorithm`).
161
161
  *
162
- * `aes-256-gcm`, not upstream's `aes-256-cbc` — see the deviation at the top
163
- * of this file.
162
+ * `aes-256-gcm`, which is what upstream configures by default now; the CBC
163
+ * construction lives on there as the `legacy` driver. See the note at the top
164
+ * of this file for what that means for a cookie written by an older app.
164
165
  */
165
166
  get algorithm(): 'aes-256-gcm' {
166
167
  return 'aes-256-gcm'