@terreno/api 0.1.0 → 0.2.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 (40) hide show
  1. package/dist/api.d.ts +28 -2
  2. package/dist/api.js +20 -7
  3. package/dist/betterAuth.d.ts +91 -0
  4. package/dist/betterAuth.js +8 -0
  5. package/dist/betterAuth.test.d.ts +1 -0
  6. package/dist/betterAuth.test.js +181 -0
  7. package/dist/betterAuthApp.d.ts +22 -0
  8. package/dist/betterAuthApp.js +38 -0
  9. package/dist/betterAuthApp.test.d.ts +1 -0
  10. package/dist/betterAuthApp.test.js +242 -0
  11. package/dist/betterAuthSetup.d.ts +60 -0
  12. package/dist/betterAuthSetup.js +278 -0
  13. package/dist/betterAuthSetup.test.d.ts +1 -0
  14. package/dist/betterAuthSetup.test.js +684 -0
  15. package/dist/expressServer.js +2 -2
  16. package/dist/index.d.ts +4 -0
  17. package/dist/index.js +4 -0
  18. package/dist/terrenoApp.d.ts +189 -0
  19. package/dist/terrenoApp.js +352 -0
  20. package/dist/terrenoApp.test.d.ts +1 -0
  21. package/dist/terrenoApp.test.js +264 -0
  22. package/dist/terrenoPlugin.d.ts +34 -0
  23. package/package.json +6 -3
  24. package/src/api.ts +61 -3
  25. package/src/betterAuth.test.ts +160 -0
  26. package/src/betterAuth.ts +104 -0
  27. package/src/betterAuthApp.test.ts +114 -0
  28. package/src/betterAuthApp.ts +60 -0
  29. package/src/betterAuthSetup.test.ts +485 -0
  30. package/src/betterAuthSetup.ts +251 -0
  31. package/src/expressServer.ts +4 -5
  32. package/src/index.ts +4 -0
  33. package/src/openApiValidator.ts +1 -1
  34. package/src/terrenoApp.test.ts +201 -0
  35. package/src/terrenoApp.ts +347 -0
  36. package/src/terrenoPlugin.ts +34 -0
  37. package/.claude/CLAUDE.local.md +0 -204
  38. package/.cursor/rules/00-root.mdc +0 -338
  39. package/.github/copilot-instructions.md +0 -333
  40. package/AGENTS.md +0 -333
package/dist/api.d.ts CHANGED
@@ -218,12 +218,38 @@ export interface ModelRouterOptions<T> {
218
218
  */
219
219
  validation?: boolean | ModelRouterValidationOptions;
220
220
  }
221
+ /**
222
+ * Registration object returned by modelRouter when called with a path.
223
+ *
224
+ * Used with `TerrenoApp.register()` to mount model routers at specific paths.
225
+ * Contains the Express router and the path it should be mounted at.
226
+ *
227
+ * @see modelRouter for creating registrations
228
+ * @see TerrenoApp for registering routers
229
+ */
230
+ export interface ModelRouterRegistration {
231
+ /** Internal type discriminator for registration detection */
232
+ __type: "modelRouter";
233
+ /** The path where the router should be mounted (e.g., "/todos") */
234
+ path: string;
235
+ /** The Express router containing CRUD endpoints */
236
+ router: express.Router;
237
+ }
221
238
  /**
222
239
  * Create a set of CRUD routes given a Mongoose model and configuration options.
223
240
  *
224
- * @param model A Mongoose Model
225
- * @param options Options for configuring the REST API, such as permissions, transformers, and hooks.
241
+ * When called with a path as the first argument, returns a `ModelRouterRegistration` that can be
242
+ * passed to `TerrenoApp.register()`.
243
+ *
244
+ * @example
245
+ * // Traditional usage (returns express.Router):
246
+ * router.use("/todos", modelRouter(Todo, options));
247
+ *
248
+ * // Registration usage (returns ModelRouterRegistration):
249
+ * const todoRouter = modelRouter("/todos", Todo, options);
250
+ * app.register(todoRouter);
226
251
  */
