@transloadit/node 4.7.2 → 4.7.4
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/README.md +19 -0
- package/dist/Transloadit.d.ts +10 -0
- package/dist/Transloadit.d.ts.map +1 -1
- package/dist/Transloadit.js +20 -0
- package/dist/Transloadit.js.map +1 -1
- package/dist/bearerToken.d.ts +31 -0
- package/dist/bearerToken.d.ts.map +1 -0
- package/dist/bearerToken.js +158 -0
- package/dist/bearerToken.js.map +1 -0
- package/dist/cli/commands/BaseCommand.d.ts.map +1 -1
- package/dist/cli/commands/BaseCommand.js +8 -5
- package/dist/cli/commands/BaseCommand.js.map +1 -1
- package/dist/cli/commands/auth.d.ts +12 -0
- package/dist/cli/commands/auth.d.ts.map +1 -1
- package/dist/cli/commands/auth.js +87 -42
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +2 -1
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/helpers.d.ts +10 -2
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/helpers.js +8 -1
- package/dist/cli/helpers.js.map +1 -1
- package/package.json +1 -1
- package/src/Transloadit.ts +32 -0
- package/src/bearerToken.ts +208 -0
- package/src/cli/commands/BaseCommand.ts +8 -7
- package/src/cli/commands/auth.ts +106 -56
- package/src/cli/commands/index.ts +2 -1
- package/src/cli/helpers.ts +16 -1
package/src/cli/commands/auth.ts
CHANGED
|
@@ -7,8 +7,9 @@ import {
|
|
|
7
7
|
assemblyInstructionsSchema,
|
|
8
8
|
} from '../../alphalib/types/template.ts'
|
|
9
9
|
import type { OptionalAuthParams } from '../../apiTypes.ts'
|
|
10
|
+
import { mintBearerTokenWithCredentials } from '../../bearerToken.ts'
|
|
10
11
|
import { Transloadit } from '../../Transloadit.ts'
|
|
11
|
-
import {
|
|
12
|
+
import { readCliInput, requireEnvCredentials } from '../helpers.ts'
|
|
12
13
|
import { UnauthenticatedCommand } from './BaseCommand.ts'
|
|
13
14
|
|
|
14
15
|
type UrlParamPrimitive = string | number | boolean
|
|
@@ -68,40 +69,51 @@ function normalizeUrlParams(params?: Record<string, unknown>): NormalizedUrlPara
|
|
|
68
69
|
return normalized
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
type OutputResult = { ok: true; output: string } | { ok: false; error: string }
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
type Result<T> = { ok: true; value: T } | { ok: false; error: string }
|
|
75
|
+
|
|
76
|
+
function parseJsonObject<TSchema extends z.ZodTypeAny>(
|
|
77
|
+
input: string,
|
|
78
|
+
schema: TSchema,
|
|
79
|
+
): Result<z.infer<TSchema>> {
|
|
80
|
+
let parsed: unknown
|
|
81
|
+
try {
|
|
82
|
+
parsed = JSON.parse(input)
|
|
83
|
+
} catch (error) {
|
|
84
|
+
return { ok: false, error: `Failed to parse JSON from stdin: ${(error as Error).message}` }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
88
|
+
return { ok: false, error: 'Invalid params provided via stdin. Expected a JSON object.' }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const parsedResult = schema.safeParse(parsed)
|
|
92
|
+
if (!parsedResult.success) {
|
|
93
|
+
return { ok: false, error: `Invalid params: ${formatIssues(parsedResult.error.issues)}` }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return { ok: true, value: parsedResult.data }
|
|
97
|
+
}
|
|
75
98
|
|
|
76
99
|
// Core logic for signature generation
|
|
77
100
|
function generateSignature(
|
|
78
101
|
input: string,
|
|
79
102
|
credentials: { authKey: string; authSecret: string },
|
|
80
103
|
algorithm?: string,
|
|
81
|
-
):
|
|
104
|
+
): OutputResult {
|
|
82
105
|
const { authKey, authSecret } = credentials
|
|
83
106
|
let params: CliSignatureParams
|
|
84
107
|
|
|
85
108
|
if (input === '') {
|
|
86
109
|
params = { auth: { key: authKey } }
|
|
87
110
|
} else {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
} catch (error) {
|
|
92
|
-
return { ok: false, error: `Failed to parse JSON from stdin: ${(error as Error).message}` }
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
96
|
-
return { ok: false, error: 'Invalid params provided via stdin. Expected a JSON object.' }
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const parsedResult = cliSignatureParamsSchema.safeParse(parsed)
|
|
100
|
-
if (!parsedResult.success) {
|
|
101
|
-
return { ok: false, error: `Invalid params: ${formatIssues(parsedResult.error.issues)}` }
|
|
111
|
+
const parsedResult = parseJsonObject(input, cliSignatureParamsSchema)
|
|
112
|
+
if (!parsedResult.ok) {
|
|
113
|
+
return { ok: false, error: parsedResult.error }
|
|
102
114
|
}
|
|
103
115
|
|
|
104
|
-
const parsedParams = parsedResult.
|
|
116
|
+
const parsedParams = parsedResult.value
|
|
105
117
|
const existingAuth = parsedParams.auth ?? {}
|
|
106
118
|
|
|
107
119
|
params = {
|
|
@@ -126,7 +138,7 @@ function generateSignature(
|
|
|
126
138
|
function generateSmartCdnUrl(
|
|
127
139
|
input: string,
|
|
128
140
|
credentials: { authKey: string; authSecret: string },
|
|
129
|
-
):
|
|
141
|
+
): OutputResult {
|
|
130
142
|
const { authKey, authSecret } = credentials
|
|
131
143
|
|
|
132
144
|
if (input === '') {
|
|
@@ -137,23 +149,12 @@ function generateSmartCdnUrl(
|
|
|
137
149
|
}
|
|
138
150
|
}
|
|
139
151
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
} catch (error) {
|
|
144
|
-
return { ok: false, error: `Failed to parse JSON from stdin: ${(error as Error).message}` }
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
148
|
-
return { ok: false, error: 'Invalid params provided via stdin. Expected a JSON object.' }
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const parsedResult = smartCdnParamsSchema.safeParse(parsed)
|
|
152
|
-
if (!parsedResult.success) {
|
|
153
|
-
return { ok: false, error: `Invalid params: ${formatIssues(parsedResult.error.issues)}` }
|
|
152
|
+
const parsedResult = parseJsonObject(input, smartCdnParamsSchema)
|
|
153
|
+
if (!parsedResult.ok) {
|
|
154
|
+
return { ok: false, error: parsedResult.error }
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
const { workspace, template, input: inputFieldRaw, url_params, expire_at_ms } = parsedResult.
|
|
157
|
+
const { workspace, template, input: inputFieldRaw, url_params, expire_at_ms } = parsedResult.value
|
|
157
158
|
const urlParams = normalizeUrlParams(url_params)
|
|
158
159
|
|
|
159
160
|
let expiresAt: number | undefined
|
|
@@ -195,14 +196,13 @@ export interface RunSmartSigOptions {
|
|
|
195
196
|
}
|
|
196
197
|
|
|
197
198
|
export async function runSig(options: RunSigOptions = {}): Promise<void> {
|
|
198
|
-
const
|
|
199
|
-
if (
|
|
200
|
-
console.error(
|
|
201
|
-
'Missing credentials. Please set TRANSLOADIT_KEY and TRANSLOADIT_SECRET environment variables.',
|
|
202
|
-
)
|
|
199
|
+
const credentialsResult = requireEnvCredentials()
|
|
200
|
+
if (!credentialsResult.ok) {
|
|
201
|
+
console.error(credentialsResult.error)
|
|
203
202
|
process.exitCode = 1
|
|
204
203
|
return
|
|
205
204
|
}
|
|
205
|
+
const credentials = credentialsResult.credentials
|
|
206
206
|
|
|
207
207
|
const { content } = await readCliInput({
|
|
208
208
|
providedInput: options.providedInput,
|
|
@@ -220,14 +220,13 @@ export async function runSig(options: RunSigOptions = {}): Promise<void> {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
export async function runSmartSig(options: RunSmartSigOptions = {}): Promise<void> {
|
|
223
|
-
const
|
|
224
|
-
if (
|
|
225
|
-
console.error(
|
|
226
|
-
'Missing credentials. Please set TRANSLOADIT_KEY and TRANSLOADIT_SECRET environment variables.',
|
|
227
|
-
)
|
|
223
|
+
const credentialsResult = requireEnvCredentials()
|
|
224
|
+
if (!credentialsResult.ok) {
|
|
225
|
+
console.error(credentialsResult.error)
|
|
228
226
|
process.exitCode = 1
|
|
229
227
|
return
|
|
230
228
|
}
|
|
229
|
+
const credentials = credentialsResult.credentials
|
|
231
230
|
|
|
232
231
|
const { content } = await readCliInput({
|
|
233
232
|
providedInput: options.providedInput,
|
|
@@ -274,13 +273,12 @@ export class SignatureCommand extends UnauthenticatedCommand {
|
|
|
274
273
|
})
|
|
275
274
|
|
|
276
275
|
protected async run(): Promise<number | undefined> {
|
|
277
|
-
const
|
|
278
|
-
if (
|
|
279
|
-
this.output.error(
|
|
280
|
-
'Missing credentials. Please set TRANSLOADIT_KEY and TRANSLOADIT_SECRET environment variables.',
|
|
281
|
-
)
|
|
276
|
+
const credentialsResult = requireEnvCredentials()
|
|
277
|
+
if (!credentialsResult.ok) {
|
|
278
|
+
this.output.error(credentialsResult.error)
|
|
282
279
|
return 1
|
|
283
280
|
}
|
|
281
|
+
const credentials = credentialsResult.credentials
|
|
284
282
|
|
|
285
283
|
const { content } = await readCliInput({ allowStdinWhenNoPath: true })
|
|
286
284
|
const rawInput = (content ?? '').trim()
|
|
@@ -328,13 +326,12 @@ export class SmartCdnSignatureCommand extends UnauthenticatedCommand {
|
|
|
328
326
|
})
|
|
329
327
|
|
|
330
328
|
protected async run(): Promise<number | undefined> {
|
|
331
|
-
const
|
|
332
|
-
if (
|
|
333
|
-
this.output.error(
|
|
334
|
-
'Missing credentials. Please set TRANSLOADIT_KEY and TRANSLOADIT_SECRET environment variables.',
|
|
335
|
-
)
|
|
329
|
+
const credentialsResult = requireEnvCredentials()
|
|
330
|
+
if (!credentialsResult.ok) {
|
|
331
|
+
this.output.error(credentialsResult.error)
|
|
336
332
|
return 1
|
|
337
333
|
}
|
|
334
|
+
const credentials = credentialsResult.credentials
|
|
338
335
|
|
|
339
336
|
const { content } = await readCliInput({ allowStdinWhenNoPath: true })
|
|
340
337
|
const rawInput = (content ?? '').trim()
|
|
@@ -349,3 +346,56 @@ export class SmartCdnSignatureCommand extends UnauthenticatedCommand {
|
|
|
349
346
|
return 1
|
|
350
347
|
}
|
|
351
348
|
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Mint a short-lived bearer token via POST /token (HTTP Basic Auth).
|
|
352
|
+
*
|
|
353
|
+
* This is intentionally stdout-clean JSON so it can be used by agents and scripts.
|
|
354
|
+
*/
|
|
355
|
+
export class TokenCommand extends UnauthenticatedCommand {
|
|
356
|
+
static override paths = [['auth', 'token']]
|
|
357
|
+
|
|
358
|
+
static override usage = Command.Usage({
|
|
359
|
+
category: 'Auth',
|
|
360
|
+
description: 'Mint a short-lived bearer token',
|
|
361
|
+
details: `
|
|
362
|
+
Calls POST /token using HTTP Basic Auth (TRANSLOADIT_KEY + TRANSLOADIT_SECRET) and prints the
|
|
363
|
+
JSON response to stdout.
|
|
364
|
+
`,
|
|
365
|
+
examples: [
|
|
366
|
+
['Mint an MCP token (default aud)', 'transloadit auth token'],
|
|
367
|
+
['Override audience', 'transloadit auth token --aud api2'],
|
|
368
|
+
],
|
|
369
|
+
})
|
|
370
|
+
|
|
371
|
+
aud = Option.String('--aud', {
|
|
372
|
+
description: 'Token audience (default: mcp).',
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
scope = Option.String('--scope', {
|
|
376
|
+
description:
|
|
377
|
+
'Comma-separated list of scopes to request (defaults to auth key scopes). Example: assemblies:write,templates:read',
|
|
378
|
+
})
|
|
379
|
+
|
|
380
|
+
protected override async run(): Promise<number | undefined> {
|
|
381
|
+
const credentialsResult = requireEnvCredentials()
|
|
382
|
+
if (!credentialsResult.ok) {
|
|
383
|
+
this.output.error(credentialsResult.error)
|
|
384
|
+
return 1
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const result = await mintBearerTokenWithCredentials(credentialsResult.credentials, {
|
|
388
|
+
endpoint: this.endpoint,
|
|
389
|
+
aud: this.aud,
|
|
390
|
+
scope: this.scope,
|
|
391
|
+
})
|
|
392
|
+
|
|
393
|
+
if (result.ok) {
|
|
394
|
+
process.stdout.write(`${result.raw}\n`)
|
|
395
|
+
return undefined
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
this.output.error(result.error)
|
|
399
|
+
return 1
|
|
400
|
+
}
|
|
401
|
+
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
AssembliesReplayCommand,
|
|
12
12
|
} from './assemblies.ts'
|
|
13
13
|
|
|
14
|
-
import { SignatureCommand, SmartCdnSignatureCommand } from './auth.ts'
|
|
14
|
+
import { SignatureCommand, SmartCdnSignatureCommand, TokenCommand } from './auth.ts'
|
|
15
15
|
|
|
16
16
|
import { BillsGetCommand } from './bills.ts'
|
|
17
17
|
import { DocsRobotsGetCommand, DocsRobotsListCommand } from './docs.ts'
|
|
@@ -40,6 +40,7 @@ export function createCli(): Cli {
|
|
|
40
40
|
// Auth commands (signature generation)
|
|
41
41
|
cli.register(SignatureCommand)
|
|
42
42
|
cli.register(SmartCdnSignatureCommand)
|
|
43
|
+
cli.register(TokenCommand)
|
|
43
44
|
|
|
44
45
|
// Assemblies commands
|
|
45
46
|
cli.register(AssembliesCreateCommand)
|
package/src/cli/helpers.ts
CHANGED
|
@@ -3,7 +3,12 @@ import fsp from 'node:fs/promises'
|
|
|
3
3
|
import type { Readable } from 'node:stream'
|
|
4
4
|
import { isAPIError } from './types.ts'
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const MISSING_CREDENTIALS_MESSAGE =
|
|
7
|
+
'Missing credentials. Please set TRANSLOADIT_KEY and TRANSLOADIT_SECRET environment variables.'
|
|
8
|
+
|
|
9
|
+
type EnvCredentials = { authKey: string; authSecret: string }
|
|
10
|
+
|
|
11
|
+
function getEnvCredentials(): { authKey: string; authSecret: string } | null {
|
|
7
12
|
const authKey = process.env.TRANSLOADIT_KEY ?? process.env.TRANSLOADIT_AUTH_KEY
|
|
8
13
|
const authSecret = process.env.TRANSLOADIT_SECRET ?? process.env.TRANSLOADIT_AUTH_SECRET
|
|
9
14
|
|
|
@@ -12,6 +17,16 @@ export function getEnvCredentials(): { authKey: string; authSecret: string } | n
|
|
|
12
17
|
return { authKey, authSecret }
|
|
13
18
|
}
|
|
14
19
|
|
|
20
|
+
type RequireEnvCredentialsResult =
|
|
21
|
+
| { ok: true; credentials: EnvCredentials }
|
|
22
|
+
| { ok: false; error: string }
|
|
23
|
+
|
|
24
|
+
export function requireEnvCredentials(): RequireEnvCredentialsResult {
|
|
25
|
+
const credentials = getEnvCredentials()
|
|
26
|
+
if (credentials == null) return { ok: false, error: MISSING_CREDENTIALS_MESSAGE }
|
|
27
|
+
return { ok: true, credentials }
|
|
28
|
+
}
|
|
29
|
+
|
|
15
30
|
export function createReadStream(file: string): Readable {
|
|
16
31
|
if (file === '-') return process.stdin
|
|
17
32
|
return fs.createReadStream(file)
|