transloadit 4.7.3 → 4.7.6

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 (152) hide show
  1. package/README.md +897 -5
  2. package/dist/Transloadit.d.ts +13 -3
  3. package/dist/Transloadit.d.ts.map +1 -1
  4. package/dist/Transloadit.js +22 -2
  5. package/dist/Transloadit.js.map +1 -1
  6. package/dist/alphalib/types/assembliesGet.d.ts +5 -0
  7. package/dist/alphalib/types/assembliesGet.d.ts.map +1 -1
  8. package/dist/alphalib/types/assemblyReplay.d.ts +5 -0
  9. package/dist/alphalib/types/assemblyReplay.d.ts.map +1 -1
  10. package/dist/alphalib/types/assemblyReplayNotification.d.ts +5 -0
  11. package/dist/alphalib/types/assemblyReplayNotification.d.ts.map +1 -1
  12. package/dist/alphalib/types/assemblyStatus.d.ts +25 -25
  13. package/dist/alphalib/types/assemblyStatus.d.ts.map +1 -1
  14. package/dist/alphalib/types/assemblyStatus.js +4 -1
  15. package/dist/alphalib/types/assemblyStatus.js.map +1 -1
  16. package/dist/alphalib/types/bill.d.ts +5 -0
  17. package/dist/alphalib/types/bill.d.ts.map +1 -1
  18. package/dist/alphalib/types/builtinTemplates.d.ts +83 -0
  19. package/dist/alphalib/types/builtinTemplates.d.ts.map +1 -0
  20. package/dist/alphalib/types/builtinTemplates.js +19 -0
  21. package/dist/alphalib/types/builtinTemplates.js.map +1 -0
  22. package/dist/alphalib/types/robots/ai-chat.d.ts.map +1 -1
  23. package/dist/alphalib/types/robots/ai-chat.js +1 -0
  24. package/dist/alphalib/types/robots/ai-chat.js.map +1 -1
  25. package/dist/alphalib/types/skillFrontmatter.d.ts +29 -0
  26. package/dist/alphalib/types/skillFrontmatter.d.ts.map +1 -0
  27. package/dist/alphalib/types/skillFrontmatter.js +19 -0
  28. package/dist/alphalib/types/skillFrontmatter.js.map +1 -0
  29. package/dist/alphalib/types/template.d.ts +36 -0
  30. package/dist/alphalib/types/template.d.ts.map +1 -1
  31. package/dist/alphalib/types/template.js +10 -0
  32. package/dist/alphalib/types/template.js.map +1 -1
  33. package/dist/alphalib/types/templateCredential.d.ts +10 -0
  34. package/dist/alphalib/types/templateCredential.d.ts.map +1 -1
  35. package/dist/bearerToken.d.ts +31 -0
  36. package/dist/bearerToken.d.ts.map +1 -0
  37. package/dist/bearerToken.js +158 -0
  38. package/dist/bearerToken.js.map +1 -0
  39. package/dist/cli/commands/assemblies.d.ts +8 -2
  40. package/dist/cli/commands/assemblies.d.ts.map +1 -1
  41. package/dist/cli/commands/assemblies.js +566 -411
  42. package/dist/cli/commands/assemblies.js.map +1 -1
  43. package/dist/cli/commands/auth.d.ts +1 -4
  44. package/dist/cli/commands/auth.d.ts.map +1 -1
  45. package/dist/cli/commands/auth.js +7 -123
  46. package/dist/cli/commands/auth.js.map +1 -1
  47. package/dist/cli/commands/index.d.ts.map +1 -1
  48. package/dist/cli/commands/index.js +5 -0
  49. package/dist/cli/commands/index.js.map +1 -1
  50. package/dist/cli/commands/templates.d.ts.map +1 -1
  51. package/dist/cli/commands/templates.js +4 -14
  52. package/dist/cli/commands/templates.js.map +1 -1
  53. package/dist/cli/fileProcessingOptions.d.ts +35 -0
  54. package/dist/cli/fileProcessingOptions.d.ts.map +1 -0
  55. package/dist/cli/fileProcessingOptions.js +182 -0
  56. package/dist/cli/fileProcessingOptions.js.map +1 -0
  57. package/dist/cli/generateIntentDocs.d.ts +2 -0
  58. package/dist/cli/generateIntentDocs.d.ts.map +1 -0
  59. package/dist/cli/generateIntentDocs.js +321 -0
  60. package/dist/cli/generateIntentDocs.js.map +1 -0
  61. package/dist/cli/intentCommandSpecs.d.ts +36 -0
  62. package/dist/cli/intentCommandSpecs.d.ts.map +1 -0
  63. package/dist/cli/intentCommandSpecs.js +181 -0
  64. package/dist/cli/intentCommandSpecs.js.map +1 -0
  65. package/dist/cli/intentCommands.d.ts +13 -0
  66. package/dist/cli/intentCommands.d.ts.map +1 -0
  67. package/dist/cli/intentCommands.js +368 -0
  68. package/dist/cli/intentCommands.js.map +1 -0
  69. package/dist/cli/intentFields.d.ts +25 -0
  70. package/dist/cli/intentFields.d.ts.map +1 -0
  71. package/dist/cli/intentFields.js +298 -0
  72. package/dist/cli/intentFields.js.map +1 -0
  73. package/dist/cli/intentInputPolicy.d.ts +10 -0
  74. package/dist/cli/intentInputPolicy.d.ts.map +1 -0
  75. package/dist/cli/intentInputPolicy.js +2 -0
  76. package/dist/cli/intentInputPolicy.js.map +1 -0
  77. package/dist/cli/intentRuntime.d.ts +114 -0
  78. package/dist/cli/intentRuntime.d.ts.map +1 -0
  79. package/dist/cli/intentRuntime.js +464 -0
  80. package/dist/cli/intentRuntime.js.map +1 -0
  81. package/dist/cli/resultFiles.d.ts +19 -0
  82. package/dist/cli/resultFiles.d.ts.map +1 -0
  83. package/dist/cli/resultFiles.js +66 -0
  84. package/dist/cli/resultFiles.js.map +1 -0
  85. package/dist/cli/resultUrls.d.ts +19 -0
  86. package/dist/cli/resultUrls.d.ts.map +1 -0
  87. package/dist/cli/resultUrls.js +36 -0
  88. package/dist/cli/resultUrls.js.map +1 -0
  89. package/dist/cli/semanticIntents/imageDescribe.d.ts +43 -0
  90. package/dist/cli/semanticIntents/imageDescribe.d.ts.map +1 -0
  91. package/dist/cli/semanticIntents/imageDescribe.js +188 -0
  92. package/dist/cli/semanticIntents/imageDescribe.js.map +1 -0
  93. package/dist/cli/semanticIntents/index.d.ts +18 -0
  94. package/dist/cli/semanticIntents/index.d.ts.map +1 -0
  95. package/dist/cli/semanticIntents/index.js +18 -0
  96. package/dist/cli/semanticIntents/index.js.map +1 -0
  97. package/dist/cli/semanticIntents/markdownPdf.d.ts +4 -0
  98. package/dist/cli/semanticIntents/markdownPdf.d.ts.map +1 -0
  99. package/dist/cli/semanticIntents/markdownPdf.js +93 -0
  100. package/dist/cli/semanticIntents/markdownPdf.js.map +1 -0
  101. package/dist/cli/semanticIntents/parsing.d.ts +11 -0
  102. package/dist/cli/semanticIntents/parsing.d.ts.map +1 -0
  103. package/dist/cli/semanticIntents/parsing.js +29 -0
  104. package/dist/cli/semanticIntents/parsing.js.map +1 -0
  105. package/dist/cli/stepsInput.d.ts +4 -0
  106. package/dist/cli/stepsInput.d.ts.map +1 -0
  107. package/dist/cli/stepsInput.js +23 -0
  108. package/dist/cli/stepsInput.js.map +1 -0
  109. package/dist/cli.d.ts +1 -1
  110. package/dist/cli.d.ts.map +1 -1
  111. package/dist/cli.js +5 -4
  112. package/dist/cli.js.map +1 -1
  113. package/dist/ensureUniqueCounter.d.ts +8 -0
  114. package/dist/ensureUniqueCounter.d.ts.map +1 -0
  115. package/dist/ensureUniqueCounter.js +48 -0
  116. package/dist/ensureUniqueCounter.js.map +1 -0
  117. package/dist/inputFiles.d.ts +9 -0
  118. package/dist/inputFiles.d.ts.map +1 -1
  119. package/dist/inputFiles.js +177 -26
  120. package/dist/inputFiles.js.map +1 -1
  121. package/dist/robots.js +1 -1
  122. package/dist/robots.js.map +1 -1
  123. package/package.json +9 -7
  124. package/src/Transloadit.ts +35 -3
  125. package/src/alphalib/types/assemblyStatus.ts +4 -1
  126. package/src/alphalib/types/builtinTemplates.ts +24 -0
  127. package/src/alphalib/types/robots/ai-chat.ts +1 -0
  128. package/src/alphalib/types/skillFrontmatter.ts +24 -0
  129. package/src/alphalib/types/template.ts +14 -0
  130. package/src/bearerToken.ts +208 -0
  131. package/src/cli/commands/assemblies.ts +825 -505
  132. package/src/cli/commands/auth.ts +9 -151
  133. package/src/cli/commands/index.ts +6 -3
  134. package/src/cli/commands/templates.ts +6 -17
  135. package/src/cli/fileProcessingOptions.ts +294 -0
  136. package/src/cli/generateIntentDocs.ts +419 -0
  137. package/src/cli/intentCommandSpecs.ts +282 -0
  138. package/src/cli/intentCommands.ts +525 -0
  139. package/src/cli/intentFields.ts +403 -0
  140. package/src/cli/intentInputPolicy.ts +11 -0
  141. package/src/cli/intentRuntime.ts +734 -0
  142. package/src/cli/resultFiles.ts +105 -0
  143. package/src/cli/resultUrls.ts +72 -0
  144. package/src/cli/semanticIntents/imageDescribe.ts +254 -0
  145. package/src/cli/semanticIntents/index.ts +48 -0
  146. package/src/cli/semanticIntents/markdownPdf.ts +120 -0
  147. package/src/cli/semanticIntents/parsing.ts +56 -0
  148. package/src/cli/stepsInput.ts +32 -0
  149. package/src/cli.ts +5 -4
  150. package/src/ensureUniqueCounter.ts +75 -0
  151. package/src/inputFiles.ts +277 -26
  152. package/src/robots.ts +1 -1
