@nestjs-kit/better-auth 0.0.0-stage → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +1078 -2
  3. package/dist/admin.cjs +88 -0
  4. package/dist/admin.cjs.map +1 -0
  5. package/dist/admin.d.cts +14 -0
  6. package/dist/admin.d.cts.map +1 -0
  7. package/dist/admin.d.mts +14 -0
  8. package/dist/admin.d.mts.map +1 -0
  9. package/dist/admin.mjs +85 -0
  10. package/dist/admin.mjs.map +1 -0
  11. package/dist/api-key.cjs +164 -0
  12. package/dist/api-key.cjs.map +1 -0
  13. package/dist/api-key.d.cts +42 -0
  14. package/dist/api-key.d.cts.map +1 -0
  15. package/dist/api-key.d.mts +42 -0
  16. package/dist/api-key.d.mts.map +1 -0
  17. package/dist/api-key.mjs +160 -0
  18. package/dist/api-key.mjs.map +1 -0
  19. package/dist/auth-contracts-Brh_Qko9.d.cts +1654 -0
  20. package/dist/auth-contracts-Brh_Qko9.d.cts.map +1 -0
  21. package/dist/auth-contracts-Cz7C4_Ch.d.mts +1654 -0
  22. package/dist/auth-contracts-Cz7C4_Ch.d.mts.map +1 -0
  23. package/dist/auth-decorators-B1mFnGJ6.mjs +284 -0
  24. package/dist/auth-decorators-B1mFnGJ6.mjs.map +1 -0
  25. package/dist/auth-decorators-Cu_nxWnF.cjs +421 -0
  26. package/dist/auth-decorators-Cu_nxWnF.cjs.map +1 -0
  27. package/dist/auth-errors-C3rbTV9p.mjs +301 -0
  28. package/dist/auth-errors-C3rbTV9p.mjs.map +1 -0
  29. package/dist/auth-errors-DmiKl0L_.cjs +378 -0
  30. package/dist/auth-errors-DmiKl0L_.cjs.map +1 -0
  31. package/dist/auth-guard-CLyhAEEj.cjs +136 -0
  32. package/dist/auth-guard-CLyhAEEj.cjs.map +1 -0
  33. package/dist/auth-guard-h9QB_l11.mjs +125 -0
  34. package/dist/auth-guard-h9QB_l11.mjs.map +1 -0
  35. package/dist/auth-module-BgcY2HpA.cjs +2809 -0
  36. package/dist/auth-module-BgcY2HpA.cjs.map +1 -0
  37. package/dist/auth-module-CtHx3gRU.mjs +2708 -0
  38. package/dist/auth-module-CtHx3gRU.mjs.map +1 -0
  39. package/dist/auth-scope-interceptor-BjxAL1-S.cjs +290 -0
  40. package/dist/auth-scope-interceptor-BjxAL1-S.cjs.map +1 -0
  41. package/dist/auth-scope-interceptor-DYPn3b8M.mjs +231 -0
  42. package/dist/auth-scope-interceptor-DYPn3b8M.mjs.map +1 -0
  43. package/dist/bridge-protocol-BDw8opAG.cjs +25 -0
  44. package/dist/bridge-protocol-BDw8opAG.cjs.map +1 -0
  45. package/dist/bridge-protocol-c66aEkr5.mjs +8 -0
  46. package/dist/bridge-protocol-c66aEkr5.mjs.map +1 -0
  47. package/dist/decorate-Cr4Q7bNE.cjs +319 -0
  48. package/dist/decorate-Cr4Q7bNE.cjs.map +1 -0
  49. package/dist/decorate-Dt0e9K6R.mjs +80 -0
  50. package/dist/decorate-Dt0e9K6R.mjs.map +1 -0
  51. package/dist/express.cjs +256 -0
  52. package/dist/express.cjs.map +1 -0
  53. package/dist/express.d.cts +37 -0
  54. package/dist/express.d.cts.map +1 -0
  55. package/dist/express.d.mts +37 -0
  56. package/dist/express.d.mts.map +1 -0
  57. package/dist/express.mjs +254 -0
  58. package/dist/express.mjs.map +1 -0
  59. package/dist/fastify.cjs +218 -0
  60. package/dist/fastify.cjs.map +1 -0
  61. package/dist/fastify.d.cts +28 -0
  62. package/dist/fastify.d.cts.map +1 -0
  63. package/dist/fastify.d.mts +28 -0
  64. package/dist/fastify.d.mts.map +1 -0
  65. package/dist/fastify.mjs +216 -0
  66. package/dist/fastify.mjs.map +1 -0
  67. package/dist/graphql.cjs +509 -0
  68. package/dist/graphql.cjs.map +1 -0
  69. package/dist/graphql.d.cts +38 -0
  70. package/dist/graphql.d.cts.map +1 -0
  71. package/dist/graphql.d.mts +38 -0
  72. package/dist/graphql.d.mts.map +1 -0
  73. package/dist/graphql.mjs +503 -0
  74. package/dist/graphql.mjs.map +1 -0
  75. package/dist/index.cjs +86 -0
  76. package/dist/index.d.cts +2 -0
  77. package/dist/index.d.mts +2 -0
  78. package/dist/index.mjs +8 -0
  79. package/dist/microservices.cjs +231 -0
  80. package/dist/microservices.cjs.map +1 -0
  81. package/dist/microservices.d.cts +39 -0
  82. package/dist/microservices.d.cts.map +1 -0
  83. package/dist/microservices.d.mts +39 -0
  84. package/dist/microservices.d.mts.map +1 -0
  85. package/dist/microservices.mjs +222 -0
  86. package/dist/microservices.mjs.map +1 -0
  87. package/dist/organization.cjs +191 -0
  88. package/dist/organization.cjs.map +1 -0
  89. package/dist/organization.d.cts +40 -0
  90. package/dist/organization.d.cts.map +1 -0
  91. package/dist/organization.d.mts +40 -0
  92. package/dist/organization.d.mts.map +1 -0
  93. package/dist/organization.mjs +177 -0
  94. package/dist/organization.mjs.map +1 -0
  95. package/dist/platform-CZl7TY8j.mjs +414 -0
  96. package/dist/platform-CZl7TY8j.mjs.map +1 -0
  97. package/dist/platform-YICqqYv6.cjs +473 -0
  98. package/dist/platform-YICqqYv6.cjs.map +1 -0
  99. package/dist/platform.cjs +10 -0
  100. package/dist/platform.d.cts +43 -0
  101. package/dist/platform.d.cts.map +1 -0
  102. package/dist/platform.d.mts +43 -0
  103. package/dist/platform.d.mts.map +1 -0
  104. package/dist/platform.mjs +1 -0
  105. package/dist/plugin.cjs +323 -0
  106. package/dist/plugin.cjs.map +1 -0
  107. package/dist/plugin.d.cts +24 -0
  108. package/dist/plugin.d.cts.map +1 -0
  109. package/dist/plugin.d.mts +24 -0
  110. package/dist/plugin.d.mts.map +1 -0
  111. package/dist/plugin.mjs +321 -0
  112. package/dist/plugin.mjs.map +1 -0
  113. package/dist/principal-readings-Chmt6rQV.cjs +208 -0
  114. package/dist/principal-readings-Chmt6rQV.cjs.map +1 -0
  115. package/dist/principal-readings-Ied2staw.mjs +191 -0
  116. package/dist/principal-readings-Ied2staw.mjs.map +1 -0
  117. package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
  118. package/dist/testing/conformance.cjs +6214 -0
  119. package/dist/testing/conformance.cjs.map +1 -0
  120. package/dist/testing/conformance.d.cts +528 -0
  121. package/dist/testing/conformance.d.cts.map +1 -0
  122. package/dist/testing/conformance.d.mts +528 -0
  123. package/dist/testing/conformance.d.mts.map +1 -0
  124. package/dist/testing/conformance.mjs +6204 -0
  125. package/dist/testing/conformance.mjs.map +1 -0
  126. package/dist/testing.cjs +221 -0
  127. package/dist/testing.cjs.map +1 -0
  128. package/dist/testing.d.cts +64 -0
  129. package/dist/testing.d.cts.map +1 -0
  130. package/dist/testing.d.mts +64 -0
  131. package/dist/testing.d.mts.map +1 -0
  132. package/dist/testing.mjs +214 -0
  133. package/dist/testing.mjs.map +1 -0
  134. package/dist/websockets.cjs +396 -0
  135. package/dist/websockets.cjs.map +1 -0
  136. package/dist/websockets.d.cts +67 -0
  137. package/dist/websockets.d.cts.map +1 -0
  138. package/dist/websockets.d.mts +67 -0
  139. package/dist/websockets.d.mts.map +1 -0
  140. package/dist/websockets.mjs +383 -0
  141. package/dist/websockets.mjs.map +1 -0
  142. package/package.json +327 -3