252
+ export declare function modelRouter<T>(path: string, model: Model<T>, options: ModelRouterOptions<T>): ModelRouterRegistration;
227
253
  export declare function modelRouter<T>(model: Model<T>, options: ModelRouterOptions<T>): express.Router;
228
254
  /**
229
255
  * Options for the asyncHandler function.
package/dist/api.js CHANGED
@@ -284,13 +284,26 @@ function getQueryValidationMiddleware(model, options) {
284
284
  }
285
285
  return (0, openApiValidator_1.validateQueryParams)(querySchema, validationOptions);
286
286
  }
287
- /**
288
- * Create a set of CRUD routes given a Mongoose model and configuration options.
289
- *
290
- * @param model A Mongoose Model
291
- * @param options Options for configuring the REST API, such as permissions, transformers, and hooks.
292
- */
293
- function modelRouter(model, options) {
287
+ function modelRouter(pathOrModel, modelOrOptions, maybeOptions) {
288
+ var model;
289
+ var options;
290
+ var path;
291
+ if (typeof pathOrModel === "string") {
292
+ path = pathOrModel;
293
+ model = modelOrOptions;
294
+ options = maybeOptions;
295
+ }
296
+ else {
297
+ model = pathOrModel;
298
+ options = modelOrOptions;
299
+ }
300
+ var router = _buildModelRouter(model, options);
301
+ if (path !== undefined) {
302
+ return { __type: "modelRouter", path: path, router: router };
303
+ }
304
+ return router;
305
+ }
306
+ function _buildModelRouter(model, options) {
294
307
  var _this = this;
295
308
  var _a;
296
309
  var router = express_1.default.Router();
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Better Auth types and configuration interfaces for @terreno/api.
3
+ *
4
+ * These types support optional Better Auth integration alongside the existing
5
+ * JWT/Passport authentication system.
6
+ */
7
+ /**
8
+ * OAuth provider configuration for Better Auth.
9
+ */
10
+ export interface BetterAuthOAuthProvider {
11
+ clientId: string;
12
+ clientSecret: string;
13
+ }
14
+ /**
15
+ * Configuration options for Better Auth integration.
16
+ */
17
+ export interface BetterAuthConfig {
18
+ /**
19
+ * Whether Better Auth is enabled for this server.
20
+ */
21
+ enabled: boolean;
22
+ /**
23
+ * Google OAuth provider configuration.
24
+ */
25
+ googleOAuth?: BetterAuthOAuthProvider;
26
+ /**
27
+ * Apple OAuth provider configuration.
28
+ */
29
+ appleOAuth?: BetterAuthOAuthProvider;
30
+ /**
31
+ * GitHub OAuth provider configuration.
32
+ */
33
+ githubOAuth?: BetterAuthOAuthProvider;
34
+ /**
35
+ * Trusted origins for CORS and redirect validation.
36
+ * Include your app's deep link schemes (e.g., "terreno://", "exp://").
37
+ */
38
+ trustedOrigins?: string[];
39
+ /**
40
+ * Base path for Better Auth routes.
41
+ * @default "/api/auth"
42
+ */
43
+ basePath?: string;
44
+ /**
45
+ * Secret key for Better Auth session encryption.
46
+ * If not provided, falls back to BETTER_AUTH_SECRET environment variable.
47
+ */
48
+ secret?: string;
49
+ /**
50
+ * Base URL for the auth server.
51
+ * If not provided, falls back to BETTER_AUTH_URL environment variable.
52
+ */
53
+ baseURL?: string;
54
+ }
55
+ /**
56
+ * Auth provider selection for setupServer.
57
+ * - "jwt": Traditional JWT/Passport authentication (default)
58
+ * - "better-auth": Better Auth with OAuth support
59
+ */
60
+ export type AuthProvider = "jwt" | "better-auth";
61
+ /**
62
+ * User data from Better Auth session.
63
+ */
64
+ export interface BetterAuthUser {
65
+ id: string;
66
+ email: string;
67
+ name: string | null;
68
+ image: string | null;
69
+ emailVerified: boolean;
70
+ createdAt: Date;
71
+ updatedAt: Date;
72
+ }
73
+ /**
74
+ * Session data from Better Auth.
75
+ */
76
+ export interface BetterAuthSession {
77
+ id: string;
78
+ userId: string;
79
+ expiresAt: Date;
80
+ ipAddress: string | null;
81
+ userAgent: string | null;
82
+ createdAt: Date;
83
+ updatedAt: Date;
84
+ }
85
+ /**
86
+ * Combined session and user data from Better Auth.
87
+ */
88
+ export interface BetterAuthSessionData {
89
+ session: BetterAuthSession;
90
+ user: BetterAuthUser;
91
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * Better Auth types and configuration interfaces for @terreno/api.
4
+ *
5
+ * These types support optional Better Auth integration alongside the existing
6
+ * JWT/Passport authentication system.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var bun_test_1 = require("bun:test");
40
+ (0, bun_test_1.describe)("Better Auth types", function () {
41
+ (0, bun_test_1.it)("defines BetterAuthOAuthProvider interface correctly", function () {
42
+ var provider = {
43
+ clientId: "test-client-id",
44
+ clientSecret: "test-client-secret",
45
+ };
46
+ (0, bun_test_1.expect)(provider.clientId).toBe("test-client-id");
47
+ (0, bun_test_1.expect)(provider.clientSecret).toBe("test-client-secret");
48
+ });
49
+ (0, bun_test_1.it)("defines BetterAuthConfig interface correctly", function () {
50
+ var _a, _b;
51
+ var config = {
52
+ basePath: "/api/auth",
53
+ baseURL: "http://localhost:3000",
54
+ enabled: true,
55
+ githubOAuth: {
56
+ clientId: "github-client-id",
57
+ clientSecret: "github-client-secret",
58
+ },
59
+ googleOAuth: {
60
+ clientId: "google-client-id",
61
+ clientSecret: "google-client-secret",
62
+ },
63
+ secret: "test-secret",
64
+ trustedOrigins: ["terreno://", "exp://"],
65
+ };
66
+ (0, bun_test_1.expect)(config.enabled).toBe(true);
67
+ (0, bun_test_1.expect)((_a = config.googleOAuth) === null || _a === void 0 ? void 0 : _a.clientId).toBe("google-client-id");
68
+ (0, bun_test_1.expect)((_b = config.githubOAuth) === null || _b === void 0 ? void 0 : _b.clientId).toBe("github-client-id");
69
+ (0, bun_test_1.expect)(config.trustedOrigins).toContain("terreno://");
70
+ (0, bun_test_1.expect)(config.basePath).toBe("/api/auth");
71
+ });
72
+ (0, bun_test_1.it)("allows minimal BetterAuthConfig", function () {
73
+ var minimalConfig = {
74
+ enabled: false,
75
+ };
76
+ (0, bun_test_1.expect)(minimalConfig.enabled).toBe(false);
77
+ (0, bun_test_1.expect)(minimalConfig.googleOAuth).toBeUndefined();
78
+ (0, bun_test_1.expect)(minimalConfig.basePath).toBeUndefined();
79
+ });
80
+ (0, bun_test_1.it)("defines AuthProvider type correctly", function () {
81
+ var jwtProvider = "jwt";
82
+ var betterAuthProvider = "better-auth";
83
+ (0, bun_test_1.expect)(jwtProvider).toBe("jwt");
84
+ (0, bun_test_1.expect)(betterAuthProvider).toBe("better-auth");
85
+ });
86
+ });
87
+ (0, bun_test_1.describe)("Better Auth setup", function () {
88
+ (0, bun_test_1.it)("syncBetterAuthUser creates a new user when not found", function () { return __awaiter(void 0, void 0, void 0, function () {
89
+ var betterAuthUser;
90
+ return __generator(this, function (_a) {
91
+ betterAuthUser = {
92
+ createdAt: new Date(),
93
+ email: "test@example.com",
94
+ emailVerified: true,
95
+ id: "ba-user-123",
96
+ image: null,
97
+ name: "Test User",
98
+ updatedAt: new Date(),
99
+ };
100
+ (0, bun_test_1.expect)(betterAuthUser.id).toBe("ba-user-123");
101
+ (0, bun_test_1.expect)(betterAuthUser.email).toBe("test@example.com");
102
+ (0, bun_test_1.expect)(betterAuthUser.name).toBe("Test User");
103
+ return [2 /*return*/];
104
+ });
105
+ }); });
106
+ (0, bun_test_1.it)("BetterAuthSession has correct structure", function () {
107
+ var session = {
108
+ createdAt: new Date(),
109
+ expiresAt: new Date(Date.now() + 3600000),
110
+ id: "session-123",
111
+ ipAddress: "127.0.0.1",
112
+ updatedAt: new Date(),
113
+ userAgent: "Mozilla/5.0",
114
+ userId: "user-456",
115
+ };
116
+ (0, bun_test_1.expect)(session.id).toBe("session-123");
117
+ (0, bun_test_1.expect)(session.userId).toBe("user-456");
118
+ (0, bun_test_1.expect)(session.expiresAt.getTime()).toBeGreaterThan(Date.now());
119
+ });
120
+ (0, bun_test_1.it)("BetterAuthSessionData combines session and user", function () {
121
+ var sessionData = {
122
+ session: {
123
+ createdAt: new Date(),
124
+ expiresAt: new Date(),
125
+ id: "session-123",
126
+ ipAddress: null,
127
+ updatedAt: new Date(),
128
+ userAgent: null,
129
+ userId: "user-456",
130
+ },
131
+ user: {
132
+ createdAt: new Date(),
133
+ email: "test@example.com",
134
+ emailVerified: false,
135
+ id: "user-456",
136
+ image: null,
137
+ name: "Test",
138
+ updatedAt: new Date(),
139
+ },
140
+ };
141
+ (0, bun_test_1.expect)(sessionData.session.userId).toBe(sessionData.user.id);
142
+ });
143
+ });
144
+ (0, bun_test_1.describe)("Better Auth config validation", function () {
145
+ (0, bun_test_1.it)("basePath defaults to /api/auth when not specified", function () {
146
+ var _a;
147
+ var config = {
148
+ enabled: true,
149
+ };
150
+ var basePath = (_a = config.basePath) !== null && _a !== void 0 ? _a : "/api/auth";
151
+ (0, bun_test_1.expect)(basePath).toBe("/api/auth");
152
+ });
153
+ (0, bun_test_1.it)("trustedOrigins defaults to empty array when not specified", function () {
154
+ var _a;
155
+ var config = {
156
+ enabled: true,
157
+ };
158
+ var trustedOrigins = (_a = config.trustedOrigins) !== null && _a !== void 0 ? _a : [];
159
+ (0, bun_test_1.expect)(trustedOrigins).toEqual([]);
160
+ });
161
+ (0, bun_test_1.it)("supports multiple OAuth providers simultaneously", function () {
162
+ var config = {
163
+ appleOAuth: {
164
+ clientId: "apple-id",
165
+ clientSecret: "apple-secret",
166
+ },
167
+ enabled: true,
168
+ githubOAuth: {
169
+ clientId: "github-id",
170
+ clientSecret: "github-secret",
171
+ },
172
+ googleOAuth: {
173
+ clientId: "google-id",
174
+ clientSecret: "google-secret",
175
+ },
176
+ };
177
+ (0, bun_test_1.expect)(config.googleOAuth).toBeDefined();
178
+ (0, bun_test_1.expect)(config.githubOAuth).toBeDefined();
179
+ (0, bun_test_1.expect)(config.appleOAuth).toBeDefined();
180
+ });
181
+ });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * BetterAuthApp plugin for @terreno/api.
3
+ *
4
+ * Registers Better Auth as a TerrenoPlugin, mounting routes, session middleware,
5
+ * and user sync on an existing Express application.
6
+ */
7
+ import type express from "express";
8
+ import type { UserModel } from "./auth";
9
+ import type { BetterAuthConfig } from "./betterAuth";
10
+ import { type BetterAuthInstance } from "./betterAuthSetup";
11
+ import type { TerrenoPlugin } from "./terrenoPlugin";
12
+ export interface BetterAuthAppOptions {
13
+ config: BetterAuthConfig;
14
+ userModel?: UserModel;
15
+ }
16
+ export declare class BetterAuthApp implements TerrenoPlugin {
17
+ private auth;
18
+ private options;
19
+ constructor(options: BetterAuthAppOptions);
20
+ register(app: express.Application): void;
21
+ getAuth(): BetterAuthInstance | undefined;
22
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /**
3
+ * BetterAuthApp plugin for @terreno/api.
4
+ *
5
+ * Registers Better Auth as a TerrenoPlugin, mounting routes, session middleware,
6
+ * and user sync on an existing Express application.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.BetterAuthApp = void 0;
10
+ var betterAuthSetup_1 = require("./betterAuthSetup");
11
+ var logger_1 = require("./logger");
12
+ var BetterAuthApp = /** @class */ (function () {
13
+ function BetterAuthApp(options) {
14
+ this.options = options;
15
+ }
16
+ BetterAuthApp.prototype.register = function (app) {
17
+ var _a;
18
+ var _b = this.options, config = _b.config, userModel = _b.userModel;
19
+ var mongoClient = (0, betterAuthSetup_1.getMongoClientFromMongoose)();
20
+ this.auth = (0, betterAuthSetup_1.createBetterAuth)({
21
+ config: config,
22
+ mongoClient: mongoClient,
23
+ userModel: userModel,
24
+ });
25
+ var basePath = (_a = config.basePath) !== null && _a !== void 0 ? _a : "/api/auth";
26
+ (0, betterAuthSetup_1.mountBetterAuthRoutes)(app, this.auth, basePath);
27
+ app.use((0, betterAuthSetup_1.createBetterAuthSessionMiddleware)(this.auth, userModel));
28
+ if (userModel) {
29
+ (0, betterAuthSetup_1.setupBetterAuthUserSync)(this.auth, userModel);
30
+ }
31
+ logger_1.logger.info("Better Auth initialized via BetterAuthApp plugin");
32
+ };
33
+ BetterAuthApp.prototype.getAuth = function () {
34
+ return this.auth;
35
+ };
36
+ return BetterAuthApp;
37
+ }());
38
+ exports.BetterAuthApp = BetterAuthApp;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
47
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
48
+ return new (P || (P = Promise))(function (resolve, reject) {
49
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
50
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
51
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
52
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
53
+ });
54
+ };
55
+ var __generator = (this && this.__generator) || function (thisArg, body) {
56
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
57
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
58
+ function verb(n) { return function (v) { return step([n, v]); }; }
59
+ function step(op) {
60
+ if (f) throw new TypeError("Generator is already executing.");
61
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
62
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
63
+ if (y = 0, t) op = [op[0] & 2, t.value];
64
+ switch (op[0]) {
65
+ case 0: case 1: t = op; break;
66
+ case 4: _.label++; return { value: op[1], done: false };
67
+ case 5: _.label++; y = op[1]; op = [0]; continue;
68
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
69
+ default:
70
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
71
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
72
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
73
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
74
+ if (t[2]) _.ops.pop();
75
+ _.trys.pop(); continue;
76
+ }
77
+ op = body.call(thisArg, _);
78
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
79
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
80
+ }
81
+ };
82
+ var __importDefault = (this && this.__importDefault) || function (mod) {
83
+ return (mod && mod.__esModule) ? mod : { "default": mod };
84
+ };
85
+ Object.defineProperty(exports, "__esModule", { value: true });
86
+ var bun_test_1 = require("bun:test");
87
+ var express_1 = __importDefault(require("express"));
88
+ var mongodb_memory_server_1 = require("mongodb-memory-server");
89
+ var mongoose_1 = __importStar(require("mongoose"));
90
+ var betterAuthApp_1 = require("./betterAuthApp");
91
+ var conn;
92
+ var mongod;
93
+ var TestUser;
94
+ var testUserSchema = new mongoose_1.Schema({
95
+ admin: { default: false, type: Boolean },
96
+ betterAuthId: { type: String },
97
+ email: { required: true, type: String },
98
+ name: { type: String },
99
+ oauthProvider: { type: String },
100
+ });
101
+ var setup = (function () { return __awaiter(void 0, void 0, void 0, function () {
102
+ return __generator(this, function (_a) {
103
+ switch (_a.label) {
104
+ case 0: return [4 /*yield*/, mongodb_memory_server_1.MongoMemoryServer.create()];
105
+ case 1:
106
+ mongod = _a.sent();
107
+ conn = mongoose_1.default.createConnection(mongod.getUri());
108
+ return [4 /*yield*/, conn.asPromise()];
109
+ case 2:
110
+ _a.sent();
111
+ TestUser = conn.model("BetterAuthAppTestUser", testUserSchema);
112
+ return [2 /*return*/];
113
+ }
114
+ });
115
+ }); })();
116
+ (0, bun_test_1.afterAll)(function () { return __awaiter(void 0, void 0, void 0, function () {
117
+ return __generator(this, function (_a) {
118
+ switch (_a.label) {
119
+ case 0: return [4 /*yield*/, (conn === null || conn === void 0 ? void 0 : conn.close())];
120
+ case 1:
121
+ _a.sent();
122
+ return [4 /*yield*/, (mongod === null || mongod === void 0 ? void 0 : mongod.stop())];
123
+ case 2:
124
+ _a.sent();
125
+ return [2 /*return*/];
126
+ }
127
+ });
128
+ }); });
129
+ (0, bun_test_1.afterEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
130
+ return __generator(this, function (_a) {
131
+ switch (_a.label) {
132
+ case 0: return [4 /*yield*/, setup];
133
+ case 1:
134
+ _a.sent();
135
+ return [4 /*yield*/, TestUser.deleteMany({})];
136
+ case 2:
137
+ _a.sent();
138
+ return [2 /*return*/];
139
+ }
140
+ });
141
+ }); });
142
+ (0, bun_test_1.describe)("BetterAuthApp", function () {
143
+ var makeConfig = function (overrides) {
144
+ if (overrides === void 0) { overrides = {}; }
145
+ return (__assign({ baseURL: "http://localhost:3000", enabled: true, secret: "test-secret-at-least-32-characters-long" }, overrides));
146
+ };
147
+ (0, bun_test_1.it)("registers on an express app without throwing", function () { return __awaiter(void 0, void 0, void 0, function () {
148
+ var app, plugin;
149
+ return __generator(this, function (_a) {
150
+ switch (_a.label) {
151
+ case 0: return [4 /*yield*/, setup];
152
+ case 1:
153
+ _a.sent();
154
+ app = (0, express_1.default)();
155
+ app.use(express_1.default.json());
156
+ plugin = new betterAuthApp_1.BetterAuthApp({
157
+ config: makeConfig(),
158
+ });
159
+ (0, bun_test_1.expect)(function () { return plugin.register(app); }).not.toThrow();
160
+ return [2 /*return*/];
161
+ }
162
+ });
163
+ }); });
164
+ (0, bun_test_1.it)("exposes the Better Auth instance after register", function () { return __awaiter(void 0, void 0, void 0, function () {
165
+ var app, plugin;
166
+ var _a;
167
+ return __generator(this, function (_b) {
168
+ switch (_b.label) {
169
+ case 0: return [4 /*yield*/, setup];
170
+ case 1:
171
+ _b.sent();
172
+ app = (0, express_1.default)();
173
+ app.use(express_1.default.json());
174
+ plugin = new betterAuthApp_1.BetterAuthApp({
175
+ config: makeConfig(),
176
+ });
177
+ (0, bun_test_1.expect)(plugin.getAuth()).toBeUndefined();
178
+ plugin.register(app);
179
+ (0, bun_test_1.expect)(plugin.getAuth()).toBeDefined();
180
+ (0, bun_test_1.expect)((_a = plugin.getAuth()) === null || _a === void 0 ? void 0 : _a.api).toBeDefined();
181
+ return [2 /*return*/];
182
+ }
183
+ });
184
+ }); });
185
+ (0, bun_test_1.it)("registers with a userModel", function () { return __awaiter(void 0, void 0, void 0, function () {
186
+ var app, plugin;
187
+ return __generator(this, function (_a) {
188
+ switch (_a.label) {
189
+ case 0: return [4 /*yield*/, setup];
190
+ case 1:
191
+ _a.sent();
192
+ app = (0, express_1.default)();
193
+ app.use(express_1.default.json());
194
+ plugin = new betterAuthApp_1.BetterAuthApp({
195
+ config: makeConfig(),
196
+ userModel: TestUser,
197
+ });
198
+ (0, bun_test_1.expect)(function () { return plugin.register(app); }).not.toThrow();
199
+ (0, bun_test_1.expect)(plugin.getAuth()).toBeDefined();
200
+ return [2 /*return*/];
201
+ }
202
+ });
203
+ }); });
204
+ (0, bun_test_1.it)("registers with a custom basePath", function () { return __awaiter(void 0, void 0, void 0, function () {
205
+ var app, plugin;
206
+ return __generator(this, function (_a) {
207
+ switch (_a.label) {
208
+ case 0: return [4 /*yield*/, setup];
209
+ case 1:
210
+ _a.sent();
211
+ app = (0, express_1.default)();
212
+ app.use(express_1.default.json());
213
+ plugin = new betterAuthApp_1.BetterAuthApp({
214
+ config: makeConfig({ basePath: "/custom/auth" }),
215
+ });
216
+ (0, bun_test_1.expect)(function () { return plugin.register(app); }).not.toThrow();
217
+ return [2 /*return*/];
218
+ }
219
+ });
220
+ }); });
221
+ (0, bun_test_1.it)("registers with social providers", function () { return __awaiter(void 0, void 0, void 0, function () {
222
+ var app, plugin;
223
+ return __generator(this, function (_a) {
224
+ switch (_a.label) {
225
+ case 0: return [4 /*yield*/, setup];
226
+ case 1:
227
+ _a.sent();
228
+ app = (0, express_1.default)();
229
+ app.use(express_1.default.json());
230
+ plugin = new betterAuthApp_1.BetterAuthApp({
231
+ config: makeConfig({
232
+ githubOAuth: { clientId: "gh-id", clientSecret: "gh-secret" },
233
+ googleOAuth: { clientId: "g-id", clientSecret: "g-secret" },
234
+ }),
235
+ });
236
+ (0, bun_test_1.expect)(function () { return plugin.register(app); }).not.toThrow();
237
+ (0, bun_test_1.expect)(plugin.getAuth()).toBeDefined();
238
+ return [2 /*return*/];
239
+ }
240
+ });
241
+ }); });
242
+ });