Skip to content

Commit dc0def8

Browse files
authored
feat: add @transloadit/notify-url-relay package (#356)
* feat: add @transloadit/notify-url-proxy workspace package * fix: make notify-url-proxy tests monorepo-safe * fix: rename notify-url-relay and handle decoded payload headers * chore: update transloadit parity baseline * refactor: complete notify-url-relay council follow-ups * Update README.md * fix(notify-url-relay): address council review findings
1 parent bd5bcb6 commit dc0def8

26 files changed

+3050
-19
lines changed

.changeset/bright-vans-cross.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@transloadit/notify-url-relay': minor
3+
---
4+
5+
Add a new `@transloadit/notify-url-relay` package for running a local Transloadit
6+
`notify_url` relay with fetch-based forwarding, assembly polling, retry logic, and a CLI/TUI.

.github/workflows/ci.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ jobs:
164164
github.event_name != 'pull_request' ||
165165
github.event.pull_request.head.repo.full_name == github.repository
166166
runs-on: ubuntu-latest
167+
env:
168+
NODE_OPTIONS: --trace-deprecation --trace-warnings
167169
steps:
168170
- uses: actions/checkout@v4
169171
- uses: actions/setup-node@v4
@@ -181,18 +183,20 @@ jobs:
181183

182184
- run: corepack yarn test
183185
env:
184-
TRANSLOADIT_KEY: ${{ secrets.TRANSLOADIT_KEY }}
185-
TRANSLOADIT_SECRET: ${{ secrets.TRANSLOADIT_SECRET }}
186-
NODE_OPTIONS: --trace-deprecation --trace-warnings
187186
CLOUDFLARED_PATH: ${{ github.workspace }}/cloudflared-linux-amd64
188187
DEBUG: 'transloadit:*'
188+
TRANSLOADIT_KEY: ${{ secrets.TRANSLOADIT_KEY }}
189+
TRANSLOADIT_SECRET: ${{ secrets.TRANSLOADIT_SECRET }}
189190

190191
- name: Run MCP server e2e tests
191192
run: corepack yarn workspace @transloadit/mcp-server test:e2e
193+
194+
- name: Run notify-url-relay real e2e test
195+
run: corepack yarn workspace @transloadit/notify-url-relay test:real
192196
env:
193197
TRANSLOADIT_KEY: ${{ secrets.TRANSLOADIT_KEY }}
194198
TRANSLOADIT_SECRET: ${{ secrets.TRANSLOADIT_SECRET }}
195-
NODE_OPTIONS: --trace-deprecation --trace-warnings
199+
TRANSLOADIT_ENDPOINT: ${{ secrets.TRANSLOADIT_ENDPOINT }}
196200

197201
- name: Generate the badge from the json-summary
198202
run: node --experimental-strip-types packages/node/test/generate-coverage-badge.ts packages/node/coverage/coverage-summary.json

docs/fingerprint/transloadit-baseline.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"packageDir": "/home/kvz/code/node-sdk/packages/transloadit",
33
"tarball": {
4-
"filename": "transloadit-4.7.4.tgz",
5-
"sizeBytes": 1247606,
6-
"sha256": "48a0c23cb4652d91594b7ff5a7e16af1397e8da663245f241de49f1057c4330e"
4+
"filename": "transloadit-4.7.5.tgz",
5+
"sizeBytes": 1247607,
6+
"sha256": "8ece4cbf0df04422d189035abb22a80c0565f95e5b10488d0e9226277702e363"
77
},
88
"packageJson": {
99
"name": "transloadit",
10-
"version": "4.7.4",
10+
"version": "4.7.5",
1111
"main": "./dist/Transloadit.js",
1212
"exports": {
1313
".": "./dist/Transloadit.js",
@@ -473,8 +473,8 @@
473473
},
474474
{
475475
"path": "dist/robots.js",
476-
"sizeBytes": 8373,
477-
"sha256": "de7fd519fcf36cbae2d1a3a316dadf331a61e933bcb666a92358502fb3e90433"
476+
"sizeBytes": 8374,
477+
"sha256": "740d92236f9b0319b73f38c9827074747b80f36694906df916039bec8cd421d2"
478478
},
479479
{
480480
"path": "dist/alphalib/types/robots/s3-import.js",
@@ -689,7 +689,7 @@
689689
{
690690
"path": "package.json",
691691
"sizeBytes": 2730,
692-
"sha256": "0cf46ccf180fd122bfa412623700b21b34b3cd962aad90102ca8ab14256de1c6"
692+
"sha256": "313dd2ac13d3e4857b71bd889b2c9fa7f2458cf2bf5be2dd5a1996eb3d23199d"
693693
},
694694
{
695695
"path": "dist/alphalib/types/robots/_index.d.ts.map",
@@ -1599,7 +1599,7 @@
15991599
{
16001600
"path": "dist/robots.js.map",
16011601
"sizeBytes": 9412,
1602-
"sha256": "79c6c465ced5d07c7d7a3b5124c4486584d43aa86468caafe886f3b291304b13"
1602+
"sha256": "72d51dbe2ba7017ec5700bd72f5247142fa2f4cc3cda60c822a92fef0becf841"
16031603
},
16041604
{
16051605
"path": "dist/alphalib/types/robots/s3-import.d.ts.map",
@@ -2938,8 +2938,8 @@
29382938
},
29392939
{
29402940
"path": "src/robots.ts",
2941-
"sizeBytes": 9642,
2942-
"sha256": "fa774b4f6f8b30eb18a94bf2a117bae924d0b80f05e9bb16d7e85a8298e19543"
2941+
"sizeBytes": 9643,
2942+
"sha256": "7afa1b895f1b28c6eb63b496450e3236e5e20fc649484ba878fd0f6179899499"
29432943
},
29442944
{
29452945
"path": "dist/alphalib/types/robots/s3-import.d.ts",

docs/fingerprint/transloadit-baseline.package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "transloadit",
3-
"version": "4.7.4",
3+
"version": "4.7.5",
44
"description": "Node.js SDK for Transloadit",
55
"homepage": "https://github.com/transloadit/node-sdk/tree/main/packages/node",
66
"bugs": {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Notify URL Relay Refactor Follow-ups (2026-03-04)
2+
3+
Tracking refactors requested after council ideas. Items are completed in order and checked off as they land.
4+
5+
- [x] 1. Consolidate repeated integration test harness helpers into shared test utilities.
6+
- [x] 2. Unify CLI option definition/validation/help generation with one declarative schema.
7+
- [x] 3. Replace cross-package source import in real E2E with workspace package import, fixing Vitest resolution the right way.
8+
- [x] 4. Remove redundant null guard in `observeTiming`.
9+
- [x] 5. Simplify timeout signal plumbing using Node native Abort APIs while preserving timeout error semantics.
10+
- [x] 6. Deduplicate repeated E2E workflow environment variables at job-level.
11+
12+
## Council Refactor Run #2 (2026-03-04)
13+
14+
- [x] 1. Stabilize and DRY test harness setup; remove `getFreePort()` TOCTOU race by binding proxy to port `0`.
15+
- [x] 2. Deduplicate `observeTiming` emission path to a single payload construction.
16+
- [x] 3. Use named export for the relay class (align with repo style guidance).
17+
- [x] 4. Replace avoidable `as` casts with stronger typing/narrowing where practical.

knip.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ const config: KnipConfig = {
4747
ignore: [...sharedIgnore],
4848
ignoreDependencies: ['@types/express', '@types/node', 'vitest', 'vitest/config'],
4949
},
50+
'packages/notify-url-relay': {
51+
entry: ['src/**/*.ts', 'test/**/*.ts', 'vitest.config.ts'],
52+
project: ['{src,test}/**/*.ts'],
53+
ignore: [...sharedIgnore],
54+
ignoreDependencies: ['@types/node', 'vitest', 'vitest/config'],
55+
},
5056
'packages/transloadit': {
5157
entry: [
5258
'src/Transloadit.ts',

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"verify": "yarn lint:changesets && yarn lint:publish && yarn lint:deps && yarn lint:js && yarn lint:ts && yarn test:unit",
1212
"verify:full": "yarn verify && yarn knip && yarn parity:transloadit && yarn test:types",
1313
"lint:js": "biome check .",
14-
"lint:ts": "yarn tsc:types && yarn tsc:node && yarn tsc:zod",
14+
"lint:ts": "yarn tsc:types && yarn tsc:node && yarn tsc:zod && yarn workspace @transloadit/notify-url-relay lint:ts",
1515
"lint:changesets": "node scripts/guard-changesets.ts",
1616
"lint": "yarn lint:js",
1717
"fix": "yarn fix:js",
@@ -23,7 +23,7 @@
2323
"knip": "yarn run --binaries-only knip --exclude binaries --no-config-hints --no-progress",
2424
"pack": "node scripts/pack-transloadit.ts",
2525
"parity:transloadit": "node scripts/prepare-transloadit.ts && node scripts/fingerprint-pack.ts packages/transloadit --ignore-scripts --quiet --out /tmp/transloadit-after.json && node scripts/verify-fingerprint.ts --current /tmp/transloadit-after.json --diff",
26-
"test:unit": "yarn workspace @transloadit/node test:unit && yarn workspace @transloadit/mcp-server test:unit && yarn workspace @transloadit/types test:unit && yarn workspace @transloadit/zod test:unit",
26+
"test:unit": "yarn workspace @transloadit/node test:unit && yarn workspace @transloadit/mcp-server test:unit && yarn workspace @transloadit/types test:unit && yarn workspace @transloadit/zod test:unit && yarn workspace @transloadit/notify-url-relay test:unit",
2727
"test:types": "yarn workspace @transloadit/zod test:types",
2828
"test:e2e": "yarn workspace @transloadit/node test:e2e",
2929
"test": "yarn workspace @transloadit/node test",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
TRANSLOADIT_KEY=your-key
2+
TRANSLOADIT_SECRET=your-secret
3+
# Optional (defaults to https://api2.transloadit.com)
4+
TRANSLOADIT_ENDPOINT=https://api2.transloadit.com
5+
# Optional (0-8 or emerg/alert/crit/err/warn/notice/info/debug/trace)
6+
TRANSLOADIT_LOG_LEVEL=info
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# @transloadit/notify-url-relay
2+
3+
## 0.1.0
4+
5+
### Minor Changes
6+
7+
- Initial release of the notify_url proxy package.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# @transloadit/notify-url-relay
2+
3+
Local `notify_url` relay for Transloadit Assemblies. This tool polls the status of Assemblies until they complete, then pushes the status to a pingback URL of your choosing. This is useful while on a development machine, which is inaccessible from the public internet and hence can't be notified by Transloadit.
4+
5+
You can alternatively use a tunnel like ngrok or [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/) for this, this is just one more way.
6+
7+
This version is modernized for:
8+
9+
- Node.js 24+
10+
- Native TypeScript execution (type stripping)
11+
- ESM
12+
- Yarn 4
13+
- Biome + Vitest + GitHub Actions + Changesets
14+
15+
Notify payloads are signed via `@transloadit/utils` using prefixed `sha384` signatures.
16+
Forwarding uses native `fetch`, polling retries use `p-retry`, and logs are emitted via `@transloadit/sev-logger`.
17+
Metrics hooks are available for counters, gauges, and timings.
18+
19+
## Install
20+
21+
```bash
22+
npm install @transloadit/notify-url-relay
23+
```
24+
25+
## CLI usage
26+
27+
```bash
28+
export TRANSLOADIT_SECRET="your-secret"
29+
30+
notify-url-relay \
31+
--notifyUrl "http://127.0.0.1:3000/transloadit" \
32+
--port 8888 \
33+
--notifyOnTerminalError \
34+
--log-level info
35+
```
36+
37+
Run `notify-url-relay --help` for all options.
38+
39+
Log level accepts `0-8` or names:
40+
`emerg`, `alert`, `crit`, `err`, `warn`, `notice`, `info`, `debug`, `trace`.
41+
You can also set `TRANSLOADIT_LOG_LEVEL`.
42+
43+
### Reactive TUI Mode
44+
45+
```bash
46+
notify-url-relay --ui --log-level info
47+
```
48+
49+
This opens a live terminal dashboard with:
50+
51+
- throughput and retry counters
52+
- in-flight queue gauges
53+
- latency sparklines
54+
- streaming logs
55+
56+
## Programmatic usage
57+
58+
```ts
59+
import { TransloaditNotifyUrlProxy } from '@transloadit/notify-url-relay'
60+
61+
const proxy = new TransloaditNotifyUrlProxy(
62+
process.env.TRANSLOADIT_SECRET ?? '',
63+
'http://127.0.0.1:3000/transloadit'
64+
)
65+
66+
proxy.run({
67+
port: 8888,
68+
target: 'https://api2.transloadit.com',
69+
forwardTimeoutMs: 15000,
70+
pollIntervalMs: 2000,
71+
pollMaxIntervalMs: 30000,
72+
pollBackoffFactor: 2,
73+
pollRequestTimeoutMs: 15000,
74+
maxPollAttempts: 10,
75+
maxInFlightPolls: 4,
76+
notifyOnTerminalError: false,
77+
notifyTimeoutMs: 15000,
78+
notifyMaxAttempts: 3,
79+
notifyIntervalMs: 500,
80+
notifyMaxIntervalMs: 5000,
81+
notifyBackoffFactor: 2
82+
})
83+
```
84+
85+
## Development
86+
87+
```bash
88+
corepack yarn
89+
corepack yarn workspace @transloadit/notify-url-relay check
90+
corepack yarn workspace @transloadit/notify-url-relay test:real
91+
```
92+
93+
## Real API E2E
94+
95+
Run an opt-in test against the real Transloadit API (default `yarn test` excludes this test):
96+
97+
```bash
98+
# set locally (for example in .env)
99+
export TRANSLOADIT_KEY="your-key"
100+
export TRANSLOADIT_SECRET="your-secret"
101+
# optional
102+
export TRANSLOADIT_ENDPOINT="https://api2.transloadit.com"
103+
104+
corepack yarn workspace @transloadit/notify-url-relay test:real
105+
```
106+
107+
For CI, configure repository secrets:
108+
109+
- `TRANSLOADIT_KEY`
110+
- `TRANSLOADIT_SECRET`
111+
- `TRANSLOADIT_ENDPOINT` (optional)
112+
113+
## Releases
114+
115+
Changesets drives releases for this package:
116+
117+
```bash
118+
corepack yarn changeset
119+
corepack yarn changeset:version
120+
```
121+
122+
On pushes to `main`, `.github/workflows/release.yml` runs `changesets/action` to publish.

0 commit comments

Comments
 (0)