transloadit 4.0.7 → 4.1.2

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +200 -21
  3. package/dist/ApiError.d.ts +1 -1
  4. package/dist/ApiError.d.ts.map +1 -1
  5. package/dist/ApiError.js.map +1 -1
  6. package/dist/Transloadit.d.ts +23 -4
  7. package/dist/Transloadit.d.ts.map +1 -1
  8. package/dist/Transloadit.js +62 -28
  9. package/dist/Transloadit.js.map +1 -1
  10. package/dist/apiTypes.d.ts +1 -1
  11. package/dist/apiTypes.d.ts.map +1 -1
  12. package/dist/cli/OutputCtl.d.ts +46 -0
  13. package/dist/cli/OutputCtl.d.ts.map +1 -0
  14. package/dist/cli/OutputCtl.js +85 -0
  15. package/dist/cli/OutputCtl.js.map +1 -0
  16. package/dist/cli/commands/BaseCommand.d.ts +23 -0
  17. package/dist/cli/commands/BaseCommand.d.ts.map +1 -0
  18. package/dist/cli/commands/BaseCommand.js +52 -0
  19. package/dist/cli/commands/BaseCommand.js.map +1 -0
  20. package/dist/cli/commands/assemblies.d.ts +93 -0
  21. package/dist/cli/commands/assemblies.d.ts.map +1 -0
  22. package/dist/cli/commands/assemblies.js +1021 -0
  23. package/dist/cli/commands/assemblies.js.map +1 -0
  24. package/dist/cli/commands/auth.d.ts +28 -0
  25. package/dist/cli/commands/auth.d.ts.map +1 -0
  26. package/dist/cli/commands/auth.js +280 -0
  27. package/dist/cli/commands/auth.js.map +1 -0
  28. package/dist/cli/commands/bills.d.ts +14 -0
  29. package/dist/cli/commands/bills.d.ts.map +1 -0
  30. package/dist/cli/commands/bills.js +69 -0
  31. package/dist/cli/commands/bills.js.map +1 -0
  32. package/dist/cli/commands/index.d.ts +3 -0
  33. package/dist/cli/commands/index.d.ts.map +1 -0
  34. package/dist/cli/commands/index.js +39 -0
  35. package/dist/cli/commands/index.js.map +1 -0
  36. package/dist/cli/commands/notifications.d.ts +16 -0
  37. package/dist/cli/commands/notifications.d.ts.map +1 -0
  38. package/dist/cli/commands/notifications.js +44 -0
  39. package/dist/cli/commands/notifications.js.map +1 -0
  40. package/dist/cli/commands/templates.d.ts +81 -0
  41. package/dist/cli/commands/templates.d.ts.map +1 -0
  42. package/dist/cli/commands/templates.js +428 -0
  43. package/dist/cli/commands/templates.js.map +1 -0
  44. package/dist/cli/helpers.d.ts +13 -0
  45. package/dist/cli/helpers.d.ts.map +1 -0
  46. package/dist/cli/helpers.js +39 -0
  47. package/dist/cli/helpers.js.map +1 -0
  48. package/dist/cli/template-last-modified.d.ts +10 -0
  49. package/dist/cli/template-last-modified.d.ts.map +1 -0
  50. package/dist/cli/template-last-modified.js +134 -0
  51. package/dist/cli/template-last-modified.js.map +1 -0
  52. package/dist/cli/types.d.ts +152 -0
  53. package/dist/cli/types.d.ts.map +1 -0
  54. package/dist/cli/types.js +64 -0
  55. package/dist/cli/types.js.map +1 -0
  56. package/dist/cli.d.ts +2 -12
  57. package/dist/cli.d.ts.map +1 -1
  58. package/dist/cli.js +11 -256
  59. package/dist/cli.js.map +1 -1
  60. package/dist/tus.d.ts +2 -1
  61. package/dist/tus.d.ts.map +1 -1
  62. package/dist/tus.js +33 -5
  63. package/dist/tus.js.map +1 -1
  64. package/package.json +12 -7
  65. package/src/ApiError.ts +2 -1
  66. package/src/Transloadit.ts +98 -39
  67. package/src/apiTypes.ts +1 -1
  68. package/src/cli/OutputCtl.ts +115 -0
  69. package/src/cli/commands/BaseCommand.ts +71 -0
  70. package/src/cli/commands/assemblies.ts +1373 -0
  71. package/src/cli/commands/auth.ts +354 -0
  72. package/src/cli/commands/bills.ts +91 -0
  73. package/src/cli/commands/index.ts +65 -0
  74. package/src/cli/commands/notifications.ts +63 -0
  75. package/src/cli/commands/templates.ts +556 -0
  76. package/src/cli/helpers.ts +50 -0
  77. package/src/cli/template-last-modified.ts +156 -0
  78. package/src/cli/types.ts +183 -0
  79. package/src/cli.ts +12 -305
  80. package/src/tus.ts +37 -5
