@convex-dev/better-auth 0.11.5 → 0.12.1
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/auth-options.d.ts.map +1 -1
- package/dist/auth-options.js +1 -0
- package/dist/auth-options.js.map +1 -1
- package/dist/client/adapter-utils.d.ts +8 -2
- package/dist/client/adapter-utils.d.ts.map +1 -1
- package/dist/client/adapter-utils.js +8 -3
- package/dist/client/adapter-utils.js.map +1 -1
- package/dist/client/adapter.d.ts +0 -1
- package/dist/client/adapter.d.ts.map +1 -1
- package/dist/client/adapter.js +5 -0
- package/dist/client/adapter.js.map +1 -1
- package/dist/client/create-api.d.ts +6 -0
- package/dist/client/create-api.d.ts.map +1 -1
- package/dist/client/create-api.js +1 -0
- package/dist/client/create-api.js.map +1 -1
- package/dist/client/create-client.d.ts +0 -2
- package/dist/client/create-client.d.ts.map +1 -1
- package/dist/client/create-client.js.map +1 -1
- package/dist/client/create-schema.d.ts.map +1 -1
- package/dist/client/create-schema.js +38 -8
- package/dist/client/create-schema.js.map +1 -1
- package/dist/component/_generated/api.d.ts +0 -2
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +543 -31
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/adapter.d.ts +6 -0
- package/dist/component/adapter.d.ts.map +1 -1
- package/dist/component/schema.d.ts +9 -4
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +4 -2
- package/dist/component/schema.js.map +1 -1
- package/dist/component/testProfiles/adapterAdditionalFields.d.ts +6 -0
- package/dist/component/testProfiles/adapterAdditionalFields.d.ts.map +1 -1
- package/dist/component/testProfiles/adapterOrganizationJoins.d.ts +6 -0
- package/dist/component/testProfiles/adapterOrganizationJoins.d.ts.map +1 -1
- package/dist/component/testProfiles/adapterPluginTable.d.ts +6 -0
- package/dist/component/testProfiles/adapterPluginTable.d.ts.map +1 -1
- package/dist/component/testProfiles/adapterRenameField.d.ts +6 -0
- package/dist/component/testProfiles/adapterRenameField.d.ts.map +1 -1
- package/dist/component/testProfiles/adapterRenameUserCustom.d.ts +6 -0
- package/dist/component/testProfiles/adapterRenameUserCustom.d.ts.map +1 -1
- package/dist/component/testProfiles/adapterRenameUserTable.d.ts +6 -0
- package/dist/component/testProfiles/adapterRenameUserTable.d.ts.map +1 -1
- package/dist/component/testProfiles/schema.profile-additional-fields.d.ts +3 -1
- package/dist/component/testProfiles/schema.profile-additional-fields.d.ts.map +1 -1
- package/dist/component/testProfiles/schema.profile-plugin-table.d.ts +3 -1
- package/dist/component/testProfiles/schema.profile-plugin-table.d.ts.map +1 -1
- package/dist/plugins/convex/client.d.ts +1 -0
- package/dist/plugins/convex/client.d.ts.map +1 -1
- package/dist/plugins/convex/client.js +2 -0
- package/dist/plugins/convex/client.js.map +1 -1
- package/dist/plugins/convex/index.d.ts +2 -1
- package/dist/plugins/convex/index.d.ts.map +1 -1
- package/dist/plugins/convex/index.js +15 -2
- package/dist/plugins/convex/index.js.map +1 -1
- package/dist/plugins/cross-domain/client.d.ts +1 -12
- package/dist/plugins/cross-domain/client.d.ts.map +1 -1
- package/dist/plugins/cross-domain/client.js +35 -27
- package/dist/plugins/cross-domain/client.js.map +1 -1
- package/dist/plugins/cross-domain/index.d.ts +1 -0
- package/dist/plugins/cross-domain/index.d.ts.map +1 -1
- package/dist/plugins/cross-domain/index.js +15 -4
- package/dist/plugins/cross-domain/index.js.map +1 -1
- package/dist/test/adapter-factory/basic.d.ts +4 -0
- package/dist/test/adapter-factory/basic.d.ts.map +1 -1
- package/dist/test/adapter-factory/convex-custom.d.ts +1 -1
- package/dist/test/adapter-factory/convex-custom.d.ts.map +1 -1
- package/dist/test/adapter-factory/convex-custom.js +20 -0
- package/dist/test/adapter-factory/convex-custom.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +6 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +6 -6
- package/src/auth-options.ts +1 -0
- package/src/client/adapter-utils.ts +13 -5
- package/src/client/adapter.test.ts +225 -2
- package/src/client/adapter.ts +7 -1
- package/src/client/create-api.ts +3 -0
- package/src/client/create-client.ts +0 -2
- package/src/client/create-schema.ts +46 -8
- package/src/component/_generated/api.ts +0 -2
- package/src/component/_generated/component.ts +718 -38
- package/src/component/schema.ts +5 -3
- package/src/plugins/convex/client.ts +2 -0
- package/src/plugins/convex/index.ts +16 -3
- package/src/plugins/cross-domain/client.test.ts +58 -28
- package/src/plugins/cross-domain/client.ts +44 -45
- package/src/plugins/cross-domain/index.test.ts +129 -51
- package/src/plugins/cross-domain/index.ts +20 -7
- package/src/test/adapter-factory/convex-custom.ts +23 -0
- package/src/utils/index.ts +7 -1
- package/src/version.ts +1 -0
- package/dist/component/adapterTest.d.ts +0 -3
- package/dist/component/adapterTest.d.ts.map +0 -1
- package/dist/component/adapterTest.js +0 -202
- package/dist/component/adapterTest.js.map +0 -1
- package/src/component/adapterTest.ts +0 -275
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAUvD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAmD7B,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,GAA0B,EACS,EAAE;IACrC,OAAO,IAAI,IAAI,GAAG,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,GAA0B,EACY,EAAE;IACxC,OAAO,IAAI,IAAI,GAAG,IAAI,WAAW,IAAI,GAAG,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,GAA0B,EACU,EAAE;IACtC,OAAO,WAAW,IAAI,GAAG,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,GAA0B,EACQ,EAAE;IACpC,OAAO,aAAa,IAAI,GAAG,CAAC;AAC9B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,GAA0B,EACE,EAAE;IAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,GAA0B,EACK,EAAE;IACjC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,GAA0B,EACG,EAAE;IAC/B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,GAA0B,EACC,EAAE;IAC7B,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/get-convex/better-auth/issues"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.12.1",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"keywords": [
|
|
12
12
|
"convex",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"preversion": "npm ci && npm run build:clean && npm run test && npm run lint && npm run typecheck",
|
|
33
33
|
"alpha": "npm version prerelease --preid alpha && npm publish --tag alpha && git push --follow-tags",
|
|
34
34
|
"release": "npm version patch && npm publish && git push --follow-tags",
|
|
35
|
-
"version": "(npm whoami || npm login) && vim -c 'normal o' -c 'normal o## '$npm_package_version CHANGELOG.md && prettier -w CHANGELOG.md && git add CHANGELOG.md"
|
|
35
|
+
"version": "(npm whoami || npm login) && node scripts/sync-version.mjs && vim -c 'normal o' -c 'normal o## '$npm_package_version CHANGELOG.md && prettier -w CHANGELOG.md && git add CHANGELOG.md src/version.ts"
|
|
36
36
|
},
|
|
37
37
|
"files": [
|
|
38
38
|
"dist",
|
|
@@ -101,13 +101,13 @@
|
|
|
101
101
|
}
|
|
102
102
|
},
|
|
103
103
|
"peerDependencies": {
|
|
104
|
-
"better-auth": ">=1.
|
|
104
|
+
"better-auth": ">=1.6.9 <1.7.0",
|
|
105
105
|
"convex": "^1.25.0",
|
|
106
106
|
"react": "^18.3.1 || ^19.0.0"
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
|
-
"@better-auth/core": "~1.
|
|
110
|
-
"@better-auth/test-utils": "~1.
|
|
109
|
+
"@better-auth/core": "~1.6.9",
|
|
110
|
+
"@better-auth/test-utils": "~1.6.9",
|
|
111
111
|
"@edge-runtime/vm": "5.0.0",
|
|
112
112
|
"@eslint/eslintrc": "3.3.1",
|
|
113
113
|
"@eslint/js": "9.39.1",
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
"@types/react": "19.2.14",
|
|
118
118
|
"@types/react-dom": "19.2.3",
|
|
119
119
|
"@types/semver": "^7.7.0",
|
|
120
|
-
"better-auth": "~1.
|
|
120
|
+
"better-auth": "~1.6.9",
|
|
121
121
|
"chokidar-cli": "3.0.0",
|
|
122
122
|
"concurrently": "^9.2.0",
|
|
123
123
|
"convex": "1.35.1",
|
package/src/auth-options.ts
CHANGED
|
@@ -41,6 +41,7 @@ export const adapterWhereValidator = v.object({
|
|
|
41
41
|
v.null()
|
|
42
42
|
),
|
|
43
43
|
connector: v.optional(v.union(v.literal("AND"), v.literal("OR"))),
|
|
44
|
+
mode: v.optional(v.union(v.literal("sensitive"), v.literal("insensitive"))),
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
export const adapterArgsValidator = v.object({
|
|
@@ -106,6 +107,7 @@ const findIndex = (
|
|
|
106
107
|
| "ends_with";
|
|
107
108
|
value: string | number | boolean | null | string[] | number[];
|
|
108
109
|
connector?: "AND" | "OR";
|
|
110
|
+
mode?: "sensitive" | "insensitive";
|
|
109
111
|
}[];
|
|
110
112
|
sortBy?: {
|
|
111
113
|
field: string;
|
|
@@ -185,11 +187,7 @@ const findIndex = (
|
|
|
185
187
|
// We internally use _creationTime in place of Better Auth's createdAt
|
|
186
188
|
const indexFields = indexEqFields
|
|
187
189
|
.map(([field]) => field)
|
|
188
|
-
.concat(
|
|
189
|
-
boundField && boundField !== "createdAt"
|
|
190
|
-
? boundField
|
|
191
|
-
: ""
|
|
192
|
-
)
|
|
190
|
+
.concat(boundField && boundField !== "createdAt" ? boundField : "")
|
|
193
191
|
.concat(
|
|
194
192
|
sortField && sortField !== "createdAt" && boundField !== sortField
|
|
195
193
|
? sortField
|
|
@@ -499,6 +497,11 @@ export const paginate = async <
|
|
|
499
497
|
`_id can only be used with eq, in, or not_in operator: ${JSON.stringify(args.where)}`
|
|
500
498
|
);
|
|
501
499
|
}
|
|
500
|
+
if (args.where?.some((w) => w.mode === "insensitive")) {
|
|
501
|
+
throw new Error(
|
|
502
|
+
`Case-insensitive queries (mode: "insensitive") are not supported by the Convex adapter. Store values in a normalized form (e.g. lowercase on write) and query against the normalized value.`
|
|
503
|
+
);
|
|
504
|
+
}
|
|
502
505
|
// If any where clause is "eq" (or missing operator) on a unique field,
|
|
503
506
|
// we can only return a single document, so we get it and use any other
|
|
504
507
|
// where clauses as static filters.
|
|
@@ -514,6 +517,11 @@ export const paginate = async <
|
|
|
514
517
|
model: args.model,
|
|
515
518
|
where: [uniqueWhere],
|
|
516
519
|
}) || {};
|
|
520
|
+
if (uniqueWhere.field !== "_id" && !index) {
|
|
521
|
+
throw new Error(
|
|
522
|
+
`No index found for ${args.model}.${uniqueWhere.field}`
|
|
523
|
+
);
|
|
524
|
+
}
|
|
517
525
|
const doc =
|
|
518
526
|
uniqueWhere.field === "_id"
|
|
519
527
|
? await ctx.db.get(uniqueWhere.value as GenericId<T>)
|
|
@@ -2,8 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
import { describe, it } from "vitest";
|
|
4
4
|
import { convexTest } from "convex-test";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
testAdapter,
|
|
7
|
+
transactionsTestSuite,
|
|
8
|
+
uuidTestSuite,
|
|
9
|
+
} from "@better-auth/test-utils/adapter";
|
|
10
|
+
import type { BetterAuthOptions } from "better-auth";
|
|
11
|
+
import { internal } from "../component/_generated/api.js";
|
|
6
12
|
import schema from "../component/testProfiles/schema.profile-plugin-table.js";
|
|
13
|
+
import { createClient } from "./index.js";
|
|
14
|
+
import type { DataModel } from "../component/_generated/dataModel.js";
|
|
15
|
+
import type { ComponentApi } from "../component/_generated/component.js";
|
|
16
|
+
import {
|
|
17
|
+
additionalFieldsAuthFlowTestSuite,
|
|
18
|
+
additionalFieldsNormalTestSuite,
|
|
19
|
+
convexCustomTestSuite,
|
|
20
|
+
coreAuthFlowTestSuite,
|
|
21
|
+
coreNormalTestSuite,
|
|
22
|
+
multiJoinsMissingRowsTestSuite,
|
|
23
|
+
pluginTableNormalTestSuite,
|
|
24
|
+
renameFieldAndJoinTestSuite,
|
|
25
|
+
renameModelUserCustomTestSuite,
|
|
26
|
+
renameModelUserTableTestSuite,
|
|
27
|
+
} from "../test/adapter-factory/index.js";
|
|
7
28
|
|
|
8
29
|
const MIN_NODE_MAJOR = 24;
|
|
9
30
|
const currentNodeMajor = Number.parseInt(
|
|
@@ -11,6 +32,85 @@ const currentNodeMajor = Number.parseInt(
|
|
|
11
32
|
10
|
|
12
33
|
);
|
|
13
34
|
|
|
35
|
+
const NORMAL_DISABLED_TESTS = [
|
|
36
|
+
// dynamic-schema-plugin-table/dynamic-schema-additional-fields:
|
|
37
|
+
// Convex validators are static in this harness, so runtime schema mutation
|
|
38
|
+
// tests are validated in dedicated profiles instead.
|
|
39
|
+
"create - should apply default values to fields",
|
|
40
|
+
"create - should return null for nullable foreign keys",
|
|
41
|
+
"create - should support arrays",
|
|
42
|
+
"create - should support json",
|
|
43
|
+
// convex-id-generation:
|
|
44
|
+
// Convex controls generated IDs at write time.
|
|
45
|
+
"create - should use generateId if provided",
|
|
46
|
+
// offset-unsupported:
|
|
47
|
+
// Convex adapter rejects offset pagination.
|
|
48
|
+
"findMany - should be able to perform a complex limited join",
|
|
49
|
+
"findMany - should find many models with limit and offset",
|
|
50
|
+
"findMany - should find many models with offset",
|
|
51
|
+
"findMany - should find many models with sortBy and limit and offset",
|
|
52
|
+
"findMany - should find many models with sortBy and limit and offset and where",
|
|
53
|
+
"findMany - should find many models with sortBy and offset",
|
|
54
|
+
"findMany - should find many with both one-to-one and one-to-many joins",
|
|
55
|
+
"findMany - should find many with join and offset",
|
|
56
|
+
"findMany - should find many with join, where, limit, and offset",
|
|
57
|
+
"findMany - should find many with one-to-one join",
|
|
58
|
+
"findMany - should handle mixed joins correctly when some are missing",
|
|
59
|
+
"findMany - should return empty array when base records don't exist with joins",
|
|
60
|
+
"findMany - should return null for one-to-one join when joined records don't exist",
|
|
61
|
+
"findMany - should select fields with one-to-one join",
|
|
62
|
+
// profile-specific coverage:
|
|
63
|
+
// These are intentionally exercised in dedicated profile suites.
|
|
64
|
+
"findOne - backwards join with modified field name (session base, users-table join)",
|
|
65
|
+
"findOne - multiple joins should return result even when some joined tables have no matching rows",
|
|
66
|
+
"findOne - should find a model with modified field name",
|
|
67
|
+
"findOne - should find a model with modified model name",
|
|
68
|
+
"findOne - should join a model with modified field name",
|
|
69
|
+
"findOne - should not apply defaultValue if value not found",
|
|
70
|
+
"findOne - should return an object for one-to-one joins",
|
|
71
|
+
"findOne - should return null for failed base model lookup that has joins",
|
|
72
|
+
"findOne - should return null for one-to-one join when joined record doesn't exist",
|
|
73
|
+
"findOne - should select fields with one-to-one join",
|
|
74
|
+
"findOne - should work with both one-to-one and one-to-many joins",
|
|
75
|
+
] as const;
|
|
76
|
+
|
|
77
|
+
const UUID_SUITE_TESTS = ["init - tests"] as const;
|
|
78
|
+
|
|
79
|
+
const toDisableMap = (testNames: readonly string[]) =>
|
|
80
|
+
Object.fromEntries(testNames.map((testName) => [testName, true]));
|
|
81
|
+
|
|
82
|
+
const toEnableOnlyMap = (testNames: readonly string[]) => ({
|
|
83
|
+
ALL: true,
|
|
84
|
+
...Object.fromEntries(testNames.map((testName) => [testName, false])),
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const getOverrideBetterAuthOptions = (
|
|
88
|
+
opts: BetterAuthOptions
|
|
89
|
+
): BetterAuthOptions => ({
|
|
90
|
+
...opts,
|
|
91
|
+
advanced: {
|
|
92
|
+
...opts.advanced,
|
|
93
|
+
database: {
|
|
94
|
+
...opts.advanced?.database,
|
|
95
|
+
generateId: "uuid",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
type AdapterModule = ComponentApi["adapter"];
|
|
101
|
+
type TestProfileName =
|
|
102
|
+
| "adapterAdditionalFields"
|
|
103
|
+
| "adapterPluginTable"
|
|
104
|
+
| "adapterRenameField"
|
|
105
|
+
| "adapterRenameUserCustom"
|
|
106
|
+
| "adapterRenameUserTable"
|
|
107
|
+
| "adapterOrganizationJoins";
|
|
108
|
+
|
|
109
|
+
type InternalWithTestProfiles = {
|
|
110
|
+
adapter: AdapterModule;
|
|
111
|
+
testProfiles: Record<TestProfileName, AdapterModule>;
|
|
112
|
+
};
|
|
113
|
+
|
|
14
114
|
if (currentNodeMajor < MIN_NODE_MAJOR) {
|
|
15
115
|
describe("Better Auth Adapter Tests", () => {
|
|
16
116
|
it.skip(
|
|
@@ -21,6 +121,129 @@ if (currentNodeMajor < MIN_NODE_MAJOR) {
|
|
|
21
121
|
} else {
|
|
22
122
|
describe("Better Auth Adapter Tests", async () => {
|
|
23
123
|
const t = convexTest(schema, import.meta.glob("../component/**/*.*s"));
|
|
24
|
-
|
|
124
|
+
|
|
125
|
+
// Bridge `convexAdapter`'s ctx surface to `convexTest`. Each adapter call
|
|
126
|
+
// re-enters convex-test's AsyncLocalStorage frame via t.query / t.mutation,
|
|
127
|
+
// which is required by convex-test ≥0.0.45. State persists across calls
|
|
128
|
+
// because the test database lives on `t`, not in ALS.
|
|
129
|
+
const wrappedCtx = {
|
|
130
|
+
runQuery: t.query.bind(t),
|
|
131
|
+
runMutation: t.mutation.bind(t),
|
|
132
|
+
} as any;
|
|
133
|
+
|
|
134
|
+
const internalWithTestProfiles =
|
|
135
|
+
internal as unknown as InternalWithTestProfiles;
|
|
136
|
+
const profileApi = (name: TestProfileName): { adapter: AdapterModule } => ({
|
|
137
|
+
adapter: internalWithTestProfiles.testProfiles[name],
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const baseProfileClient = createClient<DataModel>(
|
|
141
|
+
{ adapter: internalWithTestProfiles.adapter },
|
|
142
|
+
{ verbose: false }
|
|
143
|
+
);
|
|
144
|
+
const additionalFieldsProfileClient = createClient<DataModel>(
|
|
145
|
+
profileApi("adapterAdditionalFields"),
|
|
146
|
+
{ verbose: false }
|
|
147
|
+
);
|
|
148
|
+
const pluginTableProfileClient = createClient<DataModel>(
|
|
149
|
+
profileApi("adapterPluginTable"),
|
|
150
|
+
{ verbose: false }
|
|
151
|
+
);
|
|
152
|
+
const renameFieldProfileClient = createClient<DataModel>(
|
|
153
|
+
profileApi("adapterRenameField"),
|
|
154
|
+
{ verbose: false }
|
|
155
|
+
);
|
|
156
|
+
const renameUserCustomProfileClient = createClient<DataModel>(
|
|
157
|
+
profileApi("adapterRenameUserCustom"),
|
|
158
|
+
{ verbose: false }
|
|
159
|
+
);
|
|
160
|
+
const renameUserTableProfileClient = createClient<DataModel>(
|
|
161
|
+
profileApi("adapterRenameUserTable"),
|
|
162
|
+
{ verbose: false }
|
|
163
|
+
);
|
|
164
|
+
const organizationJoinsProfileClient = createClient<DataModel>(
|
|
165
|
+
profileApi("adapterOrganizationJoins"),
|
|
166
|
+
{ verbose: false }
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
const noMigrations = () => {
|
|
170
|
+
// Convex schema is static — no migrations needed.
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const { execute: executeBaseProfile } = await testAdapter({
|
|
174
|
+
adapter: () => baseProfileClient.adapter(wrappedCtx),
|
|
175
|
+
runMigrations: noMigrations,
|
|
176
|
+
overrideBetterAuthOptions: getOverrideBetterAuthOptions,
|
|
177
|
+
tests: [
|
|
178
|
+
coreNormalTestSuite({
|
|
179
|
+
disableTests: toDisableMap(NORMAL_DISABLED_TESTS),
|
|
180
|
+
}),
|
|
181
|
+
uuidTestSuite({
|
|
182
|
+
disableTests: toEnableOnlyMap(UUID_SUITE_TESTS),
|
|
183
|
+
}),
|
|
184
|
+
transactionsTestSuite({ disableTests: { ALL: true } }),
|
|
185
|
+
coreAuthFlowTestSuite(),
|
|
186
|
+
convexCustomTestSuite(),
|
|
187
|
+
],
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const { execute: executeAdditionalFieldsProfile } = await testAdapter({
|
|
191
|
+
adapter: () => additionalFieldsProfileClient.adapter(wrappedCtx),
|
|
192
|
+
runMigrations: noMigrations,
|
|
193
|
+
overrideBetterAuthOptions: getOverrideBetterAuthOptions,
|
|
194
|
+
prefixTests: "profile:additional-fields",
|
|
195
|
+
tests: [
|
|
196
|
+
additionalFieldsNormalTestSuite(),
|
|
197
|
+
additionalFieldsAuthFlowTestSuite(),
|
|
198
|
+
],
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const { execute: executePluginTableProfile } = await testAdapter({
|
|
202
|
+
adapter: () => pluginTableProfileClient.adapter(wrappedCtx),
|
|
203
|
+
runMigrations: noMigrations,
|
|
204
|
+
overrideBetterAuthOptions: getOverrideBetterAuthOptions,
|
|
205
|
+
prefixTests: "profile:plugin-table",
|
|
206
|
+
tests: [pluginTableNormalTestSuite()],
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
const { execute: executeRenameFieldProfile } = await testAdapter({
|
|
210
|
+
adapter: () => renameFieldProfileClient.adapter(wrappedCtx),
|
|
211
|
+
runMigrations: noMigrations,
|
|
212
|
+
overrideBetterAuthOptions: getOverrideBetterAuthOptions,
|
|
213
|
+
prefixTests: "profile:rename-field-join",
|
|
214
|
+
tests: [renameFieldAndJoinTestSuite()],
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const { execute: executeRenameUserCustomProfile } = await testAdapter({
|
|
218
|
+
adapter: () => renameUserCustomProfileClient.adapter(wrappedCtx),
|
|
219
|
+
runMigrations: noMigrations,
|
|
220
|
+
overrideBetterAuthOptions: getOverrideBetterAuthOptions,
|
|
221
|
+
prefixTests: "profile:rename-user-custom",
|
|
222
|
+
tests: [renameModelUserCustomTestSuite()],
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const { execute: executeRenameUserTableProfile } = await testAdapter({
|
|
226
|
+
adapter: () => renameUserTableProfileClient.adapter(wrappedCtx),
|
|
227
|
+
runMigrations: noMigrations,
|
|
228
|
+
overrideBetterAuthOptions: getOverrideBetterAuthOptions,
|
|
229
|
+
prefixTests: "profile:rename-user-table",
|
|
230
|
+
tests: [renameModelUserTableTestSuite()],
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const { execute: executeOrganizationJoinsProfile } = await testAdapter({
|
|
234
|
+
adapter: () => organizationJoinsProfileClient.adapter(wrappedCtx),
|
|
235
|
+
runMigrations: noMigrations,
|
|
236
|
+
overrideBetterAuthOptions: getOverrideBetterAuthOptions,
|
|
237
|
+
prefixTests: "profile:organization-joins",
|
|
238
|
+
tests: [multiJoinsMissingRowsTestSuite()],
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
await executeBaseProfile();
|
|
242
|
+
await executeAdditionalFieldsProfile();
|
|
243
|
+
await executePluginTableProfile();
|
|
244
|
+
await executeRenameFieldProfile();
|
|
245
|
+
await executeRenameUserCustomProfile();
|
|
246
|
+
await executeRenameUserTableProfile();
|
|
247
|
+
await executeOrganizationJoinsProfile();
|
|
25
248
|
});
|
|
26
249
|
}
|
package/src/client/adapter.ts
CHANGED
|
@@ -93,6 +93,13 @@ const parseWhere = (
|
|
|
93
93
|
return [];
|
|
94
94
|
}
|
|
95
95
|
const whereArray = Array.isArray(where) ? where : [where];
|
|
96
|
+
for (const w of whereArray) {
|
|
97
|
+
if (w.mode === "insensitive") {
|
|
98
|
+
throw new Error(
|
|
99
|
+
`Case-insensitive queries (mode: "insensitive") are not supported by the Convex adapter. Store values in a normalized form (e.g. lowercase on write) and query against the normalized value. Field: ${w.field}`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
96
103
|
return whereArray.map((w) => {
|
|
97
104
|
if (w.value instanceof Date) {
|
|
98
105
|
return {
|
|
@@ -164,7 +171,6 @@ export const convexAdapter = <
|
|
|
164
171
|
ctx: Ctx,
|
|
165
172
|
api: {
|
|
166
173
|
adapter: ComponentApi["adapter"];
|
|
167
|
-
adapterTest?: ComponentApi["adapterTest"];
|
|
168
174
|
},
|
|
169
175
|
config: {
|
|
170
176
|
debugLogs?: DBAdapterDebugLogOption;
|
package/src/client/create-api.ts
CHANGED
|
@@ -55,6 +55,9 @@ const whereValidator = (
|
|
|
55
55
|
v.null()
|
|
56
56
|
),
|
|
57
57
|
connector: v.optional(v.union(v.literal("AND"), v.literal("OR"))),
|
|
58
|
+
mode: v.optional(
|
|
59
|
+
v.union(v.literal("sensitive"), v.literal("insensitive"))
|
|
60
|
+
),
|
|
58
61
|
});
|
|
59
62
|
|
|
60
63
|
export const createApi = <Schema extends SchemaDefinition<any, any>>(
|
|
@@ -17,7 +17,6 @@ import type { Infer } from "convex/values";
|
|
|
17
17
|
import { convexAdapter } from "./adapter.js";
|
|
18
18
|
import { corsRouter } from "convex-helpers/server/cors";
|
|
19
19
|
import type defaultSchema from "../component/schema.js";
|
|
20
|
-
import type { ComponentApi } from "../component/_generated/component.js";
|
|
21
20
|
import type { CreateAuth, GenericCtx } from "./index.js";
|
|
22
21
|
import type { TrustedOriginsOption } from "../utils/index.js";
|
|
23
22
|
|
|
@@ -70,7 +69,6 @@ type SlimComponentApi = {
|
|
|
70
69
|
deleteOne: FunctionReference<"mutation", "internal">;
|
|
71
70
|
deleteMany: FunctionReference<"mutation", "internal">;
|
|
72
71
|
};
|
|
73
|
-
adapterTest?: ComponentApi["adapterTest"];
|
|
74
72
|
};
|
|
75
73
|
|
|
76
74
|
type RouteCorsOptions =
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { BetterAuthDBSchema, DBFieldAttribute } from "better-auth/db";
|
|
2
2
|
|
|
3
|
+
const resolveCdTarget = (
|
|
4
|
+
relativeDir: string | null,
|
|
5
|
+
cwdBasename: string
|
|
6
|
+
): string | null => {
|
|
7
|
+
if (relativeDir === "") {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
if (relativeDir !== null) {
|
|
11
|
+
return relativeDir;
|
|
12
|
+
}
|
|
13
|
+
return cwdBasename;
|
|
14
|
+
};
|
|
15
|
+
|
|
3
16
|
// Manually add fields to index on for schema generation,
|
|
4
17
|
// all fields in the schema specialFields are automatically indexed
|
|
5
18
|
export const indexFields = {
|
|
@@ -66,11 +79,12 @@ export const createSchema = async ({
|
|
|
66
79
|
tables: BetterAuthDBSchema;
|
|
67
80
|
file?: string;
|
|
68
81
|
}) => {
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const
|
|
82
|
+
// Hide these node builtins from Convex's esbuild so it doesn't try to
|
|
83
|
+
// resolve them at bundle time. Only runs from the better-auth CLI.
|
|
84
|
+
const path = await import(["p", "a", "t", "h"].join(""));
|
|
85
|
+
const fs = await import(["f", "s"].join(""));
|
|
86
|
+
const cwd = process.cwd();
|
|
87
|
+
const baseName = path.basename(path.resolve(cwd, file ?? ""));
|
|
74
88
|
// if the target directory is named "convex", they're almost definitely
|
|
75
89
|
// generating the schema in the wrong directory, likely would replace the
|
|
76
90
|
// app schema
|
|
@@ -79,11 +93,35 @@ export const createSchema = async ({
|
|
|
79
93
|
"Better Auth schema must be generated in the Better Auth component directory."
|
|
80
94
|
);
|
|
81
95
|
}
|
|
96
|
+
|
|
97
|
+
const findProjectRoot = (dir: string): string | null => {
|
|
98
|
+
if (fs.existsSync(path.join(dir, "package.json"))) {
|
|
99
|
+
return dir;
|
|
100
|
+
}
|
|
101
|
+
const parent = path.dirname(dir);
|
|
102
|
+
if (parent === dir) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return findProjectRoot(parent);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const projectRoot = findProjectRoot(cwd);
|
|
109
|
+
const relativeDir =
|
|
110
|
+
projectRoot !== null
|
|
111
|
+
? path.relative(projectRoot, cwd).split(path.sep).join("/")
|
|
112
|
+
: null;
|
|
113
|
+
const generateCommand = `npx auth generate${file ? ` --output ${file}` : ""}`;
|
|
114
|
+
const cdTarget = resolveCdTarget(relativeDir, path.basename(cwd));
|
|
115
|
+
const commandBlock = cdTarget
|
|
116
|
+
? ` * cd ${cdTarget}\n * ${generateCommand}`
|
|
117
|
+
: ` * ${generateCommand}`;
|
|
118
|
+
|
|
82
119
|
let code: string = `/**
|
|
83
120
|
* This file is auto-generated. Do not edit this file manually.
|
|
84
|
-
* To regenerate the schema,
|
|
85
|
-
*
|
|
86
|
-
|
|
121
|
+
* To regenerate the schema, from your project root:
|
|
122
|
+
*
|
|
123
|
+
${commandBlock}
|
|
124
|
+
*
|
|
87
125
|
* To customize the schema, generate to an alternate file and import
|
|
88
126
|
* the table definitions to your schema file. See
|
|
89
127
|
* https://labs.convex.dev/better-auth/features/local-install#adding-custom-indexes.
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type * as adapter from "../adapter.js";
|
|
12
|
-
import type * as adapterTest from "../adapterTest.js";
|
|
13
12
|
import type * as testProfiles_adapterAdditionalFields from "../testProfiles/adapterAdditionalFields.js";
|
|
14
13
|
import type * as testProfiles_adapterOrganizationJoins from "../testProfiles/adapterOrganizationJoins.js";
|
|
15
14
|
import type * as testProfiles_adapterPluginTable from "../testProfiles/adapterPluginTable.js";
|
|
@@ -26,7 +25,6 @@ import { anyApi, componentsGeneric } from "convex/server";
|
|
|
26
25
|
|
|
27
26
|
const fullApi: ApiFromModules<{
|
|
28
27
|
adapter: typeof adapter;
|
|
29
|
-
adapterTest: typeof adapterTest;
|
|
30
28
|
"testProfiles/adapterAdditionalFields": typeof testProfiles_adapterAdditionalFields;
|
|
31
29
|
"testProfiles/adapterOrganizationJoins": typeof testProfiles_adapterOrganizationJoins;
|
|
32
30
|
"testProfiles/adapterPluginTable": typeof testProfiles_adapterPluginTable;
|