@stratal/framework 0.0.16 → 0.0.18
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.
- package/README.md +4 -0
- package/dist/auth/index.d.mts +12 -9
- package/dist/auth/index.d.mts.map +1 -1
- package/dist/auth/index.mjs +32 -17
- package/dist/auth/index.mjs.map +1 -1
- package/dist/{auth-context-CV3Ko1ew.mjs → auth-context-BfekHvM9.mjs} +2 -2
- package/dist/{auth-context-CV3Ko1ew.mjs.map → auth-context-BfekHvM9.mjs.map} +1 -1
- package/dist/context/index.mjs +1 -1
- package/dist/database/index.d.mts +2 -2
- package/dist/database/index.mjs +129 -4
- package/dist/database/index.mjs.map +1 -1
- package/dist/{decorate-RSane8dy.mjs → decorate-C12QolJF.mjs} +1 -1
- package/dist/{decorateMetadata-CETItPez.mjs → decorateMetadata-rWbWGUuO.mjs} +1 -1
- package/dist/{decorateParam-CcTvpNsw.mjs → decorateParam-WGqsyT5s.mjs} +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/guards/index.mjs +4 -4
- package/dist/{index-Dlg8mNjq.d.mts → index-B1iGBJcO.d.mts} +216 -142
- package/dist/index-B1iGBJcO.d.mts.map +1 -0
- package/dist/rbac/index.mjs +3 -3
- package/package.json +19 -19
- package/dist/index-Dlg8mNjq.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -51,6 +51,10 @@ Stratal provides [Agent Skills](https://agentskills.io) for AI coding assistants
|
|
|
51
51
|
npx skills add strataljs/stratal
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
| Skill | Description |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `stratal` | Build Cloudflare Workers apps with the Stratal framework — modules, DI, controllers, routing, OpenAPI, queues, cron, events, seeders, CLI, auth, database, RBAC, testing, and more |
|
|
57
|
+
|
|
54
58
|
## Quick Start
|
|
55
59
|
|
|
56
60
|
```typescript
|
package/dist/auth/index.d.mts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { AsyncModuleOptions, DynamicModule } from "stratal/module";
|
|
2
2
|
import { ApplicationError } from "stratal/errors";
|
|
3
|
+
import { LoggerService } from "stratal/logger";
|
|
3
4
|
import { Auth, BetterAuthOptions } from "better-auth";
|
|
4
5
|
import { APIError } from "better-auth/api";
|
|
5
|
-
import {
|
|
6
|
-
import { Middleware, RouterContext } from "stratal/router";
|
|
6
|
+
import { Middleware, Next, RouteConfigurable, Router, RouterContext } from "stratal/router";
|
|
7
7
|
|
|
8
8
|
//#region src/auth/auth.module.d.ts
|
|
9
|
-
declare class AuthModule implements
|
|
9
|
+
declare class AuthModule implements RouteConfigurable {
|
|
10
10
|
/**
|
|
11
|
-
* Configure auth middleware.
|
|
11
|
+
* Configure auth middleware globally.
|
|
12
12
|
*
|
|
13
13
|
* Registers middlewares in order:
|
|
14
14
|
* 1. AuthContextMiddleware - Creates and registers AuthContext in request container
|
|
15
15
|
* 2. SessionVerificationMiddleware - Verifies session and populates AuthContext with userId
|
|
16
16
|
*/
|
|
17
|
-
|
|
17
|
+
configureRoutes(router: Router): void;
|
|
18
18
|
/**
|
|
19
19
|
* Configure AuthModule with async options factory
|
|
20
20
|
*/
|
|
@@ -125,7 +125,7 @@ declare class VerificationFailedError extends ApplicationError {
|
|
|
125
125
|
* that depends on AuthContext.
|
|
126
126
|
*/
|
|
127
127
|
declare class AuthContextMiddleware implements Middleware {
|
|
128
|
-
handle(ctx: RouterContext, next:
|
|
128
|
+
handle(ctx: RouterContext, next: Next): Promise<void>;
|
|
129
129
|
}
|
|
130
130
|
//#endregion
|
|
131
131
|
//#region src/auth/services/auth.service.d.ts
|
|
@@ -173,8 +173,9 @@ declare class AuthService<TOptions extends BetterAuthOptions = BetterAuthOptions
|
|
|
173
173
|
*/
|
|
174
174
|
declare class SessionVerificationMiddleware implements Middleware {
|
|
175
175
|
private readonly authService;
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
private logger;
|
|
177
|
+
constructor(authService: AuthService, logger: LoggerService);
|
|
178
|
+
handle(ctx: RouterContext, next: Next): Promise<void>;
|
|
178
179
|
}
|
|
179
180
|
//#endregion
|
|
180
181
|
//#region src/auth/utils/auth-helpers.d.ts
|
|
@@ -194,7 +195,9 @@ declare const wrapBetterAuth: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
|
194
195
|
*/
|
|
195
196
|
declare function mapBetterAuthError(error: APIError): ApplicationError;
|
|
196
197
|
/**
|
|
197
|
-
* Type guard to check if an error is a Better Auth APIError
|
|
198
|
+
* Type guard to check if an error is a Better Auth APIError.
|
|
199
|
+
* Uses duck typing to handle bundler environments (e.g. Vite)
|
|
200
|
+
* where instanceof may fail across module boundaries.
|
|
198
201
|
*/
|
|
199
202
|
declare function isAPIError(error: unknown): error is APIError;
|
|
200
203
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/auth/auth.module.ts","../../src/auth/auth.tokens.ts","../../src/auth/errors/auth-errors.ts","../../src/auth/errors/invalid-token.error.ts","../../src/auth/errors/token-required.error.ts","../../src/auth/errors/verification-failed.error.ts","../../src/auth/middleware/auth-context.middleware.ts","../../src/auth/services/auth.service.ts","../../src/auth/middleware/session-verification.middleware.ts","../../src/auth/utils/auth-helpers.ts","../../src/auth/utils/better-auth-error-handler.ts"],"mappings":";;;;;;;;cAgCa,UAAA,YAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/auth/auth.module.ts","../../src/auth/auth.tokens.ts","../../src/auth/errors/auth-errors.ts","../../src/auth/errors/invalid-token.error.ts","../../src/auth/errors/token-required.error.ts","../../src/auth/errors/verification-failed.error.ts","../../src/auth/middleware/auth-context.middleware.ts","../../src/auth/services/auth.service.ts","../../src/auth/middleware/session-verification.middleware.ts","../../src/auth/utils/auth-helpers.ts","../../src/auth/utils/better-auth-error-handler.ts"],"mappings":"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"}
|
package/dist/auth/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import "../
|
|
2
|
-
import { t as
|
|
3
|
-
import { t as
|
|
4
|
-
import { t as
|
|
5
|
-
import { t as __decorateParam } from "../decorateParam-CcTvpNsw.mjs";
|
|
1
|
+
import { t as __decorate } from "../decorate-C12QolJF.mjs";
|
|
2
|
+
import { t as AuthContext } from "../auth-context-BfekHvM9.mjs";
|
|
3
|
+
import { t as __decorateMetadata } from "../decorateMetadata-rWbWGUuO.mjs";
|
|
4
|
+
import { t as __decorateParam } from "../decorateParam-WGqsyT5s.mjs";
|
|
6
5
|
import { Module } from "stratal/module";
|
|
7
6
|
import { DI_TOKENS, Transient } from "stratal/di";
|
|
8
7
|
import { ApplicationError, ERROR_CODES, InternalError } from "stratal/errors";
|
|
8
|
+
import { LOGGER_TOKENS } from "stratal/logger";
|
|
9
9
|
import { inject } from "tsyringe";
|
|
10
10
|
import { betterAuth } from "better-auth";
|
|
11
11
|
import { APIError } from "better-auth/api";
|
|
@@ -28,19 +28,26 @@ AuthContextMiddleware = __decorate([Transient()], AuthContextMiddleware);
|
|
|
28
28
|
//#endregion
|
|
29
29
|
//#region src/auth/middleware/session-verification.middleware.ts
|
|
30
30
|
let SessionVerificationMiddleware = class SessionVerificationMiddleware {
|
|
31
|
-
constructor(authService) {
|
|
31
|
+
constructor(authService, logger) {
|
|
32
32
|
this.authService = authService;
|
|
33
|
+
this.logger = logger;
|
|
33
34
|
}
|
|
34
35
|
async handle(ctx, next) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
try {
|
|
37
|
+
const session = await this.authService.auth.api.getSession({ headers: ctx.c.req.raw.headers });
|
|
38
|
+
if (session) ctx.getContainer().resolve(DI_TOKENS.AuthContext).setAuthContext({ userId: session.user.id });
|
|
39
|
+
await next();
|
|
40
|
+
} catch (error) {
|
|
41
|
+
this.logger.debug("Session validation failed (e.g., invalidated in DB)", { error });
|
|
42
|
+
await next();
|
|
43
|
+
}
|
|
38
44
|
}
|
|
39
45
|
};
|
|
40
46
|
SessionVerificationMiddleware = __decorate([
|
|
41
47
|
Transient(),
|
|
42
48
|
__decorateParam(0, inject(AUTH_SERVICE)),
|
|
43
|
-
|
|
49
|
+
__decorateParam(1, inject(LOGGER_TOKENS.LoggerService)),
|
|
50
|
+
__decorateMetadata("design:paramtypes", [Object, Object])
|
|
44
51
|
], SessionVerificationMiddleware);
|
|
45
52
|
//#endregion
|
|
46
53
|
//#region src/auth/errors/auth-errors.ts
|
|
@@ -193,7 +200,13 @@ var VerificationFailedError = class extends ApplicationError {
|
|
|
193
200
|
function mapBetterAuthError(error) {
|
|
194
201
|
const errorCode = error.body?.code;
|
|
195
202
|
if (error.status === "FOUND") {
|
|
196
|
-
|
|
203
|
+
const location = error.headers.get("location") ?? "";
|
|
204
|
+
if (location.includes("INVALID_TOKEN")) return new InvalidTokenError();
|
|
205
|
+
if (location.includes("EXPIRED_TOKEN")) return new TokenExpiredError();
|
|
206
|
+
if (location.includes("ATTEMPTS_EXCEEDED")) return new InvalidTokenError();
|
|
207
|
+
if (location.includes("new_user_signup_disabled")) return new UserNotFoundError();
|
|
208
|
+
if (location.includes("failed_to_create_user")) return new FailedToCreateUserError();
|
|
209
|
+
if (location.includes("failed_to_create_session")) return new FailedToCreateSessionError();
|
|
197
210
|
}
|
|
198
211
|
if (!errorCode) return new InternalError({
|
|
199
212
|
originalError: `Better Auth error: ${error.message}`,
|
|
@@ -230,10 +243,13 @@ function mapBetterAuthError(error) {
|
|
|
230
243
|
});
|
|
231
244
|
}
|
|
232
245
|
/**
|
|
233
|
-
* Type guard to check if an error is a Better Auth APIError
|
|
246
|
+
* Type guard to check if an error is a Better Auth APIError.
|
|
247
|
+
* Uses duck typing to handle bundler environments (e.g. Vite)
|
|
248
|
+
* where instanceof may fail across module boundaries.
|
|
234
249
|
*/
|
|
235
250
|
function isAPIError(error) {
|
|
236
|
-
|
|
251
|
+
if (error instanceof APIError) return true;
|
|
252
|
+
return error instanceof Error && error.name === "APIError" && "status" in error && "statusCode" in error;
|
|
237
253
|
}
|
|
238
254
|
//#endregion
|
|
239
255
|
//#region src/auth/utils/auth-helpers.ts
|
|
@@ -289,15 +305,14 @@ AuthService = __decorate([
|
|
|
289
305
|
var _AuthModule;
|
|
290
306
|
let AuthModule = _AuthModule = class AuthModule {
|
|
291
307
|
/**
|
|
292
|
-
* Configure auth middleware.
|
|
308
|
+
* Configure auth middleware globally.
|
|
293
309
|
*
|
|
294
310
|
* Registers middlewares in order:
|
|
295
311
|
* 1. AuthContextMiddleware - Creates and registers AuthContext in request container
|
|
296
312
|
* 2. SessionVerificationMiddleware - Verifies session and populates AuthContext with userId
|
|
297
313
|
*/
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
consumer.apply(SessionVerificationMiddleware).forRoutes("*");
|
|
314
|
+
configureRoutes(router) {
|
|
315
|
+
router.use(AuthContextMiddleware, SessionVerificationMiddleware);
|
|
301
316
|
}
|
|
302
317
|
/**
|
|
303
318
|
* Configure AuthModule with async options factory
|
package/dist/auth/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/auth/auth.tokens.ts","../../src/auth/middleware/auth-context.middleware.ts","../../src/auth/middleware/session-verification.middleware.ts","../../src/auth/errors/auth-errors.ts","../../src/auth/errors/invalid-token.error.ts","../../src/auth/errors/token-required.error.ts","../../src/auth/errors/verification-failed.error.ts","../../src/auth/utils/better-auth-error-handler.ts","../../src/auth/utils/auth-helpers.ts","../../src/auth/services/auth.service.ts","../../src/auth/auth.module.ts"],"sourcesContent":["/** Token for AuthService - core authentication service */\nexport const AUTH_SERVICE = Symbol.for('stratal:auth:service')\n\n/** Token for Better Auth options configuration */\nexport const AUTH_OPTIONS = Symbol.for('stratal:auth:options')\n","import { Transient, DI_TOKENS } from 'stratal/di'\nimport type { Middleware, RouterContext } from 'stratal/router'\nimport { AuthContext } from '../../context/auth-context'\n\n/**\n * Auth Context Middleware\n *\n * Registers AuthContext in the request container at the start of each request.\n * This MUST run before SessionVerificationMiddleware and any other middleware\n * that depends on AuthContext.\n */\n@Transient()\nexport class AuthContextMiddleware implements Middleware {\n async handle(ctx: RouterContext, next: () => Promise<void>): Promise<void> {\n const requestContainer = ctx.getContainer()\n\n const authContext = new AuthContext()\n requestContainer.registerValue(DI_TOKENS.AuthContext, authContext)\n\n await next()\n }\n}\n","import { inject } from 'tsyringe'\nimport { Transient, DI_TOKENS } from 'stratal/di'\nimport type { Middleware, RouterContext } from 'stratal/router'\nimport { AuthContext } from '../../context/auth-context'\nimport { AUTH_SERVICE } from '../auth.tokens'\nimport type { AuthService } from '../services/auth.service'\n\n/**\n * Session Verification Middleware\n *\n * Verifies user session via Better Auth and populates AuthContext with userId.\n *\n * **Responsibilities:**\n * - Calls Better Auth's getSession() API\n * - Populates AuthContext with userId if session is valid\n * - Continues request chain regardless of session status\n */\n@Transient()\nexport class SessionVerificationMiddleware implements Middleware {\n constructor(\n @inject(AUTH_SERVICE)\n private readonly authService: AuthService\n ) {}\n\n async handle(ctx: RouterContext, next: () => Promise<void>): Promise<void> {\n const session = await this.authService.auth.api.getSession({\n headers: ctx.c.req.raw.headers\n })\n\n if (session) {\n const authContext = ctx.getContainer().resolve<AuthContext>(DI_TOKENS.AuthContext)\n authContext.setAuthContext({ userId: session.user.id })\n }\n\n await next()\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class UserNotFoundError extends ApplicationError {\n constructor(email?: string) {\n super('errors.auth.userNotFound', ERROR_CODES.RESOURCE.NOT_FOUND, email ? { email } : undefined)\n }\n}\n\nexport class InvalidCredentialsError extends ApplicationError {\n constructor() {\n super('errors.auth.invalidCredentials', ERROR_CODES.AUTH.INVALID_CREDENTIALS)\n }\n}\n\nexport class InvalidPasswordError extends ApplicationError {\n constructor() {\n super('errors.auth.invalidPassword', ERROR_CODES.AUTH.INVALID_CREDENTIALS)\n }\n}\n\nexport class InvalidEmailError extends ApplicationError {\n constructor(email?: string) {\n super('errors.auth.invalidEmail', ERROR_CODES.VALIDATION.INVALID_FORMAT, email ? { email } : undefined)\n }\n}\n\nexport class SessionExpiredError extends ApplicationError {\n constructor() {\n super('errors.auth.sessionExpired', ERROR_CODES.AUTH.SESSION_EXPIRED)\n }\n}\n\nexport class EmailNotVerifiedError extends ApplicationError {\n constructor(email?: string) {\n super('errors.auth.emailNotVerified', ERROR_CODES.AUTH.EMAIL_NOT_VERIFIED, email ? { email } : undefined)\n }\n}\n\nexport class PasswordTooShortError extends ApplicationError {\n constructor(minLength: number) {\n super('errors.auth.passwordTooShort', ERROR_CODES.AUTH.PASSWORD_TOO_SHORT, { minLength })\n }\n}\n\nexport class PasswordTooLongError extends ApplicationError {\n constructor(maxLength: number) {\n super('errors.auth.passwordTooLong', ERROR_CODES.AUTH.PASSWORD_TOO_LONG, { maxLength })\n }\n}\n\nexport class AccountAlreadyExistsError extends ApplicationError {\n constructor(email?: string) {\n super('errors.auth.accountAlreadyExists', ERROR_CODES.AUTH.ACCOUNT_ALREADY_EXISTS, email ? { email } : undefined)\n }\n}\n\nexport class FailedToCreateUserError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToCreateUser', ERROR_CODES.AUTH.FAILED_TO_CREATE_USER, reason ? { reason } : undefined)\n }\n}\n\nexport class FailedToCreateSessionError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToCreateSession', ERROR_CODES.AUTH.FAILED_TO_CREATE_SESSION, reason ? { reason } : undefined)\n }\n}\n\nexport class FailedToUpdateUserError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToUpdateUser', ERROR_CODES.AUTH.FAILED_TO_UPDATE_USER, reason ? { reason } : undefined)\n }\n}\n\nexport class SocialAccountLinkedError extends ApplicationError {\n constructor(provider?: string) {\n super('errors.auth.socialAccountLinked', ERROR_CODES.AUTH.SOCIAL_ACCOUNT_LINKED, provider ? { provider } : undefined)\n }\n}\n\nexport class CannotUnlinkLastAccountError extends ApplicationError {\n constructor() {\n super('errors.auth.cannotUnlinkLastAccount', ERROR_CODES.AUTH.CANNOT_UNLINK_LAST_ACCOUNT)\n }\n}\n\nexport class ProviderNotFoundError extends ApplicationError {\n constructor(provider?: string) {\n super('errors.auth.providerNotFound', ERROR_CODES.RESOURCE.NOT_FOUND, provider ? { provider } : undefined)\n }\n}\n\nexport class UserEmailNotFoundError extends ApplicationError {\n constructor() {\n super('errors.auth.userEmailNotFound', ERROR_CODES.RESOURCE.NOT_FOUND)\n }\n}\n\nexport class AccountNotFoundError extends ApplicationError {\n constructor() {\n super('errors.auth.accountNotFound', ERROR_CODES.RESOURCE.NOT_FOUND)\n }\n}\n\nexport class CredentialAccountNotFoundError extends ApplicationError {\n constructor() {\n super('errors.auth.credentialAccountNotFound', ERROR_CODES.RESOURCE.NOT_FOUND)\n }\n}\n\nexport class UserAlreadyHasPasswordError extends ApplicationError {\n constructor() {\n super('errors.auth.userAlreadyHasPassword', ERROR_CODES.RESOURCE.CONFLICT)\n }\n}\n\nexport class EmailCannotBeUpdatedError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.emailCannotBeUpdated', ERROR_CODES.VALIDATION.GENERIC, reason ? { reason } : undefined)\n }\n}\n\nexport class FailedToGetSessionError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToGetSession', ERROR_CODES.SYSTEM.INTERNAL_ERROR, reason ? { reason } : undefined)\n }\n}\n\nexport class FailedToGetUserInfoError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToGetUserInfo', ERROR_CODES.SYSTEM.INTERNAL_ERROR, reason ? { reason } : undefined)\n }\n}\n\nexport class IdTokenNotSupportedError extends ApplicationError {\n constructor() {\n super('errors.auth.invalidToken', ERROR_CODES.VALIDATION.GENERIC)\n }\n}\n\nexport class TokenExpiredError extends ApplicationError {\n constructor() {\n super('errors.auth.tokenExpired', ERROR_CODES.VALIDATION.GENERIC)\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class InvalidTokenError extends ApplicationError {\n constructor() {\n super('errors.auth.invalidToken', ERROR_CODES.AUTH.INVALID_TOKEN)\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class TokenRequiredError extends ApplicationError {\n constructor() {\n super('errors.auth.tokenRequired', ERROR_CODES.VALIDATION.REQUIRED_FIELD, { field: 'token' })\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class VerificationFailedError extends ApplicationError {\n constructor() {\n super('errors.auth.verificationFailed', ERROR_CODES.AUTH.INVALID_CREDENTIALS)\n }\n}\n","import { type BASE_ERROR_CODES } from '@better-auth/core/error'\nimport { APIError } from 'better-auth/api'\nimport type { ApplicationError } from 'stratal/errors'\nimport { InternalError } from 'stratal/errors'\nimport {\n AccountAlreadyExistsError,\n AccountNotFoundError,\n CannotUnlinkLastAccountError,\n CredentialAccountNotFoundError,\n EmailCannotBeUpdatedError,\n EmailNotVerifiedError,\n FailedToCreateSessionError,\n FailedToCreateUserError,\n FailedToGetSessionError,\n FailedToGetUserInfoError,\n FailedToUpdateUserError,\n IdTokenNotSupportedError,\n InvalidCredentialsError,\n InvalidEmailError,\n InvalidPasswordError,\n InvalidTokenError,\n PasswordTooLongError,\n PasswordTooShortError,\n ProviderNotFoundError,\n SessionExpiredError,\n SocialAccountLinkedError,\n TokenExpiredError,\n UserAlreadyHasPasswordError,\n UserEmailNotFoundError,\n UserNotFoundError,\n} from '../errors'\n\n/**\n * Maps Better Auth API error codes to ApplicationError instances.\n */\nexport function mapBetterAuthError(error: APIError): ApplicationError {\n const errorCode = error.body?.code as keyof typeof BASE_ERROR_CODES | 'TOKEN_EXPIRED' | undefined\n\n if (error.status === 'FOUND') {\n const headers = error.headers as Headers\n const hasInvalidToken = headers.get('location')?.includes('INVALID_TOKEN')\n\n if (hasInvalidToken) {\n return new InvalidTokenError()\n }\n }\n\n if (!errorCode) {\n return new InternalError({\n originalError: `Better Auth error: ${error.message}`,\n stack: error.stack,\n })\n }\n\n // User errors\n if (errorCode === 'USER_NOT_FOUND') return new UserNotFoundError()\n if (errorCode === 'USER_EMAIL_NOT_FOUND') return new UserEmailNotFoundError()\n\n // Credential errors\n if (errorCode === 'INVALID_EMAIL_OR_PASSWORD') return new InvalidCredentialsError()\n if (errorCode === 'INVALID_PASSWORD') return new InvalidPasswordError()\n if (errorCode === 'INVALID_EMAIL') return new InvalidEmailError()\n\n // Session errors\n if (errorCode === 'SESSION_EXPIRED') return new SessionExpiredError()\n if (errorCode === 'FAILED_TO_CREATE_SESSION') return new FailedToCreateSessionError()\n if (errorCode === 'FAILED_TO_GET_SESSION') return new FailedToGetSessionError()\n\n // Email verification\n if (errorCode === 'EMAIL_NOT_VERIFIED') return new EmailNotVerifiedError()\n if (errorCode === 'EMAIL_CAN_NOT_BE_UPDATED') return new EmailCannotBeUpdatedError()\n\n // Password validation\n if (errorCode === 'PASSWORD_TOO_SHORT') return new PasswordTooShortError(8)\n if (errorCode === 'PASSWORD_TOO_LONG') return new PasswordTooLongError(128)\n\n // Account errors\n if (errorCode === 'USER_ALREADY_EXISTS' || errorCode === 'USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL') {\n return new AccountAlreadyExistsError()\n }\n if (errorCode === 'ACCOUNT_NOT_FOUND') return new AccountNotFoundError()\n if (errorCode === 'CREDENTIAL_ACCOUNT_NOT_FOUND') return new CredentialAccountNotFoundError()\n if (errorCode === 'FAILED_TO_UNLINK_LAST_ACCOUNT') return new CannotUnlinkLastAccountError()\n\n // User creation/update errors\n if (errorCode === 'FAILED_TO_CREATE_USER') return new FailedToCreateUserError()\n if (errorCode === 'FAILED_TO_UPDATE_USER') return new FailedToUpdateUserError()\n if (errorCode === 'FAILED_TO_GET_USER_INFO') return new FailedToGetUserInfoError()\n\n // Social account errors\n if (errorCode === 'SOCIAL_ACCOUNT_ALREADY_LINKED') return new SocialAccountLinkedError()\n if (errorCode === 'PROVIDER_NOT_FOUND') return new ProviderNotFoundError()\n\n // Token errors\n if (errorCode === 'ID_TOKEN_NOT_SUPPORTED') return new IdTokenNotSupportedError()\n if (errorCode === 'INVALID_TOKEN') return new IdTokenNotSupportedError()\n if (errorCode === 'TOKEN_EXPIRED') return new TokenExpiredError()\n\n // Password management\n if (errorCode === 'USER_ALREADY_HAS_PASSWORD') return new UserAlreadyHasPasswordError()\n\n // Unknown error code\n return new InternalError({\n originalError: `Better Auth error [${errorCode}]: ${error.message}`,\n stack: error.stack,\n })\n}\n\n/**\n * Type guard to check if an error is a Better Auth APIError\n */\nexport function isAPIError(error: unknown): error is APIError {\n return error instanceof APIError\n}\n","import type { BetterAuthOptions } from 'better-auth'\nimport { isAPIError, mapBetterAuthError } from './better-auth-error-handler'\n\n/**\n * Get shared Better Auth error handler configuration.\n * Use this in Better Auth config's onAPIError option.\n */\nexport function getErrorHandlerConfig(): BetterAuthOptions['onAPIError'] {\n return {\n throw: false,\n onError: (error) => {\n if (isAPIError(error)) {\n throw mapBetterAuthError(error)\n }\n throw error\n },\n }\n}\n\n/**\n * Wrap a Better Auth function in a try/catch block and map errors to ApplicationError.\n */\nexport const wrapBetterAuth = async <T>(fn: () => Promise<T>): Promise<T> => {\n try {\n return await fn()\n } catch (error) {\n if (isAPIError(error)) {\n throw mapBetterAuthError(error)\n }\n throw error\n }\n}\n","import type { Auth, BetterAuthOptions } from 'better-auth'\nimport { betterAuth } from 'better-auth'\nimport { inject } from 'tsyringe'\nimport { Transient } from 'stratal/di'\nimport { AUTH_OPTIONS, AUTH_SERVICE } from '../auth.tokens'\nimport { getErrorHandlerConfig } from '../utils'\n\n/**\n * AuthService\n *\n * Base authentication service using Better Auth.\n * Configured via AuthModule.forRootAsync() from the application layer.\n *\n * **Extensibility:**\n * Extend this class in application layer to add custom methods.\n *\n * @example\n * ```typescript\n * @Transient(AUTH_SERVICE)\n * export class AppAuthService extends AuthService<AuthOptions> {\n * async signInMagicLink(email: string) {\n * return wrapBetterAuth(async () => {\n * return this.auth.api.signInMagicLink({ body: { email }, headers: new Headers() })\n * })\n * }\n * }\n * ```\n */\n@Transient(AUTH_SERVICE)\nexport class AuthService<TOptions extends BetterAuthOptions = BetterAuthOptions> {\n private authInstance: Auth<TOptions>\n\n constructor(\n @inject(AUTH_OPTIONS) protected readonly options: TOptions\n ) {\n this.authInstance = betterAuth({\n ...this.options,\n onAPIError: getErrorHandlerConfig()\n }) as Auth<TOptions>\n }\n\n /**\n * Get the Better Auth instance\n */\n get auth(): Auth<TOptions> {\n return this.authInstance\n }\n}\n","/**\n * Auth Module\n *\n * Provides configurable authentication using Better Auth.\n * Use `forRootAsync` to configure Better Auth options from the application layer.\n *\n * @example\n * ```typescript\n * @Module({\n * imports: [\n * AuthModule.forRootAsync({\n * inject: [DI_TOKENS.Database, CONFIG_TOKENS.ConfigService],\n * useFactory: (db, config) => createAuthOptions(db, config)\n * })\n * ]\n * })\n * export class AppModule {}\n * ```\n */\n\nimport type { BetterAuthOptions } from 'better-auth'\nimport type { MiddlewareConfigurable, MiddlewareConsumer } from 'stratal/middleware'\nimport { Module } from 'stratal/module'\nimport type { AsyncModuleOptions, DynamicModule } from 'stratal/module'\nimport { AUTH_OPTIONS, AUTH_SERVICE } from './auth.tokens'\nimport { AuthContextMiddleware } from './middleware/auth-context.middleware'\nimport { SessionVerificationMiddleware } from './middleware/session-verification.middleware'\nimport { AuthService } from './services/auth.service'\n\n@Module({\n providers: []\n})\nexport class AuthModule implements MiddlewareConfigurable {\n /**\n * Configure auth middleware.\n *\n * Registers middlewares in order:\n * 1. AuthContextMiddleware - Creates and registers AuthContext in request container\n * 2. SessionVerificationMiddleware - Verifies session and populates AuthContext with userId\n */\n configure(consumer: MiddlewareConsumer): void {\n consumer\n .apply(AuthContextMiddleware)\n .forRoutes('*')\n\n consumer\n .apply(SessionVerificationMiddleware)\n .forRoutes('*')\n }\n\n /**\n * Configure AuthModule with async options factory\n */\n static forRootAsync<TOptions extends BetterAuthOptions>(\n options: AsyncModuleOptions<TOptions>\n ): DynamicModule {\n return {\n module: AuthModule,\n providers: [\n {\n provide: AUTH_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject\n },\n {\n provide: AUTH_SERVICE,\n useClass: AuthService\n }\n ]\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/auth/auth.tokens.ts","../../src/auth/middleware/auth-context.middleware.ts","../../src/auth/middleware/session-verification.middleware.ts","../../src/auth/errors/auth-errors.ts","../../src/auth/errors/invalid-token.error.ts","../../src/auth/errors/token-required.error.ts","../../src/auth/errors/verification-failed.error.ts","../../src/auth/utils/better-auth-error-handler.ts","../../src/auth/utils/auth-helpers.ts","../../src/auth/services/auth.service.ts","../../src/auth/auth.module.ts"],"sourcesContent":["/** Token for AuthService - core authentication service */\nexport const AUTH_SERVICE = Symbol.for('stratal:auth:service')\n\n/** Token for Better Auth options configuration */\nexport const AUTH_OPTIONS = Symbol.for('stratal:auth:options')\n","import { DI_TOKENS, Transient } from 'stratal/di'\nimport type { Middleware, Next, RouterContext } from 'stratal/router'\nimport { AuthContext } from '../../context/auth-context'\n\n/**\n * Auth Context Middleware\n *\n * Registers AuthContext in the request container at the start of each request.\n * This MUST run before SessionVerificationMiddleware and any other middleware\n * that depends on AuthContext.\n */\n@Transient()\nexport class AuthContextMiddleware implements Middleware {\n async handle(ctx: RouterContext, next: Next): Promise<void> {\n const requestContainer = ctx.getContainer()\n\n const authContext = new AuthContext()\n requestContainer.registerValue(DI_TOKENS.AuthContext, authContext)\n\n await next()\n }\n}\n","import { DI_TOKENS, Transient } from 'stratal/di'\nimport { LOGGER_TOKENS, type LoggerService } from 'stratal/logger'\nimport type { Middleware, Next, RouterContext } from 'stratal/router'\nimport { inject } from 'tsyringe'\nimport { type AuthContext } from '../../context/auth-context'\nimport { AUTH_SERVICE } from '../auth.tokens'\nimport type { AuthService } from '../services/auth.service'\n\n/**\n * Session Verification Middleware\n *\n * Verifies user session via Better Auth and populates AuthContext with userId.\n *\n * **Responsibilities:**\n * - Calls Better Auth's getSession() API\n * - Populates AuthContext with userId if session is valid\n * - Continues request chain regardless of session status\n */\n@Transient()\nexport class SessionVerificationMiddleware implements Middleware {\n constructor(\n @inject(AUTH_SERVICE)\n private readonly authService: AuthService,\n @inject(LOGGER_TOKENS.LoggerService) private logger: LoggerService\n ) { }\n\n async handle(ctx: RouterContext, next: Next): Promise<void> {\n try {\n const session = await this.authService.auth.api.getSession({\n headers: ctx.c.req.raw.headers\n })\n\n if (session) {\n const authContext = ctx.getContainer().resolve<AuthContext>(DI_TOKENS.AuthContext)\n authContext.setAuthContext({ userId: session.user.id })\n }\n\n await next()\n } catch (error: unknown) {\n this.logger.debug('Session validation failed (e.g., invalidated in DB)', { error });\n await next()\n }\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class UserNotFoundError extends ApplicationError {\n constructor(email?: string) {\n super('errors.auth.userNotFound', ERROR_CODES.RESOURCE.NOT_FOUND, email ? { email } : undefined)\n }\n}\n\nexport class InvalidCredentialsError extends ApplicationError {\n constructor() {\n super('errors.auth.invalidCredentials', ERROR_CODES.AUTH.INVALID_CREDENTIALS)\n }\n}\n\nexport class InvalidPasswordError extends ApplicationError {\n constructor() {\n super('errors.auth.invalidPassword', ERROR_CODES.AUTH.INVALID_CREDENTIALS)\n }\n}\n\nexport class InvalidEmailError extends ApplicationError {\n constructor(email?: string) {\n super('errors.auth.invalidEmail', ERROR_CODES.VALIDATION.INVALID_FORMAT, email ? { email } : undefined)\n }\n}\n\nexport class SessionExpiredError extends ApplicationError {\n constructor() {\n super('errors.auth.sessionExpired', ERROR_CODES.AUTH.SESSION_EXPIRED)\n }\n}\n\nexport class EmailNotVerifiedError extends ApplicationError {\n constructor(email?: string) {\n super('errors.auth.emailNotVerified', ERROR_CODES.AUTH.EMAIL_NOT_VERIFIED, email ? { email } : undefined)\n }\n}\n\nexport class PasswordTooShortError extends ApplicationError {\n constructor(minLength: number) {\n super('errors.auth.passwordTooShort', ERROR_CODES.AUTH.PASSWORD_TOO_SHORT, { minLength })\n }\n}\n\nexport class PasswordTooLongError extends ApplicationError {\n constructor(maxLength: number) {\n super('errors.auth.passwordTooLong', ERROR_CODES.AUTH.PASSWORD_TOO_LONG, { maxLength })\n }\n}\n\nexport class AccountAlreadyExistsError extends ApplicationError {\n constructor(email?: string) {\n super('errors.auth.accountAlreadyExists', ERROR_CODES.AUTH.ACCOUNT_ALREADY_EXISTS, email ? { email } : undefined)\n }\n}\n\nexport class FailedToCreateUserError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToCreateUser', ERROR_CODES.AUTH.FAILED_TO_CREATE_USER, reason ? { reason } : undefined)\n }\n}\n\nexport class FailedToCreateSessionError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToCreateSession', ERROR_CODES.AUTH.FAILED_TO_CREATE_SESSION, reason ? { reason } : undefined)\n }\n}\n\nexport class FailedToUpdateUserError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToUpdateUser', ERROR_CODES.AUTH.FAILED_TO_UPDATE_USER, reason ? { reason } : undefined)\n }\n}\n\nexport class SocialAccountLinkedError extends ApplicationError {\n constructor(provider?: string) {\n super('errors.auth.socialAccountLinked', ERROR_CODES.AUTH.SOCIAL_ACCOUNT_LINKED, provider ? { provider } : undefined)\n }\n}\n\nexport class CannotUnlinkLastAccountError extends ApplicationError {\n constructor() {\n super('errors.auth.cannotUnlinkLastAccount', ERROR_CODES.AUTH.CANNOT_UNLINK_LAST_ACCOUNT)\n }\n}\n\nexport class ProviderNotFoundError extends ApplicationError {\n constructor(provider?: string) {\n super('errors.auth.providerNotFound', ERROR_CODES.RESOURCE.NOT_FOUND, provider ? { provider } : undefined)\n }\n}\n\nexport class UserEmailNotFoundError extends ApplicationError {\n constructor() {\n super('errors.auth.userEmailNotFound', ERROR_CODES.RESOURCE.NOT_FOUND)\n }\n}\n\nexport class AccountNotFoundError extends ApplicationError {\n constructor() {\n super('errors.auth.accountNotFound', ERROR_CODES.RESOURCE.NOT_FOUND)\n }\n}\n\nexport class CredentialAccountNotFoundError extends ApplicationError {\n constructor() {\n super('errors.auth.credentialAccountNotFound', ERROR_CODES.RESOURCE.NOT_FOUND)\n }\n}\n\nexport class UserAlreadyHasPasswordError extends ApplicationError {\n constructor() {\n super('errors.auth.userAlreadyHasPassword', ERROR_CODES.RESOURCE.CONFLICT)\n }\n}\n\nexport class EmailCannotBeUpdatedError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.emailCannotBeUpdated', ERROR_CODES.VALIDATION.GENERIC, reason ? { reason } : undefined)\n }\n}\n\nexport class FailedToGetSessionError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToGetSession', ERROR_CODES.SYSTEM.INTERNAL_ERROR, reason ? { reason } : undefined)\n }\n}\n\nexport class FailedToGetUserInfoError extends ApplicationError {\n constructor(reason?: string) {\n super('errors.auth.failedToGetUserInfo', ERROR_CODES.SYSTEM.INTERNAL_ERROR, reason ? { reason } : undefined)\n }\n}\n\nexport class IdTokenNotSupportedError extends ApplicationError {\n constructor() {\n super('errors.auth.invalidToken', ERROR_CODES.VALIDATION.GENERIC)\n }\n}\n\nexport class TokenExpiredError extends ApplicationError {\n constructor() {\n super('errors.auth.tokenExpired', ERROR_CODES.VALIDATION.GENERIC)\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class InvalidTokenError extends ApplicationError {\n constructor() {\n super('errors.auth.invalidToken', ERROR_CODES.AUTH.INVALID_TOKEN)\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class TokenRequiredError extends ApplicationError {\n constructor() {\n super('errors.auth.tokenRequired', ERROR_CODES.VALIDATION.REQUIRED_FIELD, { field: 'token' })\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class VerificationFailedError extends ApplicationError {\n constructor() {\n super('errors.auth.verificationFailed', ERROR_CODES.AUTH.INVALID_CREDENTIALS)\n }\n}\n","import { type BASE_ERROR_CODES } from '@better-auth/core/error'\nimport { APIError } from 'better-auth/api'\nimport type { ApplicationError } from 'stratal/errors'\nimport { InternalError } from 'stratal/errors'\nimport {\n AccountAlreadyExistsError,\n AccountNotFoundError,\n CannotUnlinkLastAccountError,\n CredentialAccountNotFoundError,\n EmailCannotBeUpdatedError,\n EmailNotVerifiedError,\n FailedToCreateSessionError,\n FailedToCreateUserError,\n FailedToGetSessionError,\n FailedToGetUserInfoError,\n FailedToUpdateUserError,\n IdTokenNotSupportedError,\n InvalidCredentialsError,\n InvalidEmailError,\n InvalidPasswordError,\n InvalidTokenError,\n PasswordTooLongError,\n PasswordTooShortError,\n ProviderNotFoundError,\n SessionExpiredError,\n SocialAccountLinkedError,\n TokenExpiredError,\n UserAlreadyHasPasswordError,\n UserEmailNotFoundError,\n UserNotFoundError,\n} from '../errors'\n\n/**\n * Maps Better Auth API error codes to ApplicationError instances.\n */\nexport function mapBetterAuthError(error: APIError): ApplicationError {\n const errorCode = error.body?.code as keyof typeof BASE_ERROR_CODES | 'TOKEN_EXPIRED' | undefined\n\n if (error.status === 'FOUND') {\n const headers = error.headers as Headers\n const location = headers.get('location') ?? ''\n\n if (location.includes('INVALID_TOKEN')) return new InvalidTokenError()\n if (location.includes('EXPIRED_TOKEN')) return new TokenExpiredError()\n if (location.includes('ATTEMPTS_EXCEEDED')) return new InvalidTokenError()\n if (location.includes('new_user_signup_disabled')) return new UserNotFoundError()\n if (location.includes('failed_to_create_user')) return new FailedToCreateUserError()\n if (location.includes('failed_to_create_session')) return new FailedToCreateSessionError()\n }\n\n if (!errorCode) {\n return new InternalError({\n originalError: `Better Auth error: ${error.message}`,\n stack: error.stack,\n })\n }\n\n // User errors\n if (errorCode === 'USER_NOT_FOUND') return new UserNotFoundError()\n if (errorCode === 'USER_EMAIL_NOT_FOUND') return new UserEmailNotFoundError()\n\n // Credential errors\n if (errorCode === 'INVALID_EMAIL_OR_PASSWORD') return new InvalidCredentialsError()\n if (errorCode === 'INVALID_PASSWORD') return new InvalidPasswordError()\n if (errorCode === 'INVALID_EMAIL') return new InvalidEmailError()\n\n // Session errors\n if (errorCode === 'SESSION_EXPIRED') return new SessionExpiredError()\n if (errorCode === 'FAILED_TO_CREATE_SESSION') return new FailedToCreateSessionError()\n if (errorCode === 'FAILED_TO_GET_SESSION') return new FailedToGetSessionError()\n\n // Email verification\n if (errorCode === 'EMAIL_NOT_VERIFIED') return new EmailNotVerifiedError()\n if (errorCode === 'EMAIL_CAN_NOT_BE_UPDATED') return new EmailCannotBeUpdatedError()\n\n // Password validation\n if (errorCode === 'PASSWORD_TOO_SHORT') return new PasswordTooShortError(8)\n if (errorCode === 'PASSWORD_TOO_LONG') return new PasswordTooLongError(128)\n\n // Account errors\n if (errorCode === 'USER_ALREADY_EXISTS' || errorCode === 'USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL') {\n return new AccountAlreadyExistsError()\n }\n if (errorCode === 'ACCOUNT_NOT_FOUND') return new AccountNotFoundError()\n if (errorCode === 'CREDENTIAL_ACCOUNT_NOT_FOUND') return new CredentialAccountNotFoundError()\n if (errorCode === 'FAILED_TO_UNLINK_LAST_ACCOUNT') return new CannotUnlinkLastAccountError()\n\n // User creation/update errors\n if (errorCode === 'FAILED_TO_CREATE_USER') return new FailedToCreateUserError()\n if (errorCode === 'FAILED_TO_UPDATE_USER') return new FailedToUpdateUserError()\n if (errorCode === 'FAILED_TO_GET_USER_INFO') return new FailedToGetUserInfoError()\n\n // Social account errors\n if (errorCode === 'SOCIAL_ACCOUNT_ALREADY_LINKED') return new SocialAccountLinkedError()\n if (errorCode === 'PROVIDER_NOT_FOUND') return new ProviderNotFoundError()\n\n // Token errors\n if (errorCode === 'ID_TOKEN_NOT_SUPPORTED') return new IdTokenNotSupportedError()\n if (errorCode === 'INVALID_TOKEN') return new IdTokenNotSupportedError()\n if (errorCode === 'TOKEN_EXPIRED') return new TokenExpiredError()\n\n // Password management\n if (errorCode === 'USER_ALREADY_HAS_PASSWORD') return new UserAlreadyHasPasswordError()\n\n // Unknown error code\n return new InternalError({\n originalError: `Better Auth error [${errorCode}]: ${error.message}`,\n stack: error.stack,\n })\n}\n\n/**\n * Type guard to check if an error is a Better Auth APIError.\n * Uses duck typing to handle bundler environments (e.g. Vite)\n * where instanceof may fail across module boundaries.\n */\nexport function isAPIError(error: unknown): error is APIError {\n if (error instanceof APIError) return true\n\n return (\n error instanceof Error\n && error.name === 'APIError'\n && 'status' in error\n && 'statusCode' in error\n )\n}\n","import type { BetterAuthOptions } from 'better-auth'\nimport { isAPIError, mapBetterAuthError } from './better-auth-error-handler'\n\n/**\n * Get shared Better Auth error handler configuration.\n * Use this in Better Auth config's onAPIError option.\n */\nexport function getErrorHandlerConfig(): BetterAuthOptions['onAPIError'] {\n return {\n throw: false,\n onError: (error) => {\n if (isAPIError(error)) {\n throw mapBetterAuthError(error)\n }\n throw error\n },\n }\n}\n\n/**\n * Wrap a Better Auth function in a try/catch block and map errors to ApplicationError.\n */\nexport const wrapBetterAuth = async <T>(fn: () => Promise<T>): Promise<T> => {\n try {\n return await fn()\n } catch (error) {\n if (isAPIError(error)) {\n throw mapBetterAuthError(error)\n }\n throw error\n }\n}\n","import type { Auth, BetterAuthOptions } from 'better-auth'\nimport { betterAuth } from 'better-auth'\nimport { inject } from 'tsyringe'\nimport { Transient } from 'stratal/di'\nimport { AUTH_OPTIONS, AUTH_SERVICE } from '../auth.tokens'\nimport { getErrorHandlerConfig } from '../utils'\n\n/**\n * AuthService\n *\n * Base authentication service using Better Auth.\n * Configured via AuthModule.forRootAsync() from the application layer.\n *\n * **Extensibility:**\n * Extend this class in application layer to add custom methods.\n *\n * @example\n * ```typescript\n * @Transient(AUTH_SERVICE)\n * export class AppAuthService extends AuthService<AuthOptions> {\n * async signInMagicLink(email: string) {\n * return wrapBetterAuth(async () => {\n * return this.auth.api.signInMagicLink({ body: { email }, headers: new Headers() })\n * })\n * }\n * }\n * ```\n */\n@Transient(AUTH_SERVICE)\nexport class AuthService<TOptions extends BetterAuthOptions = BetterAuthOptions> {\n private authInstance: Auth<TOptions>\n\n constructor(\n @inject(AUTH_OPTIONS) protected readonly options: TOptions\n ) {\n this.authInstance = betterAuth({\n ...this.options,\n onAPIError: getErrorHandlerConfig()\n }) as Auth<TOptions>\n }\n\n /**\n * Get the Better Auth instance\n */\n get auth(): Auth<TOptions> {\n return this.authInstance\n }\n}\n","/**\n * Auth Module\n *\n * Provides configurable authentication using Better Auth.\n * Use `forRootAsync` to configure Better Auth options from the application layer.\n *\n * @example\n * ```typescript\n * @Module({\n * imports: [\n * AuthModule.forRootAsync({\n * inject: [DI_TOKENS.Database, CONFIG_TOKENS.ConfigService],\n * useFactory: (db, config) => createAuthOptions(db, config)\n * })\n * ]\n * })\n * export class AppModule {}\n * ```\n */\n\nimport type { BetterAuthOptions } from 'better-auth'\nimport type { RouteConfigurable, Router } from 'stratal/router'\nimport { Module } from 'stratal/module'\nimport type { AsyncModuleOptions, DynamicModule } from 'stratal/module'\nimport { AUTH_OPTIONS, AUTH_SERVICE } from './auth.tokens'\nimport { AuthContextMiddleware } from './middleware/auth-context.middleware'\nimport { SessionVerificationMiddleware } from './middleware/session-verification.middleware'\nimport { AuthService } from './services/auth.service'\n\n@Module({\n providers: []\n})\nexport class AuthModule implements RouteConfigurable {\n /**\n * Configure auth middleware globally.\n *\n * Registers middlewares in order:\n * 1. AuthContextMiddleware - Creates and registers AuthContext in request container\n * 2. SessionVerificationMiddleware - Verifies session and populates AuthContext with userId\n */\n configureRoutes(router: Router): void {\n router.use(AuthContextMiddleware, SessionVerificationMiddleware)\n }\n\n /**\n * Configure AuthModule with async options factory\n */\n static forRootAsync<TOptions extends BetterAuthOptions>(\n options: AsyncModuleOptions<TOptions>\n ): DynamicModule {\n return {\n module: AuthModule,\n providers: [\n {\n provide: AUTH_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject\n },\n {\n provide: AUTH_SERVICE,\n useClass: AuthService\n }\n ]\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as UserNotAuthenticatedError, r as ContextNotInitializedError } from "./errors-C_KIIU1v.mjs";
|
|
2
|
-
import { t as __decorate } from "./decorate-
|
|
2
|
+
import { t as __decorate } from "./decorate-C12QolJF.mjs";
|
|
3
3
|
import { DI_TOKENS, Transient } from "stratal/di";
|
|
4
4
|
//#region src/context/auth-context.ts
|
|
5
5
|
let AuthContext = class AuthContext {
|
|
@@ -52,4 +52,4 @@ AuthContext = __decorate([Transient(DI_TOKENS.AuthContext)], AuthContext);
|
|
|
52
52
|
//#endregion
|
|
53
53
|
export { AuthContext as t };
|
|
54
54
|
|
|
55
|
-
//# sourceMappingURL=auth-context-
|
|
55
|
+
//# sourceMappingURL=auth-context-BfekHvM9.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-context-
|
|
1
|
+
{"version":3,"file":"auth-context-BfekHvM9.mjs","names":[],"sources":["../src/context/auth-context.ts"],"sourcesContent":["import { Transient, DI_TOKENS } from 'stratal/di'\nimport {\n ContextNotInitializedError,\n UserNotAuthenticatedError\n} from './errors'\n\nexport interface AuthInfo {\n userId?: string\n}\n\n@Transient(DI_TOKENS.AuthContext)\nexport class AuthContext {\n protected userId?: string\n\n /**\n * Set authentication context.\n * This should be called once per request with user information.\n */\n setAuthContext(info: AuthInfo): void {\n this.userId = info.userId\n }\n\n /**\n * Get user ID if available.\n * Returns undefined if no user is authenticated.\n */\n getUserId(): string | undefined {\n return this.userId\n }\n\n /**\n * Get user ID or throw if not authenticated.\n * Use this when authentication is required.\n */\n requireUserId(): string {\n const userId = this.getUserId()\n if (!userId) {\n throw new UserNotAuthenticatedError()\n }\n return userId\n }\n\n /**\n * Get full authentication context or throw if not initialized.\n */\n getAuthContext(): AuthInfo {\n if (!this.userId) {\n throw new ContextNotInitializedError('Authentication')\n }\n return {\n userId: this.userId\n }\n }\n\n /**\n * Check if user is authenticated.\n */\n isAuthenticated(): boolean {\n return !!this.userId\n }\n\n /**\n * Clear authentication context.\n * Useful for testing or cleanup.\n */\n clearAuthContext(): void {\n this.userId = undefined\n }\n}\n"],"mappings":";;;;AAWO,IAAA,cAAA,MAAM,YAAY;CACvB;;;;;CAMA,eAAe,MAAsB;AACnC,OAAK,SAAS,KAAK;;;;;;CAOrB,YAAgC;AAC9B,SAAO,KAAK;;;;;;CAOd,gBAAwB;EACtB,MAAM,SAAS,KAAK,WAAW;AAC/B,MAAI,CAAC,OACH,OAAM,IAAI,2BAA2B;AAEvC,SAAO;;;;;CAMT,iBAA2B;AACzB,MAAI,CAAC,KAAK,OACR,OAAM,IAAI,2BAA2B,iBAAiB;AAExD,SAAO,EACL,QAAQ,KAAK,QACd;;;;;CAMH,kBAA2B;AACzB,SAAO,CAAC,CAAC,KAAK;;;;;;CAOhB,mBAAyB;AACvB,OAAK,SAAS,KAAA;;;0BAxDjB,UAAU,UAAU,YAAY,CAAA,EAAA,YAAA"}
|
package/dist/context/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as UserNotAuthenticatedError, r as ContextNotInitializedError, t as UserNotAuthorizedError } from "../errors-C_KIIU1v.mjs";
|
|
2
|
-
import { t as AuthContext } from "../auth-context-
|
|
2
|
+
import { t as AuthContext } from "../auth-context-BfekHvM9.mjs";
|
|
3
3
|
export { AuthContext, ContextNotInitializedError, UserNotAuthenticatedError, UserNotAuthorizedError };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { a as InternalDatabaseEventContext, i as InferConnectionSchema, n as DefaultConnectionName, o as StratalDatabase, r as InferAnySchema, t as ConnectionName } from "../types-Gjk0d2qB.mjs";
|
|
2
|
-
import { C as
|
|
3
|
-
export { ConnectionName, DATABASE_TOKENS, DatabaseConfigError, DatabaseConnectionConfig, DatabaseError, DatabaseEventName, DatabaseEvents, DatabaseModule, DatabaseModuleConfig, DatabaseOperation, DatabaseService, DefaultConnectionName, ErrorHandlerPlugin, EventEmitterPlugin, EventEmitterPluginOptions, EventPhase, ForeignKeyConstraintError, GetData, GetResult, InferAnySchema, InferConnectionSchema, InjectDB, InternalDatabaseEventContext, InvalidErrorCodeRangeError, ModelName, ParseEvent, RecordNotFoundError, SchemaSwitcherPlugin, SchemaSwitcherPluginOptions, StratalDatabase, UniqueConstraintError, connectionSymbol, databaseI18n, fromZenStackError };
|
|
2
|
+
import { A as InjectDB, C as fromZenStackError, D as ForeignKeyConstraintError, E as InvalidErrorCodeRangeError, F as DatabaseModule, I as DatabaseModuleConfig, M as connectionSymbol, N as DatabaseService, O as DatabaseConfigError, P as DatabaseConnectionConfig, S as ParseEvent, T as RecordNotFoundError, _ as DatabaseOperation, a as DbPushCommand, b as GetResult, c as ZenStackCommand, d as EventEmitterPlugin, f as EventEmitterPluginOptions, g as DatabaseEvents, h as DatabaseEventName, i as MigrateDeployCommand, j as DATABASE_TOKENS, k as DatabaseError, l as SchemaSwitcherPlugin, m as databaseI18n, n as MigrateResetCommand, o as DbPullCommand, p as ErrorHandlerPlugin, r as MigrateDevCommand, s as DbGenerateCommand, t as MigrateStatusCommand, u as SchemaSwitcherPluginOptions, v as EventPhase, w as UniqueConstraintError, x as ModelName, y as GetData } from "../index-B1iGBJcO.mjs";
|
|
3
|
+
export { ConnectionName, DATABASE_TOKENS, DatabaseConfigError, DatabaseConnectionConfig, DatabaseError, DatabaseEventName, DatabaseEvents, DatabaseModule, DatabaseModuleConfig, DatabaseOperation, DatabaseService, DbGenerateCommand, DbPullCommand, DbPushCommand, DefaultConnectionName, ErrorHandlerPlugin, EventEmitterPlugin, EventEmitterPluginOptions, EventPhase, ForeignKeyConstraintError, GetData, GetResult, InferAnySchema, InferConnectionSchema, InjectDB, InternalDatabaseEventContext, InvalidErrorCodeRangeError, MigrateDeployCommand, MigrateDevCommand, MigrateResetCommand, MigrateStatusCommand, ModelName, ParseEvent, RecordNotFoundError, SchemaSwitcherPlugin, SchemaSwitcherPluginOptions, StratalDatabase, UniqueConstraintError, ZenStackCommand, connectionSymbol, databaseI18n, fromZenStackError };
|
package/dist/database/index.mjs
CHANGED
|
@@ -1,11 +1,128 @@
|
|
|
1
|
-
import { t as __decorate } from "../decorate-
|
|
2
|
-
import { t as __decorateMetadata } from "../decorateMetadata-
|
|
1
|
+
import { t as __decorate } from "../decorate-C12QolJF.mjs";
|
|
2
|
+
import { t as __decorateMetadata } from "../decorateMetadata-rWbWGUuO.mjs";
|
|
3
3
|
import { Module } from "stratal/module";
|
|
4
4
|
import { DI_TOKENS, Scope, Transient, delay } from "stratal/di";
|
|
5
5
|
import { ApplicationError, ERROR_CODES } from "stratal/errors";
|
|
6
6
|
import { inject } from "tsyringe";
|
|
7
|
+
import { Command } from "stratal/quarry";
|
|
7
8
|
import { ORMError, ORMErrorReason, ZenStackClient } from "@zenstackhq/orm";
|
|
8
9
|
import { withI18n, z } from "stratal/validation";
|
|
10
|
+
//#region src/database/commands/zenstack.command.ts
|
|
11
|
+
/**
|
|
12
|
+
* Base command for ZenStack CLI wrappers.
|
|
13
|
+
* Uses execFileSync with array arguments to prevent shell injection.
|
|
14
|
+
*/
|
|
15
|
+
var ZenStackCommand = class extends Command {
|
|
16
|
+
async zenstack(args) {
|
|
17
|
+
const { execFileSync } = await import("node:child_process");
|
|
18
|
+
try {
|
|
19
|
+
const output = execFileSync("npx", ["zenstack", ...args], {
|
|
20
|
+
encoding: "utf-8",
|
|
21
|
+
stdio: "pipe"
|
|
22
|
+
});
|
|
23
|
+
if (output) this.info(output.trim());
|
|
24
|
+
return 0;
|
|
25
|
+
} catch (err) {
|
|
26
|
+
const error = err;
|
|
27
|
+
if (error.stderr) this.error(error.stderr.trim());
|
|
28
|
+
if (error.stdout) this.info(error.stdout.trim());
|
|
29
|
+
return error.status ?? 1;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/database/commands/db-generate.command.ts
|
|
35
|
+
var DbGenerateCommand = class extends ZenStackCommand {
|
|
36
|
+
static command = "db:generate {--schema= : Path to schema file} {--watch : Enable watch mode}";
|
|
37
|
+
static description = "Generate ZenStack ORM client";
|
|
38
|
+
async handle() {
|
|
39
|
+
const args = ["generate"];
|
|
40
|
+
const schema = this.string("schema");
|
|
41
|
+
if (schema) args.push("--schema", schema);
|
|
42
|
+
if (this.boolean("watch")) args.push("--watch");
|
|
43
|
+
return this.zenstack(args);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/database/commands/db-pull.command.ts
|
|
48
|
+
var DbPullCommand = class extends ZenStackCommand {
|
|
49
|
+
static command = "db:pull {--schema= : Path to schema file}";
|
|
50
|
+
static description = "Introspect database and generate schema";
|
|
51
|
+
async handle() {
|
|
52
|
+
const args = ["db", "pull"];
|
|
53
|
+
const schema = this.string("schema");
|
|
54
|
+
if (schema) args.push("--schema", schema);
|
|
55
|
+
return this.zenstack(args);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/database/commands/db-push.command.ts
|
|
60
|
+
var DbPushCommand = class extends ZenStackCommand {
|
|
61
|
+
static command = "db:push {--schema= : Path to schema file} {--accept-data-loss : Accept data loss} {--force-reset : Force reset database}";
|
|
62
|
+
static description = "Push database schema changes";
|
|
63
|
+
async handle() {
|
|
64
|
+
const args = ["db", "push"];
|
|
65
|
+
const schema = this.string("schema");
|
|
66
|
+
if (schema) args.push("--schema", schema);
|
|
67
|
+
if (this.boolean("accept-data-loss")) args.push("--accept-data-loss");
|
|
68
|
+
if (this.boolean("force-reset")) args.push("--force-reset");
|
|
69
|
+
return this.zenstack(args);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/database/commands/migrate-deploy.command.ts
|
|
74
|
+
var MigrateDeployCommand = class extends ZenStackCommand {
|
|
75
|
+
static command = "migrate:deploy {--schema= : Path to schema file}";
|
|
76
|
+
static description = "Deploy pending migrations";
|
|
77
|
+
async handle() {
|
|
78
|
+
const args = ["migrate", "deploy"];
|
|
79
|
+
const schema = this.string("schema");
|
|
80
|
+
if (schema) args.push("--schema", schema);
|
|
81
|
+
return this.zenstack(args);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/database/commands/migrate-dev.command.ts
|
|
86
|
+
var MigrateDevCommand = class extends ZenStackCommand {
|
|
87
|
+
static command = "migrate:dev {--schema= : Path to schema file} {--name= : Migration name} {--create-only : Create without applying}";
|
|
88
|
+
static description = "Create and apply migration";
|
|
89
|
+
async handle() {
|
|
90
|
+
const args = ["migrate", "dev"];
|
|
91
|
+
const schema = this.string("schema");
|
|
92
|
+
const name = this.string("name");
|
|
93
|
+
if (schema) args.push("--schema", schema);
|
|
94
|
+
if (name) args.push("--name", name);
|
|
95
|
+
if (this.boolean("create-only")) args.push("--create-only");
|
|
96
|
+
return this.zenstack(args);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/database/commands/migrate-reset.command.ts
|
|
101
|
+
var MigrateResetCommand = class extends ZenStackCommand {
|
|
102
|
+
static command = "migrate:reset {--schema= : Path to schema file} {--force : Skip confirmation} {--skip-seed : Skip seeding}";
|
|
103
|
+
static description = "Reset database";
|
|
104
|
+
async handle() {
|
|
105
|
+
const args = ["migrate", "reset"];
|
|
106
|
+
const schema = this.string("schema");
|
|
107
|
+
if (schema) args.push("--schema", schema);
|
|
108
|
+
if (this.boolean("force")) args.push("--force");
|
|
109
|
+
if (this.boolean("skip-seed")) args.push("--skip-seed");
|
|
110
|
+
return this.zenstack(args);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/database/commands/migrate-status.command.ts
|
|
115
|
+
var MigrateStatusCommand = class extends ZenStackCommand {
|
|
116
|
+
static command = "migrate:status {--schema= : Path to schema file}";
|
|
117
|
+
static description = "Check migration status";
|
|
118
|
+
async handle() {
|
|
119
|
+
const args = ["migrate", "status"];
|
|
120
|
+
const schema = this.string("schema");
|
|
121
|
+
if (schema) args.push("--schema", schema);
|
|
122
|
+
return this.zenstack(args);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
//#endregion
|
|
9
126
|
//#region src/database/errors/invalid-error-code-range.error.ts
|
|
10
127
|
/**
|
|
11
128
|
* InvalidErrorCodeRangeError
|
|
@@ -353,7 +470,15 @@ let DatabaseModule = _DatabaseModule = class DatabaseModule {
|
|
|
353
470
|
context.logger.info("DatabaseModule shutdown");
|
|
354
471
|
}
|
|
355
472
|
};
|
|
356
|
-
DatabaseModule = _DatabaseModule = __decorate([Module({
|
|
473
|
+
DatabaseModule = _DatabaseModule = __decorate([Module({ providers: [
|
|
474
|
+
DbGenerateCommand,
|
|
475
|
+
DbPushCommand,
|
|
476
|
+
DbPullCommand,
|
|
477
|
+
MigrateDevCommand,
|
|
478
|
+
MigrateDeployCommand,
|
|
479
|
+
MigrateStatusCommand,
|
|
480
|
+
MigrateResetCommand
|
|
481
|
+
] })], DatabaseModule);
|
|
357
482
|
//#endregion
|
|
358
483
|
//#region src/database/decorators/inject-db.decorator.ts
|
|
359
484
|
function InjectDB(name) {
|
|
@@ -369,6 +494,6 @@ const databaseI18n = { database: {
|
|
|
369
494
|
defaultConnectionNotFound: "Default connection not found in connections"
|
|
370
495
|
} };
|
|
371
496
|
//#endregion
|
|
372
|
-
export { DATABASE_TOKENS, DatabaseConfigError, DatabaseError, DatabaseModule, ErrorHandlerPlugin, EventEmitterPlugin, ForeignKeyConstraintError, InjectDB, InvalidErrorCodeRangeError, RecordNotFoundError, SchemaSwitcherPlugin, UniqueConstraintError, connectionSymbol, databaseI18n, fromZenStackError };
|
|
497
|
+
export { DATABASE_TOKENS, DatabaseConfigError, DatabaseError, DatabaseModule, DbGenerateCommand, DbPullCommand, DbPushCommand, ErrorHandlerPlugin, EventEmitterPlugin, ForeignKeyConstraintError, InjectDB, InvalidErrorCodeRangeError, MigrateDeployCommand, MigrateDevCommand, MigrateResetCommand, MigrateStatusCommand, RecordNotFoundError, SchemaSwitcherPlugin, UniqueConstraintError, ZenStackCommand, connectionSymbol, databaseI18n, fromZenStackError };
|
|
373
498
|
|
|
374
499
|
//# sourceMappingURL=index.mjs.map
|