transloadit 4.7.4 → 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.
- package/README.md +888 -5
- package/dist/Transloadit.d.ts +3 -3
- package/dist/Transloadit.d.ts.map +1 -1
- package/dist/Transloadit.js +2 -2
- package/dist/Transloadit.js.map +1 -1
- package/dist/alphalib/types/assembliesGet.d.ts +5 -0
- package/dist/alphalib/types/assembliesGet.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyReplay.d.ts +5 -0
- package/dist/alphalib/types/assemblyReplay.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyReplayNotification.d.ts +5 -0
- package/dist/alphalib/types/assemblyReplayNotification.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyStatus.d.ts +25 -25
- package/dist/alphalib/types/assemblyStatus.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyStatus.js +4 -1
- package/dist/alphalib/types/assemblyStatus.js.map +1 -1
- package/dist/alphalib/types/bill.d.ts +5 -0
- package/dist/alphalib/types/bill.d.ts.map +1 -1
- package/dist/alphalib/types/builtinTemplates.d.ts +83 -0
- package/dist/alphalib/types/builtinTemplates.d.ts.map +1 -0
- package/dist/alphalib/types/builtinTemplates.js +19 -0
- package/dist/alphalib/types/builtinTemplates.js.map +1 -0
- package/dist/alphalib/types/robots/ai-chat.d.ts.map +1 -1
- package/dist/alphalib/types/robots/ai-chat.js +1 -0
- package/dist/alphalib/types/robots/ai-chat.js.map +1 -1
- package/dist/alphalib/types/skillFrontmatter.d.ts +29 -0
- package/dist/alphalib/types/skillFrontmatter.d.ts.map +1 -0
- package/dist/alphalib/types/skillFrontmatter.js +19 -0
- package/dist/alphalib/types/skillFrontmatter.js.map +1 -0
- package/dist/alphalib/types/template.d.ts +36 -0
- package/dist/alphalib/types/template.d.ts.map +1 -1
- package/dist/alphalib/types/template.js +10 -0
- package/dist/alphalib/types/template.js.map +1 -1
- package/dist/alphalib/types/templateCredential.d.ts +10 -0
- package/dist/alphalib/types/templateCredential.d.ts.map +1 -1
- package/dist/cli/commands/assemblies.d.ts +8 -2
- package/dist/cli/commands/assemblies.d.ts.map +1 -1
- package/dist/cli/commands/assemblies.js +566 -411
- package/dist/cli/commands/assemblies.js.map +1 -1
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +5 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/templates.d.ts.map +1 -1
- package/dist/cli/commands/templates.js +4 -14
- package/dist/cli/commands/templates.js.map +1 -1
- package/dist/cli/fileProcessingOptions.d.ts +35 -0
- package/dist/cli/fileProcessingOptions.d.ts.map +1 -0
- package/dist/cli/fileProcessingOptions.js +182 -0
- package/dist/cli/fileProcessingOptions.js.map +1 -0
- package/dist/cli/generateIntentDocs.d.ts +2 -0
- package/dist/cli/generateIntentDocs.d.ts.map +1 -0
- package/dist/cli/generateIntentDocs.js +321 -0
- package/dist/cli/generateIntentDocs.js.map +1 -0
- package/dist/cli/intentCommandSpecs.d.ts +36 -0
- package/dist/cli/intentCommandSpecs.d.ts.map +1 -0
- package/dist/cli/intentCommandSpecs.js +181 -0
- package/dist/cli/intentCommandSpecs.js.map +1 -0
- package/dist/cli/intentCommands.d.ts +13 -0
- package/dist/cli/intentCommands.d.ts.map +1 -0
- package/dist/cli/intentCommands.js +368 -0
- package/dist/cli/intentCommands.js.map +1 -0
- package/dist/cli/intentFields.d.ts +25 -0
- package/dist/cli/intentFields.d.ts.map +1 -0
- package/dist/cli/intentFields.js +298 -0
- package/dist/cli/intentFields.js.map +1 -0
- package/dist/cli/intentInputPolicy.d.ts +10 -0
- package/dist/cli/intentInputPolicy.d.ts.map +1 -0
- package/dist/cli/intentInputPolicy.js +2 -0
- package/dist/cli/intentInputPolicy.js.map +1 -0
- package/dist/cli/intentRuntime.d.ts +114 -0
- package/dist/cli/intentRuntime.d.ts.map +1 -0
- package/dist/cli/intentRuntime.js +464 -0
- package/dist/cli/intentRuntime.js.map +1 -0
- package/dist/cli/resultFiles.d.ts +19 -0
- package/dist/cli/resultFiles.d.ts.map +1 -0
- package/dist/cli/resultFiles.js +66 -0
- package/dist/cli/resultFiles.js.map +1 -0
- package/dist/cli/resultUrls.d.ts +19 -0
- package/dist/cli/resultUrls.d.ts.map +1 -0
- package/dist/cli/resultUrls.js +36 -0
- package/dist/cli/resultUrls.js.map +1 -0
- package/dist/cli/semanticIntents/imageDescribe.d.ts +43 -0
- package/dist/cli/semanticIntents/imageDescribe.d.ts.map +1 -0
- package/dist/cli/semanticIntents/imageDescribe.js +188 -0
- package/dist/cli/semanticIntents/imageDescribe.js.map +1 -0
- package/dist/cli/semanticIntents/index.d.ts +18 -0
- package/dist/cli/semanticIntents/index.d.ts.map +1 -0
- package/dist/cli/semanticIntents/index.js +18 -0
- package/dist/cli/semanticIntents/index.js.map +1 -0
- package/dist/cli/semanticIntents/markdownPdf.d.ts +4 -0
- package/dist/cli/semanticIntents/markdownPdf.d.ts.map +1 -0
- package/dist/cli/semanticIntents/markdownPdf.js +93 -0
- package/dist/cli/semanticIntents/markdownPdf.js.map +1 -0
- package/dist/cli/semanticIntents/parsing.d.ts +11 -0
- package/dist/cli/semanticIntents/parsing.d.ts.map +1 -0
- package/dist/cli/semanticIntents/parsing.js +29 -0
- package/dist/cli/semanticIntents/parsing.js.map +1 -0
- package/dist/cli/stepsInput.d.ts +4 -0
- package/dist/cli/stepsInput.d.ts.map +1 -0
- package/dist/cli/stepsInput.js +23 -0
- package/dist/cli/stepsInput.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -4
- package/dist/cli.js.map +1 -1
- package/dist/ensureUniqueCounter.d.ts +8 -0
- package/dist/ensureUniqueCounter.d.ts.map +1 -0
- package/dist/ensureUniqueCounter.js +48 -0
- package/dist/ensureUniqueCounter.js.map +1 -0
- package/dist/inputFiles.d.ts +9 -0
- package/dist/inputFiles.d.ts.map +1 -1
- package/dist/inputFiles.js +177 -26
- package/dist/inputFiles.js.map +1 -1
- package/dist/robots.js +1 -1
- package/dist/robots.js.map +1 -1
- package/package.json +9 -7
- package/src/Transloadit.ts +3 -3
- package/src/alphalib/types/assemblyStatus.ts +4 -1
- package/src/alphalib/types/builtinTemplates.ts +24 -0
- package/src/alphalib/types/robots/ai-chat.ts +1 -0
- package/src/alphalib/types/skillFrontmatter.ts +24 -0
- package/src/alphalib/types/template.ts +14 -0
- package/src/cli/commands/assemblies.ts +825 -505
- package/src/cli/commands/index.ts +6 -3
- package/src/cli/commands/templates.ts +6 -17
- package/src/cli/fileProcessingOptions.ts +294 -0
- package/src/cli/generateIntentDocs.ts +419 -0
- package/src/cli/intentCommandSpecs.ts +282 -0
- package/src/cli/intentCommands.ts +525 -0
- package/src/cli/intentFields.ts +403 -0
- package/src/cli/intentInputPolicy.ts +11 -0
- package/src/cli/intentRuntime.ts +734 -0
- package/src/cli/resultFiles.ts +105 -0
- package/src/cli/resultUrls.ts +72 -0
- package/src/cli/semanticIntents/imageDescribe.ts +254 -0
- package/src/cli/semanticIntents/index.ts +48 -0
- package/src/cli/semanticIntents/markdownPdf.ts +120 -0
- package/src/cli/semanticIntents/parsing.ts +56 -0
- package/src/cli/stepsInput.ts +32 -0
- package/src/cli.ts +5 -4
- package/src/ensureUniqueCounter.ts +75 -0
- package/src/inputFiles.ts +277 -26
- 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[]
|