@transloadit/node 4.5.1 → 4.7.0

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 (51) hide show
  1. package/dist/Transloadit.d.ts +1 -1
  2. package/dist/Transloadit.d.ts.map +1 -1
  3. package/dist/Transloadit.js +1 -1
  4. package/dist/Transloadit.js.map +1 -1
  5. package/dist/alphalib/mcache.d.ts.map +1 -1
  6. package/dist/alphalib/mcache.js +4 -2
  7. package/dist/alphalib/mcache.js.map +1 -1
  8. package/dist/alphalib/types/assemblyReplay.d.ts +2 -0
  9. package/dist/alphalib/types/assemblyReplay.d.ts.map +1 -1
  10. package/dist/alphalib/types/assemblyReplayNotification.d.ts +2 -0
  11. package/dist/alphalib/types/assemblyReplayNotification.d.ts.map +1 -1
  12. package/dist/alphalib/types/assemblyStatus.d.ts +20 -20
  13. package/dist/alphalib/types/assemblyStatus.d.ts.map +1 -1
  14. package/dist/alphalib/types/assemblyStatus.js +13 -1
  15. package/dist/alphalib/types/assemblyStatus.js.map +1 -1
  16. package/dist/alphalib/types/robots/_index.d.ts +20 -0
  17. package/dist/alphalib/types/robots/_index.d.ts.map +1 -1
  18. package/dist/alphalib/types/robots/ai-chat.d.ts +20 -0
  19. package/dist/alphalib/types/robots/ai-chat.d.ts.map +1 -1
  20. package/dist/alphalib/types/robots/ai-chat.js +5 -3
  21. package/dist/alphalib/types/robots/ai-chat.js.map +1 -1
  22. package/dist/alphalib/types/template.d.ts +36 -0
  23. package/dist/alphalib/types/template.d.ts.map +1 -1
  24. package/dist/cli/commands/assemblies.d.ts.map +1 -1
  25. package/dist/cli/commands/assemblies.js +109 -25
  26. package/dist/cli/commands/assemblies.js.map +1 -1
  27. package/dist/cli/commands/docs.d.ts +15 -0
  28. package/dist/cli/commands/docs.d.ts.map +1 -0
  29. package/dist/cli/commands/docs.js +58 -0
  30. package/dist/cli/commands/docs.js.map +1 -0
  31. package/dist/cli/commands/index.d.ts.map +1 -1
  32. package/dist/cli/commands/index.js +4 -0
  33. package/dist/cli/commands/index.js.map +1 -1
  34. package/dist/cli/commands/templates.d.ts +2 -0
  35. package/dist/cli/commands/templates.d.ts.map +1 -1
  36. package/dist/cli/commands/templates.js +65 -24
  37. package/dist/cli/commands/templates.js.map +1 -1
  38. package/dist/robots.d.ts +2 -1
  39. package/dist/robots.d.ts.map +1 -1
  40. package/dist/robots.js +9 -3
  41. package/dist/robots.js.map +1 -1
  42. package/package.json +2 -2
  43. package/src/Transloadit.ts +1 -1
  44. package/src/alphalib/mcache.ts +5 -3
  45. package/src/alphalib/types/assemblyStatus.ts +13 -1
  46. package/src/alphalib/types/robots/ai-chat.ts +11 -3
  47. package/src/cli/commands/assemblies.ts +131 -25
  48. package/src/cli/commands/docs.ts +68 -0
  49. package/src/cli/commands/index.ts +5 -2
  50. package/src/cli/commands/templates.ts +73 -23
  51. package/src/robots.ts +12 -4
