@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,528 @@
1
+ import { An as BetterAuthService, C as ConformanceCase, Ct as AuthPrincipal, E as ConformanceSkip, I as ExtensionRef, T as ConformanceRunner, U as HttpPlatform, c as AuthTransport, it as PrincipalSource, st as RequirementExpr, w as ConformanceOutcome, xt as AuthLike } from "../auth-contracts-Brh_Qko9.cjs";
2
+ import { IncomingHttpHeaders } from "node:http";
3
+ import { INestApplication, LoggerService, Provider } from "@nestjs/common";
4
+ import { AbstractHttpAdapter, NestFactory } from "@nestjs/core";
5
+ import { BetterAuthOptions, BetterAuthPlugin } from "better-auth";
6
+ import { TestingModuleBuilder } from "@nestjs/testing";
7
+ //#region src/conformance-fixtures.d.ts
8
+ /** The trusted origin the probe plugin contributes through init(), so origin cases see the post-init set. */
9
+ export declare const PROBE_TRUSTED_ORIGIN = "https://probe-plugin.example";
10
+ /**
11
+ * The conformance kits' Better Auth probe: byte-exact echo, multi-cookie, redirect, stream, HTML, method, URL
12
+ * and IP endpoints under /probe, a before hook that counts dispatches and injects faults, an after hook that
13
+ * records refresh suppression and the Set-Cookie lines each call produced, database write counters, a storage
14
+ * instrument that counts and faults every database adapter operation, and https://probe-plugin.example as a trusted
15
+ * origin contributed through init(). Put it before nestjs() in the plugin list.
16
+ */
17
+ export declare function conformanceProbePlugin(): BetterAuthPlugin;
18
+ /**
19
+ * Better Auth's origin-check flags of a conformance instance. Both default to false, so every origin check is on; a
20
+ * caller's `options.advanced` cannot change them, only this argument can.
21
+ */
22
+ interface ConformanceAuthSettings {
23
+ /**
24
+ * Better Auth's advanced.disableOriginCheck. true skips Better Auth's own origin validation of its routes; with
25
+ * disableCSRFCheck false the library's application-route checks stay on (BA-r6-01, T-csrf-http-unsafe).
26
+ */
27
+ readonly disableOriginCheck?: boolean;
28
+ /** Better Auth's advanced.disableCSRFCheck. true switches every origin check off, the library's included. */
29
+ readonly disableCSRFCheck?: boolean;
30
+ }
31
+ /**
32
+ * A memory-adapter Better Auth instance with the settings the kits assume: origin checks explicitly on
33
+ * (advanced.disableOriginCheck: false, which vitest's TEST=true would otherwise switch off, and
34
+ * advanced.disableCSRFCheck: false, which would otherwise switch every origin check off), session.updateAge 0 so
35
+ * every session read refreshes, testUtils(), bearer(), conformanceProbePlugin() and nestjs() last. The kit settings
36
+ * win over the same options in `options`; `settings` switches the origin checks off explicitly.
37
+ */
38
+ export declare function createConformanceAuth(options?: Omit<BetterAuthOptions, "database">, settings?: ConformanceAuthSettings): AuthLike;
39
+ /**
40
+ * Register cases with a runner that has describe/it (vitest, jest, node:test). Cases are grouped by id. A case with
41
+ * `skip` registers a passing test whose name states the reason, so every unsupported capability stays visible. A case
42
+ * that skips at run time calls the runner's context.skip(reason) when the runner passes a context (Vitest, node:test);
43
+ * under Jest it passes.
44
+ */
45
+ export declare function runConformance(cases: readonly ConformanceCase[], runner: ConformanceRunner): void;
46
+ //#endregion
47
+ //#region src/conformance-http.d.ts
48
+ interface HttpConformanceOptions {
49
+ platform: ExtensionRef<HttpPlatform>;
50
+ /** Fresh Nest HTTP adapter per app, e.g. () => new ExpressAdapter(). */
51
+ createHttpAdapter(): AbstractHttpAdapter;
52
+ /** Bootstraps to exercise. Default both. */
53
+ bootstrap?: readonly ("factory" | "testing")[];
54
+ /** Enable host CORS the platform's usual way. Default: app.enableCors({ origin, credentials: true }). */
55
+ enableHostCors?(app: INestApplication, origin: string): void | Promise<void>;
56
+ /**
57
+ * Configure trust in one forwarding hop on a created application the platform's usual way, e.g. app.set('trust proxy',
58
+ * 1). The trusted-hop rows (H-ip-platform, H-proxy-trust, H-url-trust-proxy, H-proxy-untrusted-warning) need this or
59
+ * createTrustingHttpAdapter; without either they are skipped with the reason.
60
+ */
61
+ trustOneProxy?(app: INestApplication): void | Promise<void>;
62
+ /**
63
+ * A fresh adapter that already trusts one forwarding hop, for platforms whose proxy trust is fixed when the adapter is
64
+ * constructed, e.g. () => new FastifyAdapter({ trustProxy: 'loopback' }). The kit's requests come from loopback, so
65
+ * trusting loopback is trusting one hop. Trusted-hop boots use it when given, instead of createHttpAdapter plus
66
+ * trustOneProxy.
67
+ */
68
+ createTrustingHttpAdapter?(): AbstractHttpAdapter;
69
+ /**
70
+ * HTTP/2 variant, required when the platform declares capabilities.http2. Its createTrustingHttpAdapter serves the
71
+ * HTTP/2 trusted-hop rows as createTrustingHttpAdapter serves the HTTP/1.1 ones.
72
+ */
73
+ http2?: {
74
+ createHttpAdapter(): AbstractHttpAdapter;
75
+ createTrustingHttpAdapter?(): AbstractHttpAdapter;
76
+ };
77
+ /** How to obtain a base URL. Default: app.listen(0) + getUrl(). */
78
+ listen?(app: INestApplication): Promise<string>;
79
+ /**
80
+ * Transport options for the H-no-adapter microservice rows, e.g. () => ({ transport: Transport.TCP, options: { host:
81
+ * '127.0.0.1', port: 0 } }). The kit does not load the optional @nestjs/microservices peer itself; without this option
82
+ * those rows are skipped with the reason.
83
+ */
84
+ microservice?(): MicroserviceOptions;
85
+ }
86
+ /** The options NestFactory.createMicroservice() and TestingModule.createNestMicroservice() accept. */
87
+ type MicroserviceOptions = NonNullable<Parameters<typeof NestFactory.createMicroservice>[1]>;
88
+ /**
89
+ * The HTTP platform kit (invariants H1–H14). Each case boots a real Nest application per bootstrap with a real Better
90
+ * Auth instance that includes conformanceProbePlugin(), an app controller, a @BeforeAuth() hook provider, a recording
91
+ * global filter and an `around` recorder. HTTP/2 is required when the platform declares capabilities.http2. A platform
92
+ * without the capability or the optional proxyTrust(), and a harness with neither trustOneProxy nor
93
+ * createTrustingHttpAdapter for the trusted-hop rows, get a skip with the reason: before the run for platform objects,
94
+ * at run time for classes and definitions. The microservice rows of H-no-adapter need the
95
+ * `microservice` option. Production-mode rows set process.env.NODE_ENV to 'production' while they run and restore it,
96
+ * so run the cases sequentially.
97
+ */
98
+ export declare function httpPlatformConformance(options: HttpConformanceOptions): ConformanceCase[];
99
+ //#endregion
100
+ //#region src/conformance-transport.d.ts
101
+ type InvocationShape = "aliases" | "batched" | "messages" | "subscriptions";
102
+ /** One fixture handler the kit supplies; the harness exposes it as a controller route, resolver field, gateway message or message pattern. */
103
+ interface FixtureHandler {
104
+ /** Method decorators to apply, in order (access, acceptance, requirements). */
105
+ readonly decorators: readonly MethodDecorator[];
106
+ /** Parameter decorators by parameter index, e.g. [CurrentSession()]. */
107
+ readonly params: readonly ParameterDecorator[];
108
+ /** 'read': HTTP GET, GraphQL query, RPC request. 'unsafe': HTTP POST, GraphQL mutation. WS messages are always enforced. */
109
+ readonly operation: "read" | "unsafe";
110
+ /** Handler body: receives the decorated parameter values, the invocation input and the harness context; its result is the response. */
111
+ handle(params: readonly unknown[], input: Record<string, unknown>, context: FixtureContext): unknown;
112
+ }
113
+ /** What the harness hands every fixture handler. */
114
+ interface FixtureContext {
115
+ /** The default instance's service (BETTER_AUTH_SERVICE). */
116
+ readonly service: BetterAuthService;
117
+ }
118
+ /**
119
+ * One method of an abstract base class, exposed through two subclasses that carry `subclasses.public` and
120
+ * `subclasses.denied` as class decorators (T-inherited-handler). A harness without invokeInherited exposes it as a
121
+ * plain handler.
122
+ */
123
+ interface InheritedFixture extends FixtureHandler {
124
+ readonly subclasses: {
125
+ readonly public: readonly ClassDecorator[];
126
+ readonly denied: readonly ClassDecorator[];
127
+ };
128
+ }
129
+ /**
130
+ * GraphQL shapes only: one object type FixtureNode, returned by the root fields and carrying the field resolvers
131
+ * below. invokeGraph selects `publicNested` as `publicNested { id reader }` and `guarded` as
132
+ * `guarded { id principal nestedReader }`, so `reader` and `nestedReader` read the reading of their enclosing field.
133
+ */
134
+ interface GraphFixtures {
135
+ readonly roots: {
136
+ readonly public: FixtureHandler;
137
+ readonly sessionOnly: FixtureHandler;
138
+ readonly mixed: FixtureHandler;
139
+ /**
140
+ * A list root: its handler returns 20 FixtureNode items, so serve it as a list of FixtureNode (`[FixtureNode]`).
141
+ * Given only to the reader rows of T-internal-error-logged-once.
142
+ */
143
+ readonly items?: FixtureHandler;
144
+ };
145
+ readonly fields: {
146
+ readonly plain: FixtureHandler;
147
+ readonly publicNested: FixtureHandler;
148
+ readonly reader: FixtureHandler;
149
+ readonly guarded?: FixtureHandler;
150
+ readonly nestedReader?: FixtureHandler;
151
+ readonly sessionReader: FixtureHandler;
152
+ /** @ForwardAuthCookies() without access metadata: an inheriting form-mode field that signs a kit user in (T-csrf-login-proxy). */
153
+ readonly forwarding?: FixtureHandler;
154
+ /** A String field reading @ActiveOrganizationId() without a requirement that provides it (T-internal-error-logged-once). */
155
+ readonly organizationReader?: FixtureHandler;
156
+ /** A String field returning the user id of the zero-argument service.getSession() (T-internal-error-logged-once). */
157
+ readonly serviceSession?: FixtureHandler;
158
+ };
159
+ /** Federation shapes only: @ResolveReference() of FixtureNode, with the kit's per-representation requirement on `orgId`. */
160
+ readonly reference?: FixtureHandler;
161
+ /** Class decorators of the resolver class that serves the roots, the fields and the reference resolver. */
162
+ readonly classDecorators?: readonly ClassDecorator[];
163
+ }
164
+ interface GraphSelection {
165
+ readonly root: keyof GraphFixtures["roots"];
166
+ readonly fields: readonly (keyof GraphFixtures["fields"])[];
167
+ }
168
+ /**
169
+ * The fixture handlers of transportConformance, by name (the `handler` argument of invoke()). Harnesses expose each
170
+ * input field as the transport's named input, so ctx.param(name) reads input[name] (HTTP: route param or query).
171
+ * `triple` and `tripleMixed` are three distinct handler methods; invoke() runs all three in one logical request when
172
+ * the transport can, otherwise the first one.
173
+ */
174
+ interface TransportFixtures {
175
+ readonly required: FixtureHandler;
176
+ readonly optional: FixtureHandler;
177
+ readonly public: FixtureHandler;
178
+ readonly forbidden: FixtureHandler;
179
+ readonly triple: readonly [FixtureHandler, FixtureHandler, FixtureHandler];
180
+ readonly tripleMixed: readonly [FixtureHandler, FixtureHandler, FixtureHandler];
181
+ readonly readsSession: FixtureHandler;
182
+ /** @AcceptPrincipals('session', 'api-key'), returns service.getSession() (T-reads-session). */
183
+ readonly readsSessionService: FixtureHandler;
184
+ readonly unsafe: FixtureHandler;
185
+ readonly loginProxy: FixtureHandler;
186
+ /** @Public() @ForwardAuthCookies(), operation 'read' (HTTP GET), calls service.api.signInEmail (T-csrf-login-proxy, T-csrf-safe-methods). */
187
+ readonly loginProxyRead: FixtureHandler;
188
+ readonly loginProxyService: FixtureHandler;
189
+ readonly publicService: FixtureHandler;
190
+ readonly acceptsApiKey: FixtureHandler;
191
+ readonly org: FixtureHandler;
192
+ readonly inherited: InheritedFixture;
193
+ readonly unguarded: FixtureHandler;
194
+ /**
195
+ * Default access, operation 'read': a direct auth.api.getSession() call presenting the invocation's `cookie` input,
196
+ * the caller's own session cookie (T-csrf-safe-methods).
197
+ */
198
+ readonly callerSession: FixtureHandler;
199
+ /** Like callerSession, with @Public(). */
200
+ readonly publicCallerSession: FixtureHandler;
201
+ /** GraphQL shapes only; other harnesses ignore it. */
202
+ readonly graph: GraphFixtures;
203
+ }
204
+ interface TransportInvocationResult {
205
+ ok: boolean;
206
+ body?: unknown;
207
+ error?: {
208
+ code?: string;
209
+ statusCode?: number;
210
+ reason?: string;
211
+ message?: string;
212
+ };
213
+ setCookies: string[];
214
+ }
215
+ interface GraphResult {
216
+ /** The operation's data, keyed like the selection: data[root][field]. */
217
+ data: unknown;
218
+ errors: readonly {
219
+ path: readonly (string | number)[];
220
+ code?: string;
221
+ reason?: string;
222
+ message?: string;
223
+ }[];
224
+ }
225
+ interface TransportConformanceOptions {
226
+ transport: ExtensionRef<AuthTransport>;
227
+ /**
228
+ * Boots an app exposing the kit's fixture handlers in the transport's shape, with BetterAuthModule's globalGuard as
229
+ * given. Pass `principals` to BetterAuthModule (the kit's API-key source), and `defaultRequirements` and
230
+ * `globalScope` when set. With `override`, boot through Test.createTestingModule() and pass the builder through it
231
+ * before compile(). Apply every fixture decorator the kit supplies, including its SetMetadata() marker. The app is
232
+ * closed by the kit.
233
+ */
234
+ createApp(fixtures: TransportFixtures, auth: AuthLike, options: {
235
+ globalGuard: boolean;
236
+ override?: (builder: TestingModuleBuilder) => TestingModuleBuilder;
237
+ defaultRequirements?: readonly RequirementExpr[];
238
+ /**
239
+ * GraphQL shapes: the fieldResolverEnhancers to serve 'graph' with. The kit boots GraphQL cases with [] and
240
+ * ['guards', 'interceptors'], and the reader rows of T-internal-error-logged-once with ['guards', 'interceptors',
241
+ * 'filters'] and ['guards', 'filters'].
242
+ */
243
+ fieldResolverEnhancers?: readonly ("guards" | "interceptors" | "filters")[];
244
+ /** GraphQL shapes: serve 'graph' from a federation subgraph (FixtureNode an entity keyed by id, with GraphFixtures.reference when given). */
245
+ federation?: boolean;
246
+ /** Principal sources for BetterAuthModule's `principals`: the kit's API-key source. */
247
+ principals?: readonly ExtensionRef<PrincipalSource>[];
248
+ /** BetterAuthModule's globalScope; unset keeps the module default (T-coverage-claims). */
249
+ globalScope?: boolean;
250
+ /** Register BetterAuthGuard as APP_GUARD and BetterAuthScopeInterceptor as APP_INTERCEPTOR yourself (with globalGuard: false; T-coverage-claims). */
251
+ appEnhancers?: boolean;
252
+ /** The logger the app uses from boot on (e.g. createNestApplication(adapter, { logger }) or moduleRef.useLogger(logger)): cases assert boot warnings. */
253
+ logger?: LoggerService;
254
+ /** BetterAuthModule's cookies.forwardDirectCalls (T-stamp-per-plan). */
255
+ forwardDirectCalls?: boolean;
256
+ /**
257
+ * BetterAuthModule's logSummary. The kit passes true where it asserts the boot summary (T-coverage-claims); unset
258
+ * leaves the harness's choice, such as false to keep other boots quiet.
259
+ */
260
+ logSummary?: boolean;
261
+ /** GraphQL shapes: the fieldResolverCoverage of the transport this boot registers (T-stamp-per-plan). */
262
+ fieldResolverCoverage?: "warn";
263
+ /** GraphQL shapes: the GraphQL module's `context` option, one of `graphqlContexts` (T-stale-context, T-subscription-origin). */
264
+ graphqlContext?: GraphqlContextShape;
265
+ }): Promise<INestApplication>;
266
+ /** Invokes a fixture handler with given credentials and browser headers; returns the transport-native outcome. */
267
+ invoke(app: INestApplication, handler: Exclude<keyof TransportFixtures, "graph">, headers: HeadersInit, input?: Record<string, unknown>): Promise<TransportInvocationResult>;
268
+ /**
269
+ * Two invocations of the 'org' fixture in ONE logical request or connection, with different inputs. Required when
270
+ * the transport has a lineage: the multiple-invocation cases then fail without it, and are skipped with a reason
271
+ * for other transports.
272
+ */
273
+ invokeTwice?(app: INestApplication, shape: InvocationShape, inputs: [Record<string, unknown>, Record<string, unknown>], headers: HeadersInit): Promise<[{
274
+ ok: boolean;
275
+ error?: {
276
+ reason?: string;
277
+ };
278
+ }, {
279
+ ok: boolean;
280
+ error?: {
281
+ reason?: string;
282
+ };
283
+ }]>;
284
+ /** Shapes invokeTwice can produce; required with it. */
285
+ invocationShapes?: readonly InvocationShape[];
286
+ /**
287
+ * GraphQL shapes: one operation over HTTP selecting the given root fields of fixtures.graph, each with the given
288
+ * FixtureNode fields. `delays` states the order in which the kit's session and API-key sources settle; the kit
289
+ * applies it to its own sources, so a harness may ignore it. Required when the transport nests handlers
290
+ * (defaultAccessFor): the GraphQL cases then fail without it, and are skipped with a reason for other transports.
291
+ */
292
+ invokeGraph?(app: INestApplication, selection: readonly GraphSelection[], headers: HeadersInit, options?: {
293
+ delays?: {
294
+ readonly session: number;
295
+ readonly apiKey: number;
296
+ };
297
+ }): Promise<GraphResult>;
298
+ /**
299
+ * Federation shapes only: one `_entities` query for the given representations of FixtureNode. Required when the
300
+ * transport claims the kit's reference resolver in a federation boot: T-reference-resolver then fails without it,
301
+ * and is skipped with a reason for other transports.
302
+ */
303
+ invokeEntities?(app: INestApplication, representations: readonly Record<string, unknown>[], fields: readonly (keyof GraphFixtures["fields"])[], headers: HeadersInit): Promise<GraphResult>;
304
+ /**
305
+ * Connection shapes (WebSocket gateways): opens ONE connection whose handshake carries `headers`, sends one message to
306
+ * each given fixture handler on it in order, each after the previous one answered, closes the connection and returns
307
+ * every outcome once the server has observed the close (T-stale-context runs a later caller after it). Required when
308
+ * the transport's browser leg is its connection's handshake: the T-ws-origin-* cases then fail without it, and are
309
+ * skipped with a reason for other transports.
310
+ */
311
+ invokeConnection?(app: INestApplication, handlers: readonly Exclude<keyof TransportFixtures, "graph">[], headers: HeadersInit, options?: {
312
+ /**
313
+ * Values the connection sends in its init payload (graphql-ws connection_init) instead of the handshake's credential
314
+ * headers; given only when `invocationShapes` includes 'subscriptions'.
315
+ */
316
+ readonly connectionParams?: Readonly<Record<string, string>>;
317
+ }): Promise<TransportInvocationResult[]>;
318
+ /**
319
+ * Invokes `fixtures.inherited` through the subclass that carries `subclasses[subclass]`. Without it T-inherited-handler
320
+ * is skipped with a reason: a transport that addresses handlers by a name that one inherited method shares across
321
+ * subclasses (an RPC pattern, a GraphQL root field) cannot expose it twice.
322
+ */
323
+ invokeInherited?(app: INestApplication, subclass: "public" | "denied", headers: HeadersInit): Promise<TransportInvocationResult>;
324
+ /**
325
+ * GraphQL shapes: the `graphqlContext` values createApp honours. T-stale-context needs 'static' and 'cached' and fails
326
+ * without them when the transport nests handlers; the custom-context rows of T-subscription-origin run for 'fresh' and
327
+ * 'plain-request' when listed.
328
+ */
329
+ graphqlContexts?: readonly GraphqlContextShape[];
330
+ /**
331
+ * Connection shapes: authenticates one connection whose handshake carries `headers` through the app's connection-time
332
+ * authentication (WS_CONNECTION_AUTH), requiring a principal: `ok` when one authenticates, otherwise the failure
333
+ * (401 without credentials). Required when the app provides WS_CONNECTION_AUTH: the T-ws-origin-* cases then fail
334
+ * without it.
335
+ */
336
+ authenticateConnection?(app: INestApplication, headers: HeadersInit): Promise<ConnectionAuthenticationResult>;
337
+ expectCookieCapable: boolean;
338
+ /**
339
+ * Whether the transport describes a browser leg (false for RPC; T-selection fails a false claim). A leg that follows each
340
+ * operation enables the T-csrf-* cases; a leg that is the connection's handshake, shared by the connection's messages and
341
+ * enforced on every one, enables the T-ws-origin-* cases instead. The kit reads which from the transport.
342
+ */
343
+ expectBrowserLeg: boolean;
344
+ }
345
+ /**
346
+ * The GraphQL module's `context` option of a boot: 'fresh' is a function returning a new object that keeps what the driver
347
+ * passes it (the native request, the graphql-ws context); 'plain-request' a function returning a new object whose `req` is a
348
+ * plain object holding only the native request's cookie header; 'cached' a function returning the object it built on its
349
+ * first call; 'static' an object.
350
+ */
351
+ type GraphqlContextShape = "fresh" | "plain-request" | "cached" | "static";
352
+ /** The outcome of connection-time authentication (authenticateConnection). */
353
+ interface ConnectionAuthenticationResult {
354
+ ok: boolean;
355
+ error?: TransportInvocationResult["error"];
356
+ }
357
+ /**
358
+ * The transport kit (invariants T1–T11 and the core behavior every transport exposes). The kit owns the Better Auth
359
+ * instance, a kit API-key source (passed as `principals`), kit policies and the fixture handlers; the harness exposes
360
+ * the fixtures in its transport's shape. Applicability comes from the transport, not from the helpers a harness
361
+ * passes: a transport with a lineage needs invokeTwice, one that nests handlers (defaultAccessFor) needs invokeGraph,
362
+ * and one that claims the kit's federation reference resolver needs invokeEntities. The kit reads those members from
363
+ * a transport object directly and boots once for a class or a definition.
364
+ */
365
+ export declare function transportConformance(options: TransportConformanceOptions): ConformanceCase[];
366
+ //#endregion
367
+ //#region src/conformance-policy-harness.d.ts
368
+ interface PolicyConformanceOptions {
369
+ /**
370
+ * The requirement to judge. Its policies must be policy objects: the kit boots no application providers, so a class
371
+ * or token reference cannot resolve. For a DI policy, pass an instance built with its dependencies (new MyPolicy(deps)).
372
+ */
373
+ requirement: RequirementExpr;
374
+ /**
375
+ * The Better Auth instance the principals belong to. It must include conformanceProbePlugin(), testUtils(), the
376
+ * policy's plugins and nestjs(): createConformanceAuth({ plugins }) builds one. Session principals are judged with
377
+ * real session headers for their user (testUtils().getAuthHeaders). Unit-specific cases use the instance's plugins
378
+ * when present: session.cookieCache for the warm-cache variants, apiKey({ enableSessionForAPIKeys: true }) for the
379
+ * API-key session and quota cases; each states the reason when it skips.
380
+ */
381
+ auth: AuthLike;
382
+ allowingPrincipal(): Promise<AuthPrincipal>;
383
+ denyingPrincipal(): Promise<AuthPrincipal>;
384
+ delegatedPrincipal?(): Promise<AuthPrincipal>;
385
+ /**
386
+ * Principal sources the kit registers besides the built-in session source, for the requirement's other principal kinds
387
+ * (e.g. apiKeyPrincipal()). Cases that send a request through the guard resolve those kinds with them; without them
388
+ * the kit registers placeholder sources that resolve nothing.
389
+ */
390
+ sources?: readonly ExtensionRef<PrincipalSource>[];
391
+ /**
392
+ * Transports to deliver the transport-specific rows through, besides the kit's in-process request: each delivery adds
393
+ * its own variants of Z-admin-banned (connection deliveries with a principal TTL), Z-admin-rejects-api-key-session,
394
+ * Z-apikey-quota-per-request and Z-org-ref-types, titled with its name.
395
+ */
396
+ deliveries?: readonly PolicyDelivery[];
397
+ /**
398
+ * Builds the instances the kit needs in another configuration (adminUserIds, customSession shapes, a dynamic baseURL,
399
+ * an instance without apiKey()) with exactly the given overrides, on the storage under test. It must add what
400
+ * createConformanceAuth() adds (testUtils(), bearer(), conformanceProbePlugin(), nestjs(), an explicit
401
+ * advanced.disableOriginCheck: false and session.updateAge 0) and have its schema migrated. Default:
402
+ * createConformanceAuth(overrides), on the memory adapter.
403
+ */
404
+ variant?(overrides: Omit<BetterAuthOptions, "database">): AuthLike | Promise<AuthLike>;
405
+ }
406
+ /**
407
+ * A transport the policy kit delivers its transport-specific rows through (design v7 §14.1). Build it from the harness
408
+ * of a transportConformance run: it exposes the kit's handlers the way that harness exposes the transport kit's fixtures.
409
+ */
410
+ interface PolicyDelivery {
411
+ /** The transport's name in case titles, e.g. 'Socket.IO'. */
412
+ readonly name: string;
413
+ /**
414
+ * Boots an app with BetterAuthModule's globalGuard that exposes each handler under its name in the transport's shape:
415
+ * a gateway message with explicit coverage, a message pattern or a GraphQL query field, plus the subscription field
416
+ * that connect()'s operations select on a GraphQL socket. Apply the handler's decorators like transportConformance's
417
+ * createApp does. The kit's only named input is `orgId`: pass its value through with its JSON type (a GraphQL
418
+ * harness declares a JSON scalar argument), so ctx.param('orgId') reads it unchanged. Pass `principals` to
419
+ * BetterAuthModule and use `logger` from boot on. The kit closes the app.
420
+ */
421
+ createApp(handlers: Readonly<Record<string, FixtureHandler>>, auth: AuthLike, options: {
422
+ readonly principals: readonly ExtensionRef<PrincipalSource>[];
423
+ readonly logger: LoggerService;
424
+ }): Promise<INestApplication>;
425
+ /**
426
+ * One logical request to a handler with the given headers: a message on its own connection, an RPC request, an
427
+ * operation. The kit's headers carry the probe plugin's trusted Origin, as a browser on a trusted page sends it.
428
+ */
429
+ invoke(app: INestApplication, handler: string, headers: HeadersInit, input?: Record<string, unknown>): Promise<TransportInvocationResult>;
430
+ /**
431
+ * Connection deliveries (WebSocket gateways, graphql-ws): opens one connection whose handshake carries `headers`.
432
+ * Its invoke() sends one message, or one subscription operation for GraphQL, after the previous one answered.
433
+ */
434
+ connect?(app: INestApplication, headers: HeadersInit): Promise<PolicyDeliveryConnection>;
435
+ /**
436
+ * The principal TTL of connect()'s connections: the transport's principalTtlMs or subscriptionPrincipalTtlMs. The
437
+ * connection variant of Z-admin-banned runs when it is positive, and checks that the connection reuses its principal.
438
+ */
439
+ readonly connectionPrincipalTtlMs?: number;
440
+ }
441
+ /** One connection of a PolicyDelivery. */
442
+ interface PolicyDeliveryConnection {
443
+ invoke(handler: string, input?: Record<string, unknown>): Promise<TransportInvocationResult>;
444
+ close(): Promise<void>;
445
+ }
446
+ //#endregion
447
+ //#region src/conformance-policy.d.ts
448
+ /**
449
+ * The authorization-policy kit (invariants Z1–Z6 and the unit-specific rows of design §14.1). Each principal is judged
450
+ * through the real AuthorizationEvaluator, so the delegation gate, error normalization and the per-invocation
451
+ * decision memo apply exactly as in the guard; an infrastructure error thrown here is the guard's 5xx. Cases that
452
+ * need route planning, acceptance or principal resolution send an in-process request through the real
453
+ * BetterAuthGuard. Storage outages are injected into the instance's database adapter, so an endpoint that swallows a
454
+ * storage error into a 401 is exercised; APIError mapping uses the probe plugin's before hook. Requirements must name
455
+ * policy objects (see PolicyConformanceOptions.requirement). Unit-specific cases run when the requirement contains
456
+ * the built-in admin, organization or API-key policy and skip with the reason otherwise.
457
+ */
458
+ export declare function policyConformance(options: PolicyConformanceOptions): ConformanceCase[];
459
+ //#endregion
460
+ //#region src/conformance-principal.d.ts
461
+ /** An API key the kit's S-apikey-* cases created, and the request headers that present it. */
462
+ interface ConformanceApiKey {
463
+ /** The key's record id, which the kit uses to disable or expire the key through the database adapter. */
464
+ readonly id: string;
465
+ readonly headers: Headers;
466
+ }
467
+ /** Real HTTP delivery for the HTTP-route rows of S-cookie-forwarded and S-infra-throws and the cookie-bridge cases (S-bridge-*). */
468
+ interface PrincipalHttpConformanceOptions {
469
+ platform: ExtensionRef<HttpPlatform>;
470
+ /** Fresh Nest HTTP adapter per app, e.g. () => new ExpressAdapter(). */
471
+ createHttpAdapter(): AbstractHttpAdapter;
472
+ /** How to obtain a base URL. Default: app.listen(0, '127.0.0.1') + getUrl(). */
473
+ listen?(app: INestApplication): Promise<string>;
474
+ }
475
+ interface PrincipalSourceConformanceOptions {
476
+ /**
477
+ * The source under test. Pass a factory reference (defineExtension({ use: { useFactory } })) when the source keeps
478
+ * per-instance state across requests, such as the API-key outage probe or a JWT key cache: every case boots its
479
+ * own module, and a factory gives each case a fresh source.
480
+ */
481
+ source: ExtensionRef<PrincipalSource>;
482
+ /**
483
+ * The Better Auth instance the credentials belong to. It must include conformanceProbePlugin(), testUtils() and
484
+ * nestjs(), with session.updateAge 0 and session refresh enabled, so every session read produces a refresh
485
+ * Set-Cookie: createConformanceAuth({ plugins }) builds one. The kit fails with CONFORMANCE_SESSION_REFRESH otherwise.
486
+ */
487
+ auth: AuthLike;
488
+ credentials: {
489
+ /**
490
+ * A fresh valid credential of `auth`: the options' instance, or a variant() instance (S-dynamic-base-url). Variant
491
+ * instances have a dynamic baseURL without fallback that allows localhost:3000 (the kit base URL's host) and
492
+ * public.example, so an auth.api call that creates the credential must pass headers with one of those hosts.
493
+ */
494
+ valid(auth: AuthLike): Promise<Headers>;
495
+ invalid(): Headers;
496
+ rateLimited?(auth: AuthLike): Promise<Headers>;
497
+ /**
498
+ * S-apikey-*: creates a key with these extra createApiKey body fields (remaining, rateLimitEnabled, ...).
499
+ * Default: a key of a new kit user through auth.api.createApiKey, presented in the source's first credential header.
500
+ */
501
+ apiKey?(auth: AuthLike, fields: Readonly<Record<string, unknown>>): Promise<ConformanceApiKey>;
502
+ /** S-apikey-org-key: an organization-owned key (references: 'organization'). The case skips without it. */
503
+ organizationKey?(auth: AuthLike): Promise<Headers>;
504
+ };
505
+ /**
506
+ * S-dynamic-base-url: another instance of the same configuration with the kit's overrides (a dynamic baseURL,
507
+ * trusted proxy headers). Default: createConformanceAuth({ ...overrides, plugins }) with the plugins of `auth`
508
+ * other than the kit's own; pass variant() when those plugin objects keep per-instance state.
509
+ */
510
+ variant?(overrides: Omit<BetterAuthOptions, "database">): AuthLike;
511
+ /**
512
+ * Boots a guarded route and the cookie-bridge routes on this HTTP platform for the HTTP-route rows of
513
+ * S-cookie-forwarded and S-infra-throws and for S-bridge-*. Those cases skip without it.
514
+ */
515
+ http?: PrincipalHttpConformanceOptions;
516
+ }
517
+ /**
518
+ * The principal-source kit (invariants P1–P7 and the unit-specific rows of design v7 §14.1). It resolves the source
519
+ * directly inside the resolver's chain scope, so a source that throws for invalid credentials fails
520
+ * S-rejected-not-thrown although core would normalize the throw at runtime; S-log-redaction resolves through the real
521
+ * principal resolver. Storage faults are injected into the instance's database adapter, below every endpoint and
522
+ * every direct adapter read, so endpoints that swallow storage errors are exercised too. A case that does not apply to
523
+ * the source (an API-key row for a session source, say) skips with the reason.
524
+ */
525
+ export declare function principalSourceConformance(options: PrincipalSourceConformanceOptions): ConformanceCase[];
526
+ //#endregion
527
+ export type { ConformanceApiKey, ConformanceAuthSettings, ConformanceCase, ConformanceOutcome, ConformanceRunner, ConformanceSkip, ConnectionAuthenticationResult, FixtureContext, FixtureHandler, GraphFixtures, GraphResult, GraphSelection, GraphqlContextShape, HttpConformanceOptions, InheritedFixture, InvocationShape, PolicyConformanceOptions, PolicyDelivery, PolicyDeliveryConnection, PrincipalHttpConformanceOptions, PrincipalSourceConformanceOptions, TransportConformanceOptions, TransportFixtures, TransportInvocationResult };
528
+ //# sourceMappingURL=conformance.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance.d.cts","names":[],"sources":["../../src/conformance-fixtures.ts","../../src/conformance-http.ts","../../src/conformance-transport.ts","../../src/conformance-policy-harness.ts","../../src/conformance-policy.ts","../../src/conformance-principal.ts"],"mappings":"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"}