@transloadit/convex 0.0.5 → 0.1.0

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 (43) hide show
  1. package/README.md +31 -212
  2. package/dist/client/index.d.ts +39 -92
  3. package/dist/client/index.d.ts.map +1 -1
  4. package/dist/client/index.js +34 -104
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/component/_generated/component.d.ts +18 -0
  7. package/dist/component/_generated/component.d.ts.map +1 -1
  8. package/dist/component/apiUtils.d.ts +1 -32
  9. package/dist/component/apiUtils.d.ts.map +1 -1
  10. package/dist/component/apiUtils.js.map +1 -1
  11. package/dist/component/lib.d.ts +33 -90
  12. package/dist/component/lib.d.ts.map +1 -1
  13. package/dist/component/lib.js +48 -157
  14. package/dist/component/lib.js.map +1 -1
  15. package/dist/component/schema.d.ts +4 -4
  16. package/dist/component/schema.d.ts.map +1 -1
  17. package/dist/component/schema.js +3 -31
  18. package/dist/component/schema.js.map +1 -1
  19. package/dist/shared/schemas.d.ts +419 -0
  20. package/dist/shared/schemas.d.ts.map +1 -0
  21. package/dist/shared/schemas.js +194 -0
  22. package/dist/shared/schemas.js.map +1 -0
  23. package/dist/test/index.d.ts +4 -4
  24. package/package.json +6 -16
  25. package/src/client/index.ts +68 -123
  26. package/src/component/_generated/component.ts +17 -0
  27. package/src/component/apiUtils.ts +7 -38
  28. package/src/component/lib.test.ts +19 -0
  29. package/src/component/lib.ts +80 -180
  30. package/src/component/schema.ts +3 -31
  31. package/src/shared/schemas.ts +279 -0
  32. package/dist/react/index.d.ts +0 -281
  33. package/dist/react/index.d.ts.map +0 -1
  34. package/dist/react/index.js +0 -784
  35. package/dist/react/index.js.map +0 -1
  36. package/dist/shared/tusUpload.d.ts +0 -13
  37. package/dist/shared/tusUpload.d.ts.map +0 -1
  38. package/dist/shared/tusUpload.js +0 -32
  39. package/dist/shared/tusUpload.js.map +0 -1
  40. package/src/react/index.test.tsx +0 -340
  41. package/src/react/index.tsx +0 -1245
  42. package/src/react/uploadWithTus.test.tsx +0 -192
  43. package/src/shared/tusUpload.ts +0 -59
