@proofkit/better-auth 0.2.4 → 0.3.1-beta.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.
- package/dist/esm/adapter.d.ts +3 -3
- package/dist/esm/adapter.js +141 -76
- package/dist/esm/adapter.js.map +1 -1
- package/dist/esm/better-auth-cli/utils/add-svelte-kit-env-modules.js +4 -12
- package/dist/esm/better-auth-cli/utils/add-svelte-kit-env-modules.js.map +1 -1
- package/dist/esm/better-auth-cli/utils/get-config.js +12 -21
- package/dist/esm/better-auth-cli/utils/get-config.js.map +1 -1
- package/dist/esm/better-auth-cli/utils/get-tsconfig-info.js +4 -11
- package/dist/esm/better-auth-cli/utils/get-tsconfig-info.js.map +1 -1
- package/dist/esm/cli/index.js +14 -26
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/migrate.d.ts +6 -6
- package/dist/esm/migrate.js +72 -44
- package/dist/esm/migrate.js.map +1 -1
- package/dist/esm/odata/index.d.ts +17 -91
- package/dist/esm/odata/index.js +141 -67
- package/dist/esm/odata/index.js.map +1 -1
- package/package.json +9 -7
- package/src/adapter.ts +171 -93
- package/src/better-auth-cli/utils/add-svelte-kit-env-modules.ts +68 -80
- package/src/better-auth-cli/utils/get-config.ts +16 -30
- package/src/better-auth-cli/utils/get-tsconfig-info.ts +12 -20
- package/src/cli/index.ts +13 -31
- package/src/index.ts +1 -0
- package/src/migrate.ts +87 -74
- package/src/odata/index.ts +195 -78
package/src/adapter.ts
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
CleanedWhere,
|
|
3
|
-
createAdapter,
|
|
4
|
-
type AdapterDebugLogs,
|
|
5
|
-
} from "better-auth/adapters";
|
|
6
|
-
import { createFmOdataFetch, type FmOdataConfig } from "./odata";
|
|
7
|
-
import { prettifyError, z } from "zod/v4";
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: library code */
|
|
8
2
|
import { logger } from "better-auth";
|
|
3
|
+
import { type AdapterDebugLogs, type CleanedWhere, createAdapter } from "better-auth/adapters";
|
|
4
|
+
import buildQuery from "odata-query";
|
|
5
|
+
import { prettifyError, z } from "zod/v4";
|
|
6
|
+
import { createRawFetch, type FmOdataConfig } from "./odata";
|
|
9
7
|
|
|
10
8
|
const configSchema = z.object({
|
|
11
9
|
debugLogs: z.unknown().optional(),
|
|
12
10
|
usePlural: z.boolean().optional(),
|
|
13
11
|
odata: z.object({
|
|
14
12
|
serverUrl: z.url(),
|
|
15
|
-
auth: z.union([
|
|
16
|
-
z.object({ username: z.string(), password: z.string() }),
|
|
17
|
-
z.object({ apiKey: z.string() }),
|
|
18
|
-
]),
|
|
13
|
+
auth: z.union([z.object({ username: z.string(), password: z.string() }), z.object({ apiKey: z.string() })]),
|
|
19
14
|
database: z.string().endsWith(".fmp12"),
|
|
20
15
|
}),
|
|
21
16
|
});
|
|
@@ -36,9 +31,9 @@ interface FileMakerAdapterConfig {
|
|
|
36
31
|
odata: FmOdataConfig;
|
|
37
32
|
}
|
|
38
33
|
|
|
39
|
-
export
|
|
34
|
+
export interface AdapterOptions {
|
|
40
35
|
config: FileMakerAdapterConfig;
|
|
41
|
-
}
|
|
36
|
+
}
|
|
42
37
|
|
|
43
38
|
const defaultConfig: Required<FileMakerAdapterConfig> = {
|
|
44
39
|
debugLogs: false,
|
|
@@ -50,6 +45,10 @@ const defaultConfig: Required<FileMakerAdapterConfig> = {
|
|
|
50
45
|
},
|
|
51
46
|
};
|
|
52
47
|
|
|
48
|
+
// Regex patterns for field validation and ISO date detection
|
|
49
|
+
const FIELD_SPECIAL_CHARS_REGEX = /[\s_]/;
|
|
50
|
+
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/;
|
|
51
|
+
|
|
53
52
|
/**
|
|
54
53
|
* Parse the where clause to an OData filter string.
|
|
55
54
|
* @param where - The where clause to parse.
|
|
@@ -57,29 +56,42 @@ const defaultConfig: Required<FileMakerAdapterConfig> = {
|
|
|
57
56
|
* @internal
|
|
58
57
|
*/
|
|
59
58
|
export function parseWhere(where?: CleanedWhere[]): string {
|
|
60
|
-
if (!where || where.length === 0)
|
|
59
|
+
if (!where || where.length === 0) {
|
|
60
|
+
return "";
|
|
61
|
+
}
|
|
61
62
|
|
|
62
63
|
// Helper to quote field names with special chars or if field is 'id'
|
|
63
64
|
function quoteField(field: string, value?: any) {
|
|
64
65
|
// Never quote for null or date values (per test expectations)
|
|
65
|
-
if (value === null || value instanceof Date)
|
|
66
|
+
if (value === null || value instanceof Date) {
|
|
67
|
+
return field;
|
|
68
|
+
}
|
|
66
69
|
// Always quote if field is 'id' or has space or underscore
|
|
67
|
-
if (field === "id" ||
|
|
70
|
+
if (field === "id" || FIELD_SPECIAL_CHARS_REGEX.test(field)) {
|
|
71
|
+
return `"${field}"`;
|
|
72
|
+
}
|
|
68
73
|
return field;
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
// Helper to format values for OData
|
|
72
77
|
function formatValue(value: any): string {
|
|
73
|
-
if (value === null)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (
|
|
78
|
+
if (value === null) {
|
|
79
|
+
return "null";
|
|
80
|
+
}
|
|
81
|
+
if (typeof value === "boolean") {
|
|
82
|
+
return value ? "true" : "false";
|
|
83
|
+
}
|
|
84
|
+
if (value instanceof Date) {
|
|
85
|
+
return value.toISOString();
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(value)) {
|
|
88
|
+
return `(${value.map(formatValue).join(",")})`;
|
|
89
|
+
}
|
|
77
90
|
|
|
78
91
|
// Handle strings - check if it's an ISO date string first
|
|
79
92
|
if (typeof value === "string") {
|
|
80
93
|
// Check if it's an ISO date string (YYYY-MM-DDTHH:mm:ss.sssZ format)
|
|
81
|
-
|
|
82
|
-
if (isoDateRegex.test(value)) {
|
|
94
|
+
if (ISO_DATE_REGEX.test(value)) {
|
|
83
95
|
return value; // Return ISO date strings without quotes
|
|
84
96
|
}
|
|
85
97
|
return `'${value.replace(/'/g, "''")}'`; // Regular strings get quotes
|
|
@@ -102,7 +114,9 @@ export function parseWhere(where?: CleanedWhere[]): string {
|
|
|
102
114
|
const clauses: string[] = [];
|
|
103
115
|
for (let i = 0; i < where.length; i++) {
|
|
104
116
|
const cond = where[i];
|
|
105
|
-
if (!cond)
|
|
117
|
+
if (!cond) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
106
120
|
const field = quoteField(cond.field, cond.value);
|
|
107
121
|
let clause = "";
|
|
108
122
|
switch (cond.operator) {
|
|
@@ -112,13 +126,11 @@ export function parseWhere(where?: CleanedWhere[]): string {
|
|
|
112
126
|
case "lte":
|
|
113
127
|
case "gt":
|
|
114
128
|
case "gte":
|
|
115
|
-
clause = `${field} ${opMap[cond.operator
|
|
129
|
+
clause = `${field} ${opMap[cond.operator]} ${formatValue(cond.value)}`;
|
|
116
130
|
break;
|
|
117
131
|
case "in":
|
|
118
132
|
if (Array.isArray(cond.value)) {
|
|
119
|
-
clause = cond.value
|
|
120
|
-
.map((v) => `${field} eq ${formatValue(v)}`)
|
|
121
|
-
.join(" or ");
|
|
133
|
+
clause = cond.value.map((v) => `${field} eq ${formatValue(v)}`).join(" or ");
|
|
122
134
|
clause = `(${clause})`;
|
|
123
135
|
}
|
|
124
136
|
break;
|
|
@@ -143,9 +155,7 @@ export function parseWhere(where?: CleanedWhere[]): string {
|
|
|
143
155
|
return clauses.join(" ");
|
|
144
156
|
}
|
|
145
157
|
|
|
146
|
-
export const FileMakerAdapter = (
|
|
147
|
-
_config: FileMakerAdapterConfig = defaultConfig,
|
|
148
|
-
) => {
|
|
158
|
+
export const FileMakerAdapter = (_config: FileMakerAdapterConfig = defaultConfig) => {
|
|
149
159
|
const parsed = configSchema.loose().safeParse(_config);
|
|
150
160
|
|
|
151
161
|
if (!parsed.success) {
|
|
@@ -153,7 +163,7 @@ export const FileMakerAdapter = (
|
|
|
153
163
|
}
|
|
154
164
|
const config = parsed.data;
|
|
155
165
|
|
|
156
|
-
const fetch =
|
|
166
|
+
const { fetch } = createRawFetch({
|
|
157
167
|
...config.odata,
|
|
158
168
|
logging: config.debugLogs ? "verbose" : "none",
|
|
159
169
|
});
|
|
@@ -169,10 +179,9 @@ export const FileMakerAdapter = (
|
|
|
169
179
|
supportsBooleans: false, // Whether the database supports booleans. (Default: true)
|
|
170
180
|
supportsNumericIds: false, // Whether the database supports auto-incrementing numeric IDs. (Default: true)
|
|
171
181
|
},
|
|
172
|
-
adapter: (
|
|
182
|
+
adapter: () => {
|
|
173
183
|
return {
|
|
174
|
-
|
|
175
|
-
create: async ({ data, model, select }) => {
|
|
184
|
+
create: async ({ data, model }) => {
|
|
176
185
|
if (model === "session") {
|
|
177
186
|
console.log("session", data);
|
|
178
187
|
}
|
|
@@ -192,114 +201,183 @@ export const FileMakerAdapter = (
|
|
|
192
201
|
count: async ({ model, where }) => {
|
|
193
202
|
const filter = parseWhere(where);
|
|
194
203
|
logger.debug("$filter", filter);
|
|
195
|
-
|
|
204
|
+
|
|
205
|
+
const query = buildQuery({
|
|
206
|
+
filter: filter.length > 0 ? filter : undefined,
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
const result = await fetch(`/${model}/$count${query}`, {
|
|
196
210
|
method: "GET",
|
|
197
|
-
query: {
|
|
198
|
-
$filter: filter,
|
|
199
|
-
},
|
|
200
211
|
output: z.object({ value: z.number() }),
|
|
201
212
|
});
|
|
202
213
|
if (!result.data) {
|
|
203
214
|
throw new Error("Failed to count records");
|
|
204
215
|
}
|
|
205
|
-
return result.data?.value ?? 0;
|
|
216
|
+
return (result.data?.value as any) ?? 0;
|
|
206
217
|
},
|
|
207
218
|
findOne: async ({ model, where }) => {
|
|
208
219
|
const filter = parseWhere(where);
|
|
209
220
|
logger.debug("$filter", filter);
|
|
210
|
-
|
|
221
|
+
|
|
222
|
+
const query = buildQuery({
|
|
223
|
+
top: 1,
|
|
224
|
+
filter: filter.length > 0 ? filter : undefined,
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const result = await fetch(`/${model}${query}`, {
|
|
211
228
|
method: "GET",
|
|
212
|
-
query: {
|
|
213
|
-
...(filter.length > 0 ? { $filter: filter } : {}),
|
|
214
|
-
$top: 1,
|
|
215
|
-
},
|
|
216
229
|
output: z.object({ value: z.array(z.any()) }),
|
|
217
230
|
});
|
|
218
231
|
if (result.error) {
|
|
219
232
|
throw new Error("Failed to find record");
|
|
220
233
|
}
|
|
221
|
-
return result.data?.value?.[0] ?? null;
|
|
234
|
+
return (result.data?.value?.[0] as any) ?? null;
|
|
222
235
|
},
|
|
223
236
|
findMany: async ({ model, where, limit, offset, sortBy }) => {
|
|
224
237
|
const filter = parseWhere(where);
|
|
225
|
-
logger.debug("
|
|
238
|
+
logger.debug("FIND MANY", { where, filter });
|
|
226
239
|
|
|
227
|
-
const
|
|
240
|
+
const query = buildQuery({
|
|
241
|
+
top: limit,
|
|
242
|
+
skip: offset,
|
|
243
|
+
orderBy: sortBy ? `${sortBy.field} ${sortBy.direction ?? "asc"}` : undefined,
|
|
244
|
+
filter: filter.length > 0 ? filter : undefined,
|
|
245
|
+
});
|
|
246
|
+
logger.debug("QUERY", query);
|
|
247
|
+
|
|
248
|
+
const result = await fetch(`/${model}${query}`, {
|
|
228
249
|
method: "GET",
|
|
229
|
-
query: {
|
|
230
|
-
...(filter.length > 0 ? { $filter: filter } : {}),
|
|
231
|
-
$top: limit,
|
|
232
|
-
$skip: offset,
|
|
233
|
-
...(sortBy
|
|
234
|
-
? { $orderby: `"${sortBy.field}" ${sortBy.direction ?? "asc"}` }
|
|
235
|
-
: {}),
|
|
236
|
-
},
|
|
237
250
|
output: z.object({ value: z.array(z.any()) }),
|
|
238
251
|
});
|
|
239
|
-
|
|
252
|
+
logger.debug("RESULT", result);
|
|
253
|
+
|
|
254
|
+
if (result.error) {
|
|
240
255
|
throw new Error("Failed to find records");
|
|
241
256
|
}
|
|
242
|
-
|
|
257
|
+
|
|
258
|
+
return (result.data?.value as any) ?? [];
|
|
243
259
|
},
|
|
244
260
|
delete: async ({ model, where }) => {
|
|
245
261
|
const filter = parseWhere(where);
|
|
262
|
+
console.log("DELETE", { model, where, filter });
|
|
246
263
|
logger.debug("$filter", filter);
|
|
247
|
-
|
|
248
|
-
|
|
264
|
+
|
|
265
|
+
// Find a single id matching the filter
|
|
266
|
+
const query = buildQuery({
|
|
267
|
+
top: 1,
|
|
268
|
+
select: [`"id"`],
|
|
269
|
+
filter: filter.length > 0 ? filter : undefined,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
const toDelete = await fetch(`/${model}${query}`, {
|
|
273
|
+
method: "GET",
|
|
274
|
+
output: z.object({ value: z.array(z.object({ id: z.string() })) }),
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
const id = toDelete.data?.value?.[0]?.id;
|
|
278
|
+
if (!id) {
|
|
279
|
+
// Nothing to delete
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const result = await fetch(`/${model}('${id}')`, {
|
|
249
284
|
method: "DELETE",
|
|
250
|
-
query: {
|
|
251
|
-
...(where.length > 0 ? { $filter: filter } : {}),
|
|
252
|
-
$top: 1,
|
|
253
|
-
},
|
|
254
285
|
});
|
|
255
286
|
if (result.error) {
|
|
287
|
+
console.log("DELETE ERROR", result.error);
|
|
256
288
|
throw new Error("Failed to delete record");
|
|
257
289
|
}
|
|
258
290
|
},
|
|
259
291
|
deleteMany: async ({ model, where }) => {
|
|
260
292
|
const filter = parseWhere(where);
|
|
261
|
-
|
|
262
|
-
where
|
|
263
|
-
.map((o) => `typeof ${o.value} is ${typeof o.value}`)
|
|
264
|
-
.join("\n"),
|
|
265
|
-
);
|
|
266
|
-
logger.debug("$filter", filter);
|
|
293
|
+
console.log("DELETE MANY", { model, where, filter });
|
|
267
294
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
},
|
|
273
|
-
output: z.coerce.number(),
|
|
295
|
+
// Find all ids matching the filter
|
|
296
|
+
const query = buildQuery({
|
|
297
|
+
select: [`"id"`],
|
|
298
|
+
filter: filter.length > 0 ? filter : undefined,
|
|
274
299
|
});
|
|
275
|
-
|
|
276
|
-
|
|
300
|
+
|
|
301
|
+
const rows = await fetch(`/${model}${query}`, {
|
|
302
|
+
method: "GET",
|
|
303
|
+
output: z.object({ value: z.array(z.object({ id: z.string() })) }),
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
const ids = rows.data?.value?.map((r: any) => r.id) ?? [];
|
|
307
|
+
let deleted = 0;
|
|
308
|
+
for (const id of ids) {
|
|
309
|
+
const res = await fetch(`/${model}('${id}')`, {
|
|
310
|
+
method: "DELETE",
|
|
311
|
+
});
|
|
312
|
+
if (!res.error) {
|
|
313
|
+
deleted++;
|
|
314
|
+
}
|
|
277
315
|
}
|
|
278
|
-
return
|
|
316
|
+
return deleted;
|
|
279
317
|
},
|
|
280
318
|
update: async ({ model, where, update }) => {
|
|
281
|
-
const
|
|
319
|
+
const filter = parseWhere(where);
|
|
320
|
+
logger.debug("UPDATE", { model, where, update });
|
|
321
|
+
logger.debug("$filter", filter);
|
|
322
|
+
// Find one id to update
|
|
323
|
+
const query = buildQuery({
|
|
324
|
+
select: [`"id"`],
|
|
325
|
+
filter: filter.length > 0 ? filter : undefined,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
const existing = await fetch(`/${model}${query}`, {
|
|
329
|
+
method: "GET",
|
|
330
|
+
output: z.object({ value: z.array(z.object({ id: z.string() })) }),
|
|
331
|
+
});
|
|
332
|
+
logger.debug("EXISTING", existing.data);
|
|
333
|
+
|
|
334
|
+
const id = existing.data?.value?.[0]?.id;
|
|
335
|
+
if (!id) {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const patchRes = await fetch(`/${model}('${id}')`, {
|
|
282
340
|
method: "PATCH",
|
|
283
|
-
query: {
|
|
284
|
-
...(where.length > 0 ? { $filter: parseWhere(where) } : {}),
|
|
285
|
-
$top: 1,
|
|
286
|
-
$select: [`"id"`],
|
|
287
|
-
},
|
|
288
341
|
body: update,
|
|
289
|
-
output: z.object({ value: z.array(z.any()) }),
|
|
290
342
|
});
|
|
291
|
-
|
|
343
|
+
logger.debug("PATCH RES", patchRes.data);
|
|
344
|
+
if (patchRes.error) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Read back the updated record
|
|
349
|
+
const readBack = await fetch(`/${model}('${id}')`, {
|
|
350
|
+
method: "GET",
|
|
351
|
+
output: z.record(z.string(), z.unknown()),
|
|
352
|
+
});
|
|
353
|
+
logger.debug("READ BACK", readBack.data);
|
|
354
|
+
return (readBack.data as any) ?? null;
|
|
292
355
|
},
|
|
293
356
|
updateMany: async ({ model, where, update }) => {
|
|
294
357
|
const filter = parseWhere(where);
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
},
|
|
300
|
-
body: update,
|
|
358
|
+
// Find all ids matching the filter
|
|
359
|
+
const query = buildQuery({
|
|
360
|
+
select: [`"id"`],
|
|
361
|
+
filter: filter.length > 0 ? filter : undefined,
|
|
301
362
|
});
|
|
302
|
-
|
|
363
|
+
|
|
364
|
+
const rows = await fetch(`/${model}${query}`, {
|
|
365
|
+
method: "GET",
|
|
366
|
+
output: z.object({ value: z.array(z.object({ id: z.string() })) }),
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
const ids = rows.data?.value?.map((r: any) => r.id) ?? [];
|
|
370
|
+
let updated = 0;
|
|
371
|
+
for (const id of ids) {
|
|
372
|
+
const res = await fetch(`/${model}('${id}')`, {
|
|
373
|
+
method: "PATCH",
|
|
374
|
+
body: update,
|
|
375
|
+
});
|
|
376
|
+
if (!res.error) {
|
|
377
|
+
updated++;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return updated as any;
|
|
303
381
|
},
|
|
304
382
|
};
|
|
305
383
|
},
|
|
@@ -1,108 +1,96 @@
|
|
|
1
1
|
export function addSvelteKitEnvModules(aliases: Record<string, string>) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
createDynamicEnvModule(),
|
|
7
|
-
);
|
|
8
|
-
aliases["$env/static/private"] = createDataUriModule(
|
|
9
|
-
createStaticEnvModule(filterPrivateEnv("PUBLIC_", "")),
|
|
10
|
-
);
|
|
11
|
-
aliases["$env/static/public"] = createDataUriModule(
|
|
12
|
-
createStaticEnvModule(filterPublicEnv("PUBLIC_", "")),
|
|
13
|
-
);
|
|
2
|
+
aliases["$env/dynamic/private"] = createDataUriModule(createDynamicEnvModule());
|
|
3
|
+
aliases["$env/dynamic/public"] = createDataUriModule(createDynamicEnvModule());
|
|
4
|
+
aliases["$env/static/private"] = createDataUriModule(createStaticEnvModule(filterPrivateEnv("PUBLIC_", "")));
|
|
5
|
+
aliases["$env/static/public"] = createDataUriModule(createStaticEnvModule(filterPublicEnv("PUBLIC_", "")));
|
|
14
6
|
}
|
|
15
7
|
|
|
16
8
|
function createDataUriModule(module: string) {
|
|
17
|
-
|
|
9
|
+
return `data:text/javascript;charset=utf-8,${encodeURIComponent(module)}`;
|
|
18
10
|
}
|
|
19
11
|
|
|
20
12
|
function createStaticEnvModule(env: Record<string, string>) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
const declarations = Object.keys(env)
|
|
14
|
+
.filter((k) => validIdentifier.test(k) && !reserved.has(k))
|
|
15
|
+
.map((k) => `export const ${k} = ${JSON.stringify(env[k])};`);
|
|
24
16
|
|
|
25
|
-
|
|
17
|
+
return `
|
|
26
18
|
${declarations.join("\n")}
|
|
27
19
|
// jiti dirty hack: .unknown
|
|
28
20
|
`;
|
|
29
21
|
}
|
|
30
22
|
|
|
31
23
|
function createDynamicEnvModule() {
|
|
32
|
-
|
|
24
|
+
return `
|
|
33
25
|
export const env = process.env;
|
|
34
26
|
// jiti dirty hack: .unknown
|
|
35
27
|
`;
|
|
36
28
|
}
|
|
37
29
|
|
|
38
30
|
export function filterPrivateEnv(publicPrefix: string, privatePrefix: string) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
),
|
|
45
|
-
) as Record<string, string>;
|
|
31
|
+
return Object.fromEntries(
|
|
32
|
+
Object.entries(process.env).filter(
|
|
33
|
+
([k]) => k.startsWith(privatePrefix) && (publicPrefix === "" || !k.startsWith(publicPrefix)),
|
|
34
|
+
),
|
|
35
|
+
) as Record<string, string>;
|
|
46
36
|
}
|
|
47
37
|
|
|
48
38
|
export function filterPublicEnv(publicPrefix: string, privatePrefix: string) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
),
|
|
55
|
-
) as Record<string, string>;
|
|
39
|
+
return Object.fromEntries(
|
|
40
|
+
Object.entries(process.env).filter(
|
|
41
|
+
([k]) => k.startsWith(publicPrefix) && (privatePrefix === "" || !k.startsWith(privatePrefix)),
|
|
42
|
+
),
|
|
43
|
+
) as Record<string, string>;
|
|
56
44
|
}
|
|
57
45
|
|
|
58
46
|
const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
59
47
|
const reserved = new Set([
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
48
|
+
"do",
|
|
49
|
+
"if",
|
|
50
|
+
"in",
|
|
51
|
+
"for",
|
|
52
|
+
"let",
|
|
53
|
+
"new",
|
|
54
|
+
"try",
|
|
55
|
+
"var",
|
|
56
|
+
"case",
|
|
57
|
+
"else",
|
|
58
|
+
"enum",
|
|
59
|
+
"eval",
|
|
60
|
+
"null",
|
|
61
|
+
"this",
|
|
62
|
+
"true",
|
|
63
|
+
"void",
|
|
64
|
+
"with",
|
|
65
|
+
"await",
|
|
66
|
+
"break",
|
|
67
|
+
"catch",
|
|
68
|
+
"class",
|
|
69
|
+
"const",
|
|
70
|
+
"false",
|
|
71
|
+
"super",
|
|
72
|
+
"throw",
|
|
73
|
+
"while",
|
|
74
|
+
"yield",
|
|
75
|
+
"delete",
|
|
76
|
+
"export",
|
|
77
|
+
"import",
|
|
78
|
+
"public",
|
|
79
|
+
"return",
|
|
80
|
+
"static",
|
|
81
|
+
"switch",
|
|
82
|
+
"typeof",
|
|
83
|
+
"default",
|
|
84
|
+
"extends",
|
|
85
|
+
"finally",
|
|
86
|
+
"package",
|
|
87
|
+
"private",
|
|
88
|
+
"continue",
|
|
89
|
+
"debugger",
|
|
90
|
+
"function",
|
|
91
|
+
"arguments",
|
|
92
|
+
"interface",
|
|
93
|
+
"protected",
|
|
94
|
+
"implements",
|
|
95
|
+
"instanceof",
|
|
108
96
|
]);
|
|
@@ -1,24 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { logger } from "better-auth";
|
|
4
|
-
import path from "path";
|
|
5
|
-
// @ts-expect-error not typed
|
|
6
|
-
import babelPresetTypeScript from "@babel/preset-typescript";
|
|
1
|
+
import fs, { existsSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
7
3
|
// @ts-expect-error not typed
|
|
8
4
|
import babelPresetReact from "@babel/preset-react";
|
|
9
|
-
|
|
10
|
-
import
|
|
5
|
+
// @ts-expect-error not typed
|
|
6
|
+
import babelPresetTypeScript from "@babel/preset-typescript";
|
|
7
|
+
import type { BetterAuthOptions } from "better-auth";
|
|
8
|
+
import { BetterAuthError, logger } from "better-auth";
|
|
9
|
+
import { loadConfig } from "c12";
|
|
11
10
|
import { addSvelteKitEnvModules } from "./add-svelte-kit-env-modules";
|
|
12
11
|
import { getTsconfigInfo } from "./get-tsconfig-info";
|
|
13
12
|
|
|
14
|
-
let possiblePaths = [
|
|
15
|
-
"auth.ts",
|
|
16
|
-
"auth.tsx",
|
|
17
|
-
"auth.js",
|
|
18
|
-
"auth.jsx",
|
|
19
|
-
"auth.server.js",
|
|
20
|
-
"auth.server.ts",
|
|
21
|
-
];
|
|
13
|
+
let possiblePaths = ["auth.ts", "auth.tsx", "auth.js", "auth.jsx", "auth.server.js", "auth.server.ts"];
|
|
22
14
|
|
|
23
15
|
possiblePaths = [
|
|
24
16
|
...possiblePaths,
|
|
@@ -47,10 +39,7 @@ function getPathAliases(cwd: string): Record<string, string> | null {
|
|
|
47
39
|
for (const aliasedPath of aliasPaths) {
|
|
48
40
|
const resolvedBaseUrl = path.join(cwd, baseUrl);
|
|
49
41
|
const finalAlias = alias.slice(-1) === "*" ? alias.slice(0, -1) : alias;
|
|
50
|
-
const finalAliasedPath =
|
|
51
|
-
aliasedPath.slice(-1) === "*"
|
|
52
|
-
? aliasedPath.slice(0, -1)
|
|
53
|
-
: aliasedPath;
|
|
42
|
+
const finalAliasedPath = aliasedPath.slice(-1) === "*" ? aliasedPath.slice(0, -1) : aliasedPath;
|
|
54
43
|
|
|
55
44
|
result[finalAlias || ""] = path.join(resolvedBaseUrl, finalAliasedPath);
|
|
56
45
|
}
|
|
@@ -99,7 +88,9 @@ export async function getConfig({
|
|
|
99
88
|
let configFile: BetterAuthOptions | null = null;
|
|
100
89
|
if (configPath) {
|
|
101
90
|
let resolvedPath: string = path.join(cwd, configPath);
|
|
102
|
-
if (existsSync(configPath))
|
|
91
|
+
if (existsSync(configPath)) {
|
|
92
|
+
resolvedPath = configPath; // If the configPath is a file, use it as is, as it means the path wasn't relative.
|
|
93
|
+
}
|
|
103
94
|
const { config } = await loadConfig<{
|
|
104
95
|
auth: {
|
|
105
96
|
options: BetterAuthOptions;
|
|
@@ -112,7 +103,7 @@ export async function getConfig({
|
|
|
112
103
|
dotenv: true,
|
|
113
104
|
jitiOptions: jitiOptions(cwd),
|
|
114
105
|
});
|
|
115
|
-
if (!config.auth
|
|
106
|
+
if (!(config.auth || config.default)) {
|
|
116
107
|
if (shouldThrowOnError) {
|
|
117
108
|
throw new Error(
|
|
118
109
|
`Couldn't read your auth config in ${resolvedPath}. Make sure to default export your auth instance or to export as a variable named auth.`,
|
|
@@ -142,8 +133,7 @@ export async function getConfig({
|
|
|
142
133
|
});
|
|
143
134
|
const hasConfig = Object.keys(config).length > 0;
|
|
144
135
|
if (hasConfig) {
|
|
145
|
-
configFile =
|
|
146
|
-
config.auth?.options || config.default?.options || null;
|
|
136
|
+
configFile = config.auth?.options || config.default?.options || null;
|
|
147
137
|
if (!configFile) {
|
|
148
138
|
if (shouldThrowOnError) {
|
|
149
139
|
throw new Error(
|
|
@@ -165,9 +155,7 @@ export async function getConfig({
|
|
|
165
155
|
e &&
|
|
166
156
|
"message" in e &&
|
|
167
157
|
typeof e.message === "string" &&
|
|
168
|
-
e.message.includes(
|
|
169
|
-
"This module cannot be imported from a Client Component module",
|
|
170
|
-
)
|
|
158
|
+
e.message.includes("This module cannot be imported from a Client Component module")
|
|
171
159
|
) {
|
|
172
160
|
if (shouldThrowOnError) {
|
|
173
161
|
throw new Error(
|
|
@@ -194,9 +182,7 @@ export async function getConfig({
|
|
|
194
182
|
e &&
|
|
195
183
|
"message" in e &&
|
|
196
184
|
typeof e.message === "string" &&
|
|
197
|
-
e.message.includes(
|
|
198
|
-
"This module cannot be imported from a Client Component module",
|
|
199
|
-
)
|
|
185
|
+
e.message.includes("This module cannot be imported from a Client Component module")
|
|
200
186
|
) {
|
|
201
187
|
if (shouldThrowOnError) {
|
|
202
188
|
throw new Error(
|