@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,7 @@
1
+ import {
2
+ getConvexRuntimeConfig,
3
+ toPublicConvexRuntimeConfig
4
+ } from "../utils/runtime-config.js";
5
+ export function useConvexConfig() {
6
+ return toPublicConvexRuntimeConfig(getConvexRuntimeConfig());
7
+ }
@@ -0,0 +1,33 @@
1
+ export type { ConnectionState } from 'convex/browser';
2
+ /** Deterministic SSR projection around the shared Vue connection store. */
3
+ export declare function useConvexConnectionState(): Readonly<{
4
+ state: import("vue").ComputedRef<import("convex/browser").ConnectionState>;
5
+ isConnected: import("vue").ComputedRef<boolean>;
6
+ isReconnecting: import("vue").ComputedRef<boolean>;
7
+ pendingMutations: import("vue").ComputedRef<number>;
8
+ pendingActions: import("vue").ComputedRef<number>;
9
+ }> | Readonly<{
10
+ state: Readonly<import("vue").Ref<{
11
+ readonly hasInflightRequests: boolean;
12
+ readonly isWebSocketConnected: boolean;
13
+ readonly timeOfOldestInflightRequest: null;
14
+ readonly hasEverConnected: boolean;
15
+ readonly connectionCount: number;
16
+ readonly connectionRetries: number;
17
+ readonly inflightMutations: number;
18
+ readonly inflightActions: number;
19
+ }, {
20
+ readonly hasInflightRequests: boolean;
21
+ readonly isWebSocketConnected: boolean;
22
+ readonly timeOfOldestInflightRequest: null;
23
+ readonly hasEverConnected: boolean;
24
+ readonly connectionCount: number;
25
+ readonly connectionRetries: number;
26
+ readonly inflightMutations: number;
27
+ readonly inflightActions: number;
28
+ }>>;
29
+ isConnected: import("vue").ComputedRef<boolean>;
30
+ isReconnecting: import("vue").ComputedRef<boolean>;
31
+ pendingMutations: import("vue").ComputedRef<number>;
32
+ pendingActions: import("vue").ComputedRef<number>;
33
+ }>;
@@ -0,0 +1,24 @@
1
+ import { useConvexConnectionState as useVueConvexConnectionState } from "@lupinum/better-convex-vue";
2
+ import { computed, readonly, ref } from "vue";
3
+ export function useConvexConnectionState() {
4
+ if (import.meta.client) return useVueConvexConnectionState();
5
+ const state = readonly(
6
+ ref({
7
+ hasInflightRequests: false,
8
+ isWebSocketConnected: false,
9
+ timeOfOldestInflightRequest: null,
10
+ hasEverConnected: false,
11
+ connectionCount: 0,
12
+ connectionRetries: 0,
13
+ inflightMutations: 0,
14
+ inflightActions: 0
15
+ })
16
+ );
17
+ return Object.freeze({
18
+ state,
19
+ isConnected: computed(() => false),
20
+ isReconnecting: computed(() => false),
21
+ pendingMutations: computed(() => 0),
22
+ pendingActions: computed(() => 0)
23
+ });
24
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * File upload composable for Convex storage.
3
+ *
4
+ * Inspired by nuxt-convex by @onmax (https://github.com/onmax/nuxt-convex)
5
+ */
6
+ import type { FunctionReference, OptionalRestArgs } from 'convex/server';
7
+ import type { GenericId } from 'convex/values';
8
+ import { type ComputedRef } from 'vue';
9
+ import { ConvexCallError } from '../errors/index.js';
10
+ import { type UploadProgressInfo } from '../utils/upload-core.js';
11
+ export type { UploadProgressInfo } from '../utils/upload-core.js';
12
+ /** A public Convex mutation that generates a browser upload URL. */
13
+ export type UploadUrlMutation = FunctionReference<'mutation', 'public', Record<string, unknown>, string>;
14
+ /**
15
+ * Upload status representing the current state of the upload
16
+ * - 'idle': not yet called or reset
17
+ * - 'pending': upload in progress
18
+ * - 'success': upload completed successfully
19
+ * - 'error': upload failed
20
+ */
21
+ export type UploadStatus = 'idle' | 'pending' | 'success' | 'error';
22
+ /**
23
+ * Return value from useConvexFileUpload
24
+ */
25
+ export interface UseConvexFileUploadReturn<Mutation extends UploadUrlMutation> {
26
+ /**
27
+ * Upload a file. Returns the storageId on success.
28
+ * Automatically tracks status, error, progress, and data.
29
+ * Throws on error (use try/catch or check error ref after).
30
+ *
31
+ * @param file - The file to upload
32
+ * @param args - Validator-derived args for the generateUploadUrl mutation
33
+ */
34
+ upload: (file: File, ...args: OptionalRestArgs<Mutation>) => Promise<GenericId<'_storage'>>;
35
+ /**
36
+ * StorageId from the last successful upload.
37
+ * undefined if upload hasn't succeeded yet.
38
+ */
39
+ readonly data: ComputedRef<GenericId<'_storage'> | undefined>;
40
+ /**
41
+ * Upload status for explicit state management.
42
+ */
43
+ readonly status: ComputedRef<UploadStatus>;
44
+ /**
45
+ * True when upload is in progress.
46
+ * Equivalent to status === 'pending'.
47
+ */
48
+ readonly pending: ComputedRef<boolean>;
49
+ /**
50
+ * Byte-level progress for the current upload.
51
+ */
52
+ readonly progress: ComputedRef<UploadProgressInfo>;
53
+ /**
54
+ * Error from the last upload attempt as the normalized {@link ConvexCallError}.
55
+ * undefined if no error or upload hasn't been called.
56
+ */
57
+ readonly error: ComputedRef<ConvexCallError | undefined>;
58
+ /**
59
+ * Cancel any in-progress upload and reset state.
60
+ * Aborts XHR, clears error, data, and progress.
61
+ */
62
+ readonly cancel: () => void;
63
+ }
64
+ /**
65
+ * Options for useConvexFileUpload
66
+ */
67
+ export interface UseConvexFileUploadOptions {
68
+ /**
69
+ * Maximum file size in bytes.
70
+ * Files exceeding this size will be rejected before upload starts.
71
+ * @example 5 * 1024 * 1024 // 5MB
72
+ */
73
+ readonly maxSize?: number;
74
+ /**
75
+ * Allowed MIME types.
76
+ * Files not matching these types will be rejected before upload starts.
77
+ *
78
+ * Supports wildcards: `image/*` matches any image type, `video/*` matches any video, etc.
79
+ *
80
+ * @example ['image/jpeg', 'image/png'] // Exact types only
81
+ * @example ['image/*'] // Any image type
82
+ * @example ['image/*', 'application/pdf'] // Any image or PDF
83
+ */
84
+ readonly allowedTypes?: readonly string[];
85
+ }
86
+ /**
87
+ * Composable for uploading files to Convex file storage with progress tracking.
88
+ *
89
+ * Handles the complete upload flow:
90
+ * 1. Generating an upload URL via mutation
91
+ * 2. POSTing the file to that URL (with progress tracking via XHR)
92
+ * 3. Returning the resulting storageId
93
+ *
94
+ * API designed to match useConvexMutation for consistency:
95
+ * - `data` - storageId from last successful upload
96
+ * - `status` - 'idle' | 'pending' | 'success' | 'error'
97
+ * - `pending` - boolean shorthand for status === 'pending'
98
+ * - `progress` - byte-level upload progress
99
+ * - `error` - Error | undefined
100
+ *
101
+ * Note: File uploads only work on the client side.
102
+ *
103
+ * @example Basic usage with progress tracking
104
+ * ```vue
105
+ * <script setup>
106
+ * import { api } from '#convex/api'
107
+ *
108
+ * const {
109
+ * upload,
110
+ * pending,
111
+ * progress,
112
+ * error,
113
+ * data: storageId,
114
+ * } = useConvexFileUpload(api.files.generateUploadUrl)
115
+ *
116
+ * async function handleFile(event: Event) {
117
+ * const input = event.target as HTMLInputElement
118
+ * if (!input.files?.[0]) return
119
+ *
120
+ * try {
121
+ * const id = await upload(input.files[0])
122
+ * console.log('Uploaded:', id)
123
+ * } catch {
124
+ * // error is automatically tracked
125
+ * }
126
+ * }
127
+ * </script>
128
+ *
129
+ * <template>
130
+ * <input type="file" @change="handleFile" :disabled="pending" />
131
+ * <div v-if="pending">Uploading: {{ progress.percent }}%</div>
132
+ * <p v-if="error" class="error">{{ error.message }}</p>
133
+ * </template>
134
+ * ```
135
+ *
136
+ * @example With cancel support
137
+ * ```vue
138
+ * <script setup>
139
+ * import { api } from '#convex/api'
140
+ *
141
+ * const { upload, pending, progress, cancel } = useConvexFileUpload(
142
+ * api.files.generateUploadUrl
143
+ * )
144
+ * </script>
145
+ *
146
+ * <template>
147
+ * <div v-if="pending">
148
+ * Uploading: {{ progress.percent }}%
149
+ * <button @click="cancel">Cancel</button>
150
+ * </div>
151
+ * </template>
152
+ * ```
153
+ *
154
+ * @example Saving storageId to a document
155
+ * ```vue
156
+ * <script setup>
157
+ * import { api } from '#convex/api'
158
+ *
159
+ * const { upload, pending, progress } = useConvexFileUpload(api.files.generateUploadUrl)
160
+ * const saveDocument = useConvexMutation(api.documents.create)
161
+ *
162
+ * async function handleUpload(file: File, title: string) {
163
+ * const storageId = await upload(file)
164
+ * await saveDocument({ title, fileId: storageId })
165
+ * }
166
+ * </script>
167
+ * ```
168
+ */
169
+ export declare function useConvexFileUpload<Mutation extends UploadUrlMutation>(generateUploadUrlMutation: Mutation, options?: UseConvexFileUploadOptions): UseConvexFileUploadReturn<Mutation>;
@@ -0,0 +1,198 @@
1
+ import { computed, getCurrentScope, onScopeDispose, shallowRef } from "vue";
2
+ import { useNuxtApp } from "#imports";
3
+ import { ConvexCallError, normalizeConvexError } from "../errors/index.js";
4
+ import { readConvexRuntimeContext } from "../runtime-context.js";
5
+ import { assertConvexComposableScope } from "../utils/composable-scope.js";
6
+ import { getFunctionName } from "../utils/convex-shared.js";
7
+ import { createIdentityChangedError, isIdentityChangedError } from "../utils/identity-changed-error.js";
8
+ import { createLogger } from "../utils/logger.js";
9
+ import { isFileTypeAllowed } from "../utils/mime-type.js";
10
+ import { getConvexRuntimeConfig } from "../utils/runtime-config.js";
11
+ import {
12
+ executeFileUpload,
13
+ isUploadAbortError
14
+ } from "../utils/upload-core.js";
15
+ const INITIAL_UPLOAD_VIEW_STATE = {
16
+ status: "idle",
17
+ error: void 0,
18
+ data: void 0,
19
+ progress: Object.freeze({ loaded: 0, total: 0, percent: 0 })
20
+ };
21
+ export function useConvexFileUpload(generateUploadUrlMutation, options) {
22
+ const fnName = getFunctionName(generateUploadUrlMutation);
23
+ const currentScope = getCurrentScope();
24
+ assertConvexComposableScope("useConvexFileUpload", import.meta.client, currentScope);
25
+ const nuxtApp = useNuxtApp();
26
+ const runtime = readConvexRuntimeContext(nuxtApp);
27
+ const attachment = runtime?.attachment;
28
+ const identityObserver = attachment?.identity;
29
+ const logger = runtime?.logger ?? createLogger(getConvexRuntimeConfig().logging);
30
+ const getIdentityGeneration = () => identityObserver?.snapshot().identityGeneration ?? 0;
31
+ const viewState = shallowRef(INITIAL_UPLOAD_VIEW_STATE);
32
+ let currentAttempt = null;
33
+ let observedIdentityGeneration = getIdentityGeneration();
34
+ const status = computed(() => viewState.value.status);
35
+ const pending = computed(() => viewState.value.status === "pending");
36
+ const error = computed(() => viewState.value.error);
37
+ const data = computed(() => viewState.value.data);
38
+ const progress = computed(() => viewState.value.progress);
39
+ const clearUploadState = (error2 = new DOMException("Upload cancelled", "AbortError")) => {
40
+ const attempt = currentAttempt;
41
+ viewState.value = INITIAL_UPLOAD_VIEW_STATE;
42
+ if (currentAttempt === attempt) currentAttempt = null;
43
+ attempt?.abort(error2);
44
+ };
45
+ const cancel = clearUploadState;
46
+ if (currentScope) {
47
+ const stopIdentitySubscription = identityObserver?.subscribe(() => {
48
+ const generation = getIdentityGeneration();
49
+ if (generation === observedIdentityGeneration) return;
50
+ observedIdentityGeneration = generation;
51
+ clearUploadState(createIdentityChangedError("upload"));
52
+ });
53
+ onScopeDispose(() => {
54
+ stopIdentitySubscription?.();
55
+ clearUploadState();
56
+ });
57
+ }
58
+ const upload = async (file, ...mutationArgs) => {
59
+ const startTime = Date.now();
60
+ const identityGeneration = getIdentityGeneration();
61
+ const identityChanged = () => getIdentityGeneration() !== identityGeneration;
62
+ if (viewState.value.status === "pending") {
63
+ const err = new ConvexCallError({
64
+ kind: "unknown",
65
+ message: "Upload already in progress for this composable instance"
66
+ });
67
+ logger.upload({
68
+ name: fnName,
69
+ event: "error",
70
+ filename: file.name,
71
+ size: file.size,
72
+ error: err
73
+ });
74
+ throw err;
75
+ }
76
+ const requireCurrentIdentity = () => {
77
+ if (identityChanged()) throw createIdentityChangedError("upload");
78
+ };
79
+ const publishTerminalState = (next) => {
80
+ requireCurrentIdentity();
81
+ viewState.value = next;
82
+ requireCurrentIdentity();
83
+ };
84
+ const publishConvexError = (err) => {
85
+ publishTerminalState({
86
+ ...viewState.value,
87
+ status: "error",
88
+ error: err
89
+ });
90
+ logger.upload({
91
+ name: fnName,
92
+ event: "error",
93
+ filename: file.name,
94
+ size: file.size,
95
+ duration: Date.now() - startTime,
96
+ error: err
97
+ });
98
+ requireCurrentIdentity();
99
+ return err;
100
+ };
101
+ const publishError = (rawError) => publishConvexError(normalizeConvexError(rawError));
102
+ let validationError;
103
+ if (options?.maxSize && file.size > options.maxSize) {
104
+ validationError = new ConvexCallError({
105
+ kind: "unknown",
106
+ message: `File size ${file.size} bytes exceeds maximum ${options.maxSize} bytes`
107
+ });
108
+ } else if (options?.allowedTypes && !isFileTypeAllowed(file.type, options.allowedTypes)) {
109
+ validationError = new ConvexCallError({
110
+ kind: "unknown",
111
+ message: `File type "${file.type}" not allowed. Allowed: ${options.allowedTypes.join(", ")}`
112
+ });
113
+ }
114
+ if (validationError) throw publishConvexError(validationError);
115
+ if (import.meta.server || !attachment || typeof attachment.client.mutation !== "function") {
116
+ throw publishConvexError(
117
+ new ConvexCallError({
118
+ kind: "unknown",
119
+ message: "[useConvexFileUpload] Convex client is unavailable. Upload files from the browser after configuring a Convex URL."
120
+ })
121
+ );
122
+ }
123
+ const attempt = new AbortController();
124
+ currentAttempt = attempt;
125
+ const isCurrentUpload = () => currentAttempt === attempt && !identityChanged() && !attempt.signal.aborted;
126
+ const requireCurrentUpload = () => {
127
+ requireCurrentIdentity();
128
+ if (!isCurrentUpload()) throw new DOMException("Upload cancelled", "AbortError");
129
+ };
130
+ try {
131
+ requireCurrentUpload();
132
+ viewState.value = {
133
+ ...viewState.value,
134
+ status: "pending",
135
+ error: void 0,
136
+ progress: { loaded: 0, total: file.size, percent: 0 }
137
+ };
138
+ requireCurrentUpload();
139
+ const storageId = await executeFileUpload(
140
+ attachment.client,
141
+ generateUploadUrlMutation,
142
+ mutationArgs[0] ?? {},
143
+ file,
144
+ {
145
+ signal: attempt.signal,
146
+ onProgress: (info) => {
147
+ if (!isCurrentUpload()) return;
148
+ viewState.value = {
149
+ ...viewState.value,
150
+ progress: info
151
+ };
152
+ }
153
+ }
154
+ );
155
+ requireCurrentUpload();
156
+ publishTerminalState({
157
+ ...viewState.value,
158
+ status: "success",
159
+ data: storageId
160
+ });
161
+ const duration = Date.now() - startTime;
162
+ logger.upload({
163
+ name: fnName,
164
+ event: "success",
165
+ filename: file.name,
166
+ size: file.size,
167
+ duration
168
+ });
169
+ requireCurrentIdentity();
170
+ return storageId;
171
+ } catch (e) {
172
+ if (identityChanged() || isIdentityChangedError(e)) {
173
+ if (currentAttempt === attempt) {
174
+ clearUploadState(createIdentityChangedError("upload"));
175
+ }
176
+ throw isIdentityChangedError(e) ? e : createIdentityChangedError("upload");
177
+ }
178
+ if (currentAttempt !== attempt) {
179
+ throw isUploadAbortError(e) ? e : new DOMException("Upload cancelled", "AbortError");
180
+ }
181
+ if (isUploadAbortError(e)) {
182
+ throw e;
183
+ }
184
+ throw publishError(e);
185
+ } finally {
186
+ if (currentAttempt === attempt) currentAttempt = null;
187
+ }
188
+ };
189
+ return {
190
+ upload,
191
+ data,
192
+ status,
193
+ pending,
194
+ progress,
195
+ error,
196
+ cancel
197
+ };
198
+ }
@@ -0,0 +1,13 @@
1
+ import { type UseConvexCall, type UseConvexMutationOptions as VueMutationOptions } from '@lupinum/better-convex-vue';
2
+ import type { OptimisticLocalStore } from 'convex/browser';
3
+ import type { FunctionArgs, FunctionReference } from 'convex/server';
4
+ export type UseConvexMutationOptions<Args extends Record<string, unknown>> = VueMutationOptions<Args>;
5
+ type OptimisticUpdateCandidate<Args> = (store: OptimisticLocalStore, args: Args) => unknown;
6
+ type ReturnHasThen<Result> = Result extends unknown ? 'then' extends keyof Result ? true : false : never;
7
+ type SynchronousOptimisticUpdate<Update extends (...args: never[]) => unknown> = true extends ReturnHasThen<ReturnType<Update>> ? 'Optimistic update handlers must be synchronous' : unknown;
8
+ /** Nuxt auto-import facade over the one shared Vue callable lifecycle. */
9
+ export declare function useConvexMutation<Mutation extends FunctionReference<'mutation'>>(mutation: Mutation, options?: UseConvexMutationOptions<FunctionArgs<Mutation>>): UseConvexCall<Mutation>;
10
+ export declare function useConvexMutation<Mutation extends FunctionReference<'mutation'>, Update extends OptimisticUpdateCandidate<FunctionArgs<Mutation>>>(mutation: Mutation, options: Readonly<{
11
+ optimisticUpdate: Update;
12
+ }> & SynchronousOptimisticUpdate<Update>): UseConvexCall<Mutation>;
13
+ export {};
@@ -0,0 +1,24 @@
1
+ import {
2
+ useConvexMutation as useVueConvexMutation
3
+ } from "@lupinum/better-convex-vue";
4
+ import { getFunctionName } from "convex/server";
5
+ import { useNuxtApp } from "#imports";
6
+ import { readConvexRuntimeContext } from "../runtime-context.js";
7
+ import { createCallableDevtoolsEvents } from "../utils/callable-devtools.js";
8
+ import { CALLABLE_OBSERVER_KEY } from "../utils/callable-observer.js";
9
+ export function useConvexMutation(mutation, options) {
10
+ const runtime = readConvexRuntimeContext(useNuxtApp());
11
+ const events = createCallableDevtoolsEvents(
12
+ {
13
+ operation: "mutation",
14
+ fnName: getFunctionName(mutation),
15
+ hasOptimisticUpdate: Boolean(options?.optimisticUpdate),
16
+ getSink: () => runtime?.getDevtoolsSink() ?? null
17
+ }
18
+ );
19
+ const internalOptions = {
20
+ ...options,
21
+ [CALLABLE_OBSERVER_KEY]: events
22
+ };
23
+ return useVueConvexMutation(mutation, internalOptions);
24
+ }
@@ -0,0 +1,13 @@
1
+ import { type PaginatedQueryArgs, type PaginatedQueryItem, type PaginatedQueryReference, type UseConvexPaginatedQueryOptions, type UseConvexPaginatedQueryState } from '@lupinum/better-convex-vue';
2
+ import { type MaybeRefOrGetter } from 'vue';
3
+ export type { PaginatedQueryArgs, PaginatedQueryItem, PaginatedQueryReference, UseConvexPaginatedQueryState, };
4
+ export interface UseNuxtConvexPaginatedQueryOptions extends UseConvexPaginatedQueryOptions {
5
+ readonly server?: boolean;
6
+ }
7
+ export type NuxtConvexPaginatedQuery<Item> = UseConvexPaginatedQueryState<Item> & Promise<UseConvexPaginatedQueryState<Item>>;
8
+ interface BuildConvexPaginatedQueryResult<Item> {
9
+ resultData: UseConvexPaginatedQueryState<Item>;
10
+ resolvePromise: Promise<void>;
11
+ }
12
+ export declare function createConvexPaginatedQueryState<Query extends PaginatedQueryReference>(query: Query, args: MaybeRefOrGetter<PaginatedQueryArgs<Query> | 'skip'>, options: UseNuxtConvexPaginatedQueryOptions, resolveImmediately?: boolean): BuildConvexPaginatedQueryResult<PaginatedQueryItem<Query>>;
13
+ export declare function useConvexPaginatedQuery<Query extends PaginatedQueryReference>(query: Query, args: MaybeRefOrGetter<PaginatedQueryArgs<Query> | 'skip'>, options: UseNuxtConvexPaginatedQueryOptions): NuxtConvexPaginatedQuery<PaginatedQueryItem<Query>>;