@@ -40,11 +40,11 @@ export declare function createTransloaditTest(): import("convex-test").TestConve
40
40
  results: import("convex/server").TableDefinition<import("convex/values").VObject<{
41
41
  userId?: string | undefined;
42
42
  album?: string | undefined;
43
- mime?: string | undefined;
43
+ resultId?: string | undefined;
44
+ sslUrl?: string | undefined;
44
45
  name?: string | undefined;
45
46
  size?: number | undefined;
46
- sslUrl?: string | undefined;
47
- resultId?: string | undefined;
47
+ mime?: string | undefined;
48
48
  assemblyId: string;
49
49
  raw: any;
50
50
  stepName: string;
@@ -61,7 +61,7 @@ export declare function createTransloaditTest(): import("convex-test").TestConve
61
61
  mime: import("convex/values").VString<string | undefined, "optional">;
62
62
  raw: import("convex/values").VAny<any, "required", string>;
63
63
  createdAt: import("convex/values").VFloat64<number, "required">;
64
- }, "required", "assemblyId" | "raw" | "userId" | "stepName" | "album" | "mime" | "name" | "size" | "sslUrl" | "resultId" | "createdAt" | `raw.${string}`>, {
64
+ }, "required", "assemblyId" | "raw" | "userId" | "stepName" | "album" | "createdAt" | `raw.${string}` | "resultId" | "sslUrl" | "name" | "size" | "mime">, {
65
65
  by_assemblyId: ["assemblyId", "_creationTime"];
66
66
  by_assemblyId_and_step: ["assemblyId", "stepName", "_creationTime"];
67
67
  by_album: ["album", "_creationTime"];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@transloadit/convex",
3
3
  "description": "Transloadit component for Convex",
4
- "version": "0.0.5",
4
+ "version": "0.1.0",
5
5
  "type": "module",
6
6
  "packageManager": "yarn@4.5.0",
7
7
  "repository": {
@@ -35,6 +35,7 @@
35
35
  "verify:convex": "yarn verify:cloud",
36
36
  "deploy:cloud": "node scripts/deploy-cloud.ts",
37
37
  "demo:cleanup": "node scripts/cleanup-demo.ts",
38
+ "demo:media": "node scripts/generate-demo-media.ts",
38
39
  "example:dev": "yarn build && node ./node_modules/next/dist/bin/next dev example",
39
40
  "example:build": "yarn build && node ./node_modules/next/dist/bin/next build example",
40
41
  "example:start": "yarn build && node ./node_modules/next/dist/bin/next start example",
@@ -57,11 +58,6 @@
57
58
  "types": "./dist/client/index.d.ts",
58
59
  "default": "./dist/client/index.js"
59
60
  },
60
- "./react": {
61
- "@convex-dev/component-source": "./src/react/index.tsx",
62
- "types": "./dist/react/index.d.ts",
63
- "default": "./dist/react/index.js"
64
- },
65
61
  "./lib": {
66
62
  "@convex-dev/component-source": "./src/component/lib.ts",
67
63
  "types": "./dist/component/lib.d.ts",
@@ -82,18 +78,11 @@
82
78
  }
83
79
  },
84
80
  "peerDependencies": {
85
- "convex": "^1.24.8",
86
- "react": "^18.3.1 || ^19.0.0"
87
- },
88
- "peerDependenciesMeta": {
89
- "react": {
90
- "optional": true
91
- }
81
+ "convex": "^1.24.8"
92
82
  },
93
83
  "dependencies": {
94
84
  "@transloadit/utils": "^4.1.9",
95
- "@transloadit/zod": "^4.1.9",
96
- "tus-js-client": "^4.3.1"
85
+ "@transloadit/zod": "^4.1.9"
97
86
  },