@@ -0,0 +1,290 @@
1
+ const require_auth_errors = require("./auth-errors-DmiKl0L_.cjs");
2
+ const require_decorate = require("./decorate-Cr4Q7bNE.cjs");
3
+ let _nestjs_common = require("@nestjs/common");
4
+ let rxjs = require("rxjs");
5
+ //#region src/principal-resolver.ts
6
+ const definePrincipalSource = (source) => source;
7
+ const authenticated = (principal) => ({
8
+ outcome: "authenticated",
9
+ principal
10
+ });
11
+ const absent = () => ({ outcome: "absent" });
12
+ const rejected = (failure) => ({
13
+ outcome: "rejected",
14
+ failure
15
+ });
16
+ var MemoKeys = class {
17
+ owners = /* @__PURE__ */ new WeakMap();
18
+ key(owner, namespace, value) {
19
+ if (typeof value === "string") return JSON.stringify([
20
+ namespace,
21
+ "string",
22
+ value
23
+ ]);
24
+ let identities = this.owners.get(owner);
25
+ if (!identities) {
26
+ identities = {
27
+ objects: /* @__PURE__ */ new WeakMap(),
28
+ symbols: /* @__PURE__ */ new Map(),
29
+ next: 0
30
+ };
31
+ this.owners.set(owner, identities);
32
+ }
33
+ let id = typeof value === "symbol" ? identities.symbols.get(value) : identities.objects.get(value);
34
+ if (id === void 0) {
35
+ id = ++identities.next;
36
+ if (typeof value === "symbol") identities.symbols.set(value, id);
37
+ else identities.objects.set(value, id);
38
+ }
39
+ return JSON.stringify([
40
+ namespace,
41
+ typeof value,
42
+ id
43
+ ]);
44
+ }
45
+ };
46
+ function requestHeaders(call, entry) {
47
+ const headers = new Headers(call.headers());
48
+ for (const name of [...headers.keys()]) if (name.startsWith(":") || name.startsWith("x-nestjs-kit-better-auth-ip-") || name === entry.bridge.clientIpHeader) headers.delete(name);
49
+ if (entry.bridge.clientIpHeader && call.clientIp) headers.set(entry.bridge.clientIpHeader, call.clientIp);
50
+ return headers;
51
+ }
52
+ function normalizeForRequest(error, where, site, entry, headers) {
53
+ try {
54
+ return require_auth_errors.normalizeThrown(error, where, site, [], entry.options.errors);
55
+ } catch (normalized) {
56
+ if (require_auth_errors.isConfigurationError(normalized)) throw normalized;
57
+ if (require_auth_errors.isInfrastructureError(error) && normalized === error) throw require_auth_errors.redactForRequest(error, {
58
+ headers,
59
+ credentialHeaders: entry.credentialHeaders,
60
+ exposeRawCause: entry.options.errors?.exposeRawCause
61
+ });
62
+ throw require_auth_errors.createInfrastructureError(error, {
63
+ headers,
64
+ credentialHeaders: entry.credentialHeaders,
65
+ exposeRawCause: entry.options.errors?.exposeRawCause
66
+ });
67
+ }
68
+ }
69
+ var ChainPrincipalResolver = class {
70
+ instances;
71
+ scope;
72
+ transports;
73
+ keys = new MemoKeys();
74
+ constructor(instances, scope, transports) {
75
+ this.instances = instances;
76
+ this.scope = scope;
77
+ this.transports = transports;
78
+ }
79
+ resolve(call, request) {
80
+ const entry = this.instances.get(request.auth.name);
81
+ const compute = async () => {
82
+ const headers = requestHeaders(call, entry);
83
+ const sources = request.reclassify ? entry.sources.filter((source) => source.id === request.reclassify.sourceId && source.sessionBacked) : entry.sources.filter((source) => source.kinds.some((kind) => request.accepts.has(kind)));
84
+ return request.auth.run({
85
+ cookies: call.cookies,
86
+ forward: "same-credential",
87
+ inbound: () => headers,
88
+ internal: true
89
+ }, async () => {
90
+ for (const source of sources) {
91
+ const input = {
92
+ headers,
93
+ cookies: call.cookies,
94
+ transport: this.transports.idOf(call),
95
+ request: call.request,
96
+ freshness: request.freshness,
97
+ auth: request.auth,
98
+ memo: (key, fn) => this.scope.memoPolicyIo(call.key, entry.name, this.keys.key(call.key, `source:${source.id}`, key), fn, entry.options.limits?.maxAuthorizationCallsPerRequest)
99
+ };
100
+ try {
101
+ if (source.appliesTo && !source.appliesTo(input)) continue;
102
+ const result = await source.resolve(input);
103
+ if (result.outcome === "authenticated" && (!source.kinds.includes(result.principal.kind) || result.principal.source !== source.id || Boolean(result.principal.delegation) !== Boolean(source.delegates))) throw new Error(`Principal source ${source.id} violated its declared principal contract`);
104
+ if (result.outcome !== "absent") return result;
105
+ } catch (error) {
106
+ const failure = normalizeForRequest(error, "source", source.id, entry, headers);
107
+ if (require_auth_errors.isAuthFailure(failure)) return rejected(failure);
108
+ throw error;
109
+ }
110
+ }
111
+ return absent();
112
+ });
113
+ };
114
+ return request.reclassify ? compute() : this.scope.memoPrincipal(call, {
115
+ instance: entry.name,
116
+ freshness: request.freshness,
117
+ sourceSet: request.sourceSet
118
+ }, compute);
119
+ }
120
+ };
121
+ //#endregion
122
+ //#region src/auth-scope-interceptor.ts
123
+ let BetterAuthScopeInterceptor = class BetterAuthScopeInterceptor {
124
+ core;
125
+ static [require_decorate.AUTH_ENHANCER] = "scope";
126
+ [require_decorate.AUTH_ENHANCER] = "scope";
127
+ constructor(core) {
128
+ this.core = core;
129
+ }
130
+ intercept(context, next) {
131
+ return this.core.intercept(context, next);
132
+ }
133
+ };
134
+ BetterAuthScopeInterceptor = require_decorate.__decorate([
135
+ (0, _nestjs_common.Injectable)(),
136
+ require_decorate.__decorateParam(0, (0, _nestjs_common.Inject)(require_decorate.SCOPE_CORE)),
137
+ require_decorate.__decorateMetadata("design:paramtypes", [typeof Pick === "undefined" ? Object : Pick])
138
+ ], BetterAuthScopeInterceptor);
139
+ var ScopeCore = class {
140
+ instances;
141
+ planner;
142
+ transports;
143
+ scope;
144
+ readings;
145
+ constructor(instances, planner, transports, scope, readings) {
146
+ this.instances = instances;
147
+ this.planner = planner;
148
+ this.transports = transports;
149
+ this.scope = scope;
150
+ this.readings = readings;
151
+ }
152
+ intercept(context, next) {
153
+ const plan = this.planner.forContext(context);
154
+ const entry = this.instances.get(plan.instance);
155
+ let described = false;
156
+ let call;
157
+ const getCall = () => {
158
+ if (!described) {
159
+ const transport = this.transports.find(context);
160
+ call = transport ? this.transports.describe(context, transport) : void 0;
161
+ described = true;
162
+ }
163
+ return call;
164
+ };
165
+ let reading;
166
+ const read = () => {
167
+ if (reading) return reading;
168
+ const lineage = this.transports.find(context)?.lineage?.(context);
169
+ reading = this.readings.read({
170
+ args: context.getArgs(),
171
+ plan,
172
+ lineage,
173
+ ...plan.access === "public" || plan.access === "inherit" ? {} : { call: getCall() }
174
+ });
175
+ return reading;
176
+ };
177
+ const instances = this.instances;
178
+ const state = {
179
+ view: {
180
+ get cookies() {
181
+ return getCall()?.cookies ?? null;
182
+ },
183
+ forward: plan.forwardDirectCalls ? "same-credential" : "none",
184
+ internal: false,
185
+ get inbound() {
186
+ return () => {
187
+ const call = getCall();
188
+ return call ? requestHeaders(call, entry) : new Headers();
189
+ };
190
+ },
191
+ get browserHeaders() {
192
+ const browser = getCall()?.browser;
193
+ return browser ? () => browser.headers() : void 0;
194
+ },
195
+ get checkCallerSession() {
196
+ if (plan.originCheck === "off") return;
197
+ const browser = getCall()?.browser;
198
+ return browser ? (path, instance) => instances.get(instance).origin.assertCallerSession(browser, path, instance) : void 0;
199
+ }
200
+ },
201
+ plan,
202
+ reading: read,
203
+ get call() {
204
+ return getCall();
205
+ }
206
+ };
207
+ const args = context.getArgs();
208
+ const bridge = {
209
+ args: [...args],
210
+ reading: read,
211
+ scope: this.scope,
212
+ readings: this.readings
213
+ };
214
+ for (const arg of [args, ...args]) if (arg && (typeof arg === "object" || typeof arg === "function") && Object.isExtensible(arg)) Object.defineProperty(arg, require_decorate.READER_CONTEXT, {
215
+ value: bridge,
216
+ configurable: true
217
+ });
218
+ return new rxjs.Observable((subscriber) => this.scope.run(state, () => {
219
+ const subscription = next.handle().subscribe({
220
+ next: (value) => this.scope.run(state, () => subscriber.next(value)),
221
+ error: (error) => this.scope.run(state, () => subscriber.error(error)),
222
+ complete: () => this.scope.run(state, () => subscriber.complete())
223
+ });
224
+ return () => this.scope.run(state, () => subscription.unsubscribe());
225
+ }));
226
+ }
227
+ };
228
+ //#endregion
229
+ Object.defineProperty(exports, "BetterAuthScopeInterceptor", {
230
+ enumerable: true,
231
+ get: function() {
232
+ return BetterAuthScopeInterceptor;
233
+ }
234
+ });
235
+ Object.defineProperty(exports, "ChainPrincipalResolver", {
236
+ enumerable: true,
237
+ get: function() {
238
+ return ChainPrincipalResolver;
239
+ }
240
+ });
241
+ Object.defineProperty(exports, "MemoKeys", {
242
+ enumerable: true,
243
+ get: function() {
244
+ return MemoKeys;
245
+ }
246
+ });
247
+ Object.defineProperty(exports, "ScopeCore", {
248
+ enumerable: true,
249
+ get: function() {
250
+ return ScopeCore;
251
+ }
252
+ });
253
+ Object.defineProperty(exports, "absent", {
254
+ enumerable: true,
255
+ get: function() {
256
+ return absent;
257
+ }
258
+ });
259
+ Object.defineProperty(exports, "authenticated", {
260
+ enumerable: true,
261
+ get: function() {
262
+ return authenticated;
263
+ }
264
+ });
265
+ Object.defineProperty(exports, "definePrincipalSource", {
266
+ enumerable: true,
267
+ get: function() {
268
+ return definePrincipalSource;
269
+ }
270
+ });
271
+ Object.defineProperty(exports, "normalizeForRequest", {
272
+ enumerable: true,
273
+ get: function() {
274
+ return normalizeForRequest;
275
+ }
276
+ });
277
+ Object.defineProperty(exports, "rejected", {
278
+ enumerable: true,
279
+ get: function() {
280
+ return rejected;
281
+ }
282
+ });
283
+ Object.defineProperty(exports, "requestHeaders", {
284
+ enumerable: true,
285
+ get: function() {
286
+ return requestHeaders;
287
+ }
288
+ });
289
+
290
+ //# sourceMappingURL=auth-scope-interceptor-BjxAL1-S.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-scope-interceptor-BjxAL1-S.cjs","names":["normalizeThrown","isConfigurationError","isInfrastructureError","redactForRequest","createInfrastructureError","isAuthFailure","AUTH_ENHANCER","Injectable","Inject","SCOPE_CORE","READER_CONTEXT","Observable"],"sources":["../src/principal-resolver.ts","../src/auth-scope-interceptor.ts"],"sourcesContent":["import type {\n AuthPrincipalBase,\n PrincipalResolver,\n PrincipalResult,\n PrincipalSource,\n ResolutionRequest,\n TransportCall,\n} from \"./auth-contracts.js\";\nimport {\n type AuthFailure,\n isAuthFailure,\n normalizeThrown,\n createInfrastructureError,\n isConfigurationError,\n isInfrastructureError,\n redactForRequest,\n} from \"./auth-errors.js\";\nimport type { InstanceEntry, InstanceLookup } from \"./instance-registry.js\";\nimport type { TransportRegistry } from \"./transport-registry.js\";\nimport type { RequestScope } from \"./request-scope.js\";\n\nexport const definePrincipalSource = <P extends AuthPrincipalBase>(\n source: PrincipalSource<P>,\n): PrincipalSource<P> => source;\nexport const authenticated = <P extends AuthPrincipalBase>(\n principal: P,\n): PrincipalResult<P> => ({ outcome: \"authenticated\", principal });\nexport const absent = (): PrincipalResult<never> => ({ outcome: \"absent\" });\nexport const rejected = (failure: AuthFailure): PrincipalResult<never> => ({\n outcome: \"rejected\",\n failure,\n});\n\nexport class MemoKeys {\n private readonly owners = new WeakMap<\n object,\n {\n objects: WeakMap<object, number>;\n symbols: Map<symbol, number>;\n next: number;\n }\n >();\n\n key(\n owner: object,\n namespace: string,\n value: string | object | symbol,\n ): string {\n if (typeof value === \"string\") {\n return JSON.stringify([namespace, \"string\", value]);\n }\n let identities = this.owners.get(owner);\n if (!identities) {\n identities = { objects: new WeakMap(), symbols: new Map(), next: 0 };\n this.owners.set(owner, identities);\n }\n let id =\n typeof value === \"symbol\"\n ? identities.symbols.get(value)\n : identities.objects.get(value);\n if (id === undefined) {\n id = ++identities.next;\n if (typeof value === \"symbol\") {\n identities.symbols.set(value, id);\n } else {\n identities.objects.set(value, id);\n }\n }\n return JSON.stringify([namespace, typeof value, id]);\n }\n}\nexport function requestHeaders(\n call: TransportCall,\n entry: InstanceEntry,\n): Headers {\n const headers = new Headers(call.headers());\n for (const name of [...headers.keys()]) {\n if (\n name.startsWith(\":\") ||\n name.startsWith(\"x-nestjs-kit-better-auth-ip-\") ||\n name === entry.bridge.clientIpHeader\n ) {\n headers.delete(name);\n }\n }\n if (entry.bridge.clientIpHeader && call.clientIp) {\n headers.set(entry.bridge.clientIpHeader, call.clientIp);\n }\n return headers;\n}\nexport function normalizeForRequest(\n error: unknown,\n where: \"source\" | \"policy\",\n site: string,\n entry: InstanceEntry,\n headers: Headers,\n) {\n try {\n return normalizeThrown(error, where, site, [], entry.options.errors);\n } catch (normalized) {\n if (isConfigurationError(normalized)) {\n throw normalized;\n }\n if (isInfrastructureError(error) && normalized === error) {\n // A source or policy classified this failure itself, redacting only what it knew.\n throw redactForRequest(error, {\n headers,\n credentialHeaders: entry.credentialHeaders,\n exposeRawCause: entry.options.errors?.exposeRawCause,\n });\n }\n throw createInfrastructureError(error, {\n headers,\n credentialHeaders: entry.credentialHeaders,\n exposeRawCause: entry.options.errors?.exposeRawCause,\n });\n }\n}\nexport class ChainPrincipalResolver implements PrincipalResolver {\n private readonly keys = new MemoKeys();\n\n constructor(\n private readonly instances: InstanceLookup,\n private readonly scope: RequestScope,\n private readonly transports: TransportRegistry,\n ) {}\n\n resolve(\n call: TransportCall,\n request: ResolutionRequest,\n ): Promise<PrincipalResult> {\n const entry = this.instances.get(request.auth.name);\n const compute = async (): Promise<PrincipalResult> => {\n const headers = requestHeaders(call, entry);\n const sources = request.reclassify\n ? entry.sources.filter(\n (source) =>\n source.id === request.reclassify!.sourceId &&\n source.sessionBacked,\n )\n : entry.sources.filter((source) =>\n source.kinds.some((kind) => request.accepts.has(kind)),\n );\n return request.auth.run(\n {\n cookies: call.cookies,\n forward: \"same-credential\",\n inbound: () => headers,\n internal: true,\n },\n async () => {\n for (const source of sources) {\n const input = {\n headers,\n cookies: call.cookies,\n transport: this.transports.idOf(call),\n request: call.request,\n freshness: request.freshness,\n auth: request.auth,\n memo: <T>(\n key: string | object | symbol,\n fn: () => Promise<T>,\n ): Promise<T> =>\n this.scope.memoPolicyIo(\n call.key,\n entry.name,\n this.keys.key(call.key, `source:${source.id}`, key),\n fn,\n entry.options.limits?.maxAuthorizationCallsPerRequest,\n ),\n };\n try {\n if (source.appliesTo && !source.appliesTo(input)) {\n continue;\n }\n const result = await source.resolve(input);\n if (\n result.outcome === \"authenticated\" &&\n (!source.kinds.includes(result.principal.kind) ||\n result.principal.source !== source.id ||\n Boolean(result.principal.delegation) !==\n Boolean(source.delegates))\n ) {\n throw new Error(\n `Principal source ${source.id} violated its declared principal contract`,\n );\n }\n if (result.outcome !== \"absent\") {\n return result;\n }\n } catch (error) {\n const failure = normalizeForRequest(\n error,\n \"source\",\n source.id,\n entry,\n headers,\n );\n if (isAuthFailure(failure)) {\n return rejected(failure);\n }\n throw error;\n }\n }\n return absent();\n },\n );\n };\n return request.reclassify\n ? compute()\n : this.scope.memoPrincipal(\n call,\n {\n instance: entry.name,\n freshness: request.freshness,\n sourceSet: request.sourceSet,\n },\n compute,\n );\n }\n}\n","import {\n Inject,\n Injectable,\n type CallHandler,\n type ExecutionContext,\n type NestInterceptor,\n} from \"@nestjs/common\";\nimport { Observable } from \"rxjs\";\nimport type { PrincipalReading, TransportCall } from \"./auth-contracts.js\";\nimport { AUTH_ENHANCER, READER_CONTEXT, SCOPE_CORE } from \"./auth-tokens.js\";\nimport type { ScopeView } from \"./bridge-protocol.js\";\nimport type { InstanceLookup } from \"./instance-registry.js\";\nimport type { PrincipalReadings } from \"./principal-readings.js\";\nimport { requestHeaders } from \"./principal-resolver.js\";\nimport type { RequestScope, ScopeState } from \"./request-scope.js\";\nimport type { RoutePlanner } from \"./route-planner.js\";\nimport type { TransportRegistry } from \"./transport-registry.js\";\n\n@Injectable()\nexport class BetterAuthScopeInterceptor implements NestInterceptor {\n static readonly [AUTH_ENHANCER] = \"scope\";\n readonly [AUTH_ENHANCER] = \"scope\";\n\n constructor(\n @Inject(SCOPE_CORE) private readonly core: Pick<ScopeCore, \"intercept\">,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n return this.core.intercept(context, next);\n }\n}\nexport class ScopeCore implements NestInterceptor {\n constructor(\n private readonly instances: InstanceLookup,\n private readonly planner: RoutePlanner,\n private readonly transports: TransportRegistry,\n private readonly scope: RequestScope,\n private readonly readings: PrincipalReadings,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n const plan = this.planner.forContext(context);\n const entry = this.instances.get(plan.instance);\n let described = false;\n let call: TransportCall | undefined;\n const getCall = (): TransportCall | undefined => {\n if (!described) {\n const transport = this.transports.find(context);\n call = transport\n ? this.transports.describe(context, transport)\n : undefined;\n described = true;\n }\n return call;\n };\n let reading: PrincipalReading | undefined;\n const read = (): PrincipalReading => {\n if (reading) {\n return reading;\n }\n const lineage = this.transports.find(context)?.lineage?.(context);\n reading = this.readings.read({\n args: context.getArgs(),\n plan,\n lineage,\n ...(plan.access === \"public\" || plan.access === \"inherit\"\n ? {}\n : { call: getCall() }),\n });\n return reading;\n };\n const instances = this.instances;\n const view: ScopeView = {\n get cookies() {\n return getCall()?.cookies ?? null;\n },\n forward: plan.forwardDirectCalls ? \"same-credential\" : \"none\",\n internal: false,\n get inbound() {\n return () => {\n const call = getCall();\n return call ? requestHeaders(call, entry) : new Headers();\n };\n },\n get browserHeaders() {\n const browser = getCall()?.browser;\n return browser ? () => browser.headers() : undefined;\n },\n get checkCallerSession() {\n if (plan.originCheck === \"off\") {\n return undefined;\n }\n const browser = getCall()?.browser;\n return browser\n ? (path: string, instance: string) =>\n instances\n .get(instance)\n .origin.assertCallerSession(browser, path, instance)\n : undefined;\n },\n };\n const state: ScopeState = {\n view,\n plan,\n reading: read,\n get call() {\n return getCall();\n },\n };\n const args = context.getArgs();\n const bridge = {\n args: [...args],\n reading: read,\n scope: this.scope,\n readings: this.readings,\n };\n for (const arg of [args, ...args]) {\n if (\n arg &&\n (typeof arg === \"object\" || typeof arg === \"function\") &&\n Object.isExtensible(arg)\n ) {\n Object.defineProperty(arg, READER_CONTEXT, {\n value: bridge,\n configurable: true,\n });\n }\n }\n return new Observable((subscriber) =>\n this.scope.run(state, () => {\n const subscription = next.handle().subscribe({\n next: (value) => this.scope.run(state, () => subscriber.next(value)),\n error: (error) =>\n this.scope.run(state, () => subscriber.error(error)),\n complete: () => this.scope.run(state, () => subscriber.complete()),\n });\n return () => this.scope.run(state, () => subscription.unsubscribe());\n }),\n );\n }\n}\n"],"mappings":";;;;;AAqBA,MAAa,yBACX,WACuB;AACzB,MAAa,iBACX,eACwB;CAAE,SAAS;CAAiB;AAAU;AAChE,MAAa,gBAAwC,EAAE,SAAS,SAAS;AACzE,MAAa,YAAY,aAAkD;CACzE,SAAS;CACT;AACF;AAEA,IAAa,WAAb,MAAsB;CACpB,yBAA0B,IAAI,QAO5B;CAEF,IACE,OACA,WACA,OACQ;EACR,IAAI,OAAO,UAAU,UACnB,OAAO,KAAK,UAAU;GAAC;GAAW;GAAU;EAAK,CAAC;EAEpD,IAAI,aAAa,KAAK,OAAO,IAAI,KAAK;EACtC,IAAI,CAAC,YAAY;GACf,aAAa;IAAE,yBAAS,IAAI,QAAQ;IAAG,yBAAS,IAAI,IAAI;IAAG,MAAM;GAAE;GACnE,KAAK,OAAO,IAAI,OAAO,UAAU;EACnC;EACA,IAAI,KACF,OAAO,UAAU,WACb,WAAW,QAAQ,IAAI,KAAK,IAC5B,WAAW,QAAQ,IAAI,KAAK;EAClC,IAAI,OAAO,KAAA,GAAW;GACpB,KAAK,EAAE,WAAW;GAClB,IAAI,OAAO,UAAU,UACnB,WAAW,QAAQ,IAAI,OAAO,EAAE;QAEhC,WAAW,QAAQ,IAAI,OAAO,EAAE;EAEpC;EACA,OAAO,KAAK,UAAU;GAAC;GAAW,OAAO;GAAO;EAAE,CAAC;CACrD;AACF;AACA,SAAgB,eACd,MACA,OACS;CACT,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ,CAAC;CAC1C,KAAK,MAAM,QAAQ,CAAC,GAAG,QAAQ,KAAK,CAAC,GACnC,IACE,KAAK,WAAW,GAAG,KACnB,KAAK,WAAW,8BAA8B,KAC9C,SAAS,MAAM,OAAO,gBAEtB,QAAQ,OAAO,IAAI;CAGvB,IAAI,MAAM,OAAO,kBAAkB,KAAK,UACtC,QAAQ,IAAI,MAAM,OAAO,gBAAgB,KAAK,QAAQ;CAExD,OAAO;AACT;AACA,SAAgB,oBACd,OACA,OACA,MACA,OACA,SACA;CACA,IAAI;EACF,OAAOA,oBAAAA,gBAAgB,OAAO,OAAO,MAAM,CAAC,GAAG,MAAM,QAAQ,MAAM;CACrE,SAAS,YAAY;EACnB,IAAIC,oBAAAA,qBAAqB,UAAU,GACjC,MAAM;EAER,IAAIC,oBAAAA,sBAAsB,KAAK,KAAK,eAAe,OAEjD,MAAMC,oBAAAA,iBAAiB,OAAO;GAC5B;GACA,mBAAmB,MAAM;GACzB,gBAAgB,MAAM,QAAQ,QAAQ;EACxC,CAAC;EAEH,MAAMC,oBAAAA,0BAA0B,OAAO;GACrC;GACA,mBAAmB,MAAM;GACzB,gBAAgB,MAAM,QAAQ,QAAQ;EACxC,CAAC;CACH;AACF;AACA,IAAa,yBAAb,MAAiE;CAI5C;CACA;CACA;CALnB,OAAwB,IAAI,SAAS;CAErC,YACE,WACA,OACA,YACA;EAHiB,KAAA,YAAA;EACA,KAAA,QAAA;EACA,KAAA,aAAA;CAChB;CAEH,QACE,MACA,SAC0B;EAC1B,MAAM,QAAQ,KAAK,UAAU,IAAI,QAAQ,KAAK,IAAI;EAClD,MAAM,UAAU,YAAsC;GACpD,MAAM,UAAU,eAAe,MAAM,KAAK;GAC1C,MAAM,UAAU,QAAQ,aACpB,MAAM,QAAQ,QACX,WACC,OAAO,OAAO,QAAQ,WAAY,YAClC,OAAO,aACX,IACA,MAAM,QAAQ,QAAQ,WACpB,OAAO,MAAM,MAAM,SAAS,QAAQ,QAAQ,IAAI,IAAI,CAAC,CACvD;GACJ,OAAO,QAAQ,KAAK,IAClB;IACE,SAAS,KAAK;IACd,SAAS;IACT,eAAe;IACf,UAAU;GACZ,GACA,YAAY;IACV,KAAK,MAAM,UAAU,SAAS;KAC5B,MAAM,QAAQ;MACZ;MACA,SAAS,KAAK;MACd,WAAW,KAAK,WAAW,KAAK,IAAI;MACpC,SAAS,KAAK;MACd,WAAW,QAAQ;MACnB,MAAM,QAAQ;MACd,OACE,KACA,OAEA,KAAK,MAAM,aACT,KAAK,KACL,MAAM,MACN,KAAK,KAAK,IAAI,KAAK,KAAK,UAAU,OAAO,MAAM,GAAG,GAClD,IACA,MAAM,QAAQ,QAAQ,+BACxB;KACJ;KACA,IAAI;MACF,IAAI,OAAO,aAAa,CAAC,OAAO,UAAU,KAAK,GAC7C;MAEF,MAAM,SAAS,MAAM,OAAO,QAAQ,KAAK;MACzC,IACE,OAAO,YAAY,oBAClB,CAAC,OAAO,MAAM,SAAS,OAAO,UAAU,IAAI,KAC3C,OAAO,UAAU,WAAW,OAAO,MACnC,QAAQ,OAAO,UAAU,UAAU,MACjC,QAAQ,OAAO,SAAS,IAE5B,MAAM,IAAI,MACR,oBAAoB,OAAO,GAAG,0CAChC;MAEF,IAAI,OAAO,YAAY,UACrB,OAAO;KAEX,SAAS,OAAO;MACd,MAAM,UAAU,oBACd,OACA,UACA,OAAO,IACP,OACA,OACF;MACA,IAAIC,oBAAAA,cAAc,OAAO,GACvB,OAAO,SAAS,OAAO;MAEzB,MAAM;KACR;IACF;IACA,OAAO,OAAO;GAChB,CACF;EACF;EACA,OAAO,QAAQ,aACX,QAAQ,IACR,KAAK,MAAM,cACT,MACA;GACE,UAAU,MAAM;GAChB,WAAW,QAAQ;GACnB,WAAW,QAAQ;EACrB,GACA,OACF;CACN;AACF;;;ACzMO,IAAM,6BAAN,MAAM,2BAAsD;CAK1B;CAJvC,QAAiBC,iBAAAA,iBAAiB;CAClC,CAAUA,iBAAAA,iBAAiB;CAE3B,YACE,MACA;EADqC,KAAA,OAAA;CACpC;CAEH,UAAU,SAA2B,MAAwC;EAC3E,OAAO,KAAK,KAAK,UAAU,SAAS,IAAI;CAC1C;AACF;;EAZCC,GAAAA,eAAAA,WAAAA,CAAW;CAMPC,iBAAAA,gBAAAA,IAAAA,GAAAA,eAAAA,OAAAA,CAAOC,iBAAAA,UAAU,CAAA;;;AAOtB,IAAa,YAAb,MAAkD;CAE7B;CACA;CACA;CACA;CACA;CALnB,YACE,WACA,SACA,YACA,OACA,UACA;EALiB,KAAA,YAAA;EACA,KAAA,UAAA;EACA,KAAA,aAAA;EACA,KAAA,QAAA;EACA,KAAA,WAAA;CAChB;CAEH,UAAU,SAA2B,MAAwC;EAC3E,MAAM,OAAO,KAAK,QAAQ,WAAW,OAAO;EAC5C,MAAM,QAAQ,KAAK,UAAU,IAAI,KAAK,QAAQ;EAC9C,IAAI,YAAY;EAChB,IAAI;EACJ,MAAM,gBAA2C;GAC/C,IAAI,CAAC,WAAW;IACd,MAAM,YAAY,KAAK,WAAW,KAAK,OAAO;IAC9C,OAAO,YACH,KAAK,WAAW,SAAS,SAAS,SAAS,IAC3C,KAAA;IACJ,YAAY;GACd;GACA,OAAO;EACT;EACA,IAAI;EACJ,MAAM,aAA+B;GACnC,IAAI,SACF,OAAO;GAET,MAAM,UAAU,KAAK,WAAW,KAAK,OAAO,CAAC,EAAE,UAAU,OAAO;GAChE,UAAU,KAAK,SAAS,KAAK;IAC3B,MAAM,QAAQ,QAAQ;IACtB;IACA;IACA,GAAI,KAAK,WAAW,YAAY,KAAK,WAAW,YAC5C,CAAC,IACD,EAAE,MAAM,QAAQ,EAAE;GACxB,CAAC;GACD,OAAO;EACT;EACA,MAAM,YAAY,KAAK;EA8BvB,MAAM,QAAoB;GACxB,MAAA;IA7BA,IAAI,UAAU;KACZ,OAAO,QAAQ,CAAC,EAAE,WAAW;IAC/B;IACA,SAAS,KAAK,qBAAqB,oBAAoB;IACvD,UAAU;IACV,IAAI,UAAU;KACZ,aAAa;MACX,MAAM,OAAO,QAAQ;MACrB,OAAO,OAAO,eAAe,MAAM,KAAK,IAAI,IAAI,QAAQ;KAC1D;IACF;IACA,IAAI,iBAAiB;KACnB,MAAM,UAAU,QAAQ,CAAC,EAAE;KAC3B,OAAO,gBAAgB,QAAQ,QAAQ,IAAI,KAAA;IAC7C;IACA,IAAI,qBAAqB;KACvB,IAAI,KAAK,gBAAgB,OACvB;KAEF,MAAM,UAAU,QAAQ,CAAC,EAAE;KAC3B,OAAO,WACF,MAAc,aACb,UACG,IAAI,QAAQ,CAAC,CACb,OAAO,oBAAoB,SAAS,MAAM,QAAQ,IACvD,KAAA;IACN;GAGG;GACH;GACA,SAAS;GACT,IAAI,OAAO;IACT,OAAO,QAAQ;GACjB;EACF;EACA,MAAM,OAAO,QAAQ,QAAQ;EAC7B,MAAM,SAAS;GACb,MAAM,CAAC,GAAG,IAAI;GACd,SAAS;GACT,OAAO,KAAK;GACZ,UAAU,KAAK;EACjB;EACA,KAAK,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,GAC9B,IACE,QACC,OAAO,QAAQ,YAAY,OAAO,QAAQ,eAC3C,OAAO,aAAa,GAAG,GAEvB,OAAO,eAAe,KAAKC,iBAAAA,gBAAgB;GACzC,OAAO;GACP,cAAc;EAChB,CAAC;EAGL,OAAO,IAAIC,KAAAA,YAAY,eACrB,KAAK,MAAM,IAAI,aAAa;GAC1B,MAAM,eAAe,KAAK,OAAO,CAAC,CAAC,UAAU;IAC3C,OAAO,UAAU,KAAK,MAAM,IAAI,aAAa,WAAW,KAAK,KAAK,CAAC;IACnE,QAAQ,UACN,KAAK,MAAM,IAAI,aAAa,WAAW,MAAM,KAAK,CAAC;IACrD,gBAAgB,KAAK,MAAM,IAAI,aAAa,WAAW,SAAS,CAAC;GACnE,CAAC;GACD,aAAa,KAAK,MAAM,IAAI,aAAa,aAAa,YAAY,CAAC;EACrE,CAAC,CACH;CACF;AACF"}
@@ -0,0 +1,231 @@
1
+ import { c as isConfigurationError, d as redactForRequest, i as createInfrastructureError, l as isInfrastructureError, s as isAuthFailure, u as normalizeThrown } from "./auth-errors-C3rbTV9p.mjs";
2
+ import { O as SCOPE_CORE, n as __decorateParam, r as __decorateMetadata, s as AUTH_ENHANCER, t as __decorate, w as READER_CONTEXT } from "./decorate-Dt0e9K6R.mjs";
3
+ import { Inject, Injectable } from "@nestjs/common";
4
+ import { Observable } from "rxjs";
5
+ //#region src/principal-resolver.ts
6
+ const definePrincipalSource = (source) => source;
7
+ const authenticated = (principal) => ({
8
+ outcome: "authenticated",
9
+ principal
10
+ });
11
+ const absent = () => ({ outcome: "absent" });
12
+ const rejected = (failure) => ({
13
+ outcome: "rejected",
14
+ failure
15
+ });
16
+ var MemoKeys = class {
17
+ owners = /* @__PURE__ */ new WeakMap();
18
+ key(owner, namespace, value) {
19
+ if (typeof value === "string") return JSON.stringify([
20
+ namespace,
21
+ "string",
22
+ value
23
+ ]);
24
+ let identities = this.owners.get(owner);
25
+ if (!identities) {
26
+ identities = {
27
+ objects: /* @__PURE__ */ new WeakMap(),
28
+ symbols: /* @__PURE__ */ new Map(),
29
+ next: 0
30
+ };
31
+ this.owners.set(owner, identities);
32
+ }
33
+ let id = typeof value === "symbol" ? identities.symbols.get(value) : identities.objects.get(value);
34
+ if (id === void 0) {
35
+ id = ++identities.next;
36
+ if (typeof value === "symbol") identities.symbols.set(value, id);
37
+ else identities.objects.set(value, id);
38
+ }
39
+ return JSON.stringify([
40
+ namespace,
41
+ typeof value,
42
+ id
43
+ ]);
44
+ }
45
+ };
46
+ function requestHeaders(call, entry) {
47
+ const headers = new Headers(call.headers());
48
+ for (const name of [...headers.keys()]) if (name.startsWith(":") || name.startsWith("x-nestjs-kit-better-auth-ip-") || name === entry.bridge.clientIpHeader) headers.delete(name);
49
+ if (entry.bridge.clientIpHeader && call.clientIp) headers.set(entry.bridge.clientIpHeader, call.clientIp);
50
+ return headers;
51
+ }
52
+ function normalizeForRequest(error, where, site, entry, headers) {
53
+ try {
54
+ return normalizeThrown(error, where, site, [], entry.options.errors);
55
+ } catch (normalized) {
56
+ if (isConfigurationError(normalized)) throw normalized;
57
+ if (isInfrastructureError(error) && normalized === error) throw redactForRequest(error, {
58
+ headers,
59
+ credentialHeaders: entry.credentialHeaders,
60
+ exposeRawCause: entry.options.errors?.exposeRawCause
61
+ });
62
+ throw createInfrastructureError(error, {
63
+ headers,
64
+ credentialHeaders: entry.credentialHeaders,
65
+ exposeRawCause: entry.options.errors?.exposeRawCause
66
+ });
67
+ }
68
+ }
69
+ var ChainPrincipalResolver = class {
70
+ instances;
71
+ scope;
72
+ transports;
73
+ keys = new MemoKeys();
74
+ constructor(instances, scope, transports) {
75
+ this.instances = instances;
76
+ this.scope = scope;
77
+ this.transports = transports;
78
+ }
79
+ resolve(call, request) {
80
+ const entry = this.instances.get(request.auth.name);
81
+ const compute = async () => {
82
+ const headers = requestHeaders(call, entry);
83
+ const sources = request.reclassify ? entry.sources.filter((source) => source.id === request.reclassify.sourceId && source.sessionBacked) : entry.sources.filter((source) => source.kinds.some((kind) => request.accepts.has(kind)));
84
+ return request.auth.run({
85
+ cookies: call.cookies,
86
+ forward: "same-credential",
87
+ inbound: () => headers,
88
+ internal: true
89
+ }, async () => {
90
+ for (const source of sources) {
91
+ const input = {
92
+ headers,
93
+ cookies: call.cookies,
94
+ transport: this.transports.idOf(call),
95
+ request: call.request,
96
+ freshness: request.freshness,
97
+ auth: request.auth,
98
+ memo: (key, fn) => this.scope.memoPolicyIo(call.key, entry.name, this.keys.key(call.key, `source:${source.id}`, key), fn, entry.options.limits?.maxAuthorizationCallsPerRequest)
99
+ };
100
+ try {
101
+ if (source.appliesTo && !source.appliesTo(input)) continue;
102
+ const result = await source.resolve(input);
103
+ if (result.outcome === "authenticated" && (!source.kinds.includes(result.principal.kind) || result.principal.source !== source.id || Boolean(result.principal.delegation) !== Boolean(source.delegates))) throw new Error(`Principal source ${source.id} violated its declared principal contract`);
104
+ if (result.outcome !== "absent") return result;
105
+ } catch (error) {
106
+ const failure = normalizeForRequest(error, "source", source.id, entry, headers);
107
+ if (isAuthFailure(failure)) return rejected(failure);
108
+ throw error;
109
+ }
110
+ }
111
+ return absent();
112
+ });
113
+ };
114
+ return request.reclassify ? compute() : this.scope.memoPrincipal(call, {
115
+ instance: entry.name,
116
+ freshness: request.freshness,
117
+ sourceSet: request.sourceSet
118
+ }, compute);
119
+ }
120
+ };
121
+ //#endregion
122
+ //#region src/auth-scope-interceptor.ts
123
+ let BetterAuthScopeInterceptor = class BetterAuthScopeInterceptor {
124
+ core;
125
+ static [AUTH_ENHANCER] = "scope";
126
+ [AUTH_ENHANCER] = "scope";
127
+ constructor(core) {
128
+ this.core = core;
129
+ }
130
+ intercept(context, next) {
131
+ return this.core.intercept(context, next);
132
+ }
133
+ };
134
+ BetterAuthScopeInterceptor = __decorate([
135
+ Injectable(),
136
+ __decorateParam(0, Inject(SCOPE_CORE)),
137
+ __decorateMetadata("design:paramtypes", [typeof Pick === "undefined" ? Object : Pick])
138
+ ], BetterAuthScopeInterceptor);
139
+ var ScopeCore = class {
140
+ instances;
141
+ planner;
142
+ transports;
143
+ scope;
144
+ readings;
145
+ constructor(instances, planner, transports, scope, readings) {
146
+ this.instances = instances;
147
+ this.planner = planner;
148
+ this.transports = transports;
149
+ this.scope = scope;
150
+ this.readings = readings;
151
+ }
152
+ intercept(context, next) {
153
+ const plan = this.planner.forContext(context);
154
+ const entry = this.instances.get(plan.instance);
155
+ let described = false;
156
+ let call;
157
+ const getCall = () => {
158
+ if (!described) {
159
+ const transport = this.transports.find(context);
160
+ call = transport ? this.transports.describe(context, transport) : void 0;
161
+ described = true;
162
+ }
163
+ return call;
164
+ };
165
+ let reading;
166
+ const read = () => {
167
+ if (reading) return reading;
168
+ const lineage = this.transports.find(context)?.lineage?.(context);
169
+ reading = this.readings.read({
170
+ args: context.getArgs(),
171
+ plan,
172
+ lineage,
173
+ ...plan.access === "public" || plan.access === "inherit" ? {} : { call: getCall() }
174
+ });
175
+ return reading;
176
+ };
177
+ const instances = this.instances;
178
+ const state = {
179
+ view: {
180
+ get cookies() {
181
+ return getCall()?.cookies ?? null;
182
+ },
183
+ forward: plan.forwardDirectCalls ? "same-credential" : "none",
184
+ internal: false,
185
+ get inbound() {
186
+ return () => {
187
+ const call = getCall();
188
+ return call ? requestHeaders(call, entry) : new Headers();
189
+ };
190
+ },
191
+ get browserHeaders() {
192
+ const browser = getCall()?.browser;
193
+ return browser ? () => browser.headers() : void 0;
194
+ },
195
+ get checkCallerSession() {
196
+ if (plan.originCheck === "off") return;
197
+ const browser = getCall()?.browser;
198
+ return browser ? (path, instance) => instances.get(instance).origin.assertCallerSession(browser, path, instance) : void 0;
199
+ }
200
+ },
201
+ plan,
202
+ reading: read,
203
+ get call() {
204
+ return getCall();
205
+ }
206
+ };
207
+ const args = context.getArgs();
208
+ const bridge = {
209
+ args: [...args],
210
+ reading: read,
211
+ scope: this.scope,
212
+ readings: this.readings
213
+ };
214
+ for (const arg of [args, ...args]) if (arg && (typeof arg === "object" || typeof arg === "function") && Object.isExtensible(arg)) Object.defineProperty(arg, READER_CONTEXT, {
215
+ value: bridge,
216
+ configurable: true
217
+ });
218
+ return new Observable((subscriber) => this.scope.run(state, () => {
219
+ const subscription = next.handle().subscribe({
220
+ next: (value) => this.scope.run(state, () => subscriber.next(value)),
221
+ error: (error) => this.scope.run(state, () => subscriber.error(error)),
222
+ complete: () => this.scope.run(state, () => subscriber.complete())
223
+ });
224
+ return () => this.scope.run(state, () => subscription.unsubscribe());
225
+ }));
226
+ }
227
+ };
228
+ //#endregion
229
+ export { absent as a, normalizeForRequest as c, MemoKeys as i, rejected as l, ScopeCore as n, authenticated as o, ChainPrincipalResolver as r, definePrincipalSource as s, BetterAuthScopeInterceptor as t, requestHeaders as u };
230
+
231
+ //# sourceMappingURL=auth-scope-interceptor-DYPn3b8M.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-scope-interceptor-DYPn3b8M.mjs","names":[],"sources":["../src/principal-resolver.ts","../src/auth-scope-interceptor.ts"],"sourcesContent":["import type {\n AuthPrincipalBase,\n PrincipalResolver,\n PrincipalResult,\n PrincipalSource,\n ResolutionRequest,\n TransportCall,\n} from \"./auth-contracts.js\";\nimport {\n type AuthFailure,\n isAuthFailure,\n normalizeThrown,\n createInfrastructureError,\n isConfigurationError,\n isInfrastructureError,\n redactForRequest,\n} from \"./auth-errors.js\";\nimport type { InstanceEntry, InstanceLookup } from \"./instance-registry.js\";\nimport type { TransportRegistry } from \"./transport-registry.js\";\nimport type { RequestScope } from \"./request-scope.js\";\n\nexport const definePrincipalSource = <P extends AuthPrincipalBase>(\n source: PrincipalSource<P>,\n): PrincipalSource<P> => source;\nexport const authenticated = <P extends AuthPrincipalBase>(\n principal: P,\n): PrincipalResult<P> => ({ outcome: \"authenticated\", principal });\nexport const absent = (): PrincipalResult<never> => ({ outcome: \"absent\" });\nexport const rejected = (failure: AuthFailure): PrincipalResult<never> => ({\n outcome: \"rejected\",\n failure,\n});\n\nexport class MemoKeys {\n private readonly owners = new WeakMap<\n object,\n {\n objects: WeakMap<object, number>;\n symbols: Map<symbol, number>;\n next: number;\n }\n >();\n\n key(\n owner: object,\n namespace: string,\n value: string | object | symbol,\n ): string {\n if (typeof value === \"string\") {\n return JSON.stringify([namespace, \"string\", value]);\n }\n let identities = this.owners.get(owner);\n if (!identities) {\n identities = { objects: new WeakMap(), symbols: new Map(), next: 0 };\n this.owners.set(owner, identities);\n }\n let id =\n typeof value === \"symbol\"\n ? identities.symbols.get(value)\n : identities.objects.get(value);\n if (id === undefined) {\n id = ++identities.next;\n if (typeof value === \"symbol\") {\n identities.symbols.set(value, id);\n } else {\n identities.objects.set(value, id);\n }\n }\n return JSON.stringify([namespace, typeof value, id]);\n }\n}\nexport function requestHeaders(\n call: TransportCall,\n entry: InstanceEntry,\n): Headers {\n const headers = new Headers(call.headers());\n for (const name of [...headers.keys()]) {\n if (\n name.startsWith(\":\") ||\n name.startsWith(\"x-nestjs-kit-better-auth-ip-\") ||\n name === entry.bridge.clientIpHeader\n ) {\n headers.delete(name);\n }\n }\n if (entry.bridge.clientIpHeader && call.clientIp) {\n headers.set(entry.bridge.clientIpHeader, call.clientIp);\n }\n return headers;\n}\nexport function normalizeForRequest(\n error: unknown,\n where: \"source\" | \"policy\",\n site: string,\n entry: InstanceEntry,\n headers: Headers,\n) {\n try {\n return normalizeThrown(error, where, site, [], entry.options.errors);\n } catch (normalized) {\n if (isConfigurationError(normalized)) {\n throw normalized;\n }\n if (isInfrastructureError(error) && normalized === error) {\n // A source or policy classified this failure itself, redacting only what it knew.\n throw redactForRequest(error, {\n headers,\n credentialHeaders: entry.credentialHeaders,\n exposeRawCause: entry.options.errors?.exposeRawCause,\n });\n }\n throw createInfrastructureError(error, {\n headers,\n credentialHeaders: entry.credentialHeaders,\n exposeRawCause: entry.options.errors?.exposeRawCause,\n });\n }\n}\nexport class ChainPrincipalResolver implements PrincipalResolver {\n private readonly keys = new MemoKeys();\n\n constructor(\n private readonly instances: InstanceLookup,\n private readonly scope: RequestScope,\n private readonly transports: TransportRegistry,\n ) {}\n\n resolve(\n call: TransportCall,\n request: ResolutionRequest,\n ): Promise<PrincipalResult> {\n const entry = this.instances.get(request.auth.name);\n const compute = async (): Promise<PrincipalResult> => {\n const headers = requestHeaders(call, entry);\n const sources = request.reclassify\n ? entry.sources.filter(\n (source) =>\n source.id === request.reclassify!.sourceId &&\n source.sessionBacked,\n )\n : entry.sources.filter((source) =>\n source.kinds.some((kind) => request.accepts.has(kind)),\n );\n return request.auth.run(\n {\n cookies: call.cookies,\n forward: \"same-credential\",\n inbound: () => headers,\n internal: true,\n },\n async () => {\n for (const source of sources) {\n const input = {\n headers,\n cookies: call.cookies,\n transport: this.transports.idOf(call),\n request: call.request,\n freshness: request.freshness,\n auth: request.auth,\n memo: <T>(\n key: string | object | symbol,\n fn: () => Promise<T>,\n ): Promise<T> =>\n this.scope.memoPolicyIo(\n call.key,\n entry.name,\n this.keys.key(call.key, `source:${source.id}`, key),\n fn,\n entry.options.limits?.maxAuthorizationCallsPerRequest,\n ),\n };\n try {\n if (source.appliesTo && !source.appliesTo(input)) {\n continue;\n }\n const result = await source.resolve(input);\n if (\n result.outcome === \"authenticated\" &&\n (!source.kinds.includes(result.principal.kind) ||\n result.principal.source !== source.id ||\n Boolean(result.principal.delegation) !==\n Boolean(source.delegates))\n ) {\n throw new Error(\n `Principal source ${source.id} violated its declared principal contract`,\n );\n }\n if (result.outcome !== \"absent\") {\n return result;\n }\n } catch (error) {\n const failure = normalizeForRequest(\n error,\n \"source\",\n source.id,\n entry,\n headers,\n );\n if (isAuthFailure(failure)) {\n return rejected(failure);\n }\n throw error;\n }\n }\n return absent();\n },\n );\n };\n return request.reclassify\n ? compute()\n : this.scope.memoPrincipal(\n call,\n {\n instance: entry.name,\n freshness: request.freshness,\n sourceSet: request.sourceSet,\n },\n compute,\n );\n }\n}\n","import {\n Inject,\n Injectable,\n type CallHandler,\n type ExecutionContext,\n type NestInterceptor,\n} from \"@nestjs/common\";\nimport { Observable } from \"rxjs\";\nimport type { PrincipalReading, TransportCall } from \"./auth-contracts.js\";\nimport { AUTH_ENHANCER, READER_CONTEXT, SCOPE_CORE } from \"./auth-tokens.js\";\nimport type { ScopeView } from \"./bridge-protocol.js\";\nimport type { InstanceLookup } from \"./instance-registry.js\";\nimport type { PrincipalReadings } from \"./principal-readings.js\";\nimport { requestHeaders } from \"./principal-resolver.js\";\nimport type { RequestScope, ScopeState } from \"./request-scope.js\";\nimport type { RoutePlanner } from \"./route-planner.js\";\nimport type { TransportRegistry } from \"./transport-registry.js\";\n\n@Injectable()\nexport class BetterAuthScopeInterceptor implements NestInterceptor {\n static readonly [AUTH_ENHANCER] = \"scope\";\n readonly [AUTH_ENHANCER] = \"scope\";\n\n constructor(\n @Inject(SCOPE_CORE) private readonly core: Pick<ScopeCore, \"intercept\">,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n return this.core.intercept(context, next);\n }\n}\nexport class ScopeCore implements NestInterceptor {\n constructor(\n private readonly instances: InstanceLookup,\n private readonly planner: RoutePlanner,\n private readonly transports: TransportRegistry,\n private readonly scope: RequestScope,\n private readonly readings: PrincipalReadings,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n const plan = this.planner.forContext(context);\n const entry = this.instances.get(plan.instance);\n let described = false;\n let call: TransportCall | undefined;\n const getCall = (): TransportCall | undefined => {\n if (!described) {\n const transport = this.transports.find(context);\n call = transport\n ? this.transports.describe(context, transport)\n : undefined;\n described = true;\n }\n return call;\n };\n let reading: PrincipalReading | undefined;\n const read = (): PrincipalReading => {\n if (reading) {\n return reading;\n }\n const lineage = this.transports.find(context)?.lineage?.(context);\n reading = this.readings.read({\n args: context.getArgs(),\n plan,\n lineage,\n ...(plan.access === \"public\" || plan.access === \"inherit\"\n ? {}\n : { call: getCall() }),\n });\n return reading;\n };\n const instances = this.instances;\n const view: ScopeView = {\n get cookies() {\n return getCall()?.cookies ?? null;\n },\n forward: plan.forwardDirectCalls ? \"same-credential\" : \"none\",\n internal: false,\n get inbound() {\n return () => {\n const call = getCall();\n return call ? requestHeaders(call, entry) : new Headers();\n };\n },\n get browserHeaders() {\n const browser = getCall()?.browser;\n return browser ? () => browser.headers() : undefined;\n },\n get checkCallerSession() {\n if (plan.originCheck === \"off\") {\n return undefined;\n }\n const browser = getCall()?.browser;\n return browser\n ? (path: string, instance: string) =>\n instances\n .get(instance)\n .origin.assertCallerSession(browser, path, instance)\n : undefined;\n },\n };\n const state: ScopeState = {\n view,\n plan,\n reading: read,\n get call() {\n return getCall();\n },\n };\n const args = context.getArgs();\n const bridge = {\n args: [...args],\n reading: read,\n scope: this.scope,\n readings: this.readings,\n };\n for (const arg of [args, ...args]) {\n if (\n arg &&\n (typeof arg === \"object\" || typeof arg === \"function\") &&\n Object.isExtensible(arg)\n ) {\n Object.defineProperty(arg, READER_CONTEXT, {\n value: bridge,\n configurable: true,\n });\n }\n }\n return new Observable((subscriber) =>\n this.scope.run(state, () => {\n const subscription = next.handle().subscribe({\n next: (value) => this.scope.run(state, () => subscriber.next(value)),\n error: (error) =>\n this.scope.run(state, () => subscriber.error(error)),\n complete: () => this.scope.run(state, () => subscriber.complete()),\n });\n return () => this.scope.run(state, () => subscription.unsubscribe());\n }),\n );\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ //#region src/bridge-protocol.ts
2
+ const BRIDGE_HANDLE = Symbol.for("@nestjs-kit/better-auth:bridge");
3
+ const EXTENSION_DEFINITION = Symbol.for("@nestjs-kit/better-auth:extension");
4
+ const UPGRADE_REQUEST = Symbol.for("@nestjs-kit/better-auth:upgrade-request");
5
+ //#endregion
6
+ Object.defineProperty(exports, "BRIDGE_HANDLE", {
7
+ enumerable: true,
8
+ get: function() {
9
+ return BRIDGE_HANDLE;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "EXTENSION_DEFINITION", {
13
+ enumerable: true,
14
+ get: function() {
15
+ return EXTENSION_DEFINITION;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "UPGRADE_REQUEST", {
19
+ enumerable: true,
20
+ get: function() {
21
+ return UPGRADE_REQUEST;
22
+ }
23
+ });
24
+
25
+ //# sourceMappingURL=bridge-protocol-BDw8opAG.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-protocol-BDw8opAG.cjs","names":[],"sources":["../src/bridge-protocol.ts"],"sourcesContent":["import type { HookEndpointContext } from \"better-auth\";\nimport type { CookieSink, DatabaseHookTarget } from \"./auth-contracts.js\";\nimport type { DatabaseHookMethod } from \"./auth-types.js\";\n\nexport const BRIDGE_HANDLE = Symbol.for(\"@nestjs-kit/better-auth:bridge\");\nexport const EXTENSION_DEFINITION = Symbol.for(\n \"@nestjs-kit/better-auth:extension\",\n);\nexport const UPGRADE_REQUEST = Symbol.for(\n \"@nestjs-kit/better-auth:upgrade-request\",\n);\n\nexport interface BridgeHandle {\n readonly protocol: 4; // checked by core (B04); v5: binding state and instance, the caller-session check\n readonly clientIpHeader: string | null; // single source of truth for the header name (§6.8)\n /** 'unbound' until the first bind(); 'bound' while an application's hooks are registered; 'closed' after its shutdown, hooks still registered. */\n readonly state: \"unbound\" | \"bound\" | \"closed\";\n /** Endpoint dispatches and database-hook dispatches (writes) seen before the first binding, reset by every bind() (B26). */\n readonly unboundDispatches: number;\n /**\n * Registers the application's hooks and returns close(), which the kernel calls in onApplicationShutdown: a closed binding keeps\n * dispatching until another application binds (§10.6). A second bind() from the same owner for the same instance is a no-op that\n * returns the existing registration (NestMicroservice.init() runs lifecycle hooks twice); from the same owner for another instance it\n * throws PLUGIN_SHARED_BETWEEN_INSTANCES (B03). Throws INSTANCE_ALREADY_BOUND if another bootstrapped application is bound; takes over\n * a never-bootstrapped one (reported, B06) and a closed one (silently). A never-bootstrapped binding it takes over becomes\n * 'displaced': an application whose init() was still running when another bound fails in onApplicationBootstrap (B06).\n */\n bind(binding: BridgeBinding): { close(): void; tookOverFrom?: string };\n /** true when an endpoint returned `value` (an object) in a non-router dispatch observed while bound; false for before-hook short-circuits (LEAD-V37). */\n producedByEndpoint(value: unknown): boolean;\n}\nexport interface BridgeBinding {\n /** The application: compared by identity for the same-owner no-op; `description` goes into the B06 message. */\n readonly owner: { readonly description: string };\n /** The instance this plugin object serves; one plugin object serves one instance (B03). */\n readonly instance: string;\n /**\n * 'initialized' at bind; the kernel sets 'bootstrapped' in onApplicationBootstrap; close() sets 'closed'; bind() of another\n * application sets 'displaced' on an 'initialized' binding it takes over.\n */\n state: \"initialized\" | \"bootstrapped\" | \"closed\" | \"displaced\";\n /** View of the kernel's RequestScope; the plugin never owns an AsyncLocalStorage. [C] */\n current(): ScopeView | undefined;\n /** Credential header names declared by the instance's principal sources (credential matching, §7.5). */\n readonly credentialHeaders: readonly string[];\n readonly before: readonly CompiledHook[]; // sorted by order, then discovery order\n readonly after: readonly CompiledHook[];\n readonly database: Readonly<{\n [E in DatabaseHookTarget]: {\n readonly before: readonly DatabaseHookMethod<E, \"before\">[];\n readonly after: readonly DatabaseHookMethod<E, \"after\">[];\n };\n }>;\n /** Debug log when the bridge drops a direct call's cookies because its credential is foreign. */\n onDropped(path: string): void;\n}\nexport interface ScopeView {\n /** Cookie-capable forwarding handlers have already passed the enforcing form check on every method/operation (§7.10). */\n readonly cookies: CookieSink | null;\n readonly forward: \"none\" | \"same-credential\" | \"any\";\n readonly inbound: (() => Headers) | undefined;\n readonly internal: boolean;\n /**\n * Present in EVERY handler scope whose transport exposes a browser leg, unless the plan's origin check is 'off' — enforcing or not,\n * so safe methods and GraphQL queries are covered too (§7.5). Returns when this leg has a passing origin verdict for `instance`, or\n * the single kernel disable predicate (§7.10 item 4) holds; a guard run without a passing verdict is insufficient. Otherwise throws the kernel's\n * BetterAuthConfigurationError PUBLIC_HANDLER_USED_CALLER_SESSION.\n */\n readonly checkCallerSession?: (path: string, instance: string) => void;\n /** The browser leg's OWN headers (TransportCall.browser.headers()), before any transport credential mapping replaced them; undefined\n * when the transport exposes no browser leg. Entry 2 recognizes an ambiently carried session cookie with it. */\n readonly browserHeaders: (() => Headers) | undefined;\n}\nexport interface CompiledHook {\n /**\n * Evaluate the user predicate once and let it throw. The dispatcher logs and\n * converts before-hook matcher failures to APIError 500; after-hook matcher\n * failures cross the next fixed SDK matcher boundary unchanged, so the SDK\n * cannot recover them as handler APIErrors. Never swallow a failure as a\n * non-match or evaluate the predicate again in run().\n */\n matches(ctx: HookEndpointContext, scope: ScopeView | undefined): boolean;\n run(ctx: HookEndpointContext): Promise<unknown>;\n}\n"],"mappings":";AAIA,MAAa,gBAAgB,OAAO,IAAI,gCAAgC;AACxE,MAAa,uBAAuB,OAAO,IACzC,mCACF;AACA,MAAa,kBAAkB,OAAO,IACpC,yCACF"}
@@ -0,0 +1,8 @@
1
+ //#region src/bridge-protocol.ts
2
+ const BRIDGE_HANDLE = Symbol.for("@nestjs-kit/better-auth:bridge");
3
+ const EXTENSION_DEFINITION = Symbol.for("@nestjs-kit/better-auth:extension");
4
+ const UPGRADE_REQUEST = Symbol.for("@nestjs-kit/better-auth:upgrade-request");
5
+ //#endregion
6
+ export { EXTENSION_DEFINITION as n, UPGRADE_REQUEST as r, BRIDGE_HANDLE as t };
7
+
8
+ //# sourceMappingURL=bridge-protocol-c66aEkr5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-protocol-c66aEkr5.mjs","names":[],"sources":["../src/bridge-protocol.ts"],"sourcesContent":["import type { HookEndpointContext } from \"better-auth\";\nimport type { CookieSink, DatabaseHookTarget } from \"./auth-contracts.js\";\nimport type { DatabaseHookMethod } from \"./auth-types.js\";\n\nexport const BRIDGE_HANDLE = Symbol.for(\"@nestjs-kit/better-auth:bridge\");\nexport const EXTENSION_DEFINITION = Symbol.for(\n \"@nestjs-kit/better-auth:extension\",\n);\nexport const UPGRADE_REQUEST = Symbol.for(\n \"@nestjs-kit/better-auth:upgrade-request\",\n);\n\nexport interface BridgeHandle {\n readonly protocol: 4; // checked by core (B04); v5: binding state and instance, the caller-session check\n readonly clientIpHeader: string | null; // single source of truth for the header name (§6.8)\n /** 'unbound' until the first bind(); 'bound' while an application's hooks are registered; 'closed' after its shutdown, hooks still registered. */\n readonly state: \"unbound\" | \"bound\" | \"closed\";\n /** Endpoint dispatches and database-hook dispatches (writes) seen before the first binding, reset by every bind() (B26). */\n readonly unboundDispatches: number;\n /**\n * Registers the application's hooks and returns close(), which the kernel calls in onApplicationShutdown: a closed binding keeps\n * dispatching until another application binds (§10.6). A second bind() from the same owner for the same instance is a no-op that\n * returns the existing registration (NestMicroservice.init() runs lifecycle hooks twice); from the same owner for another instance it\n * throws PLUGIN_SHARED_BETWEEN_INSTANCES (B03). Throws INSTANCE_ALREADY_BOUND if another bootstrapped application is bound; takes over\n * a never-bootstrapped one (reported, B06) and a closed one (silently). A never-bootstrapped binding it takes over becomes\n * 'displaced': an application whose init() was still running when another bound fails in onApplicationBootstrap (B06).\n */\n bind(binding: BridgeBinding): { close(): void; tookOverFrom?: string };\n /** true when an endpoint returned `value` (an object) in a non-router dispatch observed while bound; false for before-hook short-circuits (LEAD-V37). */\n producedByEndpoint(value: unknown): boolean;\n}\nexport interface BridgeBinding {\n /** The application: compared by identity for the same-owner no-op; `description` goes into the B06 message. */\n readonly owner: { readonly description: string };\n /** The instance this plugin object serves; one plugin object serves one instance (B03). */\n readonly instance: string;\n /**\n * 'initialized' at bind; the kernel sets 'bootstrapped' in onApplicationBootstrap; close() sets 'closed'; bind() of another\n * application sets 'displaced' on an 'initialized' binding it takes over.\n */\n state: \"initialized\" | \"bootstrapped\" | \"closed\" | \"displaced\";\n /** View of the kernel's RequestScope; the plugin never owns an AsyncLocalStorage. [C] */\n current(): ScopeView | undefined;\n /** Credential header names declared by the instance's principal sources (credential matching, §7.5). */\n readonly credentialHeaders: readonly string[];\n readonly before: readonly CompiledHook[]; // sorted by order, then discovery order\n readonly after: readonly CompiledHook[];\n readonly database: Readonly<{\n [E in DatabaseHookTarget]: {\n readonly before: readonly DatabaseHookMethod<E, \"before\">[];\n readonly after: readonly DatabaseHookMethod<E, \"after\">[];\n };\n }>;\n /** Debug log when the bridge drops a direct call's cookies because its credential is foreign. */\n onDropped(path: string): void;\n}\nexport interface ScopeView {\n /** Cookie-capable forwarding handlers have already passed the enforcing form check on every method/operation (§7.10). */\n readonly cookies: CookieSink | null;\n readonly forward: \"none\" | \"same-credential\" | \"any\";\n readonly inbound: (() => Headers) | undefined;\n readonly internal: boolean;\n /**\n * Present in EVERY handler scope whose transport exposes a browser leg, unless the plan's origin check is 'off' — enforcing or not,\n * so safe methods and GraphQL queries are covered too (§7.5). Returns when this leg has a passing origin verdict for `instance`, or\n * the single kernel disable predicate (§7.10 item 4) holds; a guard run without a passing verdict is insufficient. Otherwise throws the kernel's\n * BetterAuthConfigurationError PUBLIC_HANDLER_USED_CALLER_SESSION.\n */\n readonly checkCallerSession?: (path: string, instance: string) => void;\n /** The browser leg's OWN headers (TransportCall.browser.headers()), before any transport credential mapping replaced them; undefined\n * when the transport exposes no browser leg. Entry 2 recognizes an ambiently carried session cookie with it. */\n readonly browserHeaders: (() => Headers) | undefined;\n}\nexport interface CompiledHook {\n /**\n * Evaluate the user predicate once and let it throw. The dispatcher logs and\n * converts before-hook matcher failures to APIError 500; after-hook matcher\n * failures cross the next fixed SDK matcher boundary unchanged, so the SDK\n * cannot recover them as handler APIErrors. Never swallow a failure as a\n * non-match or evaluate the predicate again in run().\n */\n matches(ctx: HookEndpointContext, scope: ScopeView | undefined): boolean;\n run(ctx: HookEndpointContext): Promise<unknown>;\n}\n"],"mappings":";AAIA,MAAa,gBAAgB,OAAO,IAAI,gCAAgC;AACxE,MAAa,uBAAuB,OAAO,IACzC,mCACF;AACA,MAAa,kBAAkB,OAAO,IACpC,yCACF"}