@@ -0,0 +1,68 @@
1
+ import { Option } from 'clipanion'
2
+ import { getRobotHelp, isKnownRobot, listRobots } from '../../robots.ts'
3
+ import { UnauthenticatedCommand } from './BaseCommand.ts'
4
+
5
+ const splitRobotArgs = (values: string[]): string[] => {
6
+ const out: string[] = []
7
+ for (const value of values) {
8
+ for (const part of value.split(',')) {
9
+ const trimmed = part.trim()
10
+ if (trimmed) out.push(trimmed)
11
+ }
12
+ }
13
+ return out
14
+ }
15
+
16
+ export class DocsRobotsListCommand extends UnauthenticatedCommand {
17
+ static override paths = [['docs', 'robots', 'list']]
18
+
19
+ search = Option.String('--search', { description: 'Filter by substring match.' })
20
+ category = Option.String('--category', { description: 'Filter by category (service slug).' })
21
+ limit = Option.String('--limit', { description: 'Max results (default: 20).' })
22
+ cursor = Option.String('--cursor', { description: 'Pagination cursor.' })
23
+
24
+ protected override run(): Promise<number | undefined> {
25
+ const limitNum = this.limit ? Number.parseInt(this.limit, 10) : undefined
26
+ const result = listRobots({
27
+ search: this.search,
28
+ category: this.category,
29
+ limit: Number.isFinite(limitNum as number) ? (limitNum as number) : undefined,
30
+ cursor: this.cursor,
31
+ })
32
+
33
+ this.output.print(result.robots.map((r) => `${r.name} ${r.summary}`).join('\n'), {
34
+ robots: result.robots,
35
+ nextCursor: result.nextCursor,
36
+ })
37
+
38
+ return Promise.resolve(0)
39
+ }
40
+ }
41
+
42
+ export class DocsRobotsGetCommand extends UnauthenticatedCommand {
43
+ static override paths = [['docs', 'robots', 'get']]
44
+
45
+ robots = Option.Rest({ required: 1 })
46
+
47
+ protected override run(): Promise<number | undefined> {
48
+ const requested = splitRobotArgs(this.robots)
49
+ const robots = []
50
+ const notFound: string[] = []
51
+
52
+ for (const robotName of requested) {
53
+ if (!isKnownRobot(robotName)) {
54
+ notFound.push(robotName)
55
+ continue
56
+ }
57
+ const help = getRobotHelp({ robotName, detailLevel: 'full' })
58
+ robots.push(help)
59
+ }
60
+
61
+ this.output.print(robots.length === 1 ? robots[0] : robots, {
62
+ robots,
63
+ notFound,
64
+ })
65
+
66
+ return Promise.resolve(notFound.length > 0 ? 1 : 0)
67
+ }
68
+ }
@@ -14,9 +14,8 @@ import {
14
14
  import { SignatureCommand, SmartCdnSignatureCommand } from './auth.ts'
15
15
 
16
16
  import { BillsGetCommand } from './bills.ts'
17
-
17
+ import { DocsRobotsGetCommand, DocsRobotsListCommand } from './docs.ts'
18
18
  import { NotificationsReplayCommand } from './notifications.ts'
19
-
20
19
  import {
21
20
  TemplatesCreateCommand,
22
21
  TemplatesDeleteCommand,
@@ -67,5 +66,9 @@ export function createCli(): Cli {
67
66
  // Uploads commands
68
67
  cli.register(UploadCommand)
69
68
 
69
+ // Documentation commands (offline metadata)
70
+ cli.register(DocsRobotsListCommand)
71
+ cli.register(DocsRobotsGetCommand)
72
+
70
73
  return cli
71
74
  }
@@ -43,6 +43,8 @@ interface TemplateListOptions {
43
43
  order?: 'asc' | 'desc'
44
44
  sort?: string
45
45
  fields?: string[]
46
+ includeBuiltin?: 'all' | 'latest' | 'exclusively-all' | 'exclusively-latest'
47
+ includeContent?: boolean
46
48
  }
47
49
 
48
50
  export interface TemplateSyncOptions {
@@ -162,36 +164,61 @@ const TemplateIdSchema = z.object({
162
164
  id: z.string(),
163
165
  })
164
166
 
165
- function list(
167
+ const INCLUDE_BUILTIN_VALUES = ['all', 'latest', 'exclusively-all', 'exclusively-latest'] as const
168
+
169
+ const isIncludeBuiltinValue = (value: string): value is (typeof INCLUDE_BUILTIN_VALUES)[number] => {
170
+ return (INCLUDE_BUILTIN_VALUES as readonly string[]).includes(value)
171
+ }
172
+
173
+ async function list(
166
174
  output: IOutputCtl,
167
175
  client: Transloadit,
168
- { before, after, order, sort, fields }: TemplateListOptions,
169
- ): void {
170
- const stream = client.streamTemplates({
171
- todate: before,
172
- fromdate: after,
173
- order,
174
- sort: sort as 'id' | 'name' | 'created' | 'modified' | undefined,
175
- })
176
+ { before, after, order, sort, fields, includeBuiltin, includeContent }: TemplateListOptions,
177
+ ): Promise<void> {
178
+ // The CLI lists "all templates". Using listTemplates with pagination keeps this
179
+ // compatible with include_builtin and with "include content" (optional N+1 fetch).
180
+ const pagesize = 50
181
+ let page = 1
182
+
183
+ while (true) {
184
+ const response = await client.listTemplates({
185
+ page,
186
+ pagesize,
187
+ todate: before,
188
+ fromdate: after,
189
+ order,
190
+ sort: sort as 'id' | 'name' | 'created' | 'modified' | undefined,
191
+ include_builtin: includeBuiltin,
192
+ })
176
193
 
177
- stream.on('readable', () => {
178
- const template: unknown = stream.read()
179
- if (template == null) return
194
+ const items = response.items ?? []
195
+ if (items.length === 0) break
180
196
 
181
- const parsed = TemplateIdSchema.safeParse(template)
182
- if (!parsed.success) return
197
+ for (const item of items) {
198
+ const parsed = TemplateIdSchema.safeParse(item)
199
+ if (!parsed.success) continue
183
200
 
184
- if (fields == null) {
185
- output.print(parsed.data.id, template)
186
- } else {
187
- const templateRecord = template as Record<string, unknown>
188
- output.print(fields.map((field) => templateRecord[field]).join(' '), template)
201
+ let template: unknown = item
202
+ if (includeContent) {
203
+ try {
204
+ const full = await client.getTemplate(parsed.data.id)
205
+ template = { ...item, content: full.content }
206
+ } catch (err) {
207
+ output.error(formatAPIError(err))
208
+ }
209
+ }
210
+
211
+ if (fields == null) {
212
+ output.print(parsed.data.id, template)
213
+ } else {
214
+ const templateRecord = template as Record<string, unknown>
215
+ output.print(fields.map((field) => templateRecord[field]).join(' '), template)
216
+ }
189
217
  }
190
- })
191
218
 
192
- stream.on('error', (err: unknown) => {
193
- output.error(formatAPIError(err))
194
- })
219
+ if (items.length < pagesize) break
220
+ page += 1
221
+ }
195
222
  }
196
223
 
197
224
  export async function sync(
@@ -490,6 +517,17 @@ export class TemplatesListCommand extends AuthenticatedCommand {
490
517
  description: 'Comma-separated list of fields to return for each template',
491
518
  })
492
519
 
520
+ includeBuiltin = Option.String('--include-builtin', {
521
+ description:
522
+ `Include builtin templates: ${INCLUDE_BUILTIN_VALUES.join(', ')}. ` +
523
+ 'Omit to list only owned templates.',
524
+ })
525
+
526
+ includeContent = Option.Boolean('--include-content', false, {
527
+ description:
528
+ 'Include template steps/content in the list output (may make extra API requests per template).',
529
+ })
530
+
493
531
  protected async run(): Promise<number | undefined> {
494
532
  if (this.sort && !['id', 'name', 'created', 'modified'].includes(this.sort)) {
495
533
  this.output.error('invalid argument for --sort')
@@ -501,6 +539,16 @@ export class TemplatesListCommand extends AuthenticatedCommand {
501
539
  return 1
502
540
  }
503
541
 
542
+ const includeBuiltinRaw = this.includeBuiltin
543
+ let includeBuiltin: TemplateListOptions['includeBuiltin']
544
+ if (includeBuiltinRaw) {
545
+ if (!isIncludeBuiltinValue(includeBuiltinRaw)) {
546
+ this.output.error('invalid argument for --include-builtin')
547
+ return 1
548
+ }
549
+ includeBuiltin = includeBuiltinRaw
550
+ }
551
+
504
552
  const fieldList = this.fields ? this.fields.split(',') : undefined
505
553
 
506
554
  await list(this.output, this.client, {
@@ -509,6 +557,8 @@ export class TemplatesListCommand extends AuthenticatedCommand {
509
557
  sort: this.sort,
510
558
  order: this.order as 'asc' | 'desc' | undefined,
511
559
  fields: fieldList,
560
+ includeBuiltin,
561
+ includeContent: this.includeContent,
512
562
  })
513
563
  return undefined
514
564
  }
package/src/robots.ts CHANGED
@@ -36,7 +36,7 @@ export type RobotHelp = {
36
36
 
37
37
  export type RobotHelpOptions = {
38
38
  robotName: string
39
- detailLevel?: 'summary' | 'params' | 'examples'
39
+ detailLevel?: 'summary' | 'params' | 'examples' | 'full'
40
40
  }
41
41
 
42
42
  type RobotsMetaMap = typeof robotsMeta
@@ -299,11 +299,11 @@ export const getRobotHelp = (options: RobotHelpOptions): RobotHelp => {
299
299
  const help: RobotHelp = {
300
300
  name: path,
301
301
  summary,
302
- requiredParams: detailLevel === 'params' ? params.required : [],
303
- optionalParams: detailLevel === 'params' ? params.optional : [],
302
+ requiredParams: detailLevel === 'params' || detailLevel === 'full' ? params.required : [],
303
+ optionalParams: detailLevel === 'params' || detailLevel === 'full' ? params.optional : [],
304
304
  }
305
305
 
306
- if (detailLevel === 'examples' && meta?.example_code) {
306
+ if ((detailLevel === 'examples' || detailLevel === 'full') && meta?.example_code) {
307
307
  const snippet = isRecord(meta.example_code) ? meta.example_code : {}
308
308
  help.examples = [
309
309
  {
@@ -315,3 +315,11 @@ export const getRobotHelp = (options: RobotHelpOptions): RobotHelp => {
315
315
 
316
316
  return help
317
317
  }
318
+
319
+ export const isKnownRobot = (robotName: string): boolean => {
320
+ const { byPath, byName } = getMetaIndex()
321
+ const schemaIndex = getSchemaIndex()
322
+
323
+ const path = resolveRobotPath(robotName)
324
+ return byPath.has(path) || byName.has(robotName) || schemaIndex.has(path)
325
+ }