transloadit 4.8.0 → 4.8.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.
- package/README.md +92 -43
- package/dist/bearerToken.d.ts +1 -0
- package/dist/bearerToken.d.ts.map +1 -1
- package/dist/bearerToken.js +5 -3
- package/dist/bearerToken.js.map +1 -1
- package/dist/cli/commands/BaseCommand.d.ts +0 -1
- package/dist/cli/commands/BaseCommand.d.ts.map +1 -1
- package/dist/cli/commands/BaseCommand.js +7 -9
- package/dist/cli/commands/BaseCommand.js.map +1 -1
- package/dist/cli/commands/auth.d.ts.map +1 -1
- package/dist/cli/commands/auth.js +49 -29
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/generateIntentDocs.d.ts.map +1 -1
- package/dist/cli/generateIntentDocs.js +9 -7
- package/dist/cli/generateIntentDocs.js.map +1 -1
- package/dist/cli/helpers.d.ts +19 -4
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/helpers.js +232 -10
- package/dist/cli/helpers.js.map +1 -1
- package/dist/cli/intentCommands.d.ts.map +1 -1
- package/dist/cli/intentCommands.js +11 -7
- package/dist/cli/intentCommands.js.map +1 -1
- package/dist/cli/intentRuntime.d.ts +17 -2
- package/dist/cli/intentRuntime.d.ts.map +1 -1
- package/dist/cli/intentRuntime.js +163 -33
- package/dist/cli/intentRuntime.js.map +1 -1
- package/dist/cli/semanticIntents/imageDescribe.d.ts +2 -1
- package/dist/cli/semanticIntents/imageDescribe.d.ts.map +1 -1
- package/dist/cli/semanticIntents/imageDescribe.js +5 -4
- package/dist/cli/semanticIntents/imageDescribe.js.map +1 -1
- package/dist/cli/semanticIntents/imageGenerate.d.ts +1 -0
- package/dist/cli/semanticIntents/imageGenerate.d.ts.map +1 -1
- package/dist/cli/semanticIntents/imageGenerate.js +4 -3
- package/dist/cli/semanticIntents/imageGenerate.js.map +1 -1
- package/dist/cli/semanticIntents/index.d.ts +1 -0
- package/dist/cli/semanticIntents/index.d.ts.map +1 -1
- package/dist/cli/semanticIntents/index.js.map +1 -1
- package/dist/cli/semanticIntents/markdownPdf.d.ts.map +1 -1
- package/dist/cli/semanticIntents/markdownPdf.js +2 -1
- package/dist/cli/semanticIntents/markdownPdf.js.map +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/src/bearerToken.ts +14 -3
- package/src/cli/commands/BaseCommand.ts +7 -9
- package/src/cli/commands/auth.ts +66 -32
- package/src/cli/generateIntentDocs.ts +10 -7
- package/src/cli/helpers.ts +278 -13
- package/src/cli/intentCommands.ts +11 -7
- package/src/cli/intentRuntime.ts +214 -33
- package/src/cli/semanticIntents/imageDescribe.ts +5 -4
- package/src/cli/semanticIntents/imageGenerate.ts +4 -3
- package/src/cli/semanticIntents/index.ts +1 -0
- package/src/cli/semanticIntents/markdownPdf.ts +2 -1
- package/src/cli.ts +3 -2
package/src/cli/helpers.ts
CHANGED
|
@@ -1,30 +1,295 @@
|
|
|
1
1
|
import fs from 'node:fs'
|
|
2
2
|
import fsp from 'node:fs/promises'
|
|
3
|
+
import { homedir } from 'node:os'
|
|
4
|
+
import path from 'node:path'
|
|
3
5
|
import type { Readable } from 'node:stream'
|
|
6
|
+
import { parse as parseDotenv } from 'dotenv'
|
|
4
7
|
import { isAPIError } from './types.ts'
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
export type CliKeySecretCredentials = { authKey: string; authSecret: string }
|
|
10
|
+
export type CliAuthToken = { authToken: string }
|
|
11
|
+
export type CliAuth = CliKeySecretCredentials | CliAuthToken
|
|
12
|
+
type CliEnvSource = {
|
|
13
|
+
name: 'env' | 'credentialsFile'
|
|
14
|
+
values: Record<string, string | undefined>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let loadedProjectDotenvPath: string | undefined
|
|
18
|
+
let projectDotenvInjectedValues: Record<string, string> | undefined
|
|
19
|
+
let projectDotenvPreviousValues: Record<string, string | undefined> | undefined
|
|
20
|
+
let shellEnvBeforeProjectDotenv: Record<string, string | undefined> | undefined
|
|
21
|
+
|
|
22
|
+
type LoadCliEnvSourcesResult = {
|
|
23
|
+
loadError?: string
|
|
24
|
+
shellEnvSource: CliEnvSource
|
|
25
|
+
sources: CliEnvSource[]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type ResolvedCliConfig = {
|
|
29
|
+
auth?: CliAuth
|
|
30
|
+
credentials?: CliKeySecretCredentials
|
|
31
|
+
credentialsEndpoint?: string
|
|
32
|
+
endpoint?: string
|
|
33
|
+
loadError?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function normalizeEnvValue(value: string | undefined): string | undefined {
|
|
37
|
+
const trimmed = value?.trim()
|
|
38
|
+
return trimmed ? trimmed : undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getConfiguredCredentialsFilePath(): string {
|
|
42
|
+
const configuredPath = normalizeEnvValue(process.env.TRANSLOADIT_CREDENTIALS_FILE)
|
|
43
|
+
if (configuredPath != null) {
|
|
44
|
+
return path.resolve(configuredPath)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return path.join(homedir(), '.transloadit', 'credentials')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getProjectDotenvPath(): string {
|
|
51
|
+
return path.resolve(process.cwd(), '.env')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getDisplayPath(filePath: string): string {
|
|
55
|
+
const normalizedHome = path.resolve(homedir())
|
|
56
|
+
const normalizedFilePath = path.resolve(filePath)
|
|
57
|
+
if (normalizedFilePath === normalizedHome) return '~'
|
|
58
|
+
if (normalizedFilePath.startsWith(`${normalizedHome}${path.sep}`)) {
|
|
59
|
+
return `~${normalizedFilePath.slice(normalizedHome.length)}`
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return normalizedFilePath
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function buildMissingCredentialsMessage(): string {
|
|
66
|
+
return [
|
|
67
|
+
'Missing credentials.',
|
|
68
|
+
'',
|
|
69
|
+
'Looked for TRANSLOADIT_KEY + TRANSLOADIT_SECRET in this order:',
|
|
70
|
+
'1. Shell env: TRANSLOADIT_KEY / TRANSLOADIT_SECRET',
|
|
71
|
+
`2. Current directory .env: ${getProjectDotenvPath()}`,
|
|
72
|
+
`3. Credentials file: ${getDisplayPath(getConfiguredCredentialsFilePath())}`,
|
|
73
|
+
].join('\n')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function buildMissingAuthMessage(): string {
|
|
77
|
+
return [
|
|
78
|
+
'Missing authentication.',
|
|
79
|
+
'',
|
|
80
|
+
'Looked for TRANSLOADIT_AUTH_TOKEN or TRANSLOADIT_KEY + TRANSLOADIT_SECRET in this order:',
|
|
81
|
+
'1. Shell env: TRANSLOADIT_AUTH_TOKEN, or TRANSLOADIT_KEY / TRANSLOADIT_SECRET',
|
|
82
|
+
`2. Current directory .env: ${getProjectDotenvPath()}`,
|
|
83
|
+
`3. Credentials file: ${getDisplayPath(getConfiguredCredentialsFilePath())}`,
|
|
84
|
+
].join('\n')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function readEnvFile(
|
|
88
|
+
filePath: string,
|
|
89
|
+
): { ok: true; source: CliEnvSource } | { ok: false; error: string } | null {
|
|
90
|
+
if (!fs.existsSync(filePath)) return null
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
return {
|
|
94
|
+
ok: true,
|
|
95
|
+
source: {
|
|
96
|
+
name: 'credentialsFile',
|
|
97
|
+
values: parseDotenv(fs.readFileSync(filePath)),
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
} catch (err) {
|
|
101
|
+
if (!(err instanceof Error)) {
|
|
102
|
+
throw new Error(`Was thrown a non-error: ${err}`)
|
|
103
|
+
}
|
|
104
|
+
return { ok: false, error: `Failed to read ${filePath}: ${err.message}` }
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function loadProjectDotenvIntoProcessEnv(): string | undefined {
|
|
109
|
+
const projectDotenvPath = getProjectDotenvPath()
|
|
110
|
+
if (loadedProjectDotenvPath !== projectDotenvPath) {
|
|
111
|
+
restoreProjectDotenvFromProcessEnv()
|
|
112
|
+
shellEnvBeforeProjectDotenv = { ...process.env }
|
|
113
|
+
loadedProjectDotenvPath = projectDotenvPath
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const projectDotenvResult = readEnvFile(projectDotenvPath)
|
|
117
|
+
if (projectDotenvResult == null) {
|
|
118
|
+
restoreProjectDotenvFromProcessEnv()
|
|
119
|
+
projectDotenvInjectedValues = undefined
|
|
120
|
+
projectDotenvPreviousValues = undefined
|
|
121
|
+
return undefined
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!projectDotenvResult.ok) return projectDotenvResult.error
|
|
125
|
+
if (projectDotenvInjectedValues != null) return undefined
|
|
126
|
+
|
|
127
|
+
const previousValues: Record<string, string | undefined> = {}
|
|
128
|
+
const injectedValues: Record<string, string> = {}
|
|
129
|
+
for (const [key, value] of Object.entries(projectDotenvResult.source.values)) {
|
|
130
|
+
if (value == null) continue
|
|
131
|
+
if (normalizeEnvValue(process.env[key]) != null) continue
|
|
132
|
+
previousValues[key] = process.env[key]
|
|
133
|
+
process.env[key] = value
|
|
134
|
+
injectedValues[key] = value
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
projectDotenvPreviousValues = previousValues
|
|
138
|
+
projectDotenvInjectedValues = injectedValues
|
|
139
|
+
return undefined
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function getShellEnvValues(): Record<string, string | undefined> {
|
|
143
|
+
if (loadedProjectDotenvPath === getProjectDotenvPath() && shellEnvBeforeProjectDotenv != null) {
|
|
144
|
+
return shellEnvBeforeProjectDotenv
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return { ...process.env }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function restoreProjectDotenvFromProcessEnv(): void {
|
|
151
|
+
if (projectDotenvInjectedValues == null || projectDotenvPreviousValues == null) return
|
|
152
|
+
|
|
153
|
+
for (const [key, injectedValue] of Object.entries(projectDotenvInjectedValues)) {
|
|
154
|
+
if (process.env[key] !== injectedValue) continue
|
|
155
|
+
|
|
156
|
+
const previousValue = projectDotenvPreviousValues[key]
|
|
157
|
+
if (previousValue == null) {
|
|
158
|
+
delete process.env[key]
|
|
159
|
+
continue
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
process.env[key] = previousValue
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
projectDotenvInjectedValues = undefined
|
|
166
|
+
projectDotenvPreviousValues = undefined
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function loadCliEnvSources(): LoadCliEnvSourcesResult {
|
|
170
|
+
const shellEnvSource: CliEnvSource = {
|
|
171
|
+
name: 'env',
|
|
172
|
+
values: getShellEnvValues(),
|
|
173
|
+
}
|
|
174
|
+
const loadErrors: string[] = []
|
|
175
|
+
|
|
176
|
+
const projectDotenvLoadError = loadProjectDotenvIntoProcessEnv()
|
|
177
|
+
if (projectDotenvLoadError != null) {
|
|
178
|
+
loadErrors.push(projectDotenvLoadError)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const sources: CliEnvSource[] = [
|
|
182
|
+
{
|
|
183
|
+
name: 'env',
|
|
184
|
+
values: { ...process.env },
|
|
185
|
+
},
|
|
186
|
+
]
|
|
187
|
+
|
|
188
|
+
const credentialsFilePath = getConfiguredCredentialsFilePath()
|
|
189
|
+
const credentialsFileResult = readEnvFile(credentialsFilePath)
|
|
190
|
+
if (credentialsFileResult?.ok === true) {
|
|
191
|
+
sources.push(credentialsFileResult.source)
|
|
192
|
+
} else if (credentialsFileResult?.ok === false) {
|
|
193
|
+
loadErrors.push(credentialsFileResult.error)
|
|
194
|
+
} else if (normalizeEnvValue(process.env.TRANSLOADIT_CREDENTIALS_FILE) != null) {
|
|
195
|
+
loadErrors.push(`Configured credentials file does not exist: ${credentialsFilePath}`)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
shellEnvSource,
|
|
200
|
+
sources,
|
|
201
|
+
...(loadErrors[0] ? { loadError: loadErrors[0] } : {}),
|
|
202
|
+
}
|
|
203
|
+
}
|
|
8
204
|
|
|
9
|
-
|
|
205
|
+
function getSourceValue(source: CliEnvSource, keys: string[]): string | undefined {
|
|
206
|
+
for (const key of keys) {
|
|
207
|
+
const value = normalizeEnvValue(source.values[key])
|
|
208
|
+
if (value != null) return value
|
|
209
|
+
}
|
|
10
210
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const authSecret = process.env.TRANSLOADIT_SECRET ?? process.env.TRANSLOADIT_AUTH_SECRET
|
|
211
|
+
return undefined
|
|
212
|
+
}
|
|
14
213
|
|
|
15
|
-
|
|
214
|
+
function getSourceCredentials(source: CliEnvSource): CliKeySecretCredentials | undefined {
|
|
215
|
+
const authKey = getSourceValue(source, ['TRANSLOADIT_KEY', 'TRANSLOADIT_AUTH_KEY'])
|
|
216
|
+
const authSecret = getSourceValue(source, ['TRANSLOADIT_SECRET', 'TRANSLOADIT_AUTH_SECRET'])
|
|
217
|
+
if (authKey == null || authSecret == null) return undefined
|
|
16
218
|
|
|
17
219
|
return { authKey, authSecret }
|
|
18
220
|
}
|
|
19
221
|
|
|
20
|
-
|
|
21
|
-
|
|
222
|
+
function getSourceAuthToken(source: CliEnvSource): CliAuthToken | undefined {
|
|
223
|
+
const authToken = getSourceValue(source, ['TRANSLOADIT_AUTH_TOKEN'])
|
|
224
|
+
if (authToken == null) return undefined
|
|
225
|
+
|
|
226
|
+
return { authToken }
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function resolveEndpointForSource(
|
|
230
|
+
source: CliEnvSource | undefined,
|
|
231
|
+
shellEnvSource: CliEnvSource,
|
|
232
|
+
): string | undefined {
|
|
233
|
+
const shellEndpoint = getSourceValue(shellEnvSource, ['TRANSLOADIT_ENDPOINT'])
|
|
234
|
+
if (shellEndpoint != null) return shellEndpoint
|
|
235
|
+
if (source == null) return undefined
|
|
236
|
+
|
|
237
|
+
return getSourceValue(source, ['TRANSLOADIT_ENDPOINT'])
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function resolveCliConfig(): ResolvedCliConfig {
|
|
241
|
+
const { loadError, shellEnvSource, sources } = loadCliEnvSources()
|
|
242
|
+
let auth: CliAuth | undefined
|
|
243
|
+
let authSource: CliEnvSource | undefined
|
|
244
|
+
let credentials: CliKeySecretCredentials | undefined
|
|
245
|
+
let credentialsSource: CliEnvSource | undefined
|
|
246
|
+
|
|
247
|
+
for (const source of sources) {
|
|
248
|
+
if (auth == null) {
|
|
249
|
+
const authToken = getSourceAuthToken(source)
|
|
250
|
+
if (authToken != null) {
|
|
251
|
+
auth = authToken
|
|
252
|
+
authSource = source
|
|
253
|
+
} else {
|
|
254
|
+
const sourceCredentials = getSourceCredentials(source)
|
|
255
|
+
if (sourceCredentials != null) {
|
|
256
|
+
auth = sourceCredentials
|
|
257
|
+
authSource = source
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (credentials != null) continue
|
|
263
|
+
|
|
264
|
+
const sourceCredentials = getSourceCredentials(source)
|
|
265
|
+
if (sourceCredentials != null) {
|
|
266
|
+
credentials = sourceCredentials
|
|
267
|
+
credentialsSource = source
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return {
|
|
272
|
+
...(auth != null ? { auth } : {}),
|
|
273
|
+
...(credentials != null ? { credentials } : {}),
|
|
274
|
+
...(authSource != null
|
|
275
|
+
? { endpoint: resolveEndpointForSource(authSource, shellEnvSource) }
|
|
276
|
+
: {}),
|
|
277
|
+
...(credentialsSource != null
|
|
278
|
+
? { credentialsEndpoint: resolveEndpointForSource(credentialsSource, shellEnvSource) }
|
|
279
|
+
: {}),
|
|
280
|
+
...(loadError != null ? { loadError } : {}),
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
type RequireCliCredentialsResult =
|
|
285
|
+
| { ok: true; credentials: CliKeySecretCredentials }
|
|
22
286
|
| { ok: false; error: string }
|
|
23
287
|
|
|
24
|
-
export function
|
|
25
|
-
const credentials =
|
|
26
|
-
if (credentials
|
|
27
|
-
return { ok:
|
|
288
|
+
export function requireCliCredentials(): RequireCliCredentialsResult {
|
|
289
|
+
const { credentials, loadError } = resolveCliConfig()
|
|
290
|
+
if (credentials != null) return { ok: true, credentials }
|
|
291
|
+
if (loadError != null) return { ok: false, error: loadError }
|
|
292
|
+
return { ok: false, error: buildMissingCredentialsMessage() }
|
|
28
293
|
}
|
|
29
294
|
|
|
30
295
|
export function createReadStream(file: string): Readable {
|
|
@@ -278,7 +278,7 @@ function inferExamples(
|
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
return [
|
|
281
|
-
['Run the command', `transloadit ${spec.paths.join(' ')} --input input.mp4 --
|
|
281
|
+
['Run the command', `transloadit ${spec.paths.join(' ')} --input input.mp4 --output output/`],
|
|
282
282
|
]
|
|
283
283
|
}
|
|
284
284
|
|
|
@@ -310,7 +310,7 @@ function inferExamples(
|
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
const outputMode = spec.intentDefinition.outputMode ?? 'file'
|
|
313
|
-
parts.push('--
|
|
313
|
+
parts.push('--output', inferOutputPath(spec.paths, outputMode, fieldSpecs))
|
|
314
314
|
|
|
315
315
|
return [['Run the command', parts.join(' ')]]
|
|
316
316
|
}
|
|
@@ -355,11 +355,13 @@ function resolveRobotIntent(definition: RobotIntentDefinition): BuiltIntentComma
|
|
|
355
355
|
input.kind === 'none'
|
|
356
356
|
? {
|
|
357
357
|
execution,
|
|
358
|
+
defaultOutputPath: inferOutputPath(paths, outputMode, fieldSpecs),
|
|
358
359
|
outputDescription: 'Write the result to this path',
|
|
359
360
|
outputMode,
|
|
360
361
|
}
|
|
361
362
|
: {
|
|
362
363
|
commandLabel,
|
|
364
|
+
defaultOutputPath: inferOutputPath(paths, outputMode, fieldSpecs),
|
|
363
365
|
execution,
|
|
364
366
|
inputPolicy: input.inputPolicy,
|
|
365
367
|
outputDescription:
|
|
@@ -388,18 +390,18 @@ function getIntentDetails({
|
|
|
388
390
|
robot: string
|
|
389
391
|
}): string {
|
|
390
392
|
if (inputMode === 'none') {
|
|
391
|
-
return `Runs \`${robot}\` and writes the result to \`--
|
|
393
|
+
return `Runs \`${robot}\` and writes the result to \`--output\`.`
|
|
392
394
|
}
|
|
393
395
|
|
|
394
396
|
if (defaultSingleAssembly) {
|
|
395
|
-
return `Runs \`${robot}\` for the provided inputs and writes the result to \`--
|
|
397
|
+
return `Runs \`${robot}\` for the provided inputs and writes the result to \`--output\`.`
|
|
396
398
|
}
|
|
397
399
|
|
|
398
400
|
if (outputMode === 'directory') {
|
|
399
|
-
return `Runs \`${robot}\` on each input file and writes the results to \`--
|
|
401
|
+
return `Runs \`${robot}\` on each input file and writes the results to \`--output\`.`
|
|
400
402
|
}
|
|
401
403
|
|
|
402
|
-
return `Runs \`${robot}\` on each input file and writes the result to \`--
|
|
404
|
+
return `Runs \`${robot}\` on each input file and writes the result to \`--output\`.`
|
|
403
405
|
}
|
|
404
406
|
|
|
405
407
|
function resolveSemanticIntent(definition: SemanticIntentDefinition): BuiltIntentCommandDefinition {
|
|
@@ -415,6 +417,7 @@ function resolveSemanticIntent(definition: SemanticIntentDefinition): BuiltInten
|
|
|
415
417
|
runnerKind: descriptor.runnerKind,
|
|
416
418
|
intentDefinition: {
|
|
417
419
|
commandLabel: paths.join(' '),
|
|
420
|
+
defaultOutputPath: descriptor.defaultOutputPath,
|
|
418
421
|
execution: descriptor.execution,
|
|
419
422
|
inputPolicy: descriptor.inputPolicy,
|
|
420
423
|
outputDescription: descriptor.outputDescription,
|
|
@@ -430,12 +433,13 @@ function resolveTemplateIntent(
|
|
|
430
433
|
const spec: BuiltIntentCommandDefinition = {
|
|
431
434
|
className: `${toPascalCase(paths)}Command`,
|
|
432
435
|
description: `Run ${stripTrailingPunctuation(definition.templateId)}`,
|
|
433
|
-
details: `Runs the \`${definition.templateId}\` template and writes the outputs to \`--
|
|
436
|
+
details: `Runs the \`${definition.templateId}\` template and writes the outputs to \`--output\`.`,
|
|
434
437
|
examples: [],
|
|
435
438
|
paths,
|
|
436
439
|
runnerKind: 'standard',
|
|
437
440
|
intentDefinition: {
|
|
438
441
|
commandLabel: paths.join(' '),
|
|
442
|
+
defaultOutputPath: inferOutputPath(paths, outputMode, []),
|
|
439
443
|
execution: {
|
|
440
444
|
kind: 'template',
|
|
441
445
|
templateId: definition.templateId,
|