Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8c4af32
first stab at merging in transloadify
kvz Dec 2, 2025
5295273
use cli subdir. more re-use of code
kvz Dec 2, 2025
bb64157
fix e2e
kvz Dec 2, 2025
690603a
apply stricter biome & tsconfig rules
kvz Dec 2, 2025
ebbbcb7
abort assemblies
kvz Dec 2, 2025
714ea73
Improve types, make replay clearer, roll test for it
kvz Dec 2, 2025
164354e
stronger types
kvz Dec 2, 2025
2fdc525
wip
kvz Dec 2, 2025
9023343
fix version
kvz Dec 2, 2025
dbcbaf4
format
kvz Dec 3, 2025
1fc64ca
run e2e for own PRs
kvz Dec 3, 2025
228afed
dotenv
kvz Dec 3, 2025
ba3823f
cli docs
kvz Dec 3, 2025
d28058f
add missing docs
kvz Dec 3, 2025
170aba2
merge CI
kvz Dec 3, 2025
4c14d93
add node 24
kvz Dec 3, 2025
946a8f6
e2e only on 24
kvz Dec 3, 2025
90cde44
test: use unique template names to avoid CI conflicts
kvz Dec 3, 2025
21b85f7
feat: honor abort signal during awaitAssemblyCompletion polling
kvz Dec 3, 2025
35e50cd
add browser
kvz Dec 3, 2025
da6f0b4
fix bug
kvz Dec 3, 2025
ce030e9
fix: address code review feedback
kvz Dec 3, 2025
44aa6e3
feat: replace --verbose/--quiet with --log-level (-l)
kvz Dec 3, 2025
0ca0f87
feat: allow numeric values for --log-level
kvz Dec 3, 2025
887ba60
feat: add trace log level (8)
kvz Dec 3, 2025
0f795cb
add onPoll
kvz Dec 3, 2025
8c5ee5d
fix
kvz Dec 3, 2025
ce86458
format
kvz Dec 3, 2025
b62dac6
fix: CLI exits with code 1 when jobs fail, fix AbortSignal listener leak
kvz Dec 3, 2025
f22b4a1
feat(cli): add --endpoint option and --single-assembly flag
kvz Dec 3, 2025
447f73f
docs: document --endpoint and --single-assembly CLI options
kvz Dec 3, 2025
85c06b9
fix: handle templates with no steps in sync download
kvz Dec 3, 2025
c364b3b
refactor: use tryCatch utility for cleaner error handling
kvz Dec 3, 2025
243852d
fix: remove non-functional notifications list, add download abort signal
kvz Dec 3, 2025
60273d6
refactor: use got.stream + pipeline for downloads
kvz Dec 3, 2025
d73f212
test: add e2e test verifying download integrity via md5 hash
kvz Dec 3, 2025
13b3547
fix: prevent file descriptor exhaustion with concurrency limiting
kvz Dec 4, 2025
20471f1
Merge origin/cli: use got.stream for downloads
kvz Dec 4, 2025
400719f
perf: split assemblies e2e tests for parallel execution
kvz Dec 4, 2025
7d50065
upgrade yarn, add p-queue
kvz Dec 4, 2025
523e289
upgrade yarn
kvz Dec 4, 2025
9b3fe42
use p-queue instead of JobPromise
kvz Dec 4, 2025
d921f30
natives
kvz Dec 4, 2025
4299b8d
no esnureDir
kvz Dec 4, 2025
9cceb6f
unify cli files
kvz Dec 4, 2025
6386b77
format
kvz Dec 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gemini/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
}
}
}
90 changes: 86 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
name: CI

on:
workflow_dispatch:
pull_request:
push:
branches:
- main
tags:
- '*'
schedule:
- cron: '0 8 * * *'

jobs:
pack:
name: Build package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -24,6 +28,7 @@ jobs:
path: '*.tgz'

biome:
name: Lint (Biome)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -34,6 +39,7 @@ jobs:
- run: corepack yarn lint:js

typescript:
name: Lint (TypeScript)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -43,13 +49,15 @@ jobs:
- run: corepack yarn
- run: corepack yarn lint:ts

vitest:
unit:
name: Unit tests (Node ${{ matrix.node }})
runs-on: ubuntu-latest
strategy:
matrix:
node:
- 20
- 22
- 24
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -58,14 +66,75 @@ jobs:
- run: corepack yarn
- run: corepack yarn test:unit
- name: Upload coverage reports artifact
if: matrix.node == 22 # Only upload coverage from the latest Node.js version
if: matrix.node == 24
uses: actions/upload-artifact@v4
with:
name: coverage-reports
path: coverage/

e2e:
name: E2E tests
# Run on push/schedule/dispatch, or on PRs only if from same repo (not forks)
# This protects secrets from being exposed to fork PRs
if: >
github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- run: corepack yarn
- name: Download cloudflared
run: |
curl -fsSLo cloudflared-linux-amd64 https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
chmod +x cloudflared-linux-amd64

# can be used for debugging:
# - name: Setup tmate session
# uses: mxschmitt/action-tmate@v3

- run: corepack yarn test
env:
TRANSLOADIT_KEY: ${{ secrets.TRANSLOADIT_KEY }}
TRANSLOADIT_SECRET: ${{ secrets.TRANSLOADIT_SECRET }}
NODE_OPTIONS: --trace-deprecation --trace-warnings
CLOUDFLARED_PATH: ./cloudflared-linux-amd64
DEBUG: 'transloadit:*'

