@c9up/ream 0.1.24 → 0.1.26

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 (172) hide show
  1. package/dist/ConfigLoader.d.ts +46 -5
  2. package/dist/ConfigLoader.d.ts.map +1 -1
  3. package/dist/ConfigLoader.js +60 -9
  4. package/dist/ConfigLoader.js.map +1 -1
  5. package/dist/HttpKernel.d.ts.map +1 -1
  6. package/dist/HttpKernel.js +46 -6
  7. package/dist/HttpKernel.js.map +1 -1
  8. package/dist/Ignitor.d.ts.map +1 -1
  9. package/dist/Ignitor.js +21 -3
  10. package/dist/Ignitor.js.map +1 -1
  11. package/dist/container/Container.d.ts +23 -3
  12. package/dist/container/Container.d.ts.map +1 -1
  13. package/dist/container/Container.js +139 -60
  14. package/dist/container/Container.js.map +1 -1
  15. package/dist/env/Env.d.ts +29 -4
  16. package/dist/env/Env.d.ts.map +1 -1
  17. package/dist/env/Env.js +27 -4
  18. package/dist/env/Env.js.map +1 -1
  19. package/dist/env/Secret.d.ts +11 -0
  20. package/dist/env/Secret.d.ts.map +1 -0
  21. package/dist/env/Secret.js +36 -0
  22. package/dist/env/Secret.js.map +1 -0
  23. package/dist/env/interpolate.d.ts +26 -0
  24. package/dist/env/interpolate.d.ts.map +1 -0
  25. package/dist/env/interpolate.js +48 -0
  26. package/dist/env/interpolate.js.map +1 -0
  27. package/dist/env/loadEnvFiles.d.ts.map +1 -1
  28. package/dist/env/loadEnvFiles.js +14 -4
  29. package/dist/env/loadEnvFiles.js.map +1 -1
  30. package/dist/env/schema.d.ts +23 -6
  31. package/dist/env/schema.d.ts.map +1 -1
  32. package/dist/env/schema.js +67 -33
  33. package/dist/env/schema.js.map +1 -1
  34. package/dist/events/Emitter.d.ts +1 -1
  35. package/dist/events/Emitter.d.ts.map +1 -1
  36. package/dist/events/Emitter.js +1 -1
  37. package/dist/events/Emitter.js.map +1 -1
  38. package/dist/events/EventsProvider.d.ts +2 -2
  39. package/dist/events/EventsProvider.d.ts.map +1 -1
  40. package/dist/events/EventsProvider.js +3 -3
  41. package/dist/events/EventsProvider.js.map +1 -1
  42. package/dist/graphql/GraphQLEngine.d.ts +1 -1
  43. package/dist/graphql/GraphQLEngine.d.ts.map +1 -1
  44. package/dist/graphql/GraphQLEngine.js +2 -2
  45. package/dist/graphql/GraphQLEngine.js.map +1 -1
  46. package/dist/graphql/GraphQLProvider.d.ts.map +1 -1
  47. package/dist/graphql/GraphQLProvider.js +7 -3
  48. package/dist/graphql/GraphQLProvider.js.map +1 -1
  49. package/dist/http/Exception.d.ts +63 -1
  50. package/dist/http/Exception.d.ts.map +1 -1
  51. package/dist/http/Exception.js +185 -48
  52. package/dist/http/Exception.js.map +1 -1
  53. package/dist/http/HttpContext.d.ts +56 -9
  54. package/dist/http/HttpContext.d.ts.map +1 -1
  55. package/dist/http/HttpContext.js +56 -15
  56. package/dist/http/HttpContext.js.map +1 -1
  57. package/dist/http/RedirectBuilder.d.ts.map +1 -1
  58. package/dist/http/RedirectBuilder.js +4 -1
  59. package/dist/http/RedirectBuilder.js.map +1 -1
  60. package/dist/http/Request.d.ts +141 -10
  61. package/dist/http/Request.d.ts.map +1 -1
  62. package/dist/http/Request.js +244 -34
  63. package/dist/http/Request.js.map +1 -1
  64. package/dist/http/Response.d.ts +176 -9
  65. package/dist/http/Response.d.ts.map +1 -1
  66. package/dist/http/Response.js +431 -19
  67. package/dist/http/Response.js.map +1 -1
  68. package/dist/index.d.ts +5 -4
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +4 -3
  71. package/dist/index.js.map +1 -1
  72. package/dist/middleware/Pipeline.js +1 -1
  73. package/dist/middleware/Pipeline.js.map +1 -1
  74. package/dist/openapi/OpenApiProvider.js +4 -4
  75. package/dist/openapi/OpenApiProvider.js.map +1 -1
  76. package/dist/router/Router.d.ts +223 -31
  77. package/dist/router/Router.d.ts.map +1 -1
  78. package/dist/router/Router.js +520 -102
  79. package/dist/router/Router.js.map +1 -1
  80. package/dist/rpc/RpcProvider.d.ts +1 -0
  81. package/dist/rpc/RpcProvider.d.ts.map +1 -1
  82. package/dist/rpc/RpcProvider.js +7 -3
  83. package/dist/rpc/RpcProvider.js.map +1 -1
  84. package/dist/rpc/RpcRouter.d.ts +2 -2
  85. package/dist/rpc/RpcRouter.d.ts.map +1 -1
  86. package/dist/rpc/RpcRouter.js +5 -4
  87. package/dist/rpc/RpcRouter.js.map +1 -1
  88. package/dist/scheduler/ScheduleProvider.d.ts.map +1 -1
  89. package/dist/scheduler/ScheduleProvider.js +7 -15
  90. package/dist/scheduler/ScheduleProvider.js.map +1 -1
  91. package/dist/server/Server.d.ts +17 -4
  92. package/dist/server/Server.d.ts.map +1 -1
  93. package/dist/server/Server.js +41 -7
  94. package/dist/server/Server.js.map +1 -1
  95. package/dist/session/SessionMiddleware.js +3 -3
  96. package/dist/session/SessionMiddleware.js.map +1 -1
  97. package/dist/storage/StaticProvider.js +1 -1
  98. package/dist/storage/StaticProvider.js.map +1 -1
  99. package/dist/testing/RequestBuilder.d.ts +60 -0
  100. package/dist/testing/RequestBuilder.d.ts.map +1 -1
  101. package/dist/testing/RequestBuilder.js +180 -1
  102. package/dist/testing/RequestBuilder.js.map +1 -1
  103. package/dist/testing/TestClient.d.ts +22 -1
  104. package/dist/testing/TestClient.d.ts.map +1 -1
  105. package/dist/testing/TestClient.js +40 -0
  106. package/dist/testing/TestClient.js.map +1 -1
  107. package/dist/utils/Macroable.d.ts +30 -0
  108. package/dist/utils/Macroable.d.ts.map +1 -0
  109. package/dist/utils/Macroable.js +43 -0
  110. package/dist/utils/Macroable.js.map +1 -0
  111. package/dist/utils/inflect.d.ts +17 -0
  112. package/dist/utils/inflect.d.ts.map +1 -0
  113. package/dist/utils/inflect.js +32 -0
  114. package/dist/utils/inflect.js.map +1 -0
  115. package/dist/utils/objectPath.d.ts +57 -0
  116. package/dist/utils/objectPath.d.ts.map +1 -0
  117. package/dist/utils/objectPath.js +141 -0
  118. package/dist/utils/objectPath.js.map +1 -0
  119. package/events.darwin-arm64.node +0 -0
  120. package/events.darwin-x64.node +0 -0
  121. package/events.linux-arm64-gnu.node +0 -0
  122. package/events.linux-x64-gnu.node +0 -0
  123. package/events.win32-x64-msvc.node +0 -0
  124. package/index.darwin-arm64.node +0 -0
  125. package/index.darwin-x64.node +0 -0
  126. package/index.linux-arm64-gnu.node +0 -0
  127. package/index.linux-x64-gnu.node +0 -0
  128. package/index.win32-x64-msvc.node +0 -0
  129. package/package.json +6 -1
  130. package/scheduler.darwin-arm64.node +0 -0
  131. package/scheduler.darwin-x64.node +0 -0
  132. package/scheduler.linux-arm64-gnu.node +0 -0
  133. package/scheduler.linux-x64-gnu.node +0 -0
  134. package/scheduler.win32-x64-msvc.node +0 -0
  135. package/src/ConfigLoader.ts +72 -9
  136. package/src/HttpKernel.ts +53 -15
  137. package/src/Ignitor.ts +24 -3
  138. package/src/container/Container.ts +145 -61
  139. package/src/env/Env.ts +49 -5
  140. package/src/env/Secret.ts +41 -0
  141. package/src/env/interpolate.ts +54 -0
  142. package/src/env/loadEnvFiles.ts +12 -4
  143. package/src/env/schema.ts +109 -35
  144. package/src/events/Emitter.ts +2 -2
  145. package/src/events/EventsProvider.ts +5 -5
  146. package/src/graphql/GraphQLEngine.ts +4 -4
  147. package/src/graphql/GraphQLProvider.ts +7 -3
  148. package/src/http/Exception.ts +214 -37
  149. package/src/http/HttpContext.ts +93 -20
  150. package/src/http/RedirectBuilder.ts +4 -1
  151. package/src/http/Request.ts +264 -34
  152. package/src/http/Response.ts +504 -30
  153. package/src/index.ts +11 -2
  154. package/src/middleware/Pipeline.ts +1 -1
  155. package/src/openapi/OpenApiProvider.ts +4 -4
  156. package/src/router/Router.ts +631 -113
  157. package/src/rpc/RpcProvider.ts +6 -2
  158. package/src/rpc/RpcRouter.ts +7 -6
  159. package/src/scheduler/ScheduleProvider.ts +7 -15
  160. package/src/server/Server.ts +49 -10
  161. package/src/session/SessionMiddleware.ts +4 -4
  162. package/src/storage/StaticProvider.ts +1 -1
  163. package/src/testing/RequestBuilder.ts +218 -1
  164. package/src/testing/TestClient.ts +57 -1
  165. package/src/utils/Macroable.ts +54 -0
  166. package/src/utils/inflect.ts +29 -0
  167. package/src/utils/objectPath.ts +142 -0
  168. package/dist/decorators/Lazy.d.ts +0 -19
  169. package/dist/decorators/Lazy.d.ts.map +0 -1
  170. package/dist/decorators/Lazy.js +0 -53
  171. package/dist/decorators/Lazy.js.map +0 -1
  172. package/src/decorators/Lazy.ts +0 -57
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Minimal zero-dependency string inflection — the two operations resourceful
3
+ * routing needs from AdonisJS's `@poppinss/utils/string`: `snakeCase` (route
4
+ * name normalisation) and `singular` (nested-resource param naming, `photos`
5
+ * → `photo_id`).
6
+ *
7
+ * Deviation from AdonisJS (named): `singular` covers regular English plurals
8
+ * only (`-ies→-y`, `-(s|x|z|ch|sh)es→drop es`, trailing `-s→drop`). Irregular
9
+ * plurals (`people→person`, `geese→goose`) are NOT handled — resource names in
10
+ * REST APIs are overwhelmingly regular, and a full inflector (irregular tables,
11
+ * uncountables) would be a dependency-sized rabbit hole for a niche case.
12
+ */
13
+
14
+ /** Convert `camelCase`/`PascalCase`/`kebab-case`/spaced text to `snake_case`. */
15
+ export function snakeCase(value: string): string {
16
+ return value
17
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
18
+ .replace(/[-\s]+/g, '_')
19
+ .toLowerCase()
20
+ }
21
+
22
+ /** Singularize a regular English plural (see module deviation note). */
23
+ export function singular(word: string): string {
24
+ if (word.length > 3 && /ies$/i.test(word)) return word.replace(/ies$/i, 'y')
25
+ if (/(?:s|x|z|ch|sh)es$/i.test(word)) return word.replace(/es$/i, '')
26
+ if (/ss$/i.test(word)) return word
27
+ if (/s$/i.test(word)) return word.replace(/s$/i, '')
28
+ return word
29
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Zero-dependency dot-path object access — the small subset of `lodash`
3
+ * (`get`/`set`/`has`/`pick`/`omit`/`merge`) that Config and Request need for
4
+ * AdonisJS-parity nested access (`config.get('database.mysql.host')`,
5
+ * `request.input('user.address.city')`).
6
+ *
7
+ * AdonisJS uses `@poppinss/utils/lodash` for this. Ream stays lean and
8
+ * dependency-free (same stance as aurora's hand-written `cn`/`clsx`), so we
9
+ * reimplement exactly the four semantics we rely on — no more.
10
+ *
11
+ * Path syntax: `a.b.c` and `a[0].c` / `a.0.c` (bracket + dotted indices) are
12
+ * both accepted, matching lodash's tokenizer for the shapes config/request
13
+ * data actually take (plain JSON objects and arrays).
14
+ */
15
+
16
+ /** A JSON-ish record we can index by string key. */
17
+ type UnknownRecord = Record<string, unknown>
18
+
19
+ /** True for plain objects and arrays (anything indexable by a path segment). */
20
+ function isIndexable(value: unknown): value is UnknownRecord {
21
+ return typeof value === 'object' && value !== null
22
+ }
23
+
24
+ /**
25
+ * Split a dot/bracket path into segments: `a.b[0].c` → `['a','b','0','c']`.
26
+ * A single already-simple key (no `.`/`[`) is returned as-is, so keys that
27
+ * happen to contain neither delimiter cost nothing.
28
+ */
29
+ function toSegments(path: string): string[] {
30
+ if (path.indexOf('.') === -1 && path.indexOf('[') === -1) return [path]
31
+ const segments: string[] = []
32
+ const matcher = /[^.[\]]+/g
33
+ let match: RegExpExecArray | null = matcher.exec(path)
34
+ while (match !== null) {
35
+ segments.push(match[0])
36
+ match = matcher.exec(path)
37
+ }
38
+ return segments
39
+ }
40
+
41
+ /**
42
+ * Read a nested value by dot-path. Returns `defaultValue` when any segment is
43
+ * missing or the resolved value is `undefined` (lodash.get semantics).
44
+ */
45
+ export function getPath(source: unknown, path: string, defaultValue?: unknown): unknown {
46
+ const segments = toSegments(path)
47
+ let current: unknown = source
48
+ for (const segment of segments) {
49
+ if (!isIndexable(current)) return defaultValue
50
+ current = current[segment]
51
+ }
52
+ return current === undefined ? defaultValue : current
53
+ }
54
+
55
+ /**
56
+ * True when the full dot-path exists on `source` (each segment is an own key),
57
+ * even if the leaf value is `undefined` (lodash.has semantics).
58
+ */
59
+ export function hasPath(source: unknown, path: string): boolean {
60
+ const segments = toSegments(path)
61
+ let current: unknown = source
62
+ for (const segment of segments) {
63
+ if (!isIndexable(current) || !Object.hasOwn(current, segment)) return false
64
+ current = current[segment]
65
+ }
66
+ return true
67
+ }
68
+
69
+ /**
70
+ * Set a nested value by dot-path, creating intermediate plain objects as
71
+ * needed, and return the (mutated) root.
72
+ *
73
+ * Deviation from lodash.set (named): integer segments create plain objects,
74
+ * NOT arrays. Config trees and request-data picks are keyed objects; ream
75
+ * never sets array indices through a path, so array auto-vivification would be
76
+ * dead behaviour.
77
+ */
78
+ export function setPath(target: UnknownRecord, path: string, value: unknown): UnknownRecord {
79
+ const segments = toSegments(path)
80
+ let current: UnknownRecord = target
81
+ for (let i = 0; i < segments.length - 1; i += 1) {
82
+ const key = segments[i]
83
+ const next = current[key]
84
+ if (!isIndexable(next)) {
85
+ const created: UnknownRecord = {}
86
+ current[key] = created
87
+ current = created
88
+ } else {
89
+ current = next
90
+ }
91
+ }
92
+ current[segments[segments.length - 1]] = value
93
+ return target
94
+ }
95
+
96
+ /**
97
+ * Return a new object containing only the given dot-paths (lodash.pick).
98
+ * Missing paths are skipped; nested paths reconstruct their branch, so
99
+ * `pickPaths({a:{b:1,c:2}}, ['a.b'])` yields `{a:{b:1}}`.
100
+ */
101
+ export function pickPaths(source: unknown, paths: string[]): UnknownRecord {
102
+ const result: UnknownRecord = {}
103
+ for (const path of paths) {
104
+ if (hasPath(source, path)) setPath(result, path, getPath(source, path))
105
+ }
106
+ return result
107
+ }
108
+
109
+ /**
110
+ * Return a deep clone of `source` with the given dot-paths removed
111
+ * (lodash.omit). Operates on JSON-ish data (body + query), so `structuredClone`
112
+ * is a safe deep copy that never mutates the caller's input.
113
+ */
114
+ export function omitPaths(source: UnknownRecord, paths: string[]): UnknownRecord {
115
+ const result = structuredClone(source)
116
+ for (const path of paths) {
117
+ const segments = toSegments(path)
118
+ let current: unknown = result
119
+ for (let i = 0; i < segments.length - 1; i += 1) {
120
+ if (!isIndexable(current)) break
121
+ current = current[segments[i]]
122
+ }
123
+ if (isIndexable(current)) delete current[segments[segments.length - 1]]
124
+ }
125
+ return result
126
+ }
127
+
128
+ /**
129
+ * Deep-merge `source` over `target` (recursively for nested plain objects;
130
+ * scalars and arrays from `source` replace `target`). Returns a new object;
131
+ * neither input is mutated. Backs `Config.defaults` — the AdonisJS semantics
132
+ * where existing config wins over provided defaults.
133
+ */
134
+ export function mergeDeep(target: unknown, source: unknown): unknown {
135
+ if (!isIndexable(target) || Array.isArray(target)) return source === undefined ? target : source
136
+ if (!isIndexable(source) || Array.isArray(source)) return source === undefined ? target : source
137
+ const out: UnknownRecord = { ...target }
138
+ for (const key of Object.keys(source)) {
139
+ out[key] = mergeDeep(out[key], source[key])
140
+ }
141
+ return out
142
+ }
@@ -1,19 +0,0 @@
1
- /**
2
- * @Lazy() decorator — deferred injection to break circular dependencies.
3
- *
4
- * @implements FR15
5
- */
6
- import 'reflect-metadata';
7
- /**
8
- * @Lazy() — marks a constructor parameter for deferred resolution.
9
- * The dependency is resolved on first property access, not at construction.
10
- */
11
- export declare function Lazy(): ParameterDecorator;
12
- /** Get lazy parameter indices for a constructor. */
13
- export declare function getLazyParams(target: object): number[];
14
- /**
15
- * Create a lazy proxy that defers resolution until first access.
16
- * Traps get, set, has, ownKeys, getOwnPropertyDescriptor for full compatibility.
17
- */
18
- export declare function createLazyProxy<T extends object>(resolver: () => T): T;
19
- //# sourceMappingURL=Lazy.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Lazy.d.ts","sourceRoot":"","sources":["../../src/decorators/Lazy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,kBAAkB,CAAA;AAIzB;;;GAGG;AACH,wBAAgB,IAAI,IAAI,kBAAkB,CAMzC;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAEtD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAyBtE"}
@@ -1,53 +0,0 @@
1
- /**
2
- * @Lazy() decorator — deferred injection to break circular dependencies.
3
- *
4
- * @implements FR15
5
- */
6
- import 'reflect-metadata';
7
- const LAZY_KEY = Symbol.for('ream:lazy');
8
- /**
9
- * @Lazy() — marks a constructor parameter for deferred resolution.
10
- * The dependency is resolved on first property access, not at construction.
11
- */
12
- export function Lazy() {
13
- return (target, propertyKey, parameterIndex) => {
14
- const existing = Reflect.getOwnMetadata(LAZY_KEY, target, propertyKey ?? '') ?? [];
15
- existing.push(parameterIndex);
16
- Reflect.defineMetadata(LAZY_KEY, existing, target, propertyKey ?? '');
17
- };
18
- }
19
- /** Get lazy parameter indices for a constructor. */
20
- export function getLazyParams(target) {
21
- return Reflect.getOwnMetadata(LAZY_KEY, target, '') ?? [];
22
- }
23
- /**
24
- * Create a lazy proxy that defers resolution until first access.
25
- * Traps get, set, has, ownKeys, getOwnPropertyDescriptor for full compatibility.
26
- */
27
- export function createLazyProxy(resolver) {
28
- let instance;
29
- const ensure = () => {
30
- if (!instance)
31
- instance = resolver();
32
- return instance;
33
- };
34
- // biome-ignore lint/suspicious/noExplicitAny: Proxy target must be an object literal; T is branded at call site
35
- return new Proxy({}, {
36
- get(_target, prop, receiver) {
37
- return Reflect.get(ensure(), prop, receiver);
38
- },
39
- set(_target, prop, value, receiver) {
40
- return Reflect.set(ensure(), prop, value, receiver);
41
- },
42
- has(_target, prop) {
43
- return Reflect.has(ensure(), prop);
44
- },
45
- ownKeys() {
46
- return Reflect.ownKeys(ensure());
47
- },
48
- getOwnPropertyDescriptor(_target, prop) {
49
- return Object.getOwnPropertyDescriptor(ensure(), prop);
50
- },
51
- });
52
- }
53
- //# sourceMappingURL=Lazy.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Lazy.js","sourceRoot":"","sources":["../../src/decorators/Lazy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,kBAAkB,CAAA;AAEzB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;AAExC;;;GAGG;AACH,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE;QAC7C,MAAM,QAAQ,GAAa,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC,IAAI,EAAE,CAAA;QAC5F,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QAC7B,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC,CAAA;IACvE,CAAC,CAAA;AACH,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;AAC3D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAmB,QAAiB;IACjE,IAAI,QAAuB,CAAA;IAC3B,MAAM,MAAM,GAAG,GAAM,EAAE;QACrB,IAAI,CAAC,QAAQ;YAAE,QAAQ,GAAG,QAAQ,EAAE,CAAA;QACpC,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAA;IAED,gHAAgH;IAChH,OAAO,IAAI,KAAK,CAAC,EAAc,EAAE;QAC/B,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ;YACzB,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC9C,CAAC;QACD,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ;YAChC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;QACrD,CAAC;QACD,GAAG,CAAC,OAAO,EAAE,IAAI;YACf,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;QACpC,CAAC;QACD,OAAO;YACL,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;QAClC,CAAC;QACD,wBAAwB,CAAC,OAAO,EAAE,IAAI;YACpC,OAAO,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;QACxD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
@@ -1,57 +0,0 @@
1
- /**
2
- * @Lazy() decorator — deferred injection to break circular dependencies.
3
- *
4
- * @implements FR15
5
- */
6
-
7
- import 'reflect-metadata'
8
-
9
- const LAZY_KEY = Symbol.for('ream:lazy')
10
-
11
- /**
12
- * @Lazy() — marks a constructor parameter for deferred resolution.
13
- * The dependency is resolved on first property access, not at construction.
14
- */
15
- export function Lazy(): ParameterDecorator {
16
- return (target, propertyKey, parameterIndex) => {
17
- const existing: number[] = Reflect.getOwnMetadata(LAZY_KEY, target, propertyKey ?? '') ?? []
18
- existing.push(parameterIndex)
19
- Reflect.defineMetadata(LAZY_KEY, existing, target, propertyKey ?? '')
20
- }
21
- }
22
-
23
- /** Get lazy parameter indices for a constructor. */
24
- export function getLazyParams(target: object): number[] {
25
- return Reflect.getOwnMetadata(LAZY_KEY, target, '') ?? []
26
- }
27
-
28
- /**
29
- * Create a lazy proxy that defers resolution until first access.
30
- * Traps get, set, has, ownKeys, getOwnPropertyDescriptor for full compatibility.
31
- */
32
- export function createLazyProxy<T extends object>(resolver: () => T): T {
33
- let instance: T | undefined
34
- const ensure = (): T => {
35
- if (!instance) instance = resolver()
36
- return instance
37
- }
38
-
39
- // biome-ignore lint/suspicious/noExplicitAny: Proxy target must be an object literal; T is branded at call site
40
- return new Proxy({} as any as T, {
41
- get(_target, prop, receiver) {
42
- return Reflect.get(ensure(), prop, receiver)
43
- },
44
- set(_target, prop, value, receiver) {
45
- return Reflect.set(ensure(), prop, value, receiver)
46
- },
47
- has(_target, prop) {
48
- return Reflect.has(ensure(), prop)
49
- },
50
- ownKeys() {
51
- return Reflect.ownKeys(ensure())
52
- },
53
- getOwnPropertyDescriptor(_target, prop) {
54
- return Object.getOwnPropertyDescriptor(ensure(), prop)
55
- },
56
- })
57
- }