@@ -0,0 +1,156 @@
1
+ import type { Transloadit } from '../Transloadit.ts'
2
+ import { ensureError } from './types.ts'
3
+
4
+ interface TemplateItem {
5
+ id: string
6
+ modified: string
7
+ }
8
+
9
+ type FetchCallback<T> = (err: Error | null, result?: T) => void
10
+ type PageFetcher<T> = (page: number, pagesize: number, cb: FetchCallback<T[]>) => void
11
+
12
+ class MemoizedPagination<T> {
13
+ private pagesize: number
14
+ private fetch: PageFetcher<T>
15
+ private cache: (T | undefined)[]
16
+
17
+ constructor(pagesize: number, fetch: PageFetcher<T>) {
18
+ this.pagesize = pagesize
19
+ this.fetch = fetch
20
+ this.cache = []
21
+ }
22
+
23
+ get(i: number, cb: FetchCallback<T>): void {
24
+ const cached = this.cache[i]
25
+ if (cached !== undefined) {
26
+ process.nextTick(() => cb(null, cached))
27
+ return
28
+ }
29
+
30
+ const page = Math.floor(i / this.pagesize) + 1
31
+ const start = (page - 1) * this.pagesize
32
+
33
+ this.fetch(page, this.pagesize, (err, result) => {
34
+ if (err) {
35
+ cb(err)
36
+ return
37
+ }
38
+ if (!result) {
39
+ cb(new Error('No result returned from fetch'))
40
+ return
41
+ }
42
+ for (let j = 0; j < this.pagesize; j++) {
43
+ this.cache[start + j] = result[j]
44
+ }
45
+ cb(null, this.cache[i])
46
+ })
47
+ }
48
+ }
49
+
50
+ export default class ModifiedLookup {
51
+ private byOrdinal: MemoizedPagination<TemplateItem>
52
+
53
+ constructor(client: Transloadit, pagesize = 50) {
54
+ this.byOrdinal = new MemoizedPagination<TemplateItem>(pagesize, (page, pagesize, cb) => {
55
+ const params = {
56
+ sort: 'id' as const,
57
+ order: 'asc' as const,
58
+ fields: ['id', 'modified'] as ('id' | 'modified')[],
59
+ page,
60
+ pagesize,
61
+ }
62
+
63
+ client
64
+ .listTemplates(params)
65
+ .then((result) => {
66
+ const items: TemplateItem[] = new Array(pagesize)
67
+ // Fill with sentinel value larger than any hex ID
68
+ items.fill({ id: 'gggggggggggggggggggggggggggggggg', modified: '' })
69
+ for (let i = 0; i < result.items.length; i++) {
70
+ const item = result.items[i]
71
+ if (item) {
72
+ items[i] = { id: item.id, modified: item.modified }
73
+ }
74
+ }
75
+ cb(null, items)
76
+ })
77
+ .catch((err: unknown) => {
78
+ cb(ensureError(err))
79
+ })
80
+ })
81
+ }
82
+
83
+ private idByOrd(ord: number, cb: FetchCallback<string>): void {
84
+ this.byOrdinal.get(ord, (err, result) => {
85
+ if (err) {
86
+ cb(err)
87
+ return
88
+ }
89
+ if (!result) {
90
+ cb(new Error('No result found'))
91
+ return
92
+ }
93
+ cb(null, result.id)
94
+ })
95
+ }
96
+
97
+ byId(id: string, cb: FetchCallback<Date>): void {
98
+ const findUpperBound = (bound: number): void => {
99
+ this.idByOrd(bound, (err, idAtBound) => {
100
+ if (err) {
101
+ cb(err)
102
+ return
103
+ }
104
+ if (idAtBound === id) {
105
+ complete(bound)
106
+ return
107
+ }
108
+ if (idAtBound && idAtBound > id) {
109
+ refine(Math.floor(bound / 2), bound)
110
+ return
111
+ }
112
+ findUpperBound(bound * 2)
113
+ })
114
+ }
115
+
116
+ const refine = (lower: number, upper: number): void => {
117
+ if (lower >= upper - 1) {
118
+ cb(new Error(`Template ID ${id} not found in ModifiedLookup`))
119
+ return
120
+ }
121
+
122
+ const middle = Math.floor((lower + upper) / 2)
123
+ this.idByOrd(middle, (err, idAtMiddle) => {
124
+ if (err) {
125
+ cb(err)
126
+ return
127
+ }
128
+ if (idAtMiddle === id) {
129
+ complete(middle)
130
+ return
131
+ }
132
+ if (idAtMiddle && idAtMiddle < id) {
133
+ refine(middle, upper)
134
+ return
135
+ }
136
+ refine(lower, middle)
137
+ })
138
+ }
139
+
140
+ const complete = (ord: number): void => {
141
+ this.byOrdinal.get(ord, (err, result) => {
142
+ if (err) {
143
+ cb(err)
144
+ return
145
+ }
146
+ if (!result) {
147
+ cb(new Error('No result found'))
148
+ return
149
+ }
150
+ cb(null, new Date(result.modified))
151
+ })
152
+ }
153
+
154
+ findUpperBound(1)
155
+ }
156
+ }
@@ -0,0 +1,183 @@
1
+ import { z } from 'zod'
2
+ import type { Steps } from '../alphalib/types/template.ts'
3
+ import { optionalStepsSchema } from '../alphalib/types/template.ts'
4
+ import type { BillResponse, ListedTemplate, TemplateResponse } from '../apiTypes.ts'
5
+ import type { AssemblyStatus, Transloadit } from '../Transloadit.ts'
6
+ import type { IOutputCtl } from './OutputCtl.ts'
7
+
8
+ // Re-export transloadit types for CLI use
9
+ export type { AssemblyStatus, BillResponse, ListedTemplate, TemplateResponse }
10
+ export type { Transloadit }
11
+ export type { CreateAssemblyOptions } from '../Transloadit.ts'
12
+
13
+ // Zod schemas for runtime validation
14
+ export const APIErrorSchema = z.object({
15
+ error: z.string(),
16
+ message: z.string(),
17
+ })
18
+ export type APIError = z.infer<typeof APIErrorSchema>
19
+
20
+ export const TransloaditAPIErrorSchema = z.object({
21
+ error: z.string().optional(),
22
+ message: z.string(),
23
+ code: z.string().optional(),
24
+ transloaditErrorCode: z.string().optional(),
25
+ response: z
26
+ .object({
27
+ body: z
28
+ .object({
29
+ error: z.string().optional(),
30
+ })
31
+ .optional(),
32
+ statusCode: z.number().optional(),
33
+ })
34
+ .optional(),
35
+ })
36
+ export type TransloaditAPIError = z.infer<typeof TransloaditAPIErrorSchema>
37
+
38
+ // Template file data - explicit type to avoid TS inference limits
39
+ export interface TemplateFileData {
40
+ transloadit_template_id?: string
41
+ steps?: Steps
42
+ [key: string]: unknown // passthrough
43
+ }
44
+
45
+ export const TemplateFileDataSchema: z.ZodType<TemplateFileData> = z
46
+ .object({
47
+ transloadit_template_id: z.string().optional(),
48
+ steps: optionalStepsSchema,
49
+ })
50
+ .passthrough() as z.ZodType<TemplateFileData>
51
+
52
+ export interface TemplateFile {
53
+ file: string
54
+ data: TemplateFileData
55
+ }
56
+
57
+ // Template list item (from API)
58
+ export interface TemplateListItem {
59
+ id: string
60
+ modified: string
61
+ name?: string
62
+ }
63
+
64
+ // CLI Invocation types
65
+ export interface BaseInvocation {
66
+ error?: boolean
67
+ message?: string
68
+ mode: string
69
+ action?: string
70
+ logLevel?: number
71
+ jsonMode?: boolean
72
+ }
73
+
74
+ export interface AssemblyInvocation extends BaseInvocation {
75
+ mode: 'assemblies'
76
+ action?: 'create' | 'get' | 'list' | 'delete' | 'replay'
77
+ inputs: string[]
78
+ output?: string
79
+ recursive?: boolean
80
+ watch?: boolean
81
+ del?: boolean
82
+ reprocessStale?: boolean
83
+ steps?: string
84
+ template?: string
85
+ fields?: Record<string, string>
86
+ assemblies?: string[]
87
+ before?: string
88
+ after?: string
89
+ keywords?: string[]
90
+ notify_url?: string
91
+ reparse?: boolean
92
+ }
93
+
94
+ export interface TemplateInvocation extends BaseInvocation {
95
+ mode: 'templates'
96
+ action?: 'create' | 'get' | 'list' | 'delete' | 'modify' | 'sync'
97
+ templates?: string[]
98
+ template?: string
99
+ name?: string
100
+ file?: string
101
+ files?: string[]
102
+ before?: string
103
+ after?: string
104
+ order?: 'asc' | 'desc'
105
+ sort?: string
106
+ fields?: string[]
107
+ recursive?: boolean
108
+ }
109
+
110
+ export interface BillInvocation extends BaseInvocation {
111
+ mode: 'bills'
112
+ action?: 'get'
113
+ months: string[]
114
+ }
115
+
116
+ export interface NotificationInvocation extends BaseInvocation {
117
+ mode: 'assembly-notifications'
118
+ action?: 'list' | 'replay'
119
+ assemblies?: string[]
120
+ notify_url?: string
121
+ type?: string
122
+ assembly_id?: string
123
+ pagesize?: number
124
+ }
125
+
126
+ export interface HelpInvocation extends BaseInvocation {
127
+ mode: 'help' | 'version' | 'register'
128
+ }
129
+
130
+ export type Invocation =
131
+ | AssemblyInvocation
132
+ | TemplateInvocation
133
+ | BillInvocation
134
+ | NotificationInvocation
135
+ | HelpInvocation
136
+
137
+ // Command handler type
138
+ export type CommandHandler<T extends BaseInvocation = BaseInvocation> = (
139
+ output: IOutputCtl,
140
+ client: Transloadit | undefined,
141
+ invocation: T,
142
+ ) => void | Promise<void>
143
+
144
+ // Type guard for Error
145
+ export function isError(value: unknown): value is Error {
146
+ return value instanceof Error
147
+ }
148
+
149
+ // Helper to ensure error is Error type
150
+ export function ensureError(value: unknown): Error {
151
+ if (value instanceof Error) {
152
+ return value
153
+ }
154
+ return new Error(`Non-error was thrown: ${String(value)}`)
155
+ }
156
+
157
+ // Type guard for APIError
158
+ export function isAPIError(value: unknown): value is APIError {
159
+ return APIErrorSchema.safeParse(value).success
160
+ }
161
+
162
+ // Type guard for TransloaditAPIError
163
+ export function isTransloaditAPIError(value: unknown): value is TransloaditAPIError {
164
+ return TransloaditAPIErrorSchema.safeParse(value).success
165
+ }
166
+
167
+ // Type guard for NodeJS.ErrnoException
168
+ export function isErrnoException(value: unknown): value is NodeJS.ErrnoException {
169
+ return value instanceof Error && 'code' in value
170
+ }
171
+
172
+ // Safe array access helper
173
+ export function safeGet<T>(arr: T[], index: number): T | undefined {
174
+ return arr[index]
175
+ }
176
+
177
+ // Assert defined helper
178
+ export function assertDefined<T>(value: T | undefined | null, message: string): T {
179
+ if (value === undefined || value === null) {
180
+ throw new Error(message)
181
+ }
182
+ return value
183
+ }
package/src/cli.ts CHANGED
@@ -4,310 +4,8 @@ import { realpathSync } from 'node:fs'
4
4
  import path from 'node:path'
