@neutralauth/internal-auth 0.10.11
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/LICENSE +201 -0
- package/README.md +39 -0
- package/dist/auth-config.d.ts +43 -0
- package/dist/auth-config.d.ts.map +1 -0
- package/dist/auth-config.js +43 -0
- package/dist/auth-config.js.map +1 -0
- package/dist/auth-options.d.ts +3 -0
- package/dist/auth-options.d.ts.map +1 -0
- package/dist/auth-options.js +40 -0
- package/dist/auth-options.js.map +1 -0
- package/dist/auth.d.ts +2 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +4 -0
- package/dist/auth.js.map +1 -0
- package/dist/client/adapter-utils.d.ts +66 -0
- package/dist/client/adapter-utils.d.ts.map +1 -0
- package/dist/client/adapter-utils.js +437 -0
- package/dist/client/adapter-utils.js.map +1 -0
- package/dist/client/adapter.d.ts +14 -0
- package/dist/client/adapter.d.ts.map +1 -0
- package/dist/client/adapter.js +274 -0
- package/dist/client/adapter.js.map +1 -0
- package/dist/client/create-api.d.ts +141 -0
- package/dist/client/create-api.d.ts.map +1 -0
- package/dist/client/create-api.js +205 -0
- package/dist/client/create-api.js.map +1 -0
- package/dist/client/create-client.d.ts +183 -0
- package/dist/client/create-client.d.ts.map +1 -0
- package/dist/client/create-client.js +311 -0
- package/dist/client/create-client.js.map +1 -0
- package/dist/client/create-schema.d.ts +19 -0
- package/dist/client/create-schema.d.ts.map +1 -0
- package/dist/client/create-schema.js +114 -0
- package/dist/client/create-schema.js.map +1 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +10 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/plugins/index.d.ts +3 -0
- package/dist/client/plugins/index.d.ts.map +1 -0
- package/dist/client/plugins/index.js +3 -0
- package/dist/client/plugins/index.js.map +1 -0
- package/dist/component/_generated/api.d.ts +36 -0
- package/dist/component/_generated/api.d.ts.map +1 -0
- package/dist/component/_generated/api.js +31 -0
- package/dist/component/_generated/api.js.map +1 -0
- package/dist/component/_generated/component.d.ts +787 -0
- package/dist/component/_generated/component.d.ts.map +1 -0
- package/dist/component/_generated/component.js +11 -0
- package/dist/component/_generated/component.js.map +1 -0
- package/dist/component/_generated/dataModel.d.ts +46 -0
- package/dist/component/_generated/dataModel.d.ts.map +1 -0
- package/dist/component/_generated/dataModel.js +11 -0
- package/dist/component/_generated/dataModel.js.map +1 -0
- package/dist/component/_generated/server.d.ts +121 -0
- package/dist/component/_generated/server.d.ts.map +1 -0
- package/dist/component/_generated/server.js +78 -0
- package/dist/component/_generated/server.js.map +1 -0
- package/dist/component/adapter.d.ts +130 -0
- package/dist/component/adapter.d.ts.map +1 -0
- package/dist/component/adapter.js +5 -0
- package/dist/component/adapter.js.map +1 -0
- package/dist/component/adapterTest.d.ts +10 -0
- package/dist/component/adapterTest.d.ts.map +1 -0
- package/dist/component/adapterTest.js +409 -0
- package/dist/component/adapterTest.js.map +1 -0
- package/dist/component/convex.config.d.ts +3 -0
- package/dist/component/convex.config.d.ts.map +1 -0
- package/dist/component/convex.config.js +4 -0
- package/dist/component/convex.config.js.map +1 -0
- package/dist/component/schema.d.ts +474 -0
- package/dist/component/schema.d.ts.map +1 -0
- package/dist/component/schema.js +139 -0
- package/dist/component/schema.js.map +1 -0
- package/dist/nextjs/client.d.ts +4 -0
- package/dist/nextjs/client.d.ts.map +1 -0
- package/dist/nextjs/client.js +37 -0
- package/dist/nextjs/client.js.map +1 -0
- package/dist/nextjs/index.d.ts +22 -0
- package/dist/nextjs/index.d.ts.map +1 -0
- package/dist/nextjs/index.js +98 -0
- package/dist/nextjs/index.js.map +1 -0
- package/dist/plugins/convex/client.d.ts +6 -0
- package/dist/plugins/convex/client.d.ts.map +1 -0
- package/dist/plugins/convex/client.js +7 -0
- package/dist/plugins/convex/client.js.map +1 -0
- package/dist/plugins/convex/index.d.ts +322 -0
- package/dist/plugins/convex/index.d.ts.map +1 -0
- package/dist/plugins/convex/index.js +422 -0
- package/dist/plugins/convex/index.js.map +1 -0
- package/dist/plugins/cross-domain/client.d.ts +132 -0
- package/dist/plugins/cross-domain/client.d.ts.map +1 -0
- package/dist/plugins/cross-domain/client.js +192 -0
- package/dist/plugins/cross-domain/client.js.map +1 -0
- package/dist/plugins/cross-domain/index.d.ts +51 -0
- package/dist/plugins/cross-domain/index.d.ts.map +1 -0
- package/dist/plugins/cross-domain/index.js +173 -0
- package/dist/plugins/cross-domain/index.js.map +1 -0
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/react/index.d.ts +80 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +190 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react-start/index.d.ts +13 -0
- package/dist/react-start/index.d.ts.map +1 -0
- package/dist/react-start/index.js +101 -0
- package/dist/react-start/index.js.map +1 -0
- package/dist/utils/index.d.ts +33 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +91 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +208 -0
- package/src/auth-config.ts +80 -0
- package/src/auth-options.ts +54 -0
- package/src/auth.ts +4 -0
- package/src/client/adapter-utils.ts +639 -0
- package/src/client/adapter.test.ts +83 -0
- package/src/client/adapter.ts +363 -0
- package/src/client/create-api.ts +339 -0
- package/src/client/create-client.ts +452 -0
- package/src/client/create-schema.ts +166 -0
- package/src/client/index.ts +22 -0
- package/src/client/plugins/index.ts +2 -0
- package/src/component/_generated/api.ts +52 -0
- package/src/component/_generated/component.ts +2008 -0
- package/src/component/_generated/dataModel.ts +60 -0
- package/src/component/_generated/server.ts +161 -0
- package/src/component/adapter.ts +13 -0
- package/src/component/adapterTest.ts +505 -0
- package/src/component/convex.config.ts +5 -0
- package/src/component/schema.ts +142 -0
- package/src/nextjs/client.tsx +54 -0
- package/src/nextjs/index.ts +152 -0
- package/src/plugins/convex/client.ts +9 -0
- package/src/plugins/convex/index.ts +596 -0
- package/src/plugins/cross-domain/client.test.ts +217 -0
- package/src/plugins/cross-domain/client.ts +234 -0
- package/src/plugins/cross-domain/index.ts +199 -0
- package/src/plugins/index.ts +2 -0
- package/src/react/index.tsx +304 -0
- package/src/react-start/index.ts +153 -0
- package/src/react-start/vite-env.d.ts +2 -0
- package/src/test.ts +18 -0
- package/src/utils/index.ts +171 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
import { describe } from "vitest";
|
|
4
|
+
import type { runAdapterTest } from "better-auth/adapters/test";
|
|
5
|
+
import { convexTest } from "convex-test";
|
|
6
|
+
import { api } from "../component/_generated/api.js";
|
|
7
|
+
import schema from "../component/schema.js";
|
|
8
|
+
import { createClient } from "./create-client.js";
|
|
9
|
+
import type { DataModel } from "../component/_generated/dataModel.js";
|
|
10
|
+
import type { BetterAuthOptions } from "better-auth/types";
|
|
11
|
+
import type { GenericCtx } from "./index.js";
|
|
12
|
+
|
|
13
|
+
export const getAdapter: (
|
|
14
|
+
ctx: GenericCtx<DataModel>
|
|
15
|
+
) => Parameters<typeof runAdapterTest>[0]["getAdapter"] =
|
|
16
|
+
(ctx: GenericCtx<DataModel>) =>
|
|
17
|
+
async (opts?: Omit<BetterAuthOptions, "database">) => {
|
|
18
|
+
const authComponent = createClient<DataModel>(api as any, {
|
|
19
|
+
verbose: false,
|
|
20
|
+
});
|
|
21
|
+
const adapterFactory = authComponent.adapter(ctx);
|
|
22
|
+
return adapterFactory(opts ?? {});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
describe("Better Auth Adapter Tests", async () => {
|
|
26
|
+
const status = {
|
|
27
|
+
active: "active",
|
|
28
|
+
only: "only",
|
|
29
|
+
notSupported: "not supported",
|
|
30
|
+
} as const;
|
|
31
|
+
const tests: Record<string, (typeof status)[keyof typeof status]> = {
|
|
32
|
+
CREATE_MODEL: status.active,
|
|
33
|
+
CREATE_MODEL_SHOULD_ALWAYS_RETURN_AN_ID: status.active,
|
|
34
|
+
FIND_MODEL: status.active,
|
|
35
|
+
FIND_MODEL_WITHOUT_ID: status.active,
|
|
36
|
+
FIND_MODEL_WITH_SELECT: status.active,
|
|
37
|
+
// Requires a custom schema - we fake success by overriding custom user
|
|
38
|
+
// schema in the test adapter because this test creates a user that other
|
|
39
|
+
// tests rely on.
|
|
40
|
+
FIND_MODEL_WITH_MODIFIED_FIELD_NAME: status.active,
|
|
41
|
+
UPDATE_MODEL: status.active,
|
|
42
|
+
SHOULD_FIND_MANY: status.active,
|
|
43
|
+
SHOULD_FIND_MANY_WITH_WHERE: status.active,
|
|
44
|
+
SHOULD_FIND_MANY_WITH_OPERATORS: status.active,
|
|
45
|
+
SHOULD_WORK_WITH_REFERENCE_FIELDS: status.active,
|
|
46
|
+
SHOULD_FIND_MANY_WITH_NOT_IN_OPERATOR: status.active,
|
|
47
|
+
SHOULD_FIND_MANY_WITH_SORT_BY: status.active,
|
|
48
|
+
SHOULD_FIND_MANY_WITH_LIMIT: status.active,
|
|
49
|
+
SHOULD_UPDATE_WITH_MULTIPLE_WHERE: status.active,
|
|
50
|
+
DELETE_MODEL: status.active,
|
|
51
|
+
SHOULD_DELETE_MANY: status.active,
|
|
52
|
+
SHOULD_NOT_THROW_ON_DELETE_RECORD_NOT_FOUND: status.active,
|
|
53
|
+
SHOULD_NOT_THROW_ON_RECORD_NOT_FOUND: status.active,
|
|
54
|
+
SHOULD_FIND_MANY_WITH_CONTAINS_OPERATOR: status.active,
|
|
55
|
+
SHOULD_SEARCH_USERS_WITH_STARTS_WITH: status.active,
|
|
56
|
+
SHOULD_SEARCH_USERS_WITH_ENDS_WITH: status.active,
|
|
57
|
+
// Use local install and Convex paginated queries
|
|
58
|
+
SHOULD_FIND_MANY_WITH_OFFSET: status.notSupported,
|
|
59
|
+
// Convex generates ids on insert
|
|
60
|
+
SHOULD_PREFER_GENERATE_ID_IF_PROVIDED: status.notSupported,
|
|
61
|
+
// Transactions are inherent for auth.api and not possible for authClient
|
|
62
|
+
SHOULD_ROLLBACK_FAILING_TRANSACTION: status.notSupported,
|
|
63
|
+
SHOULD_RETURN_TRANSACTION_RESULT: status.notSupported,
|
|
64
|
+
SHOULD_FIND_MANY_WITH_CONNECTORS: status.active,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const disableTests = Object.fromEntries(
|
|
68
|
+
Object.entries(tests).map((entry, idx, arr) => {
|
|
69
|
+
if (arr.some((e) => e[1] === status.only)) {
|
|
70
|
+
return [entry[0], !(entry[1] === status.only)];
|
|
71
|
+
}
|
|
72
|
+
return [entry[0], !(entry[1] === status.active)];
|
|
73
|
+
})
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const t = convexTest(schema, import.meta.glob("../component/**/*.*s"));
|
|
77
|
+
await t.action(api.adapterTest.runTests, { disableTests });
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe("Convex Adapter Tests", async () => {
|
|
81
|
+
const t = convexTest(schema, import.meta.glob("../component/**/*.*s"));
|
|
82
|
+
await t.action(api.adapterTest.runCustomTests);
|
|
83
|
+
});
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { createAdapterFactory } from "better-auth/adapters";
|
|
2
|
+
import type { DBAdapterDebugLogOption } from "better-auth/adapters";
|
|
3
|
+
import { createFunctionHandle } from "convex/server";
|
|
4
|
+
import type {
|
|
5
|
+
FunctionHandle,
|
|
6
|
+
GenericActionCtx,
|
|
7
|
+
GenericDataModel,
|
|
8
|
+
PaginationOptions,
|
|
9
|
+
PaginationResult,
|
|
10
|
+
SchemaDefinition,
|
|
11
|
+
WithoutSystemFields,
|
|
12
|
+
} from "convex/server";
|
|
13
|
+
import type { SetOptional } from "type-fest";
|
|
14
|
+
import type defaultSchema from "../component/schema.js";
|
|
15
|
+
import type { Where } from "better-auth/types";
|
|
16
|
+
import { asyncMap } from "convex-helpers";
|
|
17
|
+
import { prop, sortBy, unique } from "remeda";
|
|
18
|
+
import { isRunMutationCtx } from "../utils/index.js";
|
|
19
|
+
import type { Doc, TableNames } from "../component/_generated/dataModel.js";
|
|
20
|
+
import type { ComponentApi } from "../component/_generated/component.js";
|
|
21
|
+
import type { AuthFunctions, GenericCtx, Triggers } from "./index.js";
|
|
22
|
+
|
|
23
|
+
const handlePagination = async (
|
|
24
|
+
next: ({
|
|
25
|
+
paginationOpts,
|
|
26
|
+
}: {
|
|
27
|
+
paginationOpts: PaginationOptions;
|
|
28
|
+
}) => Promise<
|
|
29
|
+
SetOptional<PaginationResult<any>, "page"> & { count?: number }
|
|
30
|
+
>,
|
|
31
|
+
{ limit, numItems }: { limit?: number; numItems?: number } = {}
|
|
32
|
+
) => {
|
|
33
|
+
const state: {
|
|
34
|
+
isDone: boolean;
|
|
35
|
+
cursor: string | null;
|
|
36
|
+
docs: any[];
|
|
37
|
+
count: number;
|
|
38
|
+
} = {
|
|
39
|
+
isDone: false,
|
|
40
|
+
cursor: null,
|
|
41
|
+
docs: [],
|
|
42
|
+
count: 0,
|
|
43
|
+
};
|
|
44
|
+
const onResult = (
|
|
45
|
+
result: SetOptional<PaginationResult<any>, "page"> & { count?: number }
|
|
46
|
+
) => {
|
|
47
|
+
state.cursor =
|
|
48
|
+
result.pageStatus === "SplitRecommended" ||
|
|
49
|
+
result.pageStatus === "SplitRequired"
|
|
50
|
+
? (result.splitCursor ?? result.continueCursor)
|
|
51
|
+
: result.continueCursor;
|
|
52
|
+
if (result.page) {
|
|
53
|
+
state.docs.push(...result.page);
|
|
54
|
+
state.isDone = (limit && state.docs.length >= limit) || result.isDone;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Update and delete only return a count
|
|
58
|
+
if (result.count) {
|
|
59
|
+
state.count += result.count;
|
|
60
|
+
state.isDone = (limit && state.count >= limit) || result.isDone;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
state.isDone = result.isDone;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
do {
|
|
67
|
+
const result = await next({
|
|
68
|
+
paginationOpts: {
|
|
69
|
+
numItems: Math.min(
|
|
70
|
+
numItems ?? 200,
|
|
71
|
+
(limit ?? 200) - state.docs.length,
|
|
72
|
+
200
|
|
73
|
+
),
|
|
74
|
+
cursor: state.cursor,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
onResult(result);
|
|
78
|
+
} while (!state.isDone);
|
|
79
|
+
return state;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
type ConvexCleanedWhere<TableName extends TableNames = TableNames> = Where & {
|
|
83
|
+
value: string | number | boolean | string[] | number[] | null;
|
|
84
|
+
field: keyof WithoutSystemFields<Doc<TableName>> & string;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const parseWhere = (
|
|
88
|
+
where?: (Where & { join?: undefined }) | (Where & { join?: undefined })[]
|
|
89
|
+
): ConvexCleanedWhere[] => {
|
|
90
|
+
if (!where) {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
const whereArray = Array.isArray(where) ? where : [where];
|
|
94
|
+
return whereArray.map((w) => {
|
|
95
|
+
if (w.value instanceof Date) {
|
|
96
|
+
return {
|
|
97
|
+
...w,
|
|
98
|
+
value: w.value.getTime(),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return w;
|
|
102
|
+
}) as ConvexCleanedWhere[];
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const convexAdapter = <
|
|
106
|
+
DataModel extends GenericDataModel,
|
|
107
|
+
Ctx extends GenericCtx<DataModel> = GenericActionCtx<DataModel>,
|
|
108
|
+
Schema extends SchemaDefinition<any, any> = typeof defaultSchema,
|
|
109
|
+
>(
|
|
110
|
+
ctx: Ctx,
|
|
111
|
+
api: {
|
|
112
|
+
adapter: ComponentApi["adapter"];
|
|
113
|
+
adapterTest?: ComponentApi["adapterTest"];
|
|
114
|
+
},
|
|
115
|
+
config: {
|
|
116
|
+
debugLogs?: DBAdapterDebugLogOption;
|
|
117
|
+
authFunctions?: AuthFunctions;
|
|
118
|
+
triggers?: Triggers<DataModel, Schema>;
|
|
119
|
+
} = {}
|
|
120
|
+
) => {
|
|
121
|
+
return createAdapterFactory({
|
|
122
|
+
config: {
|
|
123
|
+
adapterId: "convex",
|
|
124
|
+
adapterName: "Convex Adapter",
|
|
125
|
+
debugLogs: config.debugLogs || false,
|
|
126
|
+
disableIdGeneration: true,
|
|
127
|
+
transaction: false,
|
|
128
|
+
supportsNumericIds: false,
|
|
129
|
+
supportsJSON: false,
|
|
130
|
+
supportsDates: false,
|
|
131
|
+
supportsArrays: true,
|
|
132
|
+
usePlural: false,
|
|
133
|
+
mapKeysTransformInput: {
|
|
134
|
+
id: "_id",
|
|
135
|
+
},
|
|
136
|
+
mapKeysTransformOutput: {
|
|
137
|
+
_id: "id",
|
|
138
|
+
},
|
|
139
|
+
// Convert dates to numbers. This aligns with how
|
|
140
|
+
// Convex stores _creationTime and avoids a breaking change.
|
|
141
|
+
customTransformInput: ({ data, fieldAttributes }) => {
|
|
142
|
+
if (data && fieldAttributes.type === "date") {
|
|
143
|
+
return new Date(data).getTime();
|
|
144
|
+
}
|
|
145
|
+
return data;
|
|
146
|
+
},
|
|
147
|
+
customTransformOutput: ({ data, fieldAttributes }) => {
|
|
148
|
+
if (data && fieldAttributes.type === "date") {
|
|
149
|
+
return new Date(data);
|
|
150
|
+
}
|
|
151
|
+
return data;
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
adapter: ({ options }) => {
|
|
155
|
+
// Disable telemetry in all cases because it requires Node
|
|
156
|
+
options.telemetry = { enabled: false };
|
|
157
|
+
return {
|
|
158
|
+
id: "convex",
|
|
159
|
+
options: {
|
|
160
|
+
isRunMutationCtx: isRunMutationCtx(ctx),
|
|
161
|
+
},
|
|
162
|
+
createSchema: async ({ file, tables }) => {
|
|
163
|
+
const { createSchema } = await import("./create-schema.js");
|
|
164
|
+
return createSchema({ file, tables });
|
|
165
|
+
},
|
|
166
|
+
create: async ({ model, data, select }): Promise<any> => {
|
|
167
|
+
if (!("runMutation" in ctx)) {
|
|
168
|
+
throw new Error("ctx is not a mutation ctx");
|
|
169
|
+
}
|
|
170
|
+
const onCreateHandle =
|
|
171
|
+
config.authFunctions?.onCreate && config.triggers?.[model]?.onCreate
|
|
172
|
+
? ((await createFunctionHandle(
|
|
173
|
+
config.authFunctions.onCreate
|
|
174
|
+
)) as FunctionHandle<"mutation">)
|
|
175
|
+
: undefined;
|
|
176
|
+
return ctx.runMutation(api.adapter.create, {
|
|
177
|
+
input: { model: model as any, data },
|
|
178
|
+
select,
|
|
179
|
+
onCreateHandle: onCreateHandle,
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
findOne: async (data): Promise<any> => {
|
|
183
|
+
if (data.where?.every((w) => w.connector === "OR")) {
|
|
184
|
+
for (const w of data.where) {
|
|
185
|
+
const result = await ctx.runQuery(api.adapter.findOne, {
|
|
186
|
+
...data,
|
|
187
|
+
model: data.model as TableNames,
|
|
188
|
+
where: parseWhere(w),
|
|
189
|
+
});
|
|
190
|
+
if (result) {
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return await ctx.runQuery(api.adapter.findOne, {
|
|
196
|
+
...data,
|
|
197
|
+
model: data.model as TableNames,
|
|
198
|
+
where: parseWhere(data.where),
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
findMany: async (data): Promise<any[]> => {
|
|
202
|
+
if (data.offset) {
|
|
203
|
+
throw new Error("offset not supported");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (data.where?.some((w) => w.connector === "OR")) {
|
|
207
|
+
const results = await asyncMap(data.where, async (w) =>
|
|
208
|
+
handlePagination(
|
|
209
|
+
async ({ paginationOpts }) => {
|
|
210
|
+
return await ctx.runQuery(api.adapter.findMany, {
|
|
211
|
+
...data,
|
|
212
|
+
model: data.model as TableNames,
|
|
213
|
+
where: parseWhere(w),
|
|
214
|
+
paginationOpts,
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
{ limit: data.limit }
|
|
218
|
+
)
|
|
219
|
+
);
|
|
220
|
+
const docs = unique(results.flatMap((r) => r.docs));
|
|
221
|
+
if (data.sortBy) {
|
|
222
|
+
return sortBy(docs, [
|
|
223
|
+
prop(data.sortBy.field),
|
|
224
|
+
data.sortBy.direction,
|
|
225
|
+
]);
|
|
226
|
+
}
|
|
227
|
+
return docs;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const result = await handlePagination(
|
|
231
|
+
async ({ paginationOpts }) => {
|
|
232
|
+
return await ctx.runQuery(api.adapter.findMany, {
|
|
233
|
+
...data,
|
|
234
|
+
model: data.model as TableNames,
|
|
235
|
+
where: parseWhere(data.where),
|
|
236
|
+
paginationOpts,
|
|
237
|
+
});
|
|
238
|
+
},
|
|
239
|
+
{ limit: data.limit }
|
|
240
|
+
);
|
|
241
|
+
return result.docs;
|
|
242
|
+
},
|
|
243
|
+
count: async (data) => {
|
|
244
|
+
// Yes, count is just findMany returning a number.
|
|
245
|
+
if (data.where?.some((w) => w.connector === "OR")) {
|
|
246
|
+
const results = await asyncMap(data.where, async (w) =>
|
|
247
|
+
handlePagination(async ({ paginationOpts }) => {
|
|
248
|
+
return await ctx.runQuery(api.adapter.findMany, {
|
|
249
|
+
...data,
|
|
250
|
+
model: data.model as TableNames,
|
|
251
|
+
where: parseWhere(w),
|
|
252
|
+
paginationOpts,
|
|
253
|
+
});
|
|
254
|
+
})
|
|
255
|
+
);
|
|
256
|
+
const docs = unique(results.flatMap((r) => r.docs));
|
|
257
|
+
return docs.length;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const result = await handlePagination(async ({ paginationOpts }) => {
|
|
261
|
+
return await ctx.runQuery(api.adapter.findMany, {
|
|
262
|
+
...data,
|
|
263
|
+
model: data.model as TableNames,
|
|
264
|
+
where: parseWhere(data.where),
|
|
265
|
+
paginationOpts,
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
return result.docs.length;
|
|
269
|
+
},
|
|
270
|
+
update: async (data): Promise<any> => {
|
|
271
|
+
if (!("runMutation" in ctx)) {
|
|
272
|
+
throw new Error("ctx is not a mutation ctx");
|
|
273
|
+
}
|
|
274
|
+
if (data.where?.length === 1 && data.where[0].operator === "eq") {
|
|
275
|
+
const onUpdateHandle =
|
|
276
|
+
config.authFunctions?.onUpdate &&
|
|
277
|
+
config.triggers?.[data.model]?.onUpdate
|
|
278
|
+
? ((await createFunctionHandle(
|
|
279
|
+
config.authFunctions.onUpdate
|
|
280
|
+
)) as FunctionHandle<"mutation">)
|
|
281
|
+
: undefined;
|
|
282
|
+
return ctx.runMutation(api.adapter.updateOne, {
|
|
283
|
+
input: {
|
|
284
|
+
model: data.model as TableNames,
|
|
285
|
+
where: parseWhere(data.where),
|
|
286
|
+
update: data.update as any,
|
|
287
|
+
},
|
|
288
|
+
onUpdateHandle: onUpdateHandle,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
throw new Error("where clause not supported");
|
|
292
|
+
},
|
|
293
|
+
delete: async (data) => {
|
|
294
|
+
if (!("runMutation" in ctx)) {
|
|
295
|
+
throw new Error("ctx is not a mutation ctx");
|
|
296
|
+
}
|
|
297
|
+
const onDeleteHandle =
|
|
298
|
+
config.authFunctions?.onDelete &&
|
|
299
|
+
config.triggers?.[data.model]?.onDelete
|
|
300
|
+
? ((await createFunctionHandle(
|
|
301
|
+
config.authFunctions.onDelete
|
|
302
|
+
)) as FunctionHandle<"mutation">)
|
|
303
|
+
: undefined;
|
|
304
|
+
await ctx.runMutation(api.adapter.deleteOne, {
|
|
305
|
+
input: {
|
|
306
|
+
model: data.model as TableNames,
|
|
307
|
+
where: parseWhere(data.where),
|
|
308
|
+
},
|
|
309
|
+
onDeleteHandle: onDeleteHandle,
|
|
310
|
+
});
|
|
311
|
+
},
|
|
312
|
+
deleteMany: async (data) => {
|
|
313
|
+
if (!("runMutation" in ctx)) {
|
|
314
|
+
throw new Error("ctx is not a mutation ctx");
|
|
315
|
+
}
|
|
316
|
+
const onDeleteHandle =
|
|
317
|
+
config.authFunctions?.onDelete &&
|
|
318
|
+
config.triggers?.[data.model as TableNames]?.onDelete
|
|
319
|
+
? ((await createFunctionHandle(
|
|
320
|
+
config.authFunctions.onDelete
|
|
321
|
+
)) as FunctionHandle<"mutation">)
|
|
322
|
+
: undefined;
|
|
323
|
+
const result = await handlePagination(async ({ paginationOpts }) => {
|
|
324
|
+
return await ctx.runMutation(api.adapter.deleteMany, {
|
|
325
|
+
input: {
|
|
326
|
+
...data,
|
|
327
|
+
model: data.model as TableNames,
|
|
328
|
+
where: parseWhere(data.where),
|
|
329
|
+
},
|
|
330
|
+
paginationOpts,
|
|
331
|
+
onDeleteHandle: onDeleteHandle,
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
return result.count;
|
|
335
|
+
},
|
|
336
|
+
updateMany: async (data) => {
|
|
337
|
+
if (!("runMutation" in ctx)) {
|
|
338
|
+
throw new Error("ctx is not a mutation ctx");
|
|
339
|
+
}
|
|
340
|
+
const onUpdateHandle =
|
|
341
|
+
config.authFunctions?.onUpdate &&
|
|
342
|
+
config.triggers?.[data.model]?.onUpdate
|
|
343
|
+
? ((await createFunctionHandle(
|
|
344
|
+
config.authFunctions.onUpdate
|
|
345
|
+
)) as FunctionHandle<"mutation">)
|
|
346
|
+
: undefined;
|
|
347
|
+
const result = await handlePagination(async ({ paginationOpts }) => {
|
|
348
|
+
return await ctx.runMutation(api.adapter.updateMany, {
|
|
349
|
+
input: {
|
|
350
|
+
...data,
|
|
351
|
+
model: data.model as TableNames,
|
|
352
|
+
where: parseWhere(data.where),
|
|
353
|
+
},
|
|
354
|
+
paginationOpts,
|
|
355
|
+
onUpdateHandle: onUpdateHandle,
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
return result.count;
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
};
|