@transcodely/sdk 0.3.0 → 0.3.1
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.
- package/CHANGELOG.md +21 -0
- package/README.md +78 -12
- package/dist/index.cjs +5842 -2930
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2224 -56
- package/dist/index.d.ts +2224 -56
- package/dist/index.mjs +5838 -2931
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ All notable changes to the Transcodely JavaScript / TypeScript SDK will be docum
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Breaking changes are allowed on minor bumps until 1.0.0.
|
|
6
6
|
|
|
7
|
+
## [0.3.1](https://github.com/transcodely/transcodely-js/compare/v0.3.0...v0.3.1) (2026-07-29)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* expose daily usage buckets and webhook endpoint health + event object-id filtering ([#26](https://github.com/transcodely/transcodely-js/issues/26)) ([28d3c77](https://github.com/transcodely/transcodely-js/commit/28d3c775c04dea4d3f8ff5c35b232072e40144f2))
|
|
13
|
+
* post-launch feature program integration (transcodely-js) ([#38](https://github.com/transcodely/transcodely-js/issues/38)) ([c8705ca](https://github.com/transcodely/transcodely-js/commit/c8705ca411d6ad0a0a221fb4d61461b9f963f49a))
|
|
14
|
+
* sync protos with api 3.10 — billing, captions text tracks, app suspension ([#39](https://github.com/transcodely/transcodely-js/issues/39)) ([a0e158c](https://github.com/transcodely/transcodely-js/commit/a0e158ce19f40c0f983ee9bc018f53073b6bdba4))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* add working eslint setup, correct create-job example shape ([#24](https://github.com/transcodely/transcodely-js/issues/24)) ([d2e40bd](https://github.com/transcodely/transcodely-js/commit/d2e40bd922cd1b453eba903e63e67cacb512c25b))
|
|
20
|
+
* **webhooks:** restore WebhookEvent narrowing via type guards ([#40](https://github.com/transcodely/transcodely-js/issues/40)) ([c5913a3](https://github.com/transcodely/transcodely-js/commit/c5913a311a6efde2d9a29fb53a9ef0f76d5f904a))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Documentation
|
|
24
|
+
|
|
25
|
+
* note content-aware encoding is rejected at create ([#30](https://github.com/transcodely/transcodely-js/issues/30)) ([a7da4ec](https://github.com/transcodely/transcodely-js/commit/a7da4ec9474e9754aa30269e5cdeb1dd40af8815))
|
|
26
|
+
* set managed on the README quick start create-job ([#32](https://github.com/transcodely/transcodely-js/issues/32)) ([5cef326](https://github.com/transcodely/transcodely-js/commit/5cef326f2788262204fb1d986eb284f38870dffc))
|
|
27
|
+
|
|
7
28
|
## [0.3.0](https://github.com/transcodely/transcodely-js/compare/v0.2.0...v0.3.0) (2026-07-15)
|
|
8
29
|
|
|
9
30
|
|
package/README.md
CHANGED
|
@@ -16,6 +16,9 @@ const client = new Transcodely({ apiKey: process.env.TRANSCODELY_API_KEY! });
|
|
|
16
16
|
// Create a job
|
|
17
17
|
const job = await client.jobs.create({
|
|
18
18
|
inputUrl: "https://example.com/source.mp4",
|
|
19
|
+
// Write outputs to Transcodely-managed storage. Drop `managed` and set
|
|
20
|
+
// `outputOriginId: "ori_..."` to write to your own configured origin.
|
|
21
|
+
managed: true,
|
|
19
22
|
outputs: [{
|
|
20
23
|
type: OutputFormat.HLS,
|
|
21
24
|
video: [
|
|
@@ -23,6 +26,10 @@ const job = await client.jobs.create({
|
|
|
23
26
|
{ codec: VideoCodec.H264, resolution: Resolution.RESOLUTION_720P },
|
|
24
27
|
],
|
|
25
28
|
}],
|
|
29
|
+
// Optional: encode only a sub-range of the input. Applies job-wide and
|
|
30
|
+
// reduces cost (billing keys off the produced output duration). Omit
|
|
31
|
+
// `endSeconds` (or leave 0) to encode through to the end of the input.
|
|
32
|
+
clip: { startSeconds: 2, endSeconds: 7 },
|
|
26
33
|
});
|
|
27
34
|
|
|
28
35
|
console.log(job.id); // "job_a1b2c3d4e5f6"
|
|
@@ -34,6 +41,45 @@ for await (const event of client.jobs.watch(job.id)) {
|
|
|
34
41
|
}
|
|
35
42
|
```
|
|
36
43
|
|
|
44
|
+
## AI captions
|
|
45
|
+
|
|
46
|
+
Add auto-generated captions to any output with a `generate` subtitle track.
|
|
47
|
+
Leave `language` empty (or set `"auto"`) to auto-detect the spoken language, or
|
|
48
|
+
pass an ISO 639-2 code to force one. A per-job fee is metered by source minute
|
|
49
|
+
and surfaced on `job.fees`; the produced captions show up on `job.subtitleResults`
|
|
50
|
+
with `autoGenerated: true`.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { Transcodely, OutputFormat, VideoCodec, Resolution, SubtitleOperation } from "@transcodely/sdk";
|
|
54
|
+
|
|
55
|
+
const client = new Transcodely({ apiKey: process.env.TRANSCODELY_API_KEY! });
|
|
56
|
+
|
|
57
|
+
// Generate captions while transcoding a new source.
|
|
58
|
+
await client.jobs.create({
|
|
59
|
+
inputUrl: "https://example.com/source.mp4",
|
|
60
|
+
managed: true,
|
|
61
|
+
outputs: [{
|
|
62
|
+
type: OutputFormat.HLS,
|
|
63
|
+
video: [{ codec: VideoCodec.H264, resolution: Resolution.RESOLUTION_1080P }],
|
|
64
|
+
subtitleTracks: [{ operation: SubtitleOperation.GENERATE, language: "auto" }],
|
|
65
|
+
}],
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Retro-caption a video you've already hosted: reference it by inputVideoId and
|
|
69
|
+
// request a single captions-only output (no video encode).
|
|
70
|
+
const job = await client.jobs.create({
|
|
71
|
+
inputVideoId: "vid_a1b2c3d4e5f6g7",
|
|
72
|
+
outputs: [{ subtitleTracks: [{ operation: SubtitleOperation.GENERATE }] }],
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
for (const result of job.subtitleResults) {
|
|
76
|
+
console.log(result.language, result.autoGenerated, result.url);
|
|
77
|
+
}
|
|
78
|
+
for (const fee of job.fees) {
|
|
79
|
+
console.log(fee.feeType, fee.amount, fee.currency); // "captions" 0.51 "eur"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
37
83
|
## Authentication
|
|
38
84
|
|
|
39
85
|
Pass your API key in the constructor:
|
|
@@ -46,7 +92,7 @@ const client = new Transcodely({ apiKey: process.env.TRANSCODELY_API_KEY! });
|
|
|
46
92
|
|
|
47
93
|
```ts
|
|
48
94
|
client.jobs // create / get / list / cancel / confirm / watch
|
|
49
|
-
client.videos // upload helpers, multipart, get / list / update / delete / watch
|
|
95
|
+
client.videos // upload helpers, multipart, createFromUrl, get / list / update / delete / watch / getStats / listTopVideos
|
|
50
96
|
client.presets // create / get / getBySlug / list / update / duplicate / archive
|
|
51
97
|
client.origins // create / get / list / update / validate / archive
|
|
52
98
|
client.apps // create / get / list / update / archive / enableHosting
|
|
@@ -174,17 +220,22 @@ app.post(
|
|
|
174
220
|
process.env.WEBHOOK_SECRET!,
|
|
175
221
|
);
|
|
176
222
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
223
|
+
// `isKnownEvent` narrows `event` to the events this SDK types precisely,
|
|
224
|
+
// so inside the switch `event.data` is the exact resource — no casts.
|
|
225
|
+
if (client.webhooks.isKnownEvent(event)) {
|
|
226
|
+
switch (event.type) {
|
|
227
|
+
case "job.succeeded":
|
|
228
|
+
console.log("Job done:", event.data.id); // event.data is a fully-typed Job
|
|
229
|
+
break;
|
|
230
|
+
case "video.uploaded":
|
|
231
|
+
console.log("Video uploaded:", event.data.id); // event.data is a Video
|
|
232
|
+
break;
|
|
233
|
+
// ...handle the other known types you care about
|
|
234
|
+
}
|
|
235
|
+
} else {
|
|
236
|
+
// Forward-compat: an event type added to the API after this SDK
|
|
237
|
+
// release still verifies and parses; `event.data` is raw `unknown`.
|
|
238
|
+
console.log("Unhandled future type:", event.type);
|
|
188
239
|
}
|
|
189
240
|
res.sendStatus(200);
|
|
190
241
|
} catch (err) {
|
|
@@ -200,6 +251,21 @@ app.post(
|
|
|
200
251
|
|
|
201
252
|
The signed payload is the **raw HTTP body** — use `express.raw()` (or the equivalent in your framework) to receive a `Buffer`, never `express.json()`.
|
|
202
253
|
|
|
254
|
+
#### Narrowing the event
|
|
255
|
+
|
|
256
|
+
`constructEvent` (and `client.events.retrieve` / `.list`) return a `WebhookEvent`: the closed, precisely-typed `KnownWebhookEvent` union **plus** an open `UnknownWebhookEvent` arm (`type: string; data: unknown`) so a payload for an event type added after this SDK release still verifies and parses instead of being dropped. That open arm means a bare `switch (event.type)` can't narrow `event.data` on its own — funnel through one of two guards first:
|
|
257
|
+
|
|
258
|
+
- **`isKnownEvent(event)`** narrows to `KnownWebhookEvent`, re-enabling a `switch (event.type)` where every `case` narrows `event.data` to the right resource (and TypeScript flags a `case` you left out if you keep the switch exhaustive). The `else` branch is your forward-compat handler.
|
|
259
|
+
- **`isEventType(event, "job.succeeded")`** narrows to a single event type — ideal for a receiver that only cares about one or two:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
if (client.webhooks.isEventType(event, "output.ready")) {
|
|
263
|
+
console.log(event.data.outputUrl); // event.data is a fully-typed JobOutput
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Both are also exported standalone (`import { isKnownEvent, isEventType } from "@transcodely/sdk"`) for code that doesn't hold a client. `WebhookEvent`, `KnownWebhookEvent`, and `UnknownWebhookEvent` are all exported for annotating your own handler signatures.
|
|
268
|
+
|
|
203
269
|
Every event carries a `request` object. Events emitted **inside** an API request scope (e.g. `job.created`, from your `jobs.create` call) set `request.id` to the originating `req_*` ID. Events emitted **outside** a request scope — every worker-driven `job.*` / `output.*` event (`job.succeeded`, `job.failed`, `job.canceled`, `job.progress`, `output.ready`, …) — set `request.id` to `null`. `request.idempotencyKey` is `null` whenever the originating request didn't supply one.
|
|
204
270
|
|
|
205
271
|
`constructEvent` accepts `request.id: null` from **v0.1.3** onward. v0.1.2 and earlier rejected such deliveries with a `WebhookPayloadError` — upgrade if you validate worker-driven events.
|