5
5
  import process from 'node:process'
6
6
  import { fileURLToPath } from 'node:url'
7
- import { type ZodIssue, z } 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
- type UrlParamPrimitive = string | number | boolean
16
- type UrlParamArray = UrlParamPrimitive[]
17
- type NormalizedUrlParams = Record<string, UrlParamPrimitive | UrlParamArray>
18
-
19
- interface RunSigOptions {
20
- providedInput?: string
21
- algorithm?: string
22
- }
23
-
24
- interface RunSmartSigOptions {
25
- providedInput?: string
26
- }
27
-
28
- const smartCdnParamsSchema = z
29
- .object({
30
- workspace: z.string().min(1, 'workspace is required'),
31
- template: z.string().min(1, 'template is required'),
32
- input: z.union([z.string(), z.number(), z.boolean()]),
33
- url_params: z.record(z.unknown()).optional(),
34
- expire_at_ms: z.union([z.number(), z.string()]).optional(),
35
- })
36
- .passthrough()
37
-
38
- const cliSignatureParamsSchema = assemblyInstructionsSchema
39
- .extend({ auth: assemblyAuthInstructionsSchema.partial().optional() })
40
- .partial()
41
- .passthrough()
42
-
43
- export async function readStdin(): Promise<string> {
44
- if (process.stdin.isTTY) return ''
45
-
46
- process.stdin.setEncoding('utf8')
47
- let data = ''
48
-
49
- for await (const chunk of process.stdin) {
50
- data += chunk
51
- }
52
-
53
- return data
54
- }
55
-
56
- function fail(message: string): void {
57
- console.error(message)
58
- process.exitCode = 1
59
- }
60
-
61
- function formatIssues(issues: ZodIssue[]): string {
62
- return issues
63
- .map((issue) => {
64
- const path = issue.path.join('.') || '(root)'
65
- return `${path}: ${issue.message}`
66
- })
67
- .join('; ')
68
- }
69
-
70
- function normalizeUrlParam(value: unknown): UrlParamPrimitive | UrlParamArray | undefined {
71
- if (value == null) return undefined
72
- if (Array.isArray(value)) {
73
- const normalized = value.filter(
74
- (item): item is UrlParamPrimitive =>
75
- typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean',
76
- )
77
- return normalized.length > 0 ? normalized : undefined
78
- }
79
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
80
- return value
81
- }
82
- return undefined
83
- }
84
-
85
- function normalizeUrlParams(params?: Record<string, unknown>): NormalizedUrlParams | undefined {
86
- if (params == null) return undefined
87
- let normalized: NormalizedUrlParams | undefined
88
- for (const [key, value] of Object.entries(params)) {
89
- const normalizedValue = normalizeUrlParam(value)
90
- if (normalizedValue === undefined) continue
91
- if (normalized == null) normalized = {}
92
- normalized[key] = normalizedValue
93
- }
94
- return normalized
95
- }
96
-
97
- function ensureCredentials(): { authKey: string; authSecret: string } | null {
98
- const authKey = process.env.TRANSLOADIT_KEY || process.env.TRANSLOADIT_AUTH_KEY
99
- const authSecret = process.env.TRANSLOADIT_SECRET || process.env.TRANSLOADIT_AUTH_SECRET
100
-
101
- if (!authKey || !authSecret) {
102
- fail(
103
- 'Missing credentials. Please set TRANSLOADIT_KEY and TRANSLOADIT_SECRET environment variables.',
104
- )
105
- return null
106
- }
107
-
108
- return { authKey, authSecret }
109
- }
110
-
111
- export async function runSig(options: RunSigOptions = {}): Promise<void> {
112
- const credentials = ensureCredentials()
113
- if (credentials == null) return
114
- const { authKey, authSecret } = credentials
115
- const { providedInput, algorithm } = options
116
-
117
- const rawInput = providedInput ?? (await readStdin())
118
- const input = rawInput.trim()
119
- let params: Record<string, unknown>
120
-
121
- if (input === '') {
122
- params = { auth: { key: authKey } }
123
- } else {
124
- let parsed: unknown
125
- try {
126
- parsed = JSON.parse(input)
127
- } catch (error) {
128
- fail(`Failed to parse JSON from stdin: ${(error as Error).message}`)
129
- return
130
- }
131
-
132
- if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
133
- fail('Invalid params provided via stdin. Expected a JSON object.')
134
- return
135
- }
136
-
137
- const parsedResult = cliSignatureParamsSchema.safeParse(parsed)
138
- if (!parsedResult.success) {
139
- fail(`Invalid params: ${formatIssues(parsedResult.error.issues)}`)
140
- return
141
- }
142
-
143
- const parsedParams = parsedResult.data as Record<string, unknown>
144
- const existingAuth =
145
- typeof parsedParams.auth === 'object' &&
146
- parsedParams.auth != null &&
147
- !Array.isArray(parsedParams.auth)
148
- ? (parsedParams.auth as Record<string, unknown>)
149
- : {}
150
-
151
- params = {
152
- ...parsedParams,
153
- auth: {
154
- ...existingAuth,
155
- key: authKey,
156
- },
157
- }
158
- }
159
-
160
- const client = new Transloadit({ authKey, authSecret })
161
- try {
162
- const signature = client.calcSignature(params as OptionalAuthParams, algorithm)
163
- process.stdout.write(`${JSON.stringify(signature)}\n`)
164
- } catch (error) {
165
- fail(`Failed to generate signature: ${(error as Error).message}`)
166
- }
167
- }
168
-
169
- export async function runSmartSig(options: RunSmartSigOptions = {}): Promise<void> {
170
- const credentials = ensureCredentials()
171
- if (credentials == null) return
172
- const { authKey, authSecret } = credentials
173
-
174
- const rawInput = options.providedInput ?? (await readStdin())
175
- const input = rawInput.trim()
176
- if (input === '') {
177
- fail(
178
- 'Missing params provided via stdin. Expected a JSON object with workspace, template, input, and optional Smart CDN parameters.',
179
- )
180
- return
181
- }
182
-
183
- let parsed: unknown
184
- try {
185
- parsed = JSON.parse(input)
186
- } catch (error) {
187
- fail(`Failed to parse JSON from stdin: ${(error as Error).message}`)
188
- return
189
- }
190
-
191
- if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
192
- fail('Invalid params provided via stdin. Expected a JSON object.')
193
- return
194
- }
195
-
196
- const parsedResult = smartCdnParamsSchema.safeParse(parsed)
197
- if (!parsedResult.success) {
198
- fail(`Invalid params: ${formatIssues(parsedResult.error.issues)}`)
199
- return
200
- }
201
-
202
- const { workspace, template, input: inputFieldRaw, url_params, expire_at_ms } = parsedResult.data
203
- const urlParams = normalizeUrlParams(url_params as Record<string, unknown> | undefined)
204
-
205
- let expiresAt: number | undefined
206
- if (typeof expire_at_ms === 'string') {
207
- const parsedNumber = Number.parseInt(expire_at_ms, 10)
208
- if (Number.isNaN(parsedNumber)) {
209
- fail('Invalid params: expire_at_ms must be a number.')
210
- return
211
- }
212
- expiresAt = parsedNumber
213
- } else {
214
- expiresAt = expire_at_ms
215
- }
216
-
217
- const inputField = typeof inputFieldRaw === 'string' ? inputFieldRaw : String(inputFieldRaw)
218
-
219
- const client = new Transloadit({ authKey, authSecret })
220
- try {
221
- const signedUrl = client.getSignedSmartCDNUrl({
222
- workspace,
223
- template,
224
- input: inputField,
225
- urlParams,
226
- expiresAt,
227
- })
228
- process.stdout.write(`${signedUrl}\n`)
229
- } catch (error) {
230
- fail(`Failed to generate Smart CDN URL: ${(error as Error).message}`)
231
- }
232
- }
233
-
234
- function parseSigArguments(args: string[]): { algorithm?: string } {
235
- let algorithm: string | undefined
236
- let index = 0
237
- while (index < args.length) {
238
- const arg = args[index]
239
- if (arg === '--algorithm' || arg === '-a') {
240
- const next = args[index + 1]
241
- if (next == null || next.startsWith('-')) {
242
- throw new Error('Missing value for --algorithm option')
243
- }
244
- algorithm = next
245
- index += 2
246
- continue
247
- }
248
- if (arg.startsWith('--algorithm=')) {
249
- const [, value] = arg.split('=', 2)
250
- if (value === undefined || value === '') {
251
- throw new Error('Missing value for --algorithm option')
252
- }
253
- algorithm = value
254
- index += 1
255
- continue
256
- }
257
- throw new Error(`Unknown option: ${arg}`)
258
- }
259
-
260
- return { algorithm }
261
- }
262
-
263
- export async function main(args = process.argv.slice(2)): Promise<void> {
264
- const [command, ...commandArgs] = args
265
-
266
- switch (command) {
267
- case 'smart_sig': {
268
- await runSmartSig()
269
- break
270
- }
271
-
272
- case 'sig': {
273
- try {
274
- const { algorithm } = parseSigArguments(commandArgs)
275
- await runSig({ algorithm })
276
- } catch (error) {
277
- fail((error as Error).message)
278
- }
279
- break
280
- }
281
-
282
- case '-h':
283
- case '--help':
284
- case undefined: {
285
- process.stdout.write(
286
- [
287
- 'Usage:',
288
- ' npx transloadit smart_sig Read Smart CDN params JSON from stdin and output a signed URL.',
289
- ' npx transloadit sig [--algorithm <name>] Read params JSON from stdin and output signed payload JSON.',
290
- '',
291
- 'Required JSON fields:',
292
- ' smart_sig: workspace, template, input',
293
- ' sig: none (object is optional)',
294
- 'Optional JSON fields:',
295
- ' smart_sig: expire_at_ms, url_params',
296
- ' sig: auth.expires and any supported assembly params',
297
- '',
298
- 'Environment variables:',
299
- ' TRANSLOADIT_KEY, TRANSLOADIT_SECRET',
300
- ].join('\n'),
301
- )
302
- if (command === undefined) process.exitCode = 1
303
- break
304
- }
305
-
306
- default: {
307
- fail(`Unknown command: ${command}`)
308
- }
309
- }
310
- }
7
+ import 'dotenv/config'
8
+ import { createCli } from './cli/commands/index.ts'
311
9
 
312
10
  const currentFile = realpathSync(fileURLToPath(import.meta.url))
313
11
 
@@ -326,11 +24,20 @@ export function shouldRunCli(invoked?: string): boolean {
326
24
  return resolved === currentFile
327
25
  }
328
26
 
27
+ export async function main(args = process.argv.slice(2)): Promise<void> {
28
+ const cli = createCli()
29
+ const exitCode = await cli.run(args)
30
+ if (exitCode !== 0) {
31
+ process.exitCode = exitCode
32
+ }
33
+ }
34
+
329
35
  export function runCliWhenExecuted(): void {
330
36
  if (!shouldRunCli(process.argv[1])) return
331
37
 
332
38
  void main().catch((error) => {
333
- fail((error as Error).message)
39
+ console.error((error as Error).message)
40
+ process.exitCode = 1
334
41
  })
335
42
  }
336
43