- name: Generate the badge from the json-summary
run: node --experimental-strip-types test/generate-coverage-badge.ts coverage/coverage-summary.json
- name: Move HTML report and badge to the correct location
run: |
mv coverage/lcov-report static-build
mv coverage-badge.svg static-build/
# *** BEGIN PUBLISH STATIC SITE STEPS ***
# Use the standard checkout action to check out the destination repo to a separate directory
# See https://github.com/mifi/github-action-push-static
- uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.COVERAGE_REPO_SSH_PRIVATE_KEY }}
repository: transloadit/node-sdk-coverage
path: static-files-destination

# Push coverage data
- run: |
git config --global user.name github-actions
git config --global user.email github-actions@github.com
# Remove existing files:
rm -rf static-files-destination/*
# Replace with new files:
cp -a static-build/* static-files-destination/
cd static-files-destination
git add .
# git diff-index: to avoid doing the git commit failing if there are no changes to be commit
git diff-index --quiet HEAD || git commit --message 'Static file updates'
git push

coverage:
needs: vitest
name: Upload coverage
needs: unit
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
Expand All @@ -83,13 +152,26 @@ jobs:
name: node-sdk
fail_ci_if_error: true

slack-on-failure:
name: Slack notification
needs: [e2e]
if: ${{ failure() && github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
steps:
- uses: 8398a7/action-slack@v3
with:
status: failure
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

release:
name: Publish to npm
runs-on: ubuntu-latest
needs:
- pack
- biome
- typescript
- vitest
- unit
if: startsWith(github.ref, 'refs/tags/')
permissions:
id-token: write
Expand Down
88 changes: 0 additions & 88 deletions .github/workflows/integration.yml

This file was deleted.

12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

You may also want to refer to [GitHub releases](https://github.com/transloadit/node-sdk/releases).

## Unreleased

- Add `signal` option to `createAssembly()` for cancelling in-flight HTTP requests and TUS uploads via `AbortController`
- Add `signal` and `onPoll` options to `awaitAssemblyCompletion()` for cancellation and early termination (useful for custom progress reporting or superseding assemblies in watch mode)
- Integrate transloadify CLI into the SDK, providing `assemblies`, `templates`, `bills`, and `assembly-notifications` commands
- Add `--log-level (-l)` CLI option using syslog severity levels (err=3, warn=4, notice=5, info=6, debug=7, trace=8)
- Add `--endpoint` CLI option for custom API endpoint (also reads `TRANSLOADIT_ENDPOINT` env var)
- Add `--single-assembly` flag to `assemblies create` for passing multiple input files to a single assembly
- Add `--concurrency` option to `assemblies create` to limit parallel processing (default: 5)
- Fix file descriptor exhaustion by closing streams immediately and creating fresh ones on demand
- Apply stricter biome lint rules (noExplicitAny, useAwait, noForEach, noNonNullAssertion)

## v4.0.7

Released: 2025-11-26.
Expand Down
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ yarn test:unit

This will also generate a coverage report in the `coverage` directory.

### Integration tests
### e2e tests

Integration tests are in the [`test/integration`](test/integration) folder. They require some extra setup.
e2e tests are in the [`test/e2e`](test/e2e) folder. They require some extra setup.

Firstly, these tests require the Cloudflare executable. You can download this with:

Expand All @@ -63,10 +63,10 @@ chmod +x cloudflared-linux-amd64

They also require a Transloadit key and secret, which you can get from https://transloadit.com/c/credentials.

You can run the integration tests with:
You can run the e2e tests with:

```sh
TRANSLOADIT_KEY='YOUR_TRANSLOADIT_KEY' TRANSLOADIT_SECRET='YOUR_TRANSLOADIT_SECRET' CLOUDFLARED_PATH='./cloudflared-linux-amd64' yarn test:integration
TRANSLOADIT_KEY='YOUR_TRANSLOADIT_KEY' TRANSLOADIT_SECRET='YOUR_TRANSLOADIT_SECRET' CLOUDFLARED_PATH='./cloudflared-linux-amd64' yarn test:e2e
```

### Code Coverage
Expand Down
38 changes: 19 additions & 19 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ Version 4 focuses on type-safety, clearer errors, and modern Node support. Most
```js
// 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 ?? '',
})
}
```

Expand All @@ -48,16 +48,16 @@ The package also exports `AssemblyInstructionsInput`, `AssemblyIndexItem`, `Asse
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 })
```

## 3. Adjust API result handling
Expand All @@ -82,15 +82,15 @@ const createdAssembly = await transloadit.createAssembly(...);

```ts
try {
await transloadit.createAssembly({ params });
await transloadit.createAssembly({ params })
} catch (error) {
if (error instanceof ApiError && error.response.assembly_id) {
console.error(
"Troubleshoot at https://transloadit.com/c/assemblies/" +
'Troubleshoot at https://transloadit.com/c/assemblies/' +
error.response.assembly_id
);
)
}
throw error;
throw error
}
```

Expand All @@ -103,18 +103,18 @@ try {
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
Expand All @@ -135,7 +135,7 @@ As a consequence of upgrading `got` to v14, the `gotRetry` option no longer acce

## 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.
- Run your existing e2e tests on Node 20+. If you relied on CommonJS `require`, convert those modules or wrap calls in `import()` shims as shown above.
- If TypeScript raises errors about unfamiliar properties, import the respective types from `transloadit` instead of redefining them.
- Schemas intentionally mirror the current public API. Some properties remain permissive while we tighten validation in the API itself; report gaps if the SDK raises or misses invalid data.

Expand Down
Loading