@@ -0,0 +1,419 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises'
2
+ import { dirname } from 'node:path'
3
+ import {
4
+ getConcurrencyOptionDocumentation,
5
+ getDeleteAfterProcessingOptionDocumentation,
6
+ getInputPathsOptionDocumentation,
7
+ getPrintUrlsOptionDocumentation,
8
+ getRecursiveOptionDocumentation,
9
+ getReprocessStaleOptionDocumentation,
10
+ getSingleAssemblyOptionDocumentation,
11
+ getWatchOptionDocumentation,
12
+ } from './fileProcessingOptions.ts'
13
+ import type { IntentDefinition } from './intentCommandSpecs.ts'
14
+ import type { ResolvedIntentCommandDefinition } from './intentCommands.ts'
15
+ import { resolveIntentCommandDefinitions } from './intentCommands.ts'
16
+ import type { IntentOptionDefinition } from './intentRuntime.ts'
17
+ import { getInputBase64OptionDocumentation, getIntentOptionDefinitions } from './intentRuntime.ts'
18
+
19
+ interface DocOptionRow {
20
+ description: string
21
+ example: string
22
+ flags: string
23
+ required: string
24
+ type: string
25
+ }
26
+
27
+ const MAX_OPTION_DESCRIPTION_LENGTH = 180
28
+
29
+ function inlineCode(value: string): string {
30
+ return `\`${value.replaceAll('`', '\\`')}\``
31
+ }
32
+
33
+ function escapeTableCell(value: string): string {
34
+ return value.replaceAll('\n', ' ').replaceAll('|', '\\|')
35
+ }
36
+
37
+ function renderTable(headers: string[], rows: string[][]): string {
38
+ const renderedRows = rows.map((row) => `| ${row.map(escapeTableCell).join(' | ')} |`)
39
+ return [
40
+ `| ${headers.join(' | ')} |`,
41
+ `| ${headers.map(() => '---').join(' | ')} |`,
42
+ ...renderedRows,
43
+ ].join('\n')
44
+ }
45
+
46
+ function sanitizeDocsMarkdown(value: string): string {
47
+ return value
48
+ .replace(/!?\[([^\]]+)\]\([^)]+\)/g, '$1')
49
+ .replace(/<[^>]+>/g, ' ')
50
+ .replace(/```[\s\S]*?```/g, ' ')
51
+ .replace(/\{\{[\s\S]*?\}\}/g, ' ')
52
+ .replaceAll('`', '')
53
+ .replace(/\s+/g, ' ')
54
+ .trim()
55
+ }
56
+
57
+ function truncateAtSentenceBoundary(value: string, maxLength: number): string {
58
+ if (value.length <= maxLength) {
59
+ return value
60
+ }
61
+
62
+ const sentenceMatch = value.match(/^(.{1,180}?[.!?])(?:\s|$)/)
63
+ if (sentenceMatch?.[1] != null && sentenceMatch[1].length >= 60) {
64
+ return sentenceMatch[1]
65
+ }
66
+
67
+ const truncated = value.slice(0, maxLength).trimEnd()
68
+ const lastSpace = truncated.lastIndexOf(' ')
69
+ if (lastSpace > 40) {
70
+ return `${truncated.slice(0, lastSpace)}…`
71
+ }
72
+
73
+ return `${truncated}…`
74
+ }
75
+
76
+ function summarizeDescription(value: string | undefined): string {
77
+ if (value == null || value.trim().length === 0) {
78
+ return '—'
79
+ }
80
+
81
+ const sanitized = sanitizeDocsMarkdown(value)
82
+
83
+ if (sanitized.length === 0) {
84
+ return '—'
85
+ }
86
+
87
+ return truncateAtSentenceBoundary(sanitized, MAX_OPTION_DESCRIPTION_LENGTH)
88
+ }
89
+
90
+ function getInputSummary(definition: ResolvedIntentCommandDefinition): string {
91
+ if (definition.runnerKind === 'no-input') {
92
+ return 'none'
93
+ }
94
+
95
+ return 'file, dir, URL, base64'
96
+ }
97
+
98
+ function getOutputSummary(definition: ResolvedIntentCommandDefinition): string {
99
+ return definition.intentDefinition.outputMode === 'directory' ? 'directory' : 'file'
100
+ }
101
+
102
+ function getExecutionSummary(definition: ResolvedIntentCommandDefinition): string {
103
+ switch (definition.runnerKind) {
104
+ case 'bundled':
105
+ return 'single assembly'
106
+ case 'no-input':
107
+ return 'no input'
108
+ case 'standard':
109
+ return 'per-file; supports `--single-assembly` and `--watch`'
110
+ case 'watchable':
111
+ return 'per-file; supports `--watch`'
112
+ }
113
+ }
114
+
115
+ function getBackendSummary(catalogDefinition: IntentDefinition): string {
116
+ if (catalogDefinition.kind === 'robot') {
117
+ return inlineCode(catalogDefinition.robot)
118
+ }
119
+
120
+ if (catalogDefinition.kind === 'template') {
121
+ return inlineCode(catalogDefinition.templateId)
122
+ }
123
+
124
+ return `semantic alias ${inlineCode(catalogDefinition.semantic)}`
125
+ }
126
+
127
+ function getUsage(definition: ResolvedIntentCommandDefinition): string {
128
+ const parts = ['npx transloadit', ...definition.paths]
129
+ if (definition.runnerKind !== 'no-input') {
130
+ parts.push('--input', '<path|dir|url|->')
131
+ }
132
+ parts.push('[options]')
133
+ return parts.join(' ')
134
+ }
135
+
136
+ function formatOptionType(kind: IntentOptionDefinition['kind']): string {
137
+ switch (kind) {
138
+ case 'auto':
139
+ return 'auto'
140
+ case 'boolean':
141
+ return 'boolean'
142
+ case 'json':
143
+ return 'json'
144
+ case 'number':
145
+ return 'number'
146
+ case 'string':
147
+ return 'string'
148
+ case 'string-array':
149
+ return 'string[]'
150
+ }
151
+ }
152
+
153
+ function getExampleValue(field: IntentOptionDefinition): string {
154
+ const candidate = field.exampleValue
155
+ if (typeof candidate === 'string' && candidate.length > 0) {
156
+ return candidate
157
+ }
158
+
159
+ return '—'
160
+ }
161
+
162
+ function getCommandOptionRows(definition: ResolvedIntentCommandDefinition): DocOptionRow[] {
163
+ return getIntentOptionDefinitions(definition.intentDefinition).map((field) => ({
164
+ flags: field.optionFlags,
165
+ type: formatOptionType(field.kind),
166
+ required: field.required ? 'yes' : 'no',
167
+ example: getExampleValue(field),
168
+ description: summarizeDescription(field.description),
169
+ }))
170
+ }
171
+
172
+ function getSharedFileInputOutputRows(): DocOptionRow[] {
173
+ return [
174
+ getInputPathsOptionDocumentation(),
175
+ getInputBase64OptionDocumentation(),
176
+ {
177
+ flags: '--out, -o',
178
+ type: 'path',
179
+ required: 'yes*',
180
+ example: 'output.file',
181
+ description: 'Write the result to this path or directory',
182
+ },
183
+ getPrintUrlsOptionDocumentation(),
184
+ ]
185
+ }
186
+
187
+ function getSharedNoInputOutputRows(): DocOptionRow[] {
188
+ return [
189
+ {
190
+ flags: '--out, -o',
191
+ type: 'path',
192
+ required: 'yes*',
193
+ example: 'output.file',
194
+ description: 'Write the result to this path',
195
+ },
196
+ getPrintUrlsOptionDocumentation(),
197
+ ]
198
+ }
199
+
200
+ function getSharedProcessingRows(): DocOptionRow[] {
201
+ return [
202
+ getRecursiveOptionDocumentation(),
203
+ getDeleteAfterProcessingOptionDocumentation(),
204
+ getReprocessStaleOptionDocumentation(),
205
+ ]
206
+ }
207
+
208
+ function getSharedWatchRows(): DocOptionRow[] {
209
+ return [getWatchOptionDocumentation(), getConcurrencyOptionDocumentation()]
210
+ }
211
+
212
+ function getSharedBundlingRows(): DocOptionRow[] {
213
+ return [getSingleAssemblyOptionDocumentation()]
214
+ }
215
+
216
+ function getSharedFlagSupportNotes(definition: ResolvedIntentCommandDefinition): string[] {
217
+ if (definition.runnerKind === 'no-input') {
218
+ return ['Uses the shared output flags listed above.']
219
+ }
220
+
221
+ const notes = ['Uses the shared file input and output flags listed above.']
222
+ const processingGroups = ['base processing flags']
223
+
224
+ if (definition.runnerKind === 'standard' || definition.runnerKind === 'watchable') {
225
+ processingGroups.push('watch flags')
226
+ }
227
+
228
+ if (definition.runnerKind === 'standard') {
229
+ processingGroups.push('bundling flags')
230
+ }
231
+
232
+ notes.push(`Also supports the shared ${processingGroups.join(', ')} listed above.`)
233
+
234
+ return notes
235
+ }
236
+
237
+ function renderOptionSection(title: string, rows: DocOptionRow[]): string[] {
238
+ if (rows.length === 0) {
239
+ return []
240
+ }
241
+
242
+ return [
243
+ `**${title}**`,
244
+ '',
245
+ renderTable(
246
+ ['Flag', 'Type', 'Required', 'Example', 'Description'],
247
+ rows.map((row) => [
248
+ inlineCode(row.flags),
249
+ inlineCode(row.type),
250
+ row.required,
251
+ row.example === '—' ? row.example : inlineCode(row.example),
252
+ row.description,
253
+ ]),
254
+ ),
255
+ '',
256
+ ]
257
+ }
258
+
259
+ function renderExamples(examples: Array<[string, string]>): string {
260
+ const lines: string[] = ['```bash']
261
+
262
+ for (const [label, command] of examples) {
263
+ if (examples.length > 1 || label !== 'Run the command') {
264
+ lines.push(`# ${label}`)
265
+ }
266
+ lines.push(command)
267
+ }
268
+
269
+ lines.push('```')
270
+ return lines.join('\n')
271
+ }
272
+
273
+ function renderIntentSection(
274
+ definition: ResolvedIntentCommandDefinition,
275
+ headingLevel: number,
276
+ ): string {
277
+ const heading = '#'.repeat(headingLevel)
278
+ const commandLabel = definition.paths.join(' ')
279
+ const lines: string[] = [
280
+ `${heading} ${inlineCode(commandLabel)}`,
281
+ '',
282
+ definition.description,
283
+ '',
284
+ definition.details,
285
+ '',
286
+ '**Usage**',
287
+ '',
288
+ '```bash',
289
+ getUsage(definition),
290
+ '```',
291
+ '',
292
+ '**Quick facts**',
293
+ '',
294
+ `- Input: ${getInputSummary(definition)}`,
295
+ `- Output: ${getOutputSummary(definition)}`,
296
+ `- Execution: ${getExecutionSummary(definition)}`,
297
+ `- Backend: ${getBackendSummary(definition.catalogDefinition)}`,
298
+ '',
299
+ '**Shared flags**',
300
+ '',
301
+ ...getSharedFlagSupportNotes(definition).map((note) => `- ${note}`),
302
+ '',
303
+ ...renderOptionSection('Command options', getCommandOptionRows(definition)),
304
+ '**Examples**',
305
+ '',
306
+ renderExamples(definition.examples),
307
+ '',
308
+ ]
309
+
310
+ return lines.join('\n')
311
+ }
312
+
313
+ function renderAtAGlanceTable(definitions: ResolvedIntentCommandDefinition[]): string {
314
+ return renderTable(
315
+ ['Command', 'What it does', 'Input', 'Output'],
316
+ definitions.map((definition) => [
317
+ inlineCode(definition.paths.join(' ')),
318
+ definition.description,
319
+ getInputSummary(definition),
320
+ getOutputSummary(definition),
321
+ ]),
322
+ )
323
+ }
324
+
325
+ function renderIntentDocsBody({
326
+ definitions,
327
+ headingLevel,
328
+ }: {
329
+ definitions: ResolvedIntentCommandDefinition[]
330
+ headingLevel: number
331
+ }): string {
332
+ const heading = '#'.repeat(headingLevel)
333
+ const lines: string[] = [
334
+ `${heading} At a glance`,
335
+ '',
336
+ 'Intent commands are the fastest path to common one-off tasks from the CLI.',
337
+ 'Use `--print-urls` when you want temporary result URLs without downloading locally.',
338
+ 'All intent commands also support the global CLI flags `--json`, `--log-level`, `--endpoint`, and `--help`.',
339
+ '',
340
+ renderAtAGlanceTable(definitions),
341
+ '',
342
+ '> At least one of `--out` or `--print-urls` is required on every intent command.',
343
+ '',
344
+ `${heading} Shared flags`,
345
+ '',
346
+ 'These flags are available across many intent commands, so the per-command sections below focus on differences.',
347
+ '',
348
+ ...renderOptionSection('Shared file input & output flags', getSharedFileInputOutputRows()),
349
+ ...renderOptionSection('Shared no-input output flags', getSharedNoInputOutputRows()),
350
+ ...renderOptionSection('Shared processing flags', getSharedProcessingRows()),
351
+ ...renderOptionSection('Shared watch flags', getSharedWatchRows()),
352
+ ...renderOptionSection('Shared bundling flags', getSharedBundlingRows()),
353
+ ]
354
+
355
+ for (const definition of definitions) {
356
+ lines.push(renderIntentSection(definition, headingLevel))
357
+ }
358
+
359
+ return lines.join('\n').trim()
360
+ }
361
+
362
+ function replaceGeneratedBlock({
363
+ endMarker,
364
+ markdown,
365
+ readme,
366
+ startMarker,
367
+ }: {
368
+ endMarker: string
369
+ markdown: string
370
+ readme: string
371
+ startMarker: string
372
+ }): string {
373
+ const startIndex = readme.indexOf(startMarker)
374
+ const endIndex = readme.indexOf(endMarker)
375
+ if (startIndex === -1 || endIndex === -1 || endIndex < startIndex) {
376
+ throw new Error('README intent docs markers are missing or malformed')
377
+ }
378
+
379
+ const before = readme.slice(0, startIndex + startMarker.length)
380
+ const after = readme.slice(endIndex)
381
+ return `${before}\n\n${markdown}\n\n${after}`
382
+ }
383
+
384
+ async function main(): Promise<void> {
385
+ const definitions = resolveIntentCommandDefinitions()
386
+ const readmeUrl = new URL('../../README.md', import.meta.url)
387
+ const docsUrl = new URL('../../docs/intent-commands.md', import.meta.url)
388
+ const startMarker = '<!-- GENERATED_INTENT_DOCS:START -->'
389
+ const endMarker = '<!-- GENERATED_INTENT_DOCS:END -->'
390
+
391
+ const readme = await readFile(readmeUrl, 'utf8')
392
+ const readmeFragment = renderIntentDocsBody({ definitions, headingLevel: 4 })
393
+ const fullDoc = [
394
+ '# Intent Command Reference',
395
+ '',
396
+ '> Generated by `yarn workspace @transloadit/node sync:intent-docs`. Do not edit by hand.',
397
+ '',
398
+ renderIntentDocsBody({ definitions, headingLevel: 2 }),
399
+ ].join('\n')
400
+
401
+ const nextReadme = replaceGeneratedBlock({
402
+ endMarker,
403
+ markdown: readmeFragment,
404
+ readme,
405
+ startMarker,
406
+ })
407
+
408
+ await mkdir(dirname(docsUrl.pathname), { recursive: true })
409
+ await writeFile(docsUrl, `${fullDoc}\n`)
410
+ await writeFile(readmeUrl, `${nextReadme}\n`)
411
+ }
412
+
413
+ main().catch((error) => {
414
+ if (!(error instanceof Error)) {
415
+ throw new Error(`Was thrown a non-error: ${String(error)}`)
416
+ }
417
+ console.error(error)
418
+ process.exit(1)
419
+ })
@@ -0,0 +1,282 @@
1
+ import type { z } from 'zod'
2
+
3
+ import type { RobotMetaInput } from '../alphalib/types/robots/_instructions-primitives.ts'
4
+ import {
5
+ robotAudioWaveformInstructionsSchema,
6
+ meta as robotAudioWaveformMeta,
7
+ } from '../alphalib/types/robots/audio-waveform.ts'
8
+ import {
9
+ robotDocumentAutorotateInstructionsSchema,
10
+ meta as robotDocumentAutorotateMeta,
11
+ } from '../alphalib/types/robots/document-autorotate.ts'
12
+ import {
13
+ robotDocumentConvertInstructionsSchema,
14
+ meta as robotDocumentConvertMeta,
15
+ } from '../alphalib/types/robots/document-convert.ts'
16
+ import {
17
+ robotDocumentOptimizeInstructionsSchema,
18
+ meta as robotDocumentOptimizeMeta,
19
+ } from '../alphalib/types/robots/document-optimize.ts'
20
+ import {
21
+ robotDocumentThumbsInstructionsSchema,
22
+ meta as robotDocumentThumbsMeta,
23
+ } from '../alphalib/types/robots/document-thumbs.ts'
24
+ import {
25
+ robotFileCompressInstructionsSchema,
26
+ meta as robotFileCompressMeta,
27
+ } from '../alphalib/types/robots/file-compress.ts'
28
+ import {
29
+ robotFileDecompressInstructionsSchema,
30
+ meta as robotFileDecompressMeta,
31
+ } from '../alphalib/types/robots/file-decompress.ts'
32
+ import {
33
+ robotFilePreviewInstructionsSchema,
34
+ meta as robotFilePreviewMeta,
35
+ } from '../alphalib/types/robots/file-preview.ts'
36
+ import {
37
+ robotImageBgremoveInstructionsSchema,
38
+ meta as robotImageBgremoveMeta,
39
+ } from '../alphalib/types/robots/image-bgremove.ts'
40
+ import {
41
+ robotImageGenerateInstructionsSchema,
42
+ meta as robotImageGenerateMeta,
43
+ } from '../alphalib/types/robots/image-generate.ts'
44
+ import {
45
+ robotImageOptimizeInstructionsSchema,
46
+ meta as robotImageOptimizeMeta,
47
+ } from '../alphalib/types/robots/image-optimize.ts'
48
+ import {
49
+ robotImageResizeInstructionsSchema,
50
+ meta as robotImageResizeMeta,
51
+ } from '../alphalib/types/robots/image-resize.ts'
52
+ import {
53
+ robotTextSpeakInstructionsSchema,
54
+ meta as robotTextSpeakMeta,
55
+ } from '../alphalib/types/robots/text-speak.ts'
56
+ import {
57
+ robotVideoThumbsInstructionsSchema,
58
+ meta as robotVideoThumbsMeta,
59
+ } from '../alphalib/types/robots/video-thumbs.ts'
60
+
61
+ export type IntentInputMode = 'local-files' | 'none'
62
+ export type IntentOutputMode = 'directory' | 'file'
63
+
64
+ interface IntentSchemaDefinition {
65
+ meta: RobotMetaInput
66
+ schema: z.AnyZodObject
67
+ }
68
+
69
+ interface IntentBaseDefinition {
70
+ outputMode?: IntentOutputMode
71
+ paths?: string[]
72
+ }
73
+
74
+ export interface RobotIntentDefinition extends IntentBaseDefinition, IntentSchemaDefinition {
75
+ defaultSingleAssembly?: boolean
76
+ inputMode?: IntentInputMode
77
+ kind: 'robot'
78
+ robot: string
79
+ }
80
+
81
+ export interface TemplateIntentDefinition extends IntentBaseDefinition {
82
+ kind: 'template'
83
+ paths: string[]
84
+ templateId: string
85
+ }
86
+
87
+ export interface SemanticIntentDefinition extends IntentBaseDefinition {
88
+ kind: 'semantic'
89
+ paths: string[]
90
+ semantic: string
91
+ }
92
+
93
+ export type IntentDefinition =
94
+ | RobotIntentDefinition
95
+ | TemplateIntentDefinition
96
+ | SemanticIntentDefinition
97
+
98
+ const commandPathAliases = new Map([
99
+ ['autorotate', 'auto-rotate'],
100
+ ['bgremove', 'remove-background'],
101
+ ])
102
+
103
+ function defineRobotIntent(definition: RobotIntentDefinition): RobotIntentDefinition {
104
+ return definition
105
+ }
106
+
107
+ function defineTemplateIntent(definition: TemplateIntentDefinition): TemplateIntentDefinition {
108
+ return definition
109
+ }
110
+
111
+ function defineSemanticIntent(definition: SemanticIntentDefinition): SemanticIntentDefinition {
112
+ return definition
113
+ }
114
+
115
+ export function getIntentCatalogKey(definition: IntentDefinition): string {
116
+ if (definition.kind === 'robot') {
117
+ return definition.robot
118
+ }
119
+
120
+ if (definition.kind === 'template') {
121
+ return definition.templateId
122
+ }
123
+
124
+ return `${definition.semantic}:${definition.paths.join('/')}`
125
+ }
126
+
127
+ export function getIntentPaths(definition: IntentDefinition): string[] {
128
+ if (definition.paths != null) {
129
+ return definition.paths
130
+ }
131
+
132
+ if (definition.kind !== 'robot') {
133
+ throw new Error(`Intent definition ${getIntentCatalogKey(definition)} is missing paths`)
134
+ }
135
+
136
+ const segments = definition.robot.split('/').filter(Boolean)
137
+ const [group, action] = segments
138
+ if (group == null || action == null) {
139
+ throw new Error(`Could not infer command path from robot "${definition.robot}"`)
140
+ }
141
+
142
+ return [group, commandPathAliases.get(action) ?? action]
143
+ }
144
+
145
+ export function getIntentResultStepName(definition: IntentDefinition): string | null {
146
+ if (definition.kind !== 'robot') {
147
+ return null
148
+ }
149
+
150
+ const paths = getIntentPaths(definition)
151
+ const action = paths[paths.length - 1]
152
+ if (action == null) {
153
+ throw new Error(`Intent definition ${definition.robot} has no action path`)
154
+ }
155
+
156
+ return action.replaceAll('-', '_')
157
+ }
158
+
159
+ export function findIntentDefinitionByPaths(
160
+ paths: readonly string[],
161
+ ): IntentDefinition | undefined {
162
+ return intentCatalog.find((definition) => {
163
+ const definitionPaths = getIntentPaths(definition)
164
+ return (
165
+ definitionPaths.length === paths.length &&
166
+ definitionPaths.every((part, index) => part === paths[index])
167
+ )
168
+ })
169
+ }
170
+
171
+ export const intentCatalog = [
172
+ defineRobotIntent({
173
+ kind: 'robot',
174
+ robot: '/image/generate',
175
+ meta: robotImageGenerateMeta,
176
+ schema: robotImageGenerateInstructionsSchema,
177
+ }),
178
+ defineRobotIntent({
179
+ kind: 'robot',
180
+ robot: '/file/preview',
181
+ paths: ['preview', 'generate'],
182
+ meta: robotFilePreviewMeta,
183
+ schema: robotFilePreviewInstructionsSchema,
184
+ }),
185
+ defineRobotIntent({
186
+ kind: 'robot',
187
+ robot: '/image/bgremove',
188
+ meta: robotImageBgremoveMeta,
189
+ schema: robotImageBgremoveInstructionsSchema,
190
+ }),
191
+ defineRobotIntent({
192
+ kind: 'robot',
193
+ robot: '/image/optimize',
194
+ meta: robotImageOptimizeMeta,
195
+ schema: robotImageOptimizeInstructionsSchema,
196
+ }),
197
+ defineRobotIntent({
198
+ kind: 'robot',
199
+ robot: '/image/resize',
200
+ meta: robotImageResizeMeta,
201
+ schema: robotImageResizeInstructionsSchema,
202
+ }),
203
+ defineRobotIntent({
204
+ kind: 'robot',
205
+ robot: '/document/convert',
206
+ meta: robotDocumentConvertMeta,
207
+ schema: robotDocumentConvertInstructionsSchema,
208
+ }),
209
+ defineRobotIntent({
210
+ kind: 'robot',
211
+ robot: '/document/optimize',
212
+ meta: robotDocumentOptimizeMeta,
213
+ schema: robotDocumentOptimizeInstructionsSchema,
214
+ }),
215
+ defineRobotIntent({
216
+ kind: 'robot',
217
+ robot: '/document/autorotate',
218
+ meta: robotDocumentAutorotateMeta,
219
+ schema: robotDocumentAutorotateInstructionsSchema,
220
+ }),
221
+ defineRobotIntent({
222
+ kind: 'robot',
223
+ robot: '/document/thumbs',
224
+ outputMode: 'directory',
225
+ meta: robotDocumentThumbsMeta,
226
+ schema: robotDocumentThumbsInstructionsSchema,
227
+ }),
228
+ defineRobotIntent({
229
+ kind: 'robot',
230
+ robot: '/audio/waveform',
231
+ meta: robotAudioWaveformMeta,
232
+ schema: robotAudioWaveformInstructionsSchema,
233
+ }),
234
+ defineRobotIntent({
235
+ kind: 'robot',
236
+ robot: '/text/speak',
237
+ meta: robotTextSpeakMeta,
238
+ schema: robotTextSpeakInstructionsSchema,
239
+ }),
240
+ defineRobotIntent({
241
+ kind: 'robot',
242
+ robot: '/video/thumbs',
243
+ outputMode: 'directory',
244
+ meta: robotVideoThumbsMeta,
245
+ schema: robotVideoThumbsInstructionsSchema,
246
+ }),
247
+ defineTemplateIntent({
248
+ kind: 'template',
249
+ templateId: 'builtin/encode-hls-video@latest',
250
+ paths: ['video', 'encode-hls'],
251
+ outputMode: 'directory',
252
+ }),
253
+ defineSemanticIntent({
254
+ kind: 'semantic',
255
+ semantic: 'image-describe',
256
+ paths: ['image', 'describe'],
257
+ }),
258
+ defineSemanticIntent({
259
+ kind: 'semantic',
260
+ semantic: 'markdown-pdf',
261
+ paths: ['markdown', 'pdf'],
262
+ }),
263
+ defineSemanticIntent({
264
+ kind: 'semantic',
265
+ semantic: 'markdown-docx',
266
+ paths: ['markdown', 'docx'],
267
+ }),
268
+ defineRobotIntent({
269
+ kind: 'robot',
270
+ robot: '/file/compress',
271
+ defaultSingleAssembly: true,
272
+ meta: robotFileCompressMeta,
273
+ schema: robotFileCompressInstructionsSchema,
274
+ }),
275
+ defineRobotIntent({
276
+ kind: 'robot',
277
+ robot: '/file/decompress',
278
+ outputMode: 'directory',
279
+ meta: robotFileDecompressMeta,
280
+ schema: robotFileDecompressInstructionsSchema,
281
+ }),
282
+ ] satisfies IntentDefinition[]