transloadit 4.0.3 → 4.0.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/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  You may also want to refer to [GitHub releases](https://github.com/transloadit/node-sdk/releases).
4
4
 
5
+ ## v4.0.3
6
+
7
+ Released: 2025-10-16.
8
+
9
+ [Diff](https://github.com/transloadit/node-sdk/compare/v4.0.2...v4.0.3).
10
+
11
+ - [x] Fix `smart_sig` CLI to always override embedded credentials with the env-provided auth key while preserving other auth fields.
12
+ - [x] Ensure the CLI entrypoint executes when invoked through npm/yarn bin shims by resolving symlinks before bootstrapping.
13
+ - [x] Harden validation and tests around CLI invocation paths.
14
+
15
+ ## v4.0.2
16
+
17
+ Released: 2025-10-15.
18
+
19
+ [Diff](https://github.com/transloadit/node-sdk/compare/v4.0.1...v4.0.2).
20
+
21
+ - [x] Add `smart_sig` CLI command (usable via `npx transloadit smart_sig`) for signing params fed through stdin.
22
+ - [x] Document the CLI workflow and expose the binary via package metadata.
23
+ - [x] Validate CLI input with existing zod schemas and cover the flow with unit tests.
24
+
5
25
  ## v4.0.1
6
26
 
7
27
  Released: 2025-09-18.
package/README.md CHANGED
@@ -385,6 +385,17 @@ Calculates a signature for the given `params` JSON object. If the `params` objec
385
385
 
386
386
  This function returns an object with the key `signature` (containing the calculated signature string) and a key `params`, which contains the stringified version of the passed `params` object (including the set expires and authKey keys).
387
387
 
388
+ #### CLI smart_sig
389
+
390
+ Generate a signature from the command line without writing any JavaScript. The CLI reads a JSON object from stdin, injects credentials from `TRANSLOADIT_KEY`/`TRANSLOADIT_SECRET`, and prints the payload returned by `calcSignature()`.
391
+
392
+ ```sh
393
+ TRANSLOADIT_KEY=... TRANSLOADIT_SECRET=... \
394
+ printf '{"assembly_id":"12345"}' | npx transloadit smart_sig
395
+ ```
396
+
397
+ You can also use `TRANSLOADIT_AUTH_KEY`/`TRANSLOADIT_AUTH_SECRET` as aliases for the environment variables.
398
+
388
399
  #### getSignedSmartCDNUrl(params)
389
400
 
390
401
  Constructs a signed Smart CDN URL, as defined in the [API documentation](https://transloadit.com/docs/topics/signature-authentication/#smart-cdn). `params` must be an object with the following properties:
package/dist/cli.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ export declare function readStdin(): Promise<string>;
3
+ export declare function runSmartSig(providedInput?: string): Promise<void>;
4
+ export declare function main(args?: string[]): Promise<void>;
5
+ export declare function shouldRunCli(invoked?: string): boolean;
6
+ export declare function runCliWhenExecuted(): void;
7
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAcA,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAWjD;AAqBD,wBAAsB,WAAW,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDvE;AAED,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BtE;AAaD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAItD;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC"}
package/dist/cli.js ADDED
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env node
2
+ import { realpathSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import process from 'node:process';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { assemblyAuthInstructionsSchema, assemblyInstructionsSchema, } from "./alphalib/types/template.js";
7
+ import { Transloadit } from "./Transloadit.js";
8
+ export async function readStdin() {
9
+ if (process.stdin.isTTY)
10
+ return '';
11
+ process.stdin.setEncoding('utf8');
12
+ let data = '';
13
+ for await (const chunk of process.stdin) {
14
+ data += chunk;
15
+ }
16
+ return data;
17
+ }
18
+ function fail(message) {
19
+ console.error(message);
20
+ process.exitCode = 1;
21
+ }
22
+ const cliParamsSchema = assemblyInstructionsSchema
23
+ .extend({ auth: assemblyAuthInstructionsSchema.partial().optional() })
24
+ .partial()
25
+ .passthrough();
26
+ function formatIssues(issues) {
27
+ return issues
28
+ .map((issue) => {
29
+ const path = issue.path.join('.') || '(root)';
30
+ return `${path}: ${issue.message}`;
31
+ })
32
+ .join('; ');
33
+ }
34
+ export async function runSmartSig(providedInput) {
35
+ const authKey = process.env.TRANSLOADIT_KEY || process.env.TRANSLOADIT_AUTH_KEY;
36
+ const authSecret = process.env.TRANSLOADIT_SECRET || process.env.TRANSLOADIT_AUTH_SECRET;
37
+ if (!authKey || !authSecret) {
38
+ fail('Missing credentials. Please set TRANSLOADIT_KEY and TRANSLOADIT_SECRET environment variables.');
39
+ return;
40
+ }
41
+ const rawInput = providedInput ?? (await readStdin());
42
+ const input = rawInput.trim();
43
+ let params = {};
44
+ if (input !== '') {
45
+ try {
46
+ const parsed = JSON.parse(input);
47
+ if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
48
+ fail('Invalid params provided via stdin. Expected a JSON object.');
49
+ return;
50
+ }
51
+ const parsedResult = cliParamsSchema.safeParse(parsed);
52
+ if (!parsedResult.success) {
53
+ fail(`Invalid params: ${formatIssues(parsedResult.error.issues)}`);
54
+ return;
55
+ }
56
+ const parsedParams = parsedResult.data;
57
+ const existingAuth = typeof parsedParams.auth === 'object' &&
58
+ parsedParams.auth != null &&
59
+ !Array.isArray(parsedParams.auth)
60
+ ? parsedParams.auth
61
+ : {};
62
+ params = {
63
+ ...parsedParams,
64
+ auth: {
65
+ ...existingAuth,
66
+ key: authKey,
67
+ },
68
+ };
69
+ }
70
+ catch (error) {
71
+ fail(`Failed to parse JSON from stdin: ${error.message}`);
72
+ return;
73
+ }
74
+ }
75
+ const client = new Transloadit({ authKey, authSecret });
76
+ const signature = client.calcSignature(params);
77
+ process.stdout.write(`${JSON.stringify(signature)}\n`);
78
+ }
79
+ export async function main(args = process.argv.slice(2)) {
80
+ const [command] = args;
81
+ switch (command) {
82
+ case 'smart_sig': {
83
+ await runSmartSig();
84
+ break;
85
+ }
86
+ case '-h':
87
+ case '--help':
88
+ case undefined: {
89
+ process.stdout.write([
90
+ 'Usage:',
91
+ ' npx transloadit smart_sig Read params JSON from stdin and output signed payload.',
92
+ '',
93
+ 'Environment variables:',
94
+ ' TRANSLOADIT_KEY, TRANSLOADIT_SECRET',
95
+ ].join('\n'));
96
+ if (command === undefined)
97
+ process.exitCode = 1;
98
+ break;
99
+ }
100
+ default: {
101
+ fail(`Unknown command: ${command}`);
102
+ }
103
+ }
104
+ }
105
+ const currentFile = realpathSync(fileURLToPath(import.meta.url));
106
+ function resolveInvokedPath(invoked) {
107
+ if (invoked == null)
108
+ return null;
109
+ try {
110
+ return realpathSync(invoked);
111
+ }
112
+ catch {
113
+ return path.resolve(invoked);
114
+ }
115
+ }
116
+ export function shouldRunCli(invoked) {
117
+ const resolved = resolveInvokedPath(invoked);
118
+ if (resolved == null)
119
+ return false;
120
+ return resolved === currentFile;
121
+ }
122
+ export function runCliWhenExecuted() {
123
+ if (!shouldRunCli(process.argv[1]))
124
+ return;
125
+ void main().catch((error) => {
126
+ fail(error.message);
127
+ });
128
+ }
129
+ runCliWhenExecuted();
130
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "transloadit",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
4
4
  "description": "Node.js SDK for Transloadit",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -76,5 +76,6 @@
76
76
  "files": [
77
77
  "dist",
78
78
  "src"
79
- ]
79
+ ],
80
+ "bin": "./dist/cli.js"
80
81
  }
package/src/cli.ts ADDED
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { realpathSync } from 'node:fs'
4
+ import path from 'node:path'
5
+ import process from 'node:process'
6
+ import { fileURLToPath } from 'node:url'
7
+ import type { ZodIssue } from 'zod'
8
+ import {
9
+ assemblyAuthInstructionsSchema,
10
+ assemblyInstructionsSchema,
11
+ } from './alphalib/types/template.ts'
12
+ import type { OptionalAuthParams } from './apiTypes.ts'
13
+ import { Transloadit } from './Transloadit.ts'
14
+
15
+ export async function readStdin(): Promise<string> {
16
+ if (process.stdin.isTTY) return ''
17
+
18
+ process.stdin.setEncoding('utf8')
19
+ let data = ''
20
+
21
+ for await (const chunk of process.stdin) {
22
+ data += chunk
23
+ }
24
+
25
+ return data
26
+ }
27
+
28
+ function fail(message: string): void {
29
+ console.error(message)
30
+ process.exitCode = 1
31
+ }
32
+
33
+ const cliParamsSchema = assemblyInstructionsSchema
34
+ .extend({ auth: assemblyAuthInstructionsSchema.partial().optional() })
35
+ .partial()
36
+ .passthrough()
37
+
38
+ function formatIssues(issues: ZodIssue[]): string {
39
+ return issues
40
+ .map((issue) => {
41
+ const path = issue.path.join('.') || '(root)'
42
+ return `${path}: ${issue.message}`
43
+ })
44
+ .join('; ')
45
+ }
46
+
47
+ export async function runSmartSig(providedInput?: string): Promise<void> {
48
+ const authKey = process.env.TRANSLOADIT_KEY || process.env.TRANSLOADIT_AUTH_KEY
49
+ const authSecret = process.env.TRANSLOADIT_SECRET || process.env.TRANSLOADIT_AUTH_SECRET
50
+
51
+ if (!authKey || !authSecret) {
52
+ fail(
53
+ 'Missing credentials. Please set TRANSLOADIT_KEY and TRANSLOADIT_SECRET environment variables.',
54
+ )
55
+ return
56
+ }
57
+
58
+ const rawInput = providedInput ?? (await readStdin())
59
+ const input = rawInput.trim()
60
+ let params: Record<string, unknown> = {}
61
+
62
+ if (input !== '') {
63
+ try {
64
+ const parsed = JSON.parse(input)
65
+ if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
66
+ fail('Invalid params provided via stdin. Expected a JSON object.')
67
+ return
68
+ }
69
+
70
+ const parsedResult = cliParamsSchema.safeParse(parsed)
71
+ if (!parsedResult.success) {
72
+ fail(`Invalid params: ${formatIssues(parsedResult.error.issues)}`)
73
+ return
74
+ }
75
+
76
+ const parsedParams = parsedResult.data as Record<string, unknown>
77
+ const existingAuth =
78
+ typeof parsedParams.auth === 'object' &&
79
+ parsedParams.auth != null &&
80
+ !Array.isArray(parsedParams.auth)
81
+ ? (parsedParams.auth as Record<string, unknown>)
82
+ : {}
83
+
84
+ params = {
85
+ ...parsedParams,
86
+ auth: {
87
+ ...existingAuth,
88
+ key: authKey,
89
+ },
90
+ }
91
+ } catch (error: unknown) {
92
+ fail(`Failed to parse JSON from stdin: ${(error as Error).message}`)
93
+ return
94
+ }
95
+ }
96
+
97
+ const client = new Transloadit({ authKey, authSecret })
98
+ const signature = client.calcSignature(params as OptionalAuthParams)
99
+ process.stdout.write(`${JSON.stringify(signature)}\n`)
100
+ }
101
+
102
+ export async function main(args = process.argv.slice(2)): Promise<void> {
103
+ const [command] = args
104
+
105
+ switch (command) {
106
+ case 'smart_sig': {
107
+ await runSmartSig()
108
+ break
109
+ }
110
+
111
+ case '-h':
112
+ case '--help':
113
+ case undefined: {
114
+ process.stdout.write(
115
+ [
116
+ 'Usage:',
117
+ ' npx transloadit smart_sig Read params JSON from stdin and output signed payload.',
118
+ '',
119
+ 'Environment variables:',
120
+ ' TRANSLOADIT_KEY, TRANSLOADIT_SECRET',
121
+ ].join('\n'),
122
+ )
123
+ if (command === undefined) process.exitCode = 1
124
+ break
125
+ }
126
+
127
+ default: {
128
+ fail(`Unknown command: ${command}`)
129
+ }
130
+ }
131
+ }
132
+
133
+ const currentFile = realpathSync(fileURLToPath(import.meta.url))
134
+
135
+ function resolveInvokedPath(invoked?: string): string | null {
136
+ if (invoked == null) return null
137
+ try {
138
+ return realpathSync(invoked)
139
+ } catch {
140
+ return path.resolve(invoked)
141
+ }
142
+ }
143
+
144
+ export function shouldRunCli(invoked?: string): boolean {
145
+ const resolved = resolveInvokedPath(invoked)
146
+ if (resolved == null) return false
147
+ return resolved === currentFile
148
+ }
149
+
150
+ export function runCliWhenExecuted(): void {
151
+ if (!shouldRunCli(process.argv[1])) return
152
+
153
+ void main().catch((error) => {
154
+ fail((error as Error).message)
155
+ })
156
+ }
157
+
158
+ runCliWhenExecuted()