98
87
  "devDependencies": {
99
88
  "@auth/core": "^0.37.0",
@@ -102,6 +91,7 @@
102
91
  "@changesets/cli": "^2.29.8",
103
92
  "@convex-dev/auth": "^0.0.90",
104
93
  "@edge-runtime/vm": "^5.0.0",
94
+ "@fal-ai/client": "^1.8.4",
105
95
  "@playwright/test": "^1.57.0",
106
96
  "@testing-library/dom": "^10.4.1",
107
97
  "@testing-library/react": "^16.3.0",
@@ -111,7 +101,7 @@
111
101
  "@uppy/core": "^5.2.0",
112
102
  "@uppy/dashboard": "^5.1.0",
113
103
  "@uppy/react": "^5.1.1",
114
- "@uppy/tus": "^5.1.0",
104
+ "@uppy/transloadit": "^5.4.0",
115
105
  "convex": "^1.31.4",
116
106
  "convex-test": "^0.0.41",
117
107
  "dotenv": "^17.2.3",
@@ -1,10 +1,33 @@
1
1
  import type { AssemblyStatus } from "@transloadit/zod/v3/assemblyStatus";
2
2
  import type { AssemblyInstructionsInput } from "@transloadit/zod/v3/template";
3
3
  import { actionGeneric, mutationGeneric, queryGeneric } from "convex/server";
4
- import { type Infer, v } from "convex/values";
4
+ import { v } from "convex/values";
5
5
  import type { ComponentApi } from "../component/_generated/component.ts";
6
+ import {
7
+ type AssemblyOptions,
8
+ type AssemblyResponse,
9
+ type AssemblyResultResponse,
10
+ type CreateAssemblyArgs,
11
+ vAssemblyIdArgs,
12
+ vAssemblyOptions,
13
+ vAssemblyResponse,
14
+ vAssemblyResultResponse,
15
+ vCreateAssemblyArgs,
16
+ vCreateAssemblyReturn,
17
+ vListAlbumResultsArgs,
18
+ vListAssembliesArgs,
19
+ vListResultsArgs,
20
+ vPurgeAlbumArgs,
21
+ vPurgeAlbumResponse,
22
+ vQueueWebhookResponse,
23
+ vStoreAssemblyMetadataArgs,
24
+ vWebhookActionArgs,
25
+ vWebhookResponse,
26
+ } from "../shared/schemas.ts";
6
27
  import type { RunActionCtx, RunMutationCtx, RunQueryCtx } from "./types.ts";
7
28
 
29
+ export { vAssemblyResponse, vAssemblyResultResponse, vCreateAssemblyArgs };
30
+
8
31
  export {
9
32
  assemblyStatusErrCodeSchema,
10
33
  assemblyStatusOkCodeSchema,
@@ -20,11 +43,6 @@ export {
20
43
  isAssemblyTerminalOk,
21
44
  isAssemblyTerminalOkStatus,
22
45
  } from "@transloadit/zod/v3/assemblyStatus";
23
- export type {
24
- ParsedWebhookRequest,
25
- VerifiedWebhookRequest,
26
- WebhookActionArgs,
27
- } from "../component/apiUtils.ts";
28
46
  export {
29
47
  buildWebhookQueueArgs,
30
48
  handleWebhookRequest,
@@ -62,10 +80,10 @@ export {
62
80
  getResultUrl,
63
81
  } from "../shared/resultUtils.ts";
64
82
  export type {
65
- TusMetadataOptions,
66
- TusUploadConfig,
67
- } from "../shared/tusUpload.ts";
68
- export { buildTusUploadConfig } from "../shared/tusUpload.ts";
83
+ ParsedWebhookRequest,
84
+ VerifiedWebhookRequest,
85
+ WebhookActionArgs,
86
+ } from "../shared/schemas.ts";
69
87
  export type { AssemblyStatus, AssemblyInstructionsInput };
70
88
 
71
89
  export interface TransloaditConfig {
@@ -85,56 +103,13 @@ function requireEnv(names: string[]): string {
85
103
  throw new Error(`Missing ${names.join(" or ")} environment variable`);
86
104
  }
87
105
 
88
- export const vAssemblyResponse = v.object({
89
- _id: v.string(),
90
- _creationTime: v.number(),
91
- assemblyId: v.string(),
92
- status: v.optional(v.string()),
93
- ok: v.optional(v.string()),
94
- message: v.optional(v.string()),
95
- templateId: v.optional(v.string()),
96
- notifyUrl: v.optional(v.string()),
97
- numExpectedUploadFiles: v.optional(v.number()),
98
- fields: v.optional(v.record(v.string(), v.any())),
99
- uploads: v.optional(v.array(v.any())),
100
- results: v.optional(v.record(v.string(), v.array(v.any()))),
101
- error: v.optional(v.any()),
102
- raw: v.optional(v.any()),
103
- createdAt: v.number(),
104
- updatedAt: v.number(),
105
- userId: v.optional(v.string()),
106
- });
107
-
108
- export type AssemblyResponse = Infer<typeof vAssemblyResponse>;
109
-
110
- export const vAssemblyResultResponse = v.object({
111
- _id: v.string(),
112
- _creationTime: v.number(),
113
- assemblyId: v.string(),
114
- album: v.optional(v.string()),
115
- userId: v.optional(v.string()),
116
- stepName: v.string(),
117
- resultId: v.optional(v.string()),
118
- sslUrl: v.optional(v.string()),
119
- name: v.optional(v.string()),
120
- size: v.optional(v.number()),
121
- mime: v.optional(v.string()),
122
- raw: v.any(),
123
- createdAt: v.number(),
124
- });
125
-
126
- export type AssemblyResultResponse = Infer<typeof vAssemblyResultResponse>;
127
-
128
- export const vCreateAssemblyArgs = v.object({
129
- templateId: v.optional(v.string()),
130
- steps: v.optional(v.record(v.string(), v.any())),
131
- fields: v.optional(v.record(v.string(), v.any())),
132
- notifyUrl: v.optional(v.string()),
133
- numExpectedUploadFiles: v.optional(v.number()),
134
- expires: v.optional(v.string()),
135
- additionalParams: v.optional(v.record(v.string(), v.any())),
136
- userId: v.optional(v.string()),
137
- });
106
+ export { vAssemblyOptions };
107
+ export type {
108
+ AssemblyOptions,
109
+ AssemblyResponse,
110
+ AssemblyResultResponse,
111
+ CreateAssemblyArgs,
112
+ };
138
113
 
139
114
  /**
140
115
  * @deprecated Prefer `makeTransloaditAPI` or `Transloadit` for new code.
@@ -158,16 +133,20 @@ export class TransloaditClient {
158
133
  return new TransloaditClient(component, config);
159
134
  }
160
135
 
161
- async createAssembly(
162
- ctx: RunActionCtx,
163
- args: Infer<typeof vCreateAssemblyArgs>,
164
- ) {
136
+ async createAssembly(ctx: RunActionCtx, args: CreateAssemblyArgs) {
165
137
  return ctx.runAction(this.component.lib.createAssembly, {
166
138
  ...args,
167
139
  config: this.config,
168
140
  });
169
141
  }
170
142
 
143
+ async createAssemblyOptions(ctx: RunActionCtx, args: CreateAssemblyArgs) {
144
+ return ctx.runAction(this.component.lib.createAssemblyOptions, {
145
+ ...args,
146
+ config: this.config,
147
+ });
148
+ }
149
+
171
150
  async handleWebhook(
172
151
  ctx: RunActionCtx,
173
152
  args: {
@@ -266,10 +245,7 @@ export function makeTransloaditAPI(
266
245
  return {
267
246
  createAssembly: actionGeneric({
268
247
  args: vCreateAssemblyArgs,
269
- returns: v.object({
270
- assemblyId: v.string(),
271
- data: v.any(),
272
- }),
248
+ returns: vCreateAssemblyReturn,
273
249
  handler: async (ctx, args) => {
274
250
  const resolvedConfig = resolveConfig();
275
251
  return ctx.runAction(component.lib.createAssembly, {
@@ -278,18 +254,20 @@ export function makeTransloaditAPI(
278
254
  });
279
255
  },
280
256
  }),
281
- handleWebhook: actionGeneric({
282
- args: {
283
- payload: v.any(),
284
- rawBody: v.optional(v.string()),
285
- signature: v.optional(v.string()),
257
+ createAssemblyOptions: actionGeneric({
258
+ args: vCreateAssemblyArgs,
259
+ returns: vAssemblyOptions,
260
+ handler: async (ctx, args) => {
261
+ const resolvedConfig = resolveConfig();
262
+ return ctx.runAction(component.lib.createAssemblyOptions, {
263
+ ...args,
264
+ config: resolvedConfig,
265
+ });
286
266
  },
287
- returns: v.object({
288
- assemblyId: v.string(),
289
- resultCount: v.number(),
290
- ok: v.optional(v.string()),
291
- status: v.optional(v.string()),
292
- }),
267
+ }),
268
+ handleWebhook: actionGeneric({
269
+ args: vWebhookActionArgs,
270
+ returns: vWebhookResponse,
293
271
  handler: async (ctx, args) => {
294
272
  const resolvedConfig = resolveConfig();
295
273
  return ctx.runAction(component.lib.handleWebhook, {
@@ -299,15 +277,8 @@ export function makeTransloaditAPI(
299
277
  },
300
278
  }),
301
279
  queueWebhook: actionGeneric({
302
- args: {
303
- payload: v.any(),
304
- rawBody: v.optional(v.string()),
305
- signature: v.optional(v.string()),
306
- },
307
- returns: v.object({
308
- assemblyId: v.string(),
309
- queued: v.boolean(),
310
- }),
280
+ args: vWebhookActionArgs,
281
+ returns: vQueueWebhookResponse,
311
282
  handler: async (ctx, args) => {
312
283
  const resolvedConfig = resolveConfig();
313
284
  return ctx.runAction(component.lib.queueWebhook, {
@@ -317,13 +288,8 @@ export function makeTransloaditAPI(
317
288
  },
318
289
  }),
319
290
  refreshAssembly: actionGeneric({
320
- args: { assemblyId: v.string() },
321
- returns: v.object({
322
- assemblyId: v.string(),
323
- resultCount: v.number(),
324
- ok: v.optional(v.string()),
325
- status: v.optional(v.string()),
326
- }),
291
+ args: vAssemblyIdArgs,
292
+ returns: vWebhookResponse,
327
293
  handler: async (ctx, args) => {
328
294
  const resolvedConfig = resolveConfig();
329
295
  return ctx.runAction(component.lib.refreshAssembly, {
@@ -333,63 +299,42 @@ export function makeTransloaditAPI(
333
299
  },
334
300
  }),
335
301
  getAssemblyStatus: queryGeneric({
336
- args: { assemblyId: v.string() },
302
+ args: vAssemblyIdArgs,
337
303
  returns: v.union(vAssemblyResponse, v.null()),
338
304
  handler: async (ctx, args) => {
339
305
  return ctx.runQuery(component.lib.getAssemblyStatus, args);
340
306
  },
341
307
  }),
342
308
  listAssemblies: queryGeneric({
343
- args: {
344
- status: v.optional(v.string()),
345
- userId: v.optional(v.string()),
346
- limit: v.optional(v.number()),
347
- },
309
+ args: vListAssembliesArgs,
348
310
  returns: v.array(vAssemblyResponse),
349
311
  handler: async (ctx, args) => {
350
312
  return ctx.runQuery(component.lib.listAssemblies, args);
351
313
  },
352
314
  }),
353
315
  listResults: queryGeneric({
354
- args: {
355
- assemblyId: v.string(),
356
- stepName: v.optional(v.string()),
357
- limit: v.optional(v.number()),
358
- },
316
+ args: vListResultsArgs,
359
317
  returns: v.array(vAssemblyResultResponse),
360
318
  handler: async (ctx, args) => {
361
319
  return ctx.runQuery(component.lib.listResults, args);
362
320
  },
363
321
  }),
364
322
  listAlbumResults: queryGeneric({
365
- args: {
366
- album: v.string(),
367
- limit: v.optional(v.number()),
368
- },
323
+ args: vListAlbumResultsArgs,
369
324
  returns: v.array(vAssemblyResultResponse),
370
325
  handler: async (ctx, args) => {
371
326
  return ctx.runQuery(component.lib.listAlbumResults, args);
372
327
  },
373
328
  }),
374
329
  purgeAlbum: mutationGeneric({
375
- args: {
376
- album: v.string(),
377
- deleteAssemblies: v.optional(v.boolean()),
378
- },
379
- returns: v.object({
380
- deletedResults: v.number(),
381
- deletedAssemblies: v.number(),
382
- }),
330
+ args: vPurgeAlbumArgs,
331
+ returns: vPurgeAlbumResponse,
383
332
  handler: async (ctx, args) => {
384
333
  return ctx.runMutation(component.lib.purgeAlbum, args);
385
334
  },
386
335
  }),
387
336
  storeAssemblyMetadata: mutationGeneric({
388
- args: {
389
- assemblyId: v.string(),
390
- userId: v.optional(v.string()),
391
- fields: v.optional(v.record(v.string(), v.any())),
392
- },
337
+ args: vStoreAssemblyMetadataArgs,
393
338
  returns: v.union(vAssemblyResponse, v.null()),
394
339
  handler: async (ctx, args) => {
395
340
  return ctx.runMutation(component.lib.storeAssemblyMetadata, args);
@@ -60,6 +60,23 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
60
60
  { assemblyId: string; data: any },
61
61
  Name
62
62
  >;
63
+ createAssemblyOptions: FunctionReference<
64
+ "action",
65
+ "internal",
66
+ {
67
+ config: { authKey: string; authSecret: string };
68
+ templateId?: string;
69
+ steps?: any;
70
+ fields?: any;
71
+ notifyUrl?: string;
72
+ numExpectedUploadFiles?: number;
73
+ expires?: string;
74
+ additionalParams?: any;
75
+ userId?: string;
76
+ },
77
+ { params: string; signature: string; fields?: any },
78
+ Name
79
+ >;
63
80
  handleWebhook: FunctionReference<
64
81
  "action",
65
82
  "internal",
@@ -1,28 +1,13 @@
1
1
  import { signParams, verifyWebhookSignature } from "@transloadit/utils";
2
2
  import type { AssemblyStatusResults } from "@transloadit/zod/v3/assemblyStatus";
3
- import type { AssemblyInstructionsInput } from "@transloadit/zod/v3/template";
4
3
  import { transloaditError } from "../shared/errors.ts";
5
-
6
- export interface TransloaditAuthConfig {
7
- authKey: string;
8
- authSecret: string;
9
- }
10
-
11
- export interface BuildParamsOptions {
12
- authKey: string;
13
- templateId?: string;
14
- steps?: AssemblyInstructionsInput["steps"];
15
- fields?: AssemblyInstructionsInput["fields"];
16
- notifyUrl?: string;
17
- numExpectedUploadFiles?: number;
18
- expires?: string;
19
- additionalParams?: Record<string, unknown>;
20
- }
21
-
22
- export interface BuildParamsResult {
23
- params: Record<string, unknown>;
24
- paramsString: string;
25
- }
4
+ import type {
5
+ BuildParamsOptions,
6
+ BuildParamsResult,
7
+ ParsedWebhookRequest,
8
+ VerifiedWebhookRequest,
9
+ WebhookActionArgs,
10
+ } from "../shared/schemas.ts";
26
11
 
27
12
  export function buildTransloaditParams(
28
13
  options: BuildParamsOptions,
@@ -74,16 +59,6 @@ export async function signTransloaditParams(
74
59
  return signParams(paramsString, authSecret, "sha384");
75
60
  }
76
61
 
77
- export type ParsedWebhookRequest = {
78
- payload: unknown;
79
- rawBody: string;
80
- signature?: string;
81
- };
82
-
83
- export type VerifiedWebhookRequest = ParsedWebhookRequest & {
84
- verified: boolean;
85
- };
86
-
87
62
  export async function parseTransloaditWebhook(
88
63
  request: Request,
89
64
  ): Promise<ParsedWebhookRequest> {
@@ -154,12 +129,6 @@ export async function buildWebhookQueueArgs(
154
129
  };
155
130
  }
156
131
 
157
- export type WebhookActionArgs = {
158
- payload: unknown;
159
- rawBody?: string;
160
- signature?: string;
161
- };
162
-
163
132
  export async function handleWebhookRequest(
164
133
  request: Request,
165
134
  options: {
@@ -256,6 +256,25 @@ describe("Transloadit component lib", () => {
256
256
  expect(result.resultCount).toBe(1);
257
257
  });
258
258
 
259
+ test("createAssemblyOptions includes expected upload count when provided", async () => {
260
+ const t = convexTest(schema, modules);
261
+
262
+ const result = await t.action(api.lib.createAssemblyOptions, {
263
+ steps: {
264
+ resize: {
265
+ robot: "/image/resize",
266
+ width: 120,
267
+ height: 120,
268
+ },
269
+ },
270
+ numExpectedUploadFiles: 3,
271
+ config: { authKey: "test-key", authSecret: "test-secret" },
272
+ });
273
+
274
+ const params = JSON.parse(result.params) as Record<string, unknown>;
275
+ expect(params.num_expected_upload_files).toBe(3);
276
+ });
277
+
259
278
  test("queueWebhook rejects invalid signature", async () => {
260
279
  const t = convexTest(schema, modules);
261
280
  const payload = { assembly_id: "asm_bad" };