@lupinum/better-convex-nuxt 0.8.0-beta.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/Apache-2.0.txt +201 -0
  3. package/README.md +151 -0
  4. package/THIRD_PARTY_NOTICES.md +38 -0
  5. package/dist/module.d.mts +55 -0
  6. package/dist/module.json +12 -0
  7. package/dist/module.mjs +309 -0
  8. package/dist/runtime/auth/auth-identity.d.ts +31 -0
  9. package/dist/runtime/auth/auth-identity.js +21 -0
  10. package/dist/runtime/auth/better-auth-browser-adapter.d.ts +33 -0
  11. package/dist/runtime/auth/better-auth-browser-adapter.js +215 -0
  12. package/dist/runtime/auth/client-engine-types.d.ts +4 -0
  13. package/dist/runtime/auth/client-engine-types.js +0 -0
  14. package/dist/runtime/auth/integrated-client.d.ts +25 -0
  15. package/dist/runtime/auth/integrated-client.js +132 -0
  16. package/dist/runtime/auth/operation-tracker.d.ts +7 -0
  17. package/dist/runtime/auth/operation-tracker.js +14 -0
  18. package/dist/runtime/auth/session-synchronization.d.ts +23 -0
  19. package/dist/runtime/auth/session-synchronization.js +156 -0
  20. package/dist/runtime/auth/token-fetcher.d.ts +66 -0
  21. package/dist/runtime/auth/token-fetcher.js +131 -0
  22. package/dist/runtime/auth/validate-auth-client-definition.d.ts +12 -0
  23. package/dist/runtime/auth/validate-auth-client-definition.js +47 -0
  24. package/dist/runtime/auth-client/convex-client-plugin.d.ts +31 -0
  25. package/dist/runtime/auth-client/convex-client-plugin.js +14 -0
  26. package/dist/runtime/auth-client/definition-types.d.ts +6 -0
  27. package/dist/runtime/auth-client/definition-types.js +0 -0
  28. package/dist/runtime/auth-client/empty-definition.d.ts +2 -0
  29. package/dist/runtime/auth-client/empty-definition.js +2 -0
  30. package/dist/runtime/auth-client/index.d.ts +71 -0
  31. package/dist/runtime/auth-client/index.js +3 -0
  32. package/dist/runtime/cli/auth-schema.d.ts +2 -0
  33. package/dist/runtime/cli/auth-schema.js +169 -0
  34. package/dist/runtime/cli/convex.d.ts +11 -0
  35. package/dist/runtime/cli/convex.js +274 -0
  36. package/dist/runtime/composables/useConvex.d.ts +4 -0
  37. package/dist/runtime/composables/useConvex.js +9 -0
  38. package/dist/runtime/composables/useConvexAction.d.ts +4 -0
  39. package/dist/runtime/composables/useConvexAction.js +18 -0
  40. package/dist/runtime/composables/useConvexAttachment.d.ts +9 -0
  41. package/dist/runtime/composables/useConvexAttachment.js +14 -0
  42. package/dist/runtime/composables/useConvexAuth.d.ts +10 -0
  43. package/dist/runtime/composables/useConvexAuth.js +37 -0
  44. package/dist/runtime/composables/useConvexConfig.d.ts +12 -0
  45. package/dist/runtime/composables/useConvexConfig.js +7 -0
  46. package/dist/runtime/composables/useConvexConnectionState.d.ts +33 -0
  47. package/dist/runtime/composables/useConvexConnectionState.js +24 -0
  48. package/dist/runtime/composables/useConvexFileUpload.d.ts +169 -0
  49. package/dist/runtime/composables/useConvexFileUpload.js +198 -0
  50. package/dist/runtime/composables/useConvexMutation.d.ts +13 -0
  51. package/dist/runtime/composables/useConvexMutation.js +24 -0
  52. package/dist/runtime/composables/useConvexPaginatedQuery.d.ts +13 -0
  53. package/dist/runtime/composables/useConvexPaginatedQuery.js +256 -0
  54. package/dist/runtime/composables/useConvexQuery.d.ts +19 -0
  55. package/dist/runtime/composables/useConvexQuery.js +308 -0
  56. package/dist/runtime/convex-auth/adapter/create-adapter.d.ts +33 -0
  57. package/dist/runtime/convex-auth/adapter/create-adapter.js +308 -0
  58. package/dist/runtime/convex-auth/adapter/define-functions.d.ts +160 -0
  59. package/dist/runtime/convex-auth/adapter/define-functions.js +497 -0
  60. package/dist/runtime/convex-auth/adapter/generate-schema.d.ts +16 -0
  61. package/dist/runtime/convex-auth/adapter/generate-schema.js +332 -0
  62. package/dist/runtime/convex-auth/adapter/metadata.d.ts +44 -0
  63. package/dist/runtime/convex-auth/adapter/metadata.js +91 -0
  64. package/dist/runtime/convex-auth/adapter/query.d.ts +32 -0
  65. package/dist/runtime/convex-auth/adapter/query.js +275 -0
  66. package/dist/runtime/convex-auth/adapter/relationships.d.ts +20 -0
  67. package/dist/runtime/convex-auth/adapter/relationships.js +128 -0
  68. package/dist/runtime/convex-auth/component/_generated/api.js +5 -0
  69. package/dist/runtime/convex-auth/component/_generated/component.d.ts +116 -0
  70. package/dist/runtime/convex-auth/component/_generated/component.js +0 -0
  71. package/dist/runtime/convex-auth/component/_generated/dataModel.js +0 -0
  72. package/dist/runtime/convex-auth/component/_generated/server.js +16 -0
  73. package/dist/runtime/convex-auth/component/adapter.d.ts +142 -0
  74. package/dist/runtime/convex-auth/component/adapter.js +16 -0
  75. package/dist/runtime/convex-auth/component/convex.config.d.ts +2 -0
  76. package/dist/runtime/convex-auth/component/convex.config.js +3 -0
  77. package/dist/runtime/convex-auth/component/schema.d.ts +799 -0
  78. package/dist/runtime/convex-auth/component/schema.js +180 -0
  79. package/dist/runtime/convex-auth/component/schemaMetadata.d.ts +2094 -0
  80. package/dist/runtime/convex-auth/component/schemaMetadata.js +2161 -0
  81. package/dist/runtime/convex-auth/context.d.ts +5 -0
  82. package/dist/runtime/convex-auth/context.js +8 -0
  83. package/dist/runtime/convex-auth/create-auth-component.d.ts +41 -0
  84. package/dist/runtime/convex-auth/create-auth-component.js +157 -0
  85. package/dist/runtime/convex-auth/index.d.ts +11 -0
  86. package/dist/runtime/convex-auth/index.js +7 -0
  87. package/dist/runtime/convex-auth/internal-session.d.ts +2 -0
  88. package/dist/runtime/convex-auth/internal-session.js +1 -0
  89. package/dist/runtime/convex-auth/jwks-rotation.d.ts +58 -0
  90. package/dist/runtime/convex-auth/jwks-rotation.js +163 -0
  91. package/dist/runtime/convex-auth/oauth-live-access.d.ts +17 -0
  92. package/dist/runtime/convex-auth/oauth-live-access.js +78 -0
  93. package/dist/runtime/convex-auth/oauth-provider-compat.d.ts +10 -0
  94. package/dist/runtime/convex-auth/oauth-provider-compat.js +170 -0
  95. package/dist/runtime/convex-auth/oauth-resource.d.ts +39 -0
  96. package/dist/runtime/convex-auth/oauth-resource.js +118 -0
  97. package/dist/runtime/convex-auth/oauth-security.d.ts +82 -0
  98. package/dist/runtime/convex-auth/oauth-security.js +454 -0
  99. package/dist/runtime/convex-auth/origin.d.ts +4 -0
  100. package/dist/runtime/convex-auth/origin.js +9 -0
  101. package/dist/runtime/convex-auth/plugin.d.ts +18 -0
  102. package/dist/runtime/convex-auth/plugin.js +605 -0
  103. package/dist/runtime/convex-auth/provider.d.ts +2 -0
  104. package/dist/runtime/convex-auth/provider.js +11 -0
  105. package/dist/runtime/convex-auth/test.d.ts +410 -0
  106. package/dist/runtime/convex-auth/test.js +9 -0
  107. package/dist/runtime/convex-auth/types.d.ts +18 -0
  108. package/dist/runtime/convex-auth/types.js +0 -0
  109. package/dist/runtime/convex-auth/user-projection.d.ts +106 -0
  110. package/dist/runtime/convex-auth/user-projection.js +128 -0
  111. package/dist/runtime/devtools/auth-proxy-registry.d.ts +4 -0
  112. package/dist/runtime/devtools/auth-proxy-registry.js +47 -0
  113. package/dist/runtime/devtools/bridge-setup.d.ts +21 -0
  114. package/dist/runtime/devtools/bridge-setup.js +165 -0
  115. package/dist/runtime/devtools/path-utils.d.ts +2 -0
  116. package/dist/runtime/devtools/path-utils.js +12 -0
  117. package/dist/runtime/devtools/server.d.ts +2 -0
  118. package/dist/runtime/devtools/server.js +108 -0
  119. package/dist/runtime/devtools/setup-client.d.ts +16 -0
  120. package/dist/runtime/devtools/setup-client.js +43 -0
  121. package/dist/runtime/devtools/sink.d.ts +18 -0
  122. package/dist/runtime/devtools/sink.js +110 -0
  123. package/dist/runtime/devtools/transport.d.ts +16 -0
  124. package/dist/runtime/devtools/transport.js +149 -0
  125. package/dist/runtime/devtools/types.d.ts +167 -0
  126. package/dist/runtime/devtools/types.js +1 -0
  127. package/dist/runtime/devtools/ui/dist/200.html +1 -0
  128. package/dist/runtime/devtools/ui/dist/404.html +1 -0
  129. package/dist/runtime/devtools/ui/dist/_nuxt/C4MASuCh.js +1 -0
  130. package/dist/runtime/devtools/ui/dist/_nuxt/DJHkqtZq.js +3 -0
  131. package/dist/runtime/devtools/ui/dist/_nuxt/DWwrCltl.js +2 -0
  132. package/dist/runtime/devtools/ui/dist/_nuxt/DZ_UiYoH.js +1 -0
  133. package/dist/runtime/devtools/ui/dist/_nuxt/_m9ujb-i.js +1 -0
  134. package/dist/runtime/devtools/ui/dist/_nuxt/builds/latest.json +1 -0
  135. package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/better-convex-nuxt-devtools.json +1 -0
  136. package/dist/runtime/devtools/ui/dist/_nuxt/entry.DpFDKYZ5.css +1 -0
  137. package/dist/runtime/devtools/ui/dist/_nuxt/error-404.DYUJo5xt.css +1 -0
  138. package/dist/runtime/devtools/ui/dist/_nuxt/error-500.DQdoJJXg.css +1 -0
  139. package/dist/runtime/devtools/ui/dist/convex-logo.svg +5 -0
  140. package/dist/runtime/devtools/ui/dist/index.html +1 -0
  141. package/dist/runtime/errors/index.d.ts +7 -0
  142. package/dist/runtime/errors/index.js +5 -0
  143. package/dist/runtime/middleware/convex-auth.global.d.ts +2 -0
  144. package/dist/runtime/middleware/convex-auth.global.js +31 -0
  145. package/dist/runtime/plugin.auth.client.d.ts +3 -0
  146. package/dist/runtime/plugin.auth.client.js +217 -0
  147. package/dist/runtime/plugin.client.d.ts +3 -0
  148. package/dist/runtime/plugin.client.js +43 -0
  149. package/dist/runtime/plugin.server.d.ts +12 -0
  150. package/dist/runtime/plugin.server.js +98 -0
  151. package/dist/runtime/plugins/convex-call-error-payload.d.ts +14 -0
  152. package/dist/runtime/plugins/convex-call-error-payload.js +12 -0
  153. package/dist/runtime/runtime-context.d.ts +26 -0
  154. package/dist/runtime/runtime-context.js +48 -0
  155. package/dist/runtime/server/api/auth/[...].d.ts +10 -0
  156. package/dist/runtime/server/api/auth/[...].js +509 -0
  157. package/dist/runtime/server/api/auth/authorization-server-metadata.d.ts +2 -0
  158. package/dist/runtime/server/api/auth/authorization-server-metadata.js +6 -0
  159. package/dist/runtime/server/api/auth/body-size.d.ts +15 -0
  160. package/dist/runtime/server/api/auth/body-size.js +179 -0
  161. package/dist/runtime/server/api/auth/headers.d.ts +6 -0
  162. package/dist/runtime/server/api/auth/headers.js +98 -0
  163. package/dist/runtime/server/api/auth/jwks.d.ts +2 -0
  164. package/dist/runtime/server/api/auth/jwks.js +6 -0
  165. package/dist/runtime/server/api/auth/security.d.ts +14 -0
  166. package/dist/runtime/server/api/auth/security.js +85 -0
  167. package/dist/runtime/server/api/release-fingerprint.d.ts +2 -0
  168. package/dist/runtime/server/api/release-fingerprint.js +36 -0
  169. package/dist/runtime/server/index.d.ts +1 -0
  170. package/dist/runtime/server/index.js +3 -0
  171. package/dist/runtime/server/plugins/runtime-config.d.ts +7 -0
  172. package/dist/runtime/server/plugins/runtime-config.js +7 -0
  173. package/dist/runtime/server/utils/auth-snapshot.d.ts +26 -0
  174. package/dist/runtime/server/utils/auth-snapshot.js +165 -0
  175. package/dist/runtime/server/utils/http.d.ts +16 -0
  176. package/dist/runtime/server/utils/http.js +133 -0
  177. package/dist/runtime/server/utils/server-convex-caller.d.ts +31 -0
  178. package/dist/runtime/server/utils/server-convex-caller.js +151 -0
  179. package/dist/runtime/server/utils/server-convex-options.d.ts +83 -0
  180. package/dist/runtime/server/utils/server-convex-options.js +69 -0
  181. package/dist/runtime/server/utils/signed-client-ip.d.ts +6 -0
  182. package/dist/runtime/server/utils/signed-client-ip.js +29 -0
  183. package/dist/runtime/server/utils/ssr-auth-headers.d.ts +26 -0
  184. package/dist/runtime/server/utils/ssr-auth-headers.js +49 -0
  185. package/dist/runtime/server/utils/token-exchange.d.ts +27 -0
  186. package/dist/runtime/server/utils/token-exchange.js +96 -0
  187. package/dist/runtime/shared/auth-cookie.d.ts +4 -0
  188. package/dist/runtime/shared/auth-cookie.js +25 -0
  189. package/dist/runtime/shared/auth-origin.d.ts +15 -0
  190. package/dist/runtime/shared/auth-origin.js +42 -0
  191. package/dist/runtime/shared/bounded-stream.d.ts +2 -0
  192. package/dist/runtime/shared/bounded-stream.js +50 -0
  193. package/dist/runtime/shared/client-ip.d.ts +21 -0
  194. package/dist/runtime/shared/client-ip.js +123 -0
  195. package/dist/runtime/shared/release-fingerprint.d.ts +5 -0
  196. package/dist/runtime/shared/release-fingerprint.js +17 -0
  197. package/dist/runtime/types.d.ts +19 -0
  198. package/dist/runtime/utils/auth-config.d.ts +24 -0
  199. package/dist/runtime/utils/auth-config.js +45 -0
  200. package/dist/runtime/utils/auth-contract.d.ts +22 -0
  201. package/dist/runtime/utils/auth-contract.js +0 -0
  202. package/dist/runtime/utils/auth-errors.d.ts +5 -0
  203. package/dist/runtime/utils/auth-errors.js +22 -0
  204. package/dist/runtime/utils/auth-identity-state.d.ts +4 -0
  205. package/dist/runtime/utils/auth-identity-state.js +8 -0
  206. package/dist/runtime/utils/auth-pending-state.d.ts +13 -0
  207. package/dist/runtime/utils/auth-pending-state.js +4 -0
  208. package/dist/runtime/utils/auth-pending.d.ts +10 -0
  209. package/dist/runtime/utils/auth-pending.js +30 -0
  210. package/dist/runtime/utils/auth-route-protection.d.ts +16 -0
  211. package/dist/runtime/utils/auth-route-protection.js +58 -0
  212. package/dist/runtime/utils/auth-status.d.ts +47 -0
  213. package/dist/runtime/utils/auth-status.js +8 -0
  214. package/dist/runtime/utils/bounded-convex-fetch.d.ts +18 -0
  215. package/dist/runtime/utils/bounded-convex-fetch.js +152 -0
  216. package/dist/runtime/utils/callable-devtools.d.ts +17 -0
  217. package/dist/runtime/utils/callable-devtools.js +49 -0
  218. package/dist/runtime/utils/callable-observer.d.ts +2 -0
  219. package/dist/runtime/utils/callable-observer.js +1 -0
  220. package/dist/runtime/utils/composable-scope.d.ts +2 -0
  221. package/dist/runtime/utils/composable-scope.js +8 -0
  222. package/dist/runtime/utils/config-defaults.d.ts +8 -0
  223. package/dist/runtime/utils/config-defaults.js +8 -0
  224. package/dist/runtime/utils/convex-cache.d.ts +68 -0
  225. package/dist/runtime/utils/convex-cache.js +47 -0
  226. package/dist/runtime/utils/convex-config.d.ts +16 -0
  227. package/dist/runtime/utils/convex-config.js +50 -0
  228. package/dist/runtime/utils/convex-shared.d.ts +67 -0
  229. package/dist/runtime/utils/convex-shared.js +134 -0
  230. package/dist/runtime/utils/identity-changed-error.d.ts +4 -0
  231. package/dist/runtime/utils/identity-changed-error.js +12 -0
  232. package/dist/runtime/utils/identity-key.d.ts +19 -0
  233. package/dist/runtime/utils/identity-key.js +10 -0
  234. package/dist/runtime/utils/integrated-auth-client.d.ts +5 -0
  235. package/dist/runtime/utils/integrated-auth-client.js +0 -0
  236. package/dist/runtime/utils/logger.d.ts +42 -0
  237. package/dist/runtime/utils/logger.js +190 -0
  238. package/dist/runtime/utils/mime-type.d.ts +33 -0
  239. package/dist/runtime/utils/mime-type.js +10 -0
  240. package/dist/runtime/utils/query-execution-gate.d.ts +47 -0
  241. package/dist/runtime/utils/query-execution-gate.js +63 -0
  242. package/dist/runtime/utils/query-execution.d.ts +8 -0
  243. package/dist/runtime/utils/query-execution.js +19 -0
  244. package/dist/runtime/utils/query-foundation.d.ts +20 -0
  245. package/dist/runtime/utils/query-foundation.js +39 -0
  246. package/dist/runtime/utils/query-state.d.ts +12 -0
  247. package/dist/runtime/utils/query-state.js +12 -0
  248. package/dist/runtime/utils/reactive-args.d.ts +5 -0
  249. package/dist/runtime/utils/reactive-args.js +42 -0
  250. package/dist/runtime/utils/runtime-config-normalize.d.ts +22 -0
  251. package/dist/runtime/utils/runtime-config-normalize.js +28 -0
  252. package/dist/runtime/utils/runtime-config.d.ts +4 -0
  253. package/dist/runtime/utils/runtime-config.js +8 -0
  254. package/dist/runtime/utils/sanitize-diagnostic.d.ts +6 -0
  255. package/dist/runtime/utils/sanitize-diagnostic.js +81 -0
  256. package/dist/runtime/utils/shared-helpers.d.ts +46 -0
  257. package/dist/runtime/utils/shared-helpers.js +139 -0
  258. package/dist/runtime/utils/site-url.d.ts +4 -0
  259. package/dist/runtime/utils/site-url.js +15 -0
  260. package/dist/runtime/utils/ssr-pagination-state.d.ts +3 -0
  261. package/dist/runtime/utils/ssr-pagination-state.js +3 -0
  262. package/dist/runtime/utils/types.d.ts +29 -0
  263. package/dist/runtime/utils/types.js +0 -0
  264. package/dist/runtime/utils/upload-core.d.ts +16 -0
  265. package/dist/runtime/utils/upload-core.js +116 -0
  266. package/dist/types.d.mts +21 -0
  267. package/package.json +253 -0
  268. package/security/upstream-convex-better-auth.json +477 -0
