kitcn 0.13.1 → 0.13.3
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/aggregate/index.d.ts +1 -1
- package/dist/{backend-core-yq-eWLRJ.mjs → backend-core-BV61sNRx.mjs} +1159 -57
- package/dist/cli.mjs +4 -4
- package/dist/orm/index.d.ts +1 -1
- package/dist/watcher.mjs +1 -1
- package/dist/{where-clause-compiler-TMppDl9g.d.ts → where-clause-compiler-DcEhkJ12.d.ts} +59 -59
- package/package.json +1 -1
- package/skills/convex/references/setup/expo.md +73 -0
- package/skills/convex/references/setup/index.md +9 -0
- package/skills/convex/references/setup/server.md +1 -1
- package/dist/convex-plugin-tWTDqoKJ.mjs +0 -276
- package/dist/upstream-BUCdbLok.mjs +0 -26
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { t as omit } from "./upstream-BUCdbLok.mjs";
|
|
3
|
-
import { createAuthEndpoint, createAuthMiddleware, sessionMiddleware } from "better-auth/api";
|
|
4
|
-
import { bearer } from "better-auth/plugins/bearer";
|
|
5
|
-
import { jwt } from "better-auth/plugins/jwt";
|
|
6
|
-
import { oidcProvider } from "better-auth/plugins/oidc-provider";
|
|
7
|
-
|
|
8
|
-
//#region src/auth/internal/convex-plugin.ts
|
|
9
|
-
const JWT_COOKIE_NAME = "convex_jwt";
|
|
10
|
-
const normalizeAfterHooks = (hooks) => {
|
|
11
|
-
return hooks.map((hook) => ({
|
|
12
|
-
...hook,
|
|
13
|
-
matcher: (ctx) => Boolean(hook.matcher(ctx))
|
|
14
|
-
}));
|
|
15
|
-
};
|
|
16
|
-
const getJwksAlg = (authProvider) => {
|
|
17
|
-
const isCustomJwt = "type" in authProvider && authProvider.type === "customJwt";
|
|
18
|
-
if (isCustomJwt && authProvider.algorithm !== "RS256") throw new Error("Only RS256 is supported for custom JWT with Better Auth");
|
|
19
|
-
return isCustomJwt ? authProvider.algorithm : "EdDSA";
|
|
20
|
-
};
|
|
21
|
-
const parseAuthConfig = (authConfig, opts) => {
|
|
22
|
-
const providerConfigs = authConfig.providers.filter((provider) => provider.applicationID === "convex");
|
|
23
|
-
if (providerConfigs.length > 1) throw new Error("Multiple auth providers with applicationID 'convex' detected. Please use only one.");
|
|
24
|
-
const providerConfig = providerConfigs[0];
|
|
25
|
-
if (!providerConfig) throw new Error("No auth provider with applicationID 'convex' found. Please add one to your auth config.");
|
|
26
|
-
if (!("type" in providerConfig) || providerConfig.type !== "customJwt") return providerConfig;
|
|
27
|
-
const isDataUriJwks = providerConfig.jwks?.startsWith("data:text/");
|
|
28
|
-
if (isDataUriJwks && !opts.jwks) throw new Error("Static JWKS detected in auth config, but missing from Convex plugin");
|
|
29
|
-
if (!isDataUriJwks && opts.jwks) console.warn("Static JWKS provided to Convex plugin, but not to auth config. This adds an unnecessary network request for token verification.");
|
|
30
|
-
return providerConfig;
|
|
31
|
-
};
|
|
32
|
-
const convex = (opts) => {
|
|
33
|
-
const jwtExpirationSeconds = opts.jwt?.expirationSeconds ?? opts.jwtExpirationSeconds ?? 900;
|
|
34
|
-
const oidcProvider$1 = oidcProvider({
|
|
35
|
-
loginPage: "/not-used",
|
|
36
|
-
metadata: {
|
|
37
|
-
issuer: `${process.env.CONVEX_SITE_URL}`,
|
|
38
|
-
jwks_uri: `${process.env.CONVEX_SITE_URL}${opts.options?.basePath ?? "/api/auth"}/convex/jwks`
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
const providerConfig = parseAuthConfig(opts.authConfig, opts);
|
|
42
|
-
const jwtOptions = {
|
|
43
|
-
jwt: {
|
|
44
|
-
issuer: `${process.env.CONVEX_SITE_URL}`,
|
|
45
|
-
audience: "convex",
|
|
46
|
-
expirationTime: `${jwtExpirationSeconds}s`,
|
|
47
|
-
definePayload: async ({ user, session }) => ({
|
|
48
|
-
...opts.jwt?.definePayload ? await opts.jwt.definePayload({
|
|
49
|
-
session,
|
|
50
|
-
user
|
|
51
|
-
}) : omit(user, ["id", "image"]),
|
|
52
|
-
sessionId: session.id,
|
|
53
|
-
iat: Math.floor(Date.now() / 1e3)
|
|
54
|
-
})
|
|
55
|
-
},
|
|
56
|
-
jwks: { keyPairConfig: { alg: getJwksAlg(providerConfig) } }
|
|
57
|
-
};
|
|
58
|
-
const jwks = opts.jwks ? JSON.parse(opts.jwks) : void 0;
|
|
59
|
-
const jwt$1 = jwt({
|
|
60
|
-
...jwtOptions,
|
|
61
|
-
adapter: {
|
|
62
|
-
createJwk: async (webKey, ctx) => {
|
|
63
|
-
if (opts.jwks) throw new Error("Not implemented");
|
|
64
|
-
return await ctx.context.adapter.create({
|
|
65
|
-
model: "jwks",
|
|
66
|
-
data: {
|
|
67
|
-
...webKey,
|
|
68
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
},
|
|
72
|
-
getJwks: async (ctx) => {
|
|
73
|
-
if (opts.jwks) return jwks;
|
|
74
|
-
return (await ctx.context.adapter.findMany({
|
|
75
|
-
model: "jwks",
|
|
76
|
-
sortBy: {
|
|
77
|
-
direction: "desc",
|
|
78
|
-
field: "createdAt"
|
|
79
|
-
}
|
|
80
|
-
})).map((key) => ({
|
|
81
|
-
...key,
|
|
82
|
-
createdAt: new Date(key.createdAt),
|
|
83
|
-
...key.expiresAt ? { expiresAt: new Date(key.expiresAt) } : {}
|
|
84
|
-
}));
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
const bearer$1 = bearer();
|
|
89
|
-
const schema = {
|
|
90
|
-
user: { fields: { userId: {
|
|
91
|
-
type: "string",
|
|
92
|
-
required: false,
|
|
93
|
-
input: false
|
|
94
|
-
} } },
|
|
95
|
-
...jwt$1.schema
|
|
96
|
-
};
|
|
97
|
-
return {
|
|
98
|
-
id: "convex",
|
|
99
|
-
init: (ctx) => {
|
|
100
|
-
const { options } = ctx;
|
|
101
|
-
if (options.basePath !== "/api/auth" && !opts.options?.basePath) console.warn(`Better Auth basePath set to ${options.basePath} but no basePath is set in the Convex plugin. This is probably a mistake.`);
|
|
102
|
-
if (opts.options?.basePath && options.basePath !== opts.options?.basePath) console.warn(`Better Auth basePath ${options.basePath} does not match Convex plugin basePath ${opts.options?.basePath}. This is probably a mistake.`);
|
|
103
|
-
},
|
|
104
|
-
hooks: {
|
|
105
|
-
before: [...bearer$1.hooks.before, {
|
|
106
|
-
matcher: (ctx) => {
|
|
107
|
-
return !ctx.context.adapter.options?.isRunMutationCtx;
|
|
108
|
-
},
|
|
109
|
-
handler: createAuthMiddleware(async (ctx) => {
|
|
110
|
-
ctx.query = {
|
|
111
|
-
...ctx.query,
|
|
112
|
-
disableRefresh: true
|
|
113
|
-
};
|
|
114
|
-
ctx.context.internalAdapter.deleteSession = async (..._args) => {};
|
|
115
|
-
const knownSafePaths = ["/api-key/list", "/api-key/get"];
|
|
116
|
-
const noopWrite = (method) => {
|
|
117
|
-
return async (..._args) => {
|
|
118
|
-
if (ctx.path && !knownSafePaths.includes(ctx.path)) console.warn(`[convex-better-auth] Write operation "${method}" skipped in query context for ${ctx.path}`);
|
|
119
|
-
return 0;
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
ctx.context.adapter.create = noopWrite("create");
|
|
123
|
-
ctx.context.adapter.update = noopWrite("update");
|
|
124
|
-
ctx.context.adapter.updateMany = noopWrite("updateMany");
|
|
125
|
-
ctx.context.adapter.delete = noopWrite("delete");
|
|
126
|
-
ctx.context.adapter.deleteMany = noopWrite("deleteMany");
|
|
127
|
-
return { context: ctx };
|
|
128
|
-
})
|
|
129
|
-
}],
|
|
130
|
-
after: [
|
|
131
|
-
...normalizeAfterHooks(oidcProvider$1.hooks.after),
|
|
132
|
-
{
|
|
133
|
-
matcher: (ctx) => {
|
|
134
|
-
return Boolean(ctx.path?.startsWith("/sign-in") || ctx.path?.startsWith("/sign-up") || ctx.path?.startsWith("/callback") || ctx.path?.startsWith("/oauth2/callback") || ctx.path?.startsWith("/magic-link/verify") || ctx.path?.startsWith("/email-otp/verify-email") || ctx.path?.startsWith("/phone-number/verify") || ctx.path?.startsWith("/siwe/verify") || ctx.path?.startsWith("/update-session") || ctx.path?.startsWith("/get-session") && ctx.context.session);
|
|
135
|
-
},
|
|
136
|
-
handler: createAuthMiddleware(async (ctx) => {
|
|
137
|
-
const originalSession = ctx.context.session;
|
|
138
|
-
try {
|
|
139
|
-
ctx.context.session = ctx.context.session ?? ctx.context.newSession;
|
|
140
|
-
const { token } = await jwt$1.endpoints.getToken({
|
|
141
|
-
...ctx,
|
|
142
|
-
headers: {},
|
|
143
|
-
method: "GET",
|
|
144
|
-
returnHeaders: false,
|
|
145
|
-
returnStatus: false
|
|
146
|
-
});
|
|
147
|
-
const jwtCookie = ctx.context.createAuthCookie(JWT_COOKIE_NAME, { maxAge: jwtExpirationSeconds });
|
|
148
|
-
ctx.setCookie(jwtCookie.name, token, jwtCookie.attributes);
|
|
149
|
-
} catch (_error) {}
|
|
150
|
-
ctx.context.session = originalSession;
|
|
151
|
-
})
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
matcher: (ctx) => {
|
|
155
|
-
return Boolean(ctx.path?.startsWith("/sign-out") || ctx.path?.startsWith("/delete-user") || ctx.path?.startsWith("/get-session") && !ctx.context.session);
|
|
156
|
-
},
|
|
157
|
-
handler: createAuthMiddleware(async (ctx) => {
|
|
158
|
-
const jwtCookie = ctx.context.createAuthCookie(JWT_COOKIE_NAME, { maxAge: 0 });
|
|
159
|
-
ctx.setCookie(jwtCookie.name, "", jwtCookie.attributes);
|
|
160
|
-
})
|
|
161
|
-
}
|
|
162
|
-
]
|
|
163
|
-
},
|
|
164
|
-
endpoints: {
|
|
165
|
-
getOpenIdConfig: createAuthEndpoint("/convex/.well-known/openid-configuration", {
|
|
166
|
-
method: "GET",
|
|
167
|
-
metadata: { isAction: false }
|
|
168
|
-
}, async (ctx) => {
|
|
169
|
-
return await oidcProvider$1.endpoints.getOpenIdConfig({
|
|
170
|
-
...ctx,
|
|
171
|
-
returnHeaders: false,
|
|
172
|
-
returnStatus: false
|
|
173
|
-
});
|
|
174
|
-
}),
|
|
175
|
-
getJwks: createAuthEndpoint("/convex/jwks", {
|
|
176
|
-
method: "GET",
|
|
177
|
-
metadata: { openapi: {
|
|
178
|
-
description: "Get the JSON Web Key Set",
|
|
179
|
-
responses: { "200": { description: "JSON Web Key Set retrieved successfully" } }
|
|
180
|
-
} }
|
|
181
|
-
}, async (ctx) => {
|
|
182
|
-
return await jwt$1.endpoints.getJwks({
|
|
183
|
-
...ctx,
|
|
184
|
-
returnHeaders: false,
|
|
185
|
-
returnStatus: false
|
|
186
|
-
});
|
|
187
|
-
}),
|
|
188
|
-
getLatestJwks: createAuthEndpoint("/convex/latest-jwks", {
|
|
189
|
-
isAction: true,
|
|
190
|
-
method: "POST",
|
|
191
|
-
metadata: {
|
|
192
|
-
SERVER_ONLY: true,
|
|
193
|
-
openapi: { description: "Delete and regenerate JWKS, and return the new JWKS for static usage" }
|
|
194
|
-
}
|
|
195
|
-
}, async (ctx) => {
|
|
196
|
-
await jwt(jwtOptions).endpoints.getJwks({
|
|
197
|
-
...ctx,
|
|
198
|
-
method: "GET"
|
|
199
|
-
});
|
|
200
|
-
const jwks = await ctx.context.adapter.findMany({
|
|
201
|
-
model: "jwks",
|
|
202
|
-
limit: 1,
|
|
203
|
-
sortBy: {
|
|
204
|
-
direction: "desc",
|
|
205
|
-
field: "createdAt"
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
jwks[0].alg = jwtOptions.jwks.keyPairConfig.alg;
|
|
209
|
-
return jwks;
|
|
210
|
-
}),
|
|
211
|
-
rotateKeys: createAuthEndpoint("/convex/rotate-keys", {
|
|
212
|
-
isAction: true,
|
|
213
|
-
method: "POST",
|
|
214
|
-
metadata: {
|
|
215
|
-
SERVER_ONLY: true,
|
|
216
|
-
openapi: { description: "Delete and regenerate JWKS, and return the new JWKS for static usage" }
|
|
217
|
-
}
|
|
218
|
-
}, async (ctx) => {
|
|
219
|
-
await ctx.context.adapter.deleteMany({
|
|
220
|
-
model: "jwks",
|
|
221
|
-
where: []
|
|
222
|
-
});
|
|
223
|
-
await jwt(jwtOptions).endpoints.getJwks({
|
|
224
|
-
...ctx,
|
|
225
|
-
method: "GET"
|
|
226
|
-
});
|
|
227
|
-
const jwks = await ctx.context.adapter.findMany({
|
|
228
|
-
model: "jwks",
|
|
229
|
-
limit: 1,
|
|
230
|
-
sortBy: {
|
|
231
|
-
direction: "desc",
|
|
232
|
-
field: "createdAt"
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
jwks[0].alg = jwtOptions.jwks.keyPairConfig.alg;
|
|
236
|
-
return jwks;
|
|
237
|
-
}),
|
|
238
|
-
getToken: createAuthEndpoint("/convex/token", {
|
|
239
|
-
method: "GET",
|
|
240
|
-
requireHeaders: true,
|
|
241
|
-
use: [sessionMiddleware],
|
|
242
|
-
metadata: { openapi: { description: "Get a JWT token" } }
|
|
243
|
-
}, async (ctx) => {
|
|
244
|
-
const runEndpoint = async () => {
|
|
245
|
-
const response = await jwt$1.endpoints.getToken({
|
|
246
|
-
...ctx,
|
|
247
|
-
returnHeaders: false,
|
|
248
|
-
returnStatus: false
|
|
249
|
-
});
|
|
250
|
-
const jwtCookie = ctx.context.createAuthCookie(JWT_COOKIE_NAME, { maxAge: jwtExpirationSeconds });
|
|
251
|
-
ctx.setCookie(jwtCookie.name, response.token, jwtCookie.attributes);
|
|
252
|
-
return response;
|
|
253
|
-
};
|
|
254
|
-
try {
|
|
255
|
-
return await runEndpoint();
|
|
256
|
-
} catch (error) {
|
|
257
|
-
if (!opts.jwks && error?.code === "ERR_JOSE_NOT_SUPPORTED") {
|
|
258
|
-
if (opts.jwksRotateOnTokenGenerationError) {
|
|
259
|
-
await ctx.context.adapter.deleteMany({
|
|
260
|
-
model: "jwks",
|
|
261
|
-
where: []
|
|
262
|
-
});
|
|
263
|
-
return await runEndpoint();
|
|
264
|
-
}
|
|
265
|
-
console.error("Try temporarily setting jwksRotateOnTokenGenerationError: true on the Convex Better Auth plugin.");
|
|
266
|
-
}
|
|
267
|
-
throw error;
|
|
268
|
-
}
|
|
269
|
-
})
|
|
270
|
-
},
|
|
271
|
-
schema
|
|
272
|
-
};
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
//#endregion
|
|
276
|
-
export { convex };
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
//#region src/internal/upstream/index.ts
|
|
3
|
-
/**
|
|
4
|
-
* omit helps you omit keys from an object more concisely.
|
|
5
|
-
*
|
|
6
|
-
* e.g. `omit({a: v.string(), b: v.number()}, ["a"])` is equivalent to
|
|
7
|
-
* `{b: v.number()}`
|
|
8
|
-
*
|
|
9
|
-
* The alternative could be something like:
|
|
10
|
-
* ```js
|
|
11
|
-
* const obj = { a: v.string(), b: v.number() };
|
|
12
|
-
* // omit does the following
|
|
13
|
-
* const { a, ...rest } = obj;
|
|
14
|
-
* const withoutA = rest;
|
|
15
|
-
* ```
|
|
16
|
-
*
|
|
17
|
-
* @param obj The object to return a copy of without the specified keys.
|
|
18
|
-
* @param keys The keys to omit from the object.
|
|
19
|
-
* @returns A new object with the keys you omitted removed.
|
|
20
|
-
*/
|
|
21
|
-
function omit(obj, keys) {
|
|
22
|
-
return Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
//#endregion
|
|
26
|
-
export { omit as t };
|