diff --git a/CHANGELOG.md b/CHANGELOG.md index 4163e4b9..253799ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,10 +17,11 @@ Released: 2025-09-18. [Diff](https://github.com/transloadit/node-sdk/compare/v3.0.2...v4.0.0). - [x] **Breaking:** Package is now pure ESM, requires Node.js 20+, and exports `{ Transloadit }` instead of a default client. -- [x] **Breaking:** Assembly inputs are validated against rich schemas; migrate to the new `AssemblyInstructionsInput` types and expect `listAssemblies()` to return `{ items, count }`. -- [x] Added end-to-end TypeScript typings for robots, assemblies, templates, and responses, so assembly instructions now autocomplete every robot and its supported parameters. -- [x] Introduced structured error classes (`ApiError`, `InconsistentResponseError`, `PollingTimeoutError`) that preserve assembly IDs and server metadata. +- [x] **Breaking** `TransloaditError` removed in favor of a new, slightly different `ApiError`. +- [x] Added end-to-end TypeScript typings for robots, assemblies, templates, and responses, so assembly instructions now autocomplete every robot and its supported parameters. Notably, Assembly instructions and statuses are validates against rich TypeScript types; migrate to the new `AssemblyInstructionsInput` types and `AssemblyStatus` in responses. +- [x] New rich error stacktraces that aid in debugging issues. - [x] Added opt-in `validateResponses` safeguard and a `getSignedSmartCDNUrl` helper for generating signed Smart CDN URLs. +- [x] Fix broken rate limiting #217 - [x] Modernized tooling, tests, and examples (Vitest, Biome, TypeScript examples). See [MIGRATION.md](./MIGRATION.md) for a guided upgrade path. ## v3.0.2 diff --git a/MIGRATION.md b/MIGRATION.md index cca8754c..83b5528b 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -7,7 +7,7 @@ Version 4 focuses on type-safety, clearer errors, and modern Node support. Most - [ ] Ensure your runtime is Node.js **20 or newer**. - [ ] Switch from the v3 default export to the named `{ Transloadit }` ESM export. - [ ] Adopt the new typed assembly instructions (`AssemblyInstructionsInput`) and update code that reads `listAssemblies()` results. -- [ ] Adjust error handling to account for the new `ApiError`, `InconsistentResponseError`, and `PollingTimeoutError` classes. +- [ ] Migrate from `TransloaditError` to `ApiError` signature. - [ ] (Optional) Opt into `validateResponses` or use `getSignedSmartCDNUrl` if you need the new safeguards and helpers. ## Before you begin @@ -17,13 +17,13 @@ Version 4 focuses on type-safety, clearer errors, and modern Node support. Most - The SDK ships with `"type": "module"` and `.d.ts` typings. Pure CommonJS projects will need to either migrate to ESM or load the client via `import()` inside async code. ```js -// CommonJS example +// CommonJS import example async function getClient() { - const { Transloadit } = await import('transloadit') + const { Transloadit } = await import("transloadit"); return new Transloadit({ - authKey: process.env.TRANSLOADIT_KEY ?? '', - authSecret: process.env.TRANSLOADIT_SECRET ?? '', - }) + authKey: process.env.TRANSLOADIT_KEY ?? "", + authSecret: process.env.TRANSLOADIT_SECRET ?? "", + }); } ``` @@ -42,80 +42,97 @@ The package also exports `AssemblyInstructionsInput`, `AssemblyIndexItem`, `Asse ## 2. Adopt typed assembly instructions -`createAssembly` now validates its `params` using rich schemas. TypeScript users get autocomplete for every robot and parameter out of the box. +`createAssembly` now validates its `params` using rich TypeScript types, and users get autocomplete for every robot and parameter out of the box. ```ts const params: AssemblyInstructionsInput = { steps: { resize: { - use: ':original', - robot: '/image/resize', + use: ":original", + robot: "/image/resize", width: 320, height: 240, result: true, }, }, -} +}; -await transloadit.createAssembly({ params, waitForCompletion: true }) +await transloadit.createAssembly({ params, waitForCompletion: true }); ``` -If validation fails, `createAssembly` throws an `ApiError` before making a network request, helping you catch mistakes locally. - ## 3. Adjust API result handling -- `listAssemblies()` now returns a `PaginationListWithCount` instead of the legacy `ListedAssembly` array. - - ```ts - const { items, count } = await transloadit.listAssemblies() - items.forEach((assembly) => console.log(assembly.id, assembly.status)) - ``` +`AssemblyStatus` objects are now fully typed. Update any custom helpers to use the exported types instead of hand-rolled interfaces. -- `AssemblyStatus` objects are now fully typed. Update any custom helpers to use the exported types instead of hand-rolled interfaces. -- The pagination helpers (`PaginationStream`) are written in TypeScript and ship `.d.ts` files; imports work the same, but you can lean on the IDE for guidance now. +```ts +// `createdAssembly` is fully typed +const createdAssembly = await transloadit.createAssembly(...); +``` ## 4. Update error handling -- `ApiError` wraps responses that contain an `error` payload even when the HTTP status code is 2xx. It carries `assemblyId`, `transloaditErrorCode`, and the raw `body`. -- `InconsistentResponseError` is thrown if the Transloadit API omits critical fields (for example, missing assembly URLs). -- `PollingTimeoutError` is thrown when waiting for an assembly to finish via `waitForCompletion` exceeds the timeout. +`TransloaditError` has been renamed to `ApiError`. Key differences between `TransloaditError` and `ApiError`: + +- This error is also thrown when `body.error` is set, even if status from server is 2xx. +- `TransloaditError.response.body` can now be found in `ApiError.response`. +- `TransloaditError.assemblyId` can now be found in `ApiError.response.assembly_id`. +- `TransloaditError.transloaditErrorCode` can now be found in `ApiError.response.error`. +- `ApiError` does not inherit from `got.HTTPError`, but `ApiError.cause` will be the `got.HTTPError` instance that caused this error, except for when Tranloadit API responds with HTTP 200 and `error` prop set in JSON response (in which case `cause` will be `undefined`). +- Note that (just like before) when the Transloadit API responds with an error we will always throw an `ApiError` - In all other cases (like request timeout, connection error, TypeError etc.), we don't wrap the error in `ApiError`. ```ts try { - await transloadit.createAssembly({ params }) + await transloadit.createAssembly({ params }); } catch (error) { - if (error instanceof ApiError && error.assemblyId) { + if (error instanceof ApiError && error.response.assembly_id) { console.error( - 'Troubleshoot at https://transloadit.com/c/assemblies/' + error.assemblyId - ) + "Troubleshoot at https://transloadit.com/c/assemblies/" + + error.response.assembly_id + ); } - throw error + throw error; } ``` ## 5. Optional enhancements -- `validateResponses` (client option) replays schema validation against responses you receive. Enable it when integrating with new workflows to surface unexpected fields early: +- `validateResponses` (client option) runs schema validation against responses you receive from Transloadit's servers. It will then throw additional `InconsistentResponseError` errors if responses are inconsistent with the schema. This will normally not happen, but enabling this will catch any bugs in Transloadit's API code where the response does not (yet) adhere with the schemas, instead of silently accepting the types as something else than what you expect (which is the case when the value is `false` - the default). We are of course working on making sure all our responses adhere to the schemas. In the future we want to make this option default to `true`. ```ts const transloadit = new Transloadit({ authKey, authSecret, validateResponses: true, - }) + }); ``` - `getSignedSmartCDNUrl` generates Smart CDN URLs with signatures that match the server-side implementation: ```ts const signedUrl = transloadit.getSignedSmartCDNUrl({ - workspace: 'my-team', - template: 'hero-image', - input: 'landing.jpg', - urlParams: { format: 'webp' }, - }) + workspace: "my-team", + template: "hero-image", + input: "landing.jpg", + urlParams: { format: "webp" }, + }); ``` +## 6. Removed `createAssembly` callback support + +Use the returned promise instead. + +## 7. Removed `isResumable` option + +Only Tus uploads (which we call resumable uploads) are now supported using the SDK, and this option has therefore been removed. + +## 8. `form-data` testing + +`form-data` upgraded from 3 to 4 - this might cause some subtle differences in behavior related to file uploads. Be sure to test file uploads. + +## 9. `got` upgraded + +As a consequence of upgrading `got` to v14, the `gotRetry` option no longer accepts `number`. Instead use `{ limit: 0 }`. See [`got` `retry` object documentation](https://github.com/sindresorhus/got/blob/v14.4.9/documentation/7-retry.md). + ## Testing & troubleshooting - Run your existing integration tests on Node 20+. If you relied on CommonJS `require`, convert those modules or wrap calls in `import()` shims as shown above.