@@ -0,0 +1,497 @@
1
+ import {
2
+ mutationGeneric,
3
+ paginationOptsValidator,
4
+ queryGeneric
5
+ } from "convex/server";
6
+ import { v } from "convex/values";
7
+ import {
8
+ JWKS_GRACE_PERIOD_SECONDS,
9
+ normalizeSigningKeyCandidate,
10
+ signingKeyCandidateValidator
11
+ } from "../jwks-rotation.js";
12
+ import {
13
+ assertAuthSchemaMatchesMetadata,
14
+ getAuthFieldMetadata,
15
+ getAuthModelMetadata
16
+ } from "./metadata.js";
17
+ import {
18
+ collectAuthRows,
19
+ countAuthRows,
20
+ findAuthRows,
21
+ paginateAuthRows,
22
+ toBetterAuthDocument
23
+ } from "./query.js";
24
+ import { createAuthRelationshipEngine } from "./relationships.js";
25
+ const whereValidator = v.object({
26
+ field: v.string(),
27
+ operator: v.optional(
28
+ v.union(
29
+ v.literal("lt"),
30
+ v.literal("lte"),
31
+ v.literal("gt"),
32
+ v.literal("gte"),
33
+ v.literal("eq"),
34
+ v.literal("in"),
35
+ v.literal("not_in"),
36
+ v.literal("ne"),
37
+ v.literal("contains"),
38
+ v.literal("starts_with"),
39
+ v.literal("ends_with")
40
+ )
41
+ ),
42
+ value: v.union(
43
+ v.string(),
44
+ v.number(),
45
+ v.boolean(),
46
+ v.array(v.string()),
47
+ v.array(v.number()),
48
+ v.null()
49
+ ),
50
+ connector: v.optional(v.union(v.literal("AND"), v.literal("OR"))),
51
+ mode: v.optional(v.union(v.literal("sensitive"), v.literal("insensitive")))
52
+ });
53
+ const readArgs = {
54
+ model: v.string(),
55
+ where: v.optional(v.array(whereValidator)),
56
+ select: v.optional(v.array(v.string())),
57
+ sortBy: v.optional(
58
+ v.object({
59
+ field: v.string(),
60
+ direction: v.union(v.literal("asc"), v.literal("desc"))
61
+ })
62
+ ),
63
+ offset: v.optional(v.number())
64
+ };
65
+ function assertRecord(value, code) {
66
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(code);
67
+ }
68
+ function assertValue(field, value) {
69
+ if (value === null) {
70
+ if (!field.nullable) throw new Error(`AUTH_FIELD_NULL_FORBIDDEN:${field.physicalName}`);
71
+ return;
72
+ }
73
+ switch (field.kind) {
74
+ case "string":
75
+ case "json":
76
+ if (typeof value !== "string") throw new Error(`AUTH_FIELD_TYPE:${field.physicalName}`);
77
+ return;
78
+ case "number":
79
+ case "date":
80
+ if (typeof value !== "number" || !Number.isFinite(value)) {
81
+ throw new TypeError(`AUTH_FIELD_TYPE:${field.physicalName}`);
82
+ }
83
+ return;
84
+ case "boolean":
85
+ if (typeof value !== "boolean") throw new Error(`AUTH_FIELD_TYPE:${field.physicalName}`);
86
+ return;
87
+ case "string[]":
88
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
89
+ throw new Error(`AUTH_FIELD_TYPE:${field.physicalName}`);
90
+ }
91
+ return;
92
+ case "number[]":
93
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "number" || !Number.isFinite(entry))) {
94
+ throw new Error(`AUTH_FIELD_TYPE:${field.physicalName}`);
95
+ }
96
+ }
97
+ }
98
+ function normalizeCreate(metadata, modelName, input) {
99
+ assertRecord(input, "AUTH_CREATE_DATA_INVALID");
100
+ const model = getAuthModelMetadata(metadata, modelName);
101
+ const result = {};
102
+ for (const key of Object.keys(input)) getAuthFieldMetadata(metadata, modelName, key);
103
+ for (const field of Object.values(model.fields)) {
104
+ const value = input[field.physicalName];
105
+ if (value === void 0) {
106
+ if (field.nullable) {
107
+ result[field.physicalName] = null;
108
+ continue;
109
+ }
110
+ throw new Error(`AUTH_FIELD_REQUIRED:${modelName}.${field.physicalName}`);
111
+ }
112
+ assertValue(field, value);
113
+ result[field.physicalName] = value;
114
+ }
115
+ if (typeof result.id !== "string" || result.id.length === 0) {
116
+ throw new Error(`AUTH_LOGICAL_ID_REQUIRED:${modelName}`);
117
+ }
118
+ return result;
119
+ }
120
+ function normalizeUpdate(metadata, modelName, input, options) {
121
+ assertRecord(input, "AUTH_UPDATE_DATA_INVALID");
122
+ const result = {};
123
+ for (const [key, value] of Object.entries(input)) {
124
+ if (value === void 0) continue;
125
+ const field = getAuthFieldMetadata(metadata, modelName, key);
126
+ if (!field.updatable || field.logicalName === "id") {
127
+ throw new Error(`AUTH_FIELD_IMMUTABLE:${modelName}.${field.physicalName}`);
128
+ }
129
+ if (!options.allowUnique && field.unique) {
130
+ throw new Error(`AUTH_BULK_UNIQUE_UPDATE_FORBIDDEN:${modelName}.${field.physicalName}`);
131
+ }
132
+ assertValue(field, value);
133
+ result[field.physicalName] = value;
134
+ }
135
+ if (!options.allowEmpty && Object.keys(result).length === 0) throw new Error("AUTH_UPDATE_EMPTY");
136
+ return result;
137
+ }
138
+ function readShape(args) {
139
+ return {
140
+ model: args.model,
141
+ where: args.where,
142
+ select: args.select,
143
+ sortBy: args.sortBy,
144
+ offset: args.offset
145
+ };
146
+ }
147
+ async function assertUniqueConstraints(ctx, schema, metadata, modelName, changes, current) {
148
+ const model = getAuthModelMetadata(metadata, modelName);
149
+ const data = current ? { ...current, ...changes } : changes;
150
+ for (const index of model.indexes) {
151
+ if (index.unique !== true) continue;
152
+ if (current && index.fields.every((fieldName) => !(fieldName in changes))) continue;
153
+ const where = [];
154
+ let complete = true;
155
+ for (const fieldName of index.fields) {
156
+ const value = data[fieldName];
157
+ if (value === null || value === void 0) {
158
+ complete = false;
159
+ break;
160
+ }
161
+ where.push({ field: fieldName, operator: "eq", value });
162
+ }
163
+ if (!complete) continue;
164
+ const matches = await findAuthRows(
165
+ ctx,
166
+ schema,
167
+ metadata,
168
+ {
169
+ model: modelName,
170
+ where
171
+ },
172
+ 2
173
+ );
174
+ if (matches.some((row) => row._id !== current?._id)) {
175
+ throw new Error(`AUTH_UNIQUE_CONFLICT:${modelName}.${index.descriptor}`);
176
+ }
177
+ }
178
+ }
179
+ function assertBulkUniqueConstraints(metadata, modelName, patch, rows) {
180
+ const model = getAuthModelMetadata(metadata, modelName);
181
+ for (const index of model.indexes) {
182
+ if (index.unique !== true || !index.fields.some((field) => field in patch)) continue;
183
+ const seen = /* @__PURE__ */ new Set();
184
+ for (const current of rows) {
185
+ const candidate = { ...current, ...patch };
186
+ const values = index.fields.map((field) => candidate[field]);
187
+ if (values.some((value) => value === null || value === void 0)) continue;
188
+ const key = JSON.stringify(values);
189
+ if (seen.has(key)) throw new Error(`AUTH_UNIQUE_CONFLICT:${modelName}.${index.descriptor}`);
190
+ seen.add(key);
191
+ }
192
+ }
193
+ }
194
+ async function runTrigger(ctx, handle, payload) {
195
+ if (!handle) return;
196
+ await ctx.runMutation(handle, payload);
197
+ }
198
+ function oneOrNull(rows, operation) {
199
+ if (rows.length === 0) return null;
200
+ if (rows.length > 1) throw new Error(`${operation}_MATCHED_MULTIPLE_ROWS`);
201
+ return rows[0] ?? null;
202
+ }
203
+ export function defineAuthAdapterFunctions({
204
+ schema,
205
+ metadata
206
+ }) {
207
+ assertAuthSchemaMatchesMetadata(schema, metadata);
208
+ const relationships = createAuthRelationshipEngine({ schema, metadata, runTrigger });
209
+ return {
210
+ create: mutationGeneric({
211
+ args: {
212
+ model: v.string(),
213
+ data: v.any(),
214
+ onCreateHandle: v.optional(v.string())
215
+ },
216
+ handler: async (ctx, args) => {
217
+ const row = normalizeCreate(metadata, args.model, args.data);
218
+ await relationships.assertTargets(ctx, args.model, row);
219
+ await assertUniqueConstraints(ctx, schema, metadata, args.model, row);
220
+ const storageId = await ctx.db.insert(args.model, row);
221
+ const created = await ctx.db.get(args.model, storageId);
222
+ if (!created) throw new Error("AUTH_CREATE_READBACK_FAILED");
223
+ await runTrigger(ctx, args.onCreateHandle, {
224
+ model: args.model,
225
+ doc: toBetterAuthDocument(created)
226
+ });
227
+ const finalRow = await ctx.db.get(args.model, storageId);
228
+ if (!finalRow) throw new Error("AUTH_CREATE_TRIGGER_DELETED_ROW");
229
+ return toBetterAuthDocument(finalRow);
230
+ }
231
+ }),
232
+ findOne: queryGeneric({
233
+ args: { ...readArgs, join: v.optional(v.any()) },
234
+ handler: async (ctx, args) => {
235
+ const rows = await findAuthRows(ctx, schema, metadata, readShape(args), 2);
236
+ return toBetterAuthDocument(oneOrNull(rows, "AUTH_FIND_ONE"), args.select);
237
+ }
238
+ }),
239
+ findMany: queryGeneric({
240
+ args: {
241
+ ...readArgs,
242
+ join: v.optional(v.any()),
243
+ limit: v.optional(v.number()),
244
+ paginationOpts: paginationOptsValidator
245
+ },
246
+ handler: async (ctx, args) => {
247
+ const result = await paginateAuthRows(
248
+ ctx,
249
+ schema,
250
+ metadata,
251
+ readShape(args),
252
+ args.paginationOpts
253
+ );
254
+ return args.limit === void 0 ? result : { ...result, page: result.page.slice(0, args.limit) };
255
+ }
256
+ }),
257
+ count: queryGeneric({
258
+ args: { model: v.string(), where: v.optional(v.array(whereValidator)) },
259
+ handler: (ctx, args) => countAuthRows(ctx, schema, metadata, readShape(args))
260
+ }),
261
+ updateOne: mutationGeneric({
262
+ args: {
263
+ model: v.string(),
264
+ where: v.array(whereValidator),
265
+ update: v.any(),
266
+ onUpdateHandle: v.optional(v.string())
267
+ },
268
+ handler: async (ctx, args) => {
269
+ if (args.where.length === 0) return null;
270
+ const patch = normalizeUpdate(metadata, args.model, args.update, {
271
+ allowUnique: true
272
+ });
273
+ const current = oneOrNull(
274
+ await findAuthRows(ctx, schema, metadata, readShape(args), 2),
275
+ "AUTH_UPDATE_ONE"
276
+ );
277
+ if (!current) return null;
278
+ await relationships.assertTargets(
279
+ ctx,
280
+ args.model,
281
+ { ...current, ...patch },
282
+ new Set(Object.keys(patch))
283
+ );
284
+ await assertUniqueConstraints(ctx, schema, metadata, args.model, patch, current);
285
+ await ctx.db.patch(args.model, current._id, patch);
286
+ const updated = await ctx.db.get(args.model, current._id);
287
+ if (!updated) throw new Error("AUTH_UPDATE_READBACK_FAILED");
288
+ await runTrigger(ctx, args.onUpdateHandle, {
289
+ model: args.model,
290
+ oldDoc: toBetterAuthDocument(current),
291
+ newDoc: toBetterAuthDocument(updated)
292
+ });
293
+ const finalRow = await ctx.db.get(args.model, current._id);
294
+ if (!finalRow) throw new Error("AUTH_UPDATE_TRIGGER_DELETED_ROW");
295
+ return toBetterAuthDocument(finalRow);
296
+ }
297
+ }),
298
+ updateMany: mutationGeneric({
299
+ args: {
300
+ model: v.string(),
301
+ where: v.array(whereValidator),
302
+ update: v.any(),
303
+ onUpdateHandle: v.optional(v.string())
304
+ },
305
+ handler: async (ctx, args) => {
306
+ const patch = normalizeUpdate(metadata, args.model, args.update, {
307
+ allowUnique: false
308
+ });
309
+ const rows = await relationships.collectOperationRows(ctx, readShape(args));
310
+ assertBulkUniqueConstraints(metadata, args.model, patch, rows);
311
+ for (const current of rows) {
312
+ await relationships.assertTargets(
313
+ ctx,
314
+ args.model,
315
+ { ...current, ...patch },
316
+ new Set(Object.keys(patch))
317
+ );
318
+ await assertUniqueConstraints(ctx, schema, metadata, args.model, patch, current);
319
+ }
320
+ for (const current of rows) {
321
+ await ctx.db.patch(args.model, current._id, patch);
322
+ if (!args.onUpdateHandle) continue;
323
+ const updated = await ctx.db.get(args.model, current._id);
324
+ if (!updated) throw new Error("AUTH_BULK_UPDATE_READBACK_FAILED");
325
+ await runTrigger(ctx, args.onUpdateHandle, {
326
+ model: args.model,
327
+ oldDoc: toBetterAuthDocument(current),
328
+ newDoc: toBetterAuthDocument(updated)
329
+ });
330
+ }
331
+ return rows.length;
332
+ }
333
+ }),
334
+ deleteOne: mutationGeneric({
335
+ args: {
336
+ model: v.string(),
337
+ where: v.array(whereValidator),
338
+ onDeleteHandle: v.optional(v.string()),
339
+ onDeleteModels: v.optional(v.array(v.string())),
340
+ onUpdateHandle: v.optional(v.string()),
341
+ onUpdateModels: v.optional(v.array(v.string()))
342
+ },
343
+ handler: async (ctx, args) => {
344
+ const current = oneOrNull(
345
+ await findAuthRows(ctx, schema, metadata, readShape(args), 2),
346
+ "AUTH_DELETE_ONE"
347
+ );
348
+ if (!current) return null;
349
+ await relationships.applyDeletion(ctx, [current], args.model, args);
350
+ return toBetterAuthDocument(current);
351
+ }
352
+ }),
353
+ deleteMany: mutationGeneric({
354
+ args: {
355
+ model: v.string(),
356
+ where: v.array(whereValidator),
357
+ onDeleteHandle: v.optional(v.string()),
358
+ onDeleteModels: v.optional(v.array(v.string())),
359
+ onUpdateHandle: v.optional(v.string()),
360
+ onUpdateModels: v.optional(v.array(v.string()))
361
+ },
362
+ handler: async (ctx, args) => {
363
+ const rows = await relationships.collectOperationRows(ctx, readShape(args));
364
+ await relationships.applyDeletion(ctx, rows, args.model, args);
365
+ return rows.length;
366
+ }
367
+ }),
368
+ consumeOne: mutationGeneric({
369
+ args: {
370
+ model: v.string(),
371
+ where: v.array(whereValidator),
372
+ onDeleteHandle: v.optional(v.string()),
373
+ onDeleteModels: v.optional(v.array(v.string())),
374
+ onUpdateHandle: v.optional(v.string()),
375
+ onUpdateModels: v.optional(v.array(v.string()))
376
+ },
377
+ handler: async (ctx, args) => {
378
+ if (args.where.length === 0) throw new Error("AUTH_CONSUME_REQUIRES_GUARD");
379
+ const current = oneOrNull(
380
+ await findAuthRows(ctx, schema, metadata, readShape(args), 2),
381
+ "AUTH_CONSUME_ONE"
382
+ );
383
+ if (!current) return null;
384
+ await relationships.applyDeletion(ctx, [current], args.model, args);
385
+ return toBetterAuthDocument(current);
386
+ }
387
+ }),
388
+ incrementOne: mutationGeneric({
389
+ args: {
390
+ model: v.string(),
391
+ where: v.array(whereValidator),
392
+ increment: v.any(),
393
+ set: v.optional(v.any()),
394
+ onUpdateHandle: v.optional(v.string())
395
+ },
396
+ handler: async (ctx, args) => {
397
+ assertRecord(args.increment, "AUTH_INCREMENT_INVALID");
398
+ assertRecord(args.set ?? {}, "AUTH_INCREMENT_SET_INVALID");
399
+ const incrementEntries = Object.entries(args.increment);
400
+ const set = normalizeUpdate(metadata, args.model, args.set ?? {}, {
401
+ allowEmpty: true,
402
+ allowUnique: false
403
+ });
404
+ if (incrementEntries.length === 0 && Object.keys(set).length === 0) {
405
+ throw new Error("AUTH_INCREMENT_EMPTY");
406
+ }
407
+ for (const [fieldName, delta] of incrementEntries) {
408
+ if (fieldName in set) throw new Error(`AUTH_INCREMENT_SET_OVERLAP:${fieldName}`);
409
+ const field = getAuthFieldMetadata(metadata, args.model, fieldName);
410
+ if (field.kind !== "number" || field.unique || !field.updatable) {
411
+ throw new Error(`AUTH_INCREMENT_FIELD_INVALID:${args.model}.${fieldName}`);
412
+ }
413
+ if (typeof delta !== "number" || !Number.isFinite(delta)) {
414
+ throw new TypeError(`AUTH_INCREMENT_DELTA_INVALID:${fieldName}`);
415
+ }
416
+ }
417
+ const current = oneOrNull(
418
+ await findAuthRows(ctx, schema, metadata, readShape(args), 2),
419
+ "AUTH_INCREMENT_ONE"
420
+ );
421
+ if (!current) return null;
422
+ const patch = { ...set };
423
+ for (const [fieldName, delta] of incrementEntries) {
424
+ const value = current[fieldName];
425
+ if (typeof value !== "number" || !Number.isFinite(value)) {
426
+ throw new TypeError(`AUTH_INCREMENT_CURRENT_INVALID:${fieldName}`);
427
+ }
428
+ const next = value + delta;
429
+ if (!Number.isFinite(next)) throw new Error(`AUTH_INCREMENT_OVERFLOW:${fieldName}`);
430
+ patch[fieldName] = next;
431
+ }
432
+ await assertUniqueConstraints(ctx, schema, metadata, args.model, patch, current);
433
+ await relationships.assertTargets(
434
+ ctx,
435
+ args.model,
436
+ { ...current, ...patch },
437
+ new Set(Object.keys(patch))
438
+ );
439
+ await ctx.db.patch(args.model, current._id, patch);
440
+ const updated = await ctx.db.get(args.model, current._id);
441
+ if (!updated) throw new Error("AUTH_INCREMENT_READBACK_FAILED");
442
+ await runTrigger(ctx, args.onUpdateHandle, {
443
+ model: args.model,
444
+ oldDoc: toBetterAuthDocument(current),
445
+ newDoc: toBetterAuthDocument(updated)
446
+ });
447
+ return toBetterAuthDocument(updated);
448
+ }
449
+ }),
450
+ rotateSigningKey: mutationGeneric({
451
+ args: { next: signingKeyCandidateValidator },
452
+ handler: async (ctx, args) => {
453
+ const next = normalizeSigningKeyCandidate(args.next);
454
+ const rotationNow = Date.now();
455
+ const rows = await collectAuthRows(ctx, schema, metadata, { model: "jwks" }, 1e4);
456
+ if (rows.some((row) => row.id === next.id)) {
457
+ throw new Error("AUTH_UNIQUE_CONFLICT:jwks.id");
458
+ }
459
+ const keysCurrentAtCommit = rows.filter((row) => {
460
+ const expiresAt = row.expiresAt;
461
+ return expiresAt === null || typeof expiresAt === "number" && expiresAt > rotationNow;
462
+ }).sort((left, right) => {
463
+ const byCreatedAt = Number(left.createdAt) - Number(right.createdAt);
464
+ return byCreatedAt || String(left.id).localeCompare(String(right.id));
465
+ });
466
+ const latestCreatedAt = rows.reduce((latest, row) => {
467
+ if (typeof row.createdAt !== "number" || !Number.isSafeInteger(row.createdAt)) {
468
+ throw new TypeError("AUTH_JWKS_CREATED_AT_INVALID");
469
+ }
470
+ return Math.max(latest, row.createdAt);
471
+ }, rotationNow - 1);
472
+ if (latestCreatedAt >= Number.MAX_SAFE_INTEGER) {
473
+ throw new Error("AUTH_JWKS_CREATED_AT_INVALID");
474
+ }
475
+ const createdAt = Math.max(rotationNow, latestCreatedAt + 1);
476
+ await ctx.db.insert(
477
+ "jwks",
478
+ {
479
+ ...next,
480
+ createdAt,
481
+ expiresAt: null
482
+ }
483
+ );
484
+ for (const previous of keysCurrentAtCommit) {
485
+ await ctx.db.patch(previous._id, { expiresAt: rotationNow });
486
+ }
487
+ return {
488
+ createdAt,
489
+ newKid: next.id,
490
+ previousKids: keysCurrentAtCommit.map((key) => String(key.id)),
491
+ previousVerifyUntil: rotationNow + JWKS_GRACE_PERIOD_SECONDS * 1e3,
492
+ rotatedAt: rotationNow
493
+ };
494
+ }
495
+ })
496
+ };
497
+ }
@@ -0,0 +1,16 @@
1
+ import type { BetterAuthDBSchema } from 'better-auth/db';
2
+ import { type AuthSchemaMetadata } from './metadata.js';
3
+ export interface GeneratedAuthSchemaArtifacts {
4
+ metadata: AuthSchemaMetadata;
5
+ metadataCode: string;
6
+ schemaCode: string;
7
+ }
8
+ export declare function generateAuthSchemaArtifacts(tables: BetterAuthDBSchema): GeneratedAuthSchemaArtifacts;
9
+ export declare function createAuthSchema({ file, tables, }: {
10
+ file?: string;
11
+ tables: BetterAuthDBSchema;
12
+ }): Promise<{
13
+ code: string;
14
+ path: string;
15
+ overwrite: boolean;
16
+ }>;