@zapier/zapier-sdk-cli 0.66.2 → 0.66.3
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/CHANGELOG.md +9 -0
- package/dist/cli.cjs +300 -1759
- package/dist/cli.mjs +264 -1722
- package/dist/experimental.cjs +1 -1
- package/dist/experimental.mjs +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +3 -3
package/dist/cli.cjs
CHANGED
|
@@ -5,1554 +5,82 @@ var commander = require('commander');
|
|
|
5
5
|
var zapierSdk = require('@zapier/zapier-sdk');
|
|
6
6
|
var zod = require('zod');
|
|
7
7
|
var inquirer = require('inquirer');
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var ora = require('ora');
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var
|
|
15
|
-
var
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
var
|
|
19
|
-
var
|
|
20
|
-
var
|
|
21
|
-
var
|
|
22
|
-
var
|
|
23
|
-
var
|
|
24
|
-
var
|
|
25
|
-
var
|
|
26
|
-
var
|
|
27
|
-
var
|
|
28
|
-
var
|
|
29
|
-
var
|
|
30
|
-
var
|
|
31
|
-
var
|
|
32
|
-
var
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
var
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
get: function () { return e[k]; }
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
n.default = e;
|
|
57
|
-
return Object.freeze(n);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
61
|
-
var search__default = /*#__PURE__*/_interopDefault(search);
|
|
62
|
-
var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
63
|
-
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
64
|
-
var util__default = /*#__PURE__*/_interopDefault(util);
|
|
65
|
-
var wrapAnsi3__default = /*#__PURE__*/_interopDefault(wrapAnsi3);
|
|
66
|
-
var jwt__namespace = /*#__PURE__*/_interopNamespace(jwt);
|
|
67
|
-
var Conf__default = /*#__PURE__*/_interopDefault(Conf);
|
|
68
|
-
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
69
|
-
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
70
|
-
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
71
|
-
var lockfile__namespace = /*#__PURE__*/_interopNamespace(lockfile);
|
|
72
|
-
var express__default = /*#__PURE__*/_interopDefault(express);
|
|
73
|
-
var open__default = /*#__PURE__*/_interopDefault(open);
|
|
74
|
-
var pkceChallenge__default = /*#__PURE__*/_interopDefault(pkceChallenge);
|
|
75
|
-
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
76
|
-
var isInstalledGlobally__default = /*#__PURE__*/_interopDefault(isInstalledGlobally);
|
|
77
|
-
var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
|
|
78
|
-
var packageJsonLib__default = /*#__PURE__*/_interopDefault(packageJsonLib);
|
|
79
|
-
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
80
|
-
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
81
|
-
|
|
82
|
-
var __defProp = Object.defineProperty;
|
|
83
|
-
var __export = (target, all) => {
|
|
84
|
-
for (var name in all)
|
|
85
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
86
|
-
};
|
|
87
|
-
var ZapierCliError = class extends zapierSdk.ZapierError {
|
|
88
|
-
};
|
|
89
|
-
var ZapierCliUserCancellationError = class extends ZapierCliError {
|
|
90
|
-
constructor(message = "Operation cancelled by user") {
|
|
91
|
-
super(message);
|
|
92
|
-
this.name = "ZapierCliUserCancellationError";
|
|
93
|
-
this.code = "ZAPIER_CLI_USER_CANCELLATION";
|
|
94
|
-
this.exitCode = 0;
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
var ZapierCliExitError = class extends ZapierCliError {
|
|
98
|
-
constructor(message, exitCode = 1) {
|
|
99
|
-
super(message);
|
|
100
|
-
this.name = "ZapierCliExitError";
|
|
101
|
-
this.code = "ZAPIER_CLI_EXIT";
|
|
102
|
-
this.exitCode = exitCode;
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
var ZapierCliValidationError = class _ZapierCliValidationError extends ZapierCliError {
|
|
106
|
-
constructor(message, options = {}) {
|
|
107
|
-
super(message);
|
|
108
|
-
this.exitCode = 1;
|
|
109
|
-
this.name = options.name ?? "ZapierCliValidationError";
|
|
110
|
-
this.code = options.code ?? "ZAPIER_CLI_VALIDATION_ERROR";
|
|
111
|
-
}
|
|
112
|
-
withMessage(message) {
|
|
113
|
-
return new _ZapierCliValidationError(message, {
|
|
114
|
-
name: this.name,
|
|
115
|
-
code: this.code
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
var ZapierCliMissingParametersError = class extends ZapierCliError {
|
|
120
|
-
constructor(params) {
|
|
121
|
-
super(
|
|
122
|
-
`Missing required parameters: ${params.map((p) => p.name).join(", ")}`
|
|
123
|
-
);
|
|
124
|
-
this.name = "ZapierCliMissingParametersError";
|
|
125
|
-
this.code = "ZAPIER_CLI_MISSING_PARAMETERS";
|
|
126
|
-
this.exitCode = 1;
|
|
127
|
-
this.params = params;
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// src/utils/parameter-resolver.ts
|
|
132
|
-
function formatZodError(error) {
|
|
133
|
-
return error.issues.map((issue) => {
|
|
134
|
-
const field = issue.path.length > 0 ? issue.path.join(".") : "input";
|
|
135
|
-
return `${field}: ${issue.message}`;
|
|
136
|
-
}).join(", ");
|
|
137
|
-
}
|
|
138
|
-
function getLocalResolutionOrder(paramName, resolvers, resolved = /* @__PURE__ */ new Set()) {
|
|
139
|
-
const resolver = resolvers[paramName];
|
|
140
|
-
if (!resolver || resolver.type === "static" || resolver.type === "constant") {
|
|
141
|
-
return [paramName];
|
|
142
|
-
}
|
|
143
|
-
const order = [];
|
|
144
|
-
if ("depends" in resolver && resolver.depends) {
|
|
145
|
-
for (const dependency of resolver.depends) {
|
|
146
|
-
if (!resolved.has(dependency)) {
|
|
147
|
-
order.push(...getLocalResolutionOrder(dependency, resolvers, resolved));
|
|
148
|
-
resolved.add(dependency);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (!resolved.has(paramName)) {
|
|
153
|
-
order.push(paramName);
|
|
154
|
-
resolved.add(paramName);
|
|
155
|
-
}
|
|
156
|
-
return order;
|
|
157
|
-
}
|
|
158
|
-
function getLocalResolutionOrderForParams(paramNames, resolvers) {
|
|
159
|
-
const resolved = /* @__PURE__ */ new Set();
|
|
160
|
-
const order = [];
|
|
161
|
-
for (const paramName of paramNames) {
|
|
162
|
-
const paramOrder = getLocalResolutionOrder(paramName, resolvers, resolved);
|
|
163
|
-
for (const param of paramOrder) {
|
|
164
|
-
if (!order.includes(param)) {
|
|
165
|
-
order.push(param);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return order;
|
|
170
|
-
}
|
|
171
|
-
function unwrapSchema(schema) {
|
|
172
|
-
let current = schema;
|
|
173
|
-
while (current instanceof zod.z.ZodOptional || current instanceof zod.z.ZodDefault || current instanceof zod.z.ZodNullable) {
|
|
174
|
-
current = current._zod.def.innerType;
|
|
175
|
-
}
|
|
176
|
-
return current;
|
|
177
|
-
}
|
|
178
|
-
function coerceToSchemaType(value, schema) {
|
|
179
|
-
if (typeof value !== "string") return value;
|
|
180
|
-
const base = unwrapSchema(schema);
|
|
181
|
-
if (base instanceof zod.z.ZodNumber) {
|
|
182
|
-
const n = Number(value);
|
|
183
|
-
return Number.isNaN(n) ? value : n;
|
|
184
|
-
}
|
|
185
|
-
if (base instanceof zod.z.ZodBoolean) {
|
|
186
|
-
if (value === "true") return true;
|
|
187
|
-
if (value === "false") return false;
|
|
188
|
-
}
|
|
189
|
-
return value;
|
|
190
|
-
}
|
|
191
|
-
function renderChoiceLabel(choice) {
|
|
192
|
-
const baseName = choice.label ?? choice.name ?? "";
|
|
193
|
-
const alreadyNamed = choice.name === baseName;
|
|
194
|
-
let effectiveHint = choice.hint;
|
|
195
|
-
if (effectiveHint === void 0 && (typeof choice.value === "string" || typeof choice.value === "number")) {
|
|
196
|
-
effectiveHint = String(choice.value);
|
|
197
|
-
}
|
|
198
|
-
if (!effectiveHint || Array.isArray(effectiveHint) && effectiveHint.length === 0) {
|
|
199
|
-
return alreadyNamed ? choice : { ...choice, name: baseName };
|
|
200
|
-
}
|
|
201
|
-
const hintText = Array.isArray(effectiveHint) ? effectiveHint.join(", ") : effectiveHint;
|
|
202
|
-
if (hintText === baseName) {
|
|
203
|
-
return alreadyNamed ? choice : { ...choice, name: baseName };
|
|
204
|
-
}
|
|
205
|
-
return { ...choice, name: `${baseName} ${chalk__default.default.dim(`(${hintText})`)}` };
|
|
206
|
-
}
|
|
207
|
-
var SchemaParameterResolver = class {
|
|
208
|
-
constructor() {
|
|
209
|
-
this.debug = false;
|
|
210
|
-
this.spinner = null;
|
|
211
|
-
}
|
|
212
|
-
debugLog(message) {
|
|
213
|
-
if (this.debug) {
|
|
214
|
-
this.stopSpinner();
|
|
215
|
-
console.error(chalk__default.default.gray(`[Zapier CLI] ${message}`));
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
startSpinner() {
|
|
219
|
-
if (!this.debug && !this.spinner) {
|
|
220
|
-
this.spinner = ora__default.default({ text: "", spinner: "dots" }).start();
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
stopSpinner() {
|
|
224
|
-
if (this.spinner) {
|
|
225
|
-
this.spinner.stop();
|
|
226
|
-
this.spinner = null;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
async resolveParameters(schema, providedParams, sdk, functionName, options) {
|
|
230
|
-
return zapierSdk.runWithTelemetryContext(async () => {
|
|
231
|
-
this.debug = options?.debug ?? false;
|
|
232
|
-
const interactiveMode = (options?.interactiveMode ?? true) && !!process.stdin.isTTY;
|
|
233
|
-
const parseResult = schema.safeParse(providedParams);
|
|
234
|
-
const allParams = this.extractParametersFromSchema(schema);
|
|
235
|
-
const resolvableParams = allParams.filter(
|
|
236
|
-
(param) => this.hasResolver(param.name, sdk, functionName)
|
|
237
|
-
);
|
|
238
|
-
const missingResolvable = resolvableParams.filter((param) => {
|
|
239
|
-
const hasValue = this.getNestedValue(providedParams, param.path) !== void 0;
|
|
240
|
-
return !hasValue;
|
|
241
|
-
});
|
|
242
|
-
const required = missingResolvable.filter((param) => param.isRequired);
|
|
243
|
-
const optional = missingResolvable.filter((param) => !param.isRequired);
|
|
244
|
-
if (parseResult.success && required.length === 0 && optional.length === 0) {
|
|
245
|
-
return parseResult.data;
|
|
246
|
-
}
|
|
247
|
-
if (required.length === 0 && optional.length === 0) {
|
|
248
|
-
if (!parseResult.success) {
|
|
249
|
-
throw new ZapierCliValidationError(formatZodError(parseResult.error));
|
|
250
|
-
}
|
|
251
|
-
return parseResult.data;
|
|
252
|
-
}
|
|
253
|
-
const resolverConstants = this.getResolverConstants(sdk, functionName);
|
|
254
|
-
const resolvedParams = {
|
|
255
|
-
...resolverConstants,
|
|
256
|
-
...providedParams
|
|
257
|
-
};
|
|
258
|
-
const context = {
|
|
259
|
-
sdk,
|
|
260
|
-
currentParams: providedParams,
|
|
261
|
-
resolvedParams,
|
|
262
|
-
functionName
|
|
263
|
-
};
|
|
264
|
-
const localResolvers = this.getLocalResolvers(sdk, functionName);
|
|
265
|
-
if (required.length > 0) {
|
|
266
|
-
const requiredParamNames = required.map((p) => p.name);
|
|
267
|
-
const requiredResolutionOrder = getLocalResolutionOrderForParams(
|
|
268
|
-
requiredParamNames,
|
|
269
|
-
localResolvers
|
|
270
|
-
);
|
|
271
|
-
const orderedRequiredParams = requiredResolutionOrder.map((paramName) => {
|
|
272
|
-
let param = required.find((p) => p.name === paramName);
|
|
273
|
-
if (!param) {
|
|
274
|
-
param = optional.find((p) => p.name === paramName);
|
|
275
|
-
}
|
|
276
|
-
return param;
|
|
277
|
-
}).filter((param) => param !== void 0);
|
|
278
|
-
if (!interactiveMode) {
|
|
279
|
-
await this.resolveRequiredParamsNonInteractive(
|
|
280
|
-
orderedRequiredParams,
|
|
281
|
-
context,
|
|
282
|
-
resolvedParams,
|
|
283
|
-
functionName
|
|
284
|
-
);
|
|
285
|
-
} else {
|
|
286
|
-
for (const param of orderedRequiredParams) {
|
|
287
|
-
try {
|
|
288
|
-
const value = await this.resolveParameter(
|
|
289
|
-
param,
|
|
290
|
-
context,
|
|
291
|
-
functionName,
|
|
292
|
-
{ isOptional: !param.isRequired }
|
|
293
|
-
);
|
|
294
|
-
if (param.isRequired || value !== void 0) {
|
|
295
|
-
this.setNestedValue(resolvedParams, param.path, value);
|
|
296
|
-
context.resolvedParams = resolvedParams;
|
|
297
|
-
}
|
|
298
|
-
} catch (error) {
|
|
299
|
-
if (this.isUserCancellation(error)) {
|
|
300
|
-
console.log(chalk__default.default.yellow("\n\nOperation cancelled by user"));
|
|
301
|
-
throw new ZapierCliUserCancellationError();
|
|
302
|
-
}
|
|
303
|
-
throw error;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
const resolvedParamNames = new Set(
|
|
308
|
-
orderedRequiredParams.map((p) => p.name)
|
|
309
|
-
);
|
|
310
|
-
optional.splice(
|
|
311
|
-
0,
|
|
312
|
-
optional.length,
|
|
313
|
-
...optional.filter((p) => !resolvedParamNames.has(p.name))
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
if (interactiveMode && optional.length > 0) {
|
|
317
|
-
const optionalParamNames = optional.map((p) => p.name);
|
|
318
|
-
const optionalResolutionOrder = getLocalResolutionOrderForParams(
|
|
319
|
-
optionalParamNames,
|
|
320
|
-
localResolvers
|
|
321
|
-
);
|
|
322
|
-
const orderedOptionalParams = optionalResolutionOrder.map((paramName) => optional.find((p) => p.name === paramName)).filter((param) => param !== void 0);
|
|
323
|
-
for (const param of orderedOptionalParams) {
|
|
324
|
-
try {
|
|
325
|
-
const value = await this.resolveParameter(
|
|
326
|
-
param,
|
|
327
|
-
context,
|
|
328
|
-
functionName,
|
|
329
|
-
{ isOptional: true }
|
|
330
|
-
);
|
|
331
|
-
if (value !== void 0) {
|
|
332
|
-
this.setNestedValue(resolvedParams, param.path, value);
|
|
333
|
-
context.resolvedParams = resolvedParams;
|
|
334
|
-
}
|
|
335
|
-
} catch (error) {
|
|
336
|
-
if (this.isUserCancellation(error)) {
|
|
337
|
-
console.log(chalk__default.default.yellow("\n\nOperation cancelled by user"));
|
|
338
|
-
throw new ZapierCliUserCancellationError();
|
|
339
|
-
}
|
|
340
|
-
throw error;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
const finalResult = schema.safeParse(resolvedParams);
|
|
345
|
-
if (!finalResult.success) {
|
|
346
|
-
throw new ZapierCliValidationError(
|
|
347
|
-
`Parameter validation failed: ${formatZodError(finalResult.error)}`
|
|
348
|
-
);
|
|
349
|
-
}
|
|
350
|
-
return finalResult.data;
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
extractParametersFromSchema(schema) {
|
|
354
|
-
const parameters = [];
|
|
355
|
-
if (schema instanceof zod.z.ZodObject) {
|
|
356
|
-
const shape = schema.shape;
|
|
357
|
-
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
358
|
-
const param = this.analyzeFieldSchema(key, fieldSchema);
|
|
359
|
-
if (param) {
|
|
360
|
-
parameters.push(param);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
return parameters;
|
|
365
|
-
}
|
|
366
|
-
analyzeFieldSchema(fieldName, fieldSchema) {
|
|
367
|
-
let baseSchema = fieldSchema;
|
|
368
|
-
let isRequired = true;
|
|
369
|
-
if (baseSchema instanceof zod.z.ZodOptional) {
|
|
370
|
-
isRequired = false;
|
|
371
|
-
baseSchema = baseSchema._zod.def.innerType;
|
|
372
|
-
}
|
|
373
|
-
if (baseSchema instanceof zod.z.ZodDefault) {
|
|
374
|
-
isRequired = false;
|
|
375
|
-
baseSchema = baseSchema._zod.def.innerType;
|
|
376
|
-
}
|
|
377
|
-
return this.createResolvableParameter([fieldName], baseSchema, isRequired);
|
|
378
|
-
}
|
|
379
|
-
createResolvableParameter(path2, schema, isRequired) {
|
|
380
|
-
if (path2.length === 0) return null;
|
|
381
|
-
const name = path2[path2.length - 1];
|
|
382
|
-
return {
|
|
383
|
-
name,
|
|
384
|
-
path: path2,
|
|
385
|
-
schema,
|
|
386
|
-
description: schema.description,
|
|
387
|
-
isRequired
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Calls `tryResolveWithoutPrompt` on a dynamic resolver.
|
|
392
|
-
* Returns the resolution result object, or null if unresolvable / throws.
|
|
393
|
-
* Note: { resolvedValue: undefined } is a valid result (e.g. connection when app has no auth);
|
|
394
|
-
* only a null return from the resolver itself means "could not auto-resolve".
|
|
395
|
-
*/
|
|
396
|
-
async tryAutoResolve(dynamicResolver, context) {
|
|
397
|
-
if (!dynamicResolver.tryResolveWithoutPrompt) return null;
|
|
398
|
-
try {
|
|
399
|
-
return await dynamicResolver.tryResolveWithoutPrompt(
|
|
400
|
-
context.sdk,
|
|
401
|
-
context.resolvedParams
|
|
402
|
-
);
|
|
403
|
-
} catch (err) {
|
|
404
|
-
console.warn(
|
|
405
|
-
`Auto-resolver threw unexpectedly; treating as unresolved. Error: ${err instanceof Error ? err.message : String(err)}`
|
|
406
|
-
);
|
|
407
|
-
return null;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Non-interactive resolution: auto-resolves what it can via tryAutoResolve,
|
|
412
|
-
* throws ZapierCliMissingParametersError for anything that requires user input.
|
|
413
|
-
*/
|
|
414
|
-
async resolveRequiredParamsNonInteractive(params, context, resolvedParams, functionName) {
|
|
415
|
-
const missingParams = [];
|
|
416
|
-
for (const param of params) {
|
|
417
|
-
const resolver = this.getResolver(param.name, context.sdk, functionName);
|
|
418
|
-
let autoResolved = null;
|
|
419
|
-
if (resolver?.type === "constant") {
|
|
420
|
-
autoResolved = {
|
|
421
|
-
resolvedValue: resolver.value
|
|
422
|
-
};
|
|
423
|
-
} else if (resolver?.type === "dynamic") {
|
|
424
|
-
autoResolved = await this.tryAutoResolve(
|
|
425
|
-
resolver,
|
|
426
|
-
context
|
|
427
|
-
);
|
|
428
|
-
}
|
|
429
|
-
if (autoResolved != null) {
|
|
430
|
-
this.setNestedValue(
|
|
431
|
-
resolvedParams,
|
|
432
|
-
param.path,
|
|
433
|
-
autoResolved.resolvedValue
|
|
434
|
-
);
|
|
435
|
-
context.resolvedParams = resolvedParams;
|
|
436
|
-
} else {
|
|
437
|
-
missingParams.push({
|
|
438
|
-
name: param.name,
|
|
439
|
-
// Required params render as positional CLI args (<name>); so do explicitly positional optional params.
|
|
440
|
-
isPositional: param.isRequired || zapierSdk.isPositional(param.schema)
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
if (missingParams.length > 0) {
|
|
445
|
-
throw new ZapierCliMissingParametersError(missingParams);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Wrap a PromptConfig.validate so internal sentinels (Symbols) bypass
|
|
450
|
-
* it. The resolver's validator is intended for actual user values; our
|
|
451
|
-
* Skip / Custom / Load-more sentinels are internal control-flow and
|
|
452
|
-
* should pass through. Returns `undefined` when the resolver didn't
|
|
453
|
-
* supply a validator (so `await search({ ...rest })` doesn't get a
|
|
454
|
-
* pass-through identity function).
|
|
455
|
-
*/
|
|
456
|
-
wrapPromptValidate(validate) {
|
|
457
|
-
if (!validate) return void 0;
|
|
458
|
-
return (value) => typeof value === "symbol" ? true : validate(value);
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* Apply a PromptConfig.filter to a selected value, but only when the
|
|
462
|
-
* value is a real data choice (not an internal sentinel). @inquirer/search
|
|
463
|
-
* has no built-in filter hook, so the search-backed paths call this
|
|
464
|
-
* explicitly before returning.
|
|
465
|
-
*/
|
|
466
|
-
applyPromptFilter(filter, value) {
|
|
467
|
-
if (!filter || typeof value === "symbol") return value;
|
|
468
|
-
return filter(value);
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* If the resolver's PromptConfig sets a `default` value, move the
|
|
472
|
-
* matching choice to the front so it's the first selectable item in
|
|
473
|
-
* the rendered source. @inquirer/search has no built-in `default`
|
|
474
|
-
* option; first-selectable is what Enter picks, so reordering achieves
|
|
475
|
-
* the same semantics inquirer.prompt's list had natively.
|
|
476
|
-
*
|
|
477
|
-
* Returns the original array if no default is set or the default
|
|
478
|
-
* doesn't match any current choice.
|
|
479
|
-
*/
|
|
480
|
-
reorderForDefault(matches, defaultValue) {
|
|
481
|
-
if (defaultValue === void 0) return matches;
|
|
482
|
-
const idx = matches.findIndex((c) => c.value === defaultValue);
|
|
483
|
-
if (idx <= 0) return matches;
|
|
484
|
-
return [matches[idx], ...matches.slice(0, idx), ...matches.slice(idx + 1)];
|
|
485
|
-
}
|
|
486
|
-
/**
|
|
487
|
-
* Build the disabled "if you had X capability, more results would show"
|
|
488
|
-
* hints for any unmet capabilities the resolver declared. Returns the
|
|
489
|
-
* raw hint strings — callers wrap them into choice objects with whatever
|
|
490
|
-
* sentinel value they prefer (disabled choices' values are inert).
|
|
491
|
-
*/
|
|
492
|
-
async computeCapabilityHints(resolver, context) {
|
|
493
|
-
if (!resolver.requireCapabilities) return [];
|
|
494
|
-
const capContext = context.sdk.context;
|
|
495
|
-
if (!capContext.hasCapability) return [];
|
|
496
|
-
const messages = [];
|
|
497
|
-
for (const cap of resolver.requireCapabilities) {
|
|
498
|
-
const enabled = await capContext.hasCapability(cap);
|
|
499
|
-
if (!enabled) messages.push(zapierSdk.buildCapabilityMessage(cap));
|
|
500
|
-
}
|
|
501
|
-
return messages;
|
|
502
|
-
}
|
|
503
|
-
/**
|
|
504
|
-
* Unpack a DynamicResolver.fetch result into the three shapes the caller
|
|
505
|
-
* cares about: a flat items array, an optional AsyncIterator for further
|
|
506
|
-
* pagination, and a hasMore flag. Centralizing keeps the AsyncIterable /
|
|
507
|
-
* `{data, nextCursor}` / `TItem[]` discrimination in one place — both
|
|
508
|
-
* the main dropdown loop and the search-mode flow consume it.
|
|
509
|
-
*
|
|
510
|
-
* The function is `async` for the AsyncIterable branch only (we eagerly
|
|
511
|
-
* consume the first page so callers don't have to discriminate). The
|
|
512
|
-
* other two branches return synchronously; an explicit Promise.resolve
|
|
513
|
-
* is unnecessary because async automatically wraps.
|
|
514
|
-
*
|
|
515
|
-
* Note: callers in search mode intentionally drop `pageIterator` /
|
|
516
|
-
* `hasMore` because each search() invocation re-prompts from scratch;
|
|
517
|
-
* pagination only matters when the prompt is the dropdown itself.
|
|
518
|
-
*/
|
|
519
|
-
async unpackFetchResult(fetchResult, promptLabel) {
|
|
520
|
-
if (fetchResult != null && typeof fetchResult === "object" && Symbol.asyncIterator in fetchResult) {
|
|
521
|
-
const pageIterator = fetchResult[Symbol.asyncIterator]();
|
|
522
|
-
const first = await pageIterator.next();
|
|
523
|
-
if (!first.done && first.value) {
|
|
524
|
-
return {
|
|
525
|
-
items: Array.isArray(first.value.data) ? first.value.data : [],
|
|
526
|
-
pageIterator,
|
|
527
|
-
hasMore: first.value.nextCursor != null
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
return { items: [], pageIterator, hasMore: false };
|
|
531
|
-
}
|
|
532
|
-
if (fetchResult != null && typeof fetchResult === "object" && "data" in fetchResult) {
|
|
533
|
-
const page = fetchResult;
|
|
534
|
-
const hasMore = page.nextCursor != null;
|
|
535
|
-
if (hasMore) {
|
|
536
|
-
this.debugLog(
|
|
537
|
-
`Resolver for ${promptLabel} has more pages but no iterator. Return the paginated result's .pages() instead of an awaited page to enable "Load more..." support.`
|
|
538
|
-
);
|
|
539
|
-
}
|
|
540
|
-
return {
|
|
541
|
-
items: Array.isArray(page.data) ? page.data : [],
|
|
542
|
-
pageIterator: null,
|
|
543
|
-
hasMore
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
return {
|
|
547
|
-
items: Array.isArray(fetchResult) ? fetchResult : [],
|
|
548
|
-
pageIterator: null,
|
|
549
|
-
hasMore: false
|
|
550
|
-
};
|
|
551
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* Search-mode dynamic resolver: prompts the user for free-form text, passes
|
|
554
|
-
* it to fetch via `search`, and either short-circuits on a primitive return
|
|
555
|
-
* (exact match) or renders the results as a search-filterable dropdown.
|
|
556
|
-
* Empty results still render the dropdown so the user can fall through to
|
|
557
|
-
* "(Use 'foo' as-is)" or "(Try a different search)" rather than being
|
|
558
|
-
* stuck.
|
|
559
|
-
*
|
|
560
|
-
* Known limitation: pagination beyond the first page is dropped. Each
|
|
561
|
-
* search() invocation re-prompts from scratch and the user is expected
|
|
562
|
-
* to refine their query if too many results came back. If a future
|
|
563
|
-
* high-cardinality search resolver needs Load-more here, the
|
|
564
|
-
* `pageIterator` / `hasMore` from `unpackFetchResult` is what to wire in.
|
|
565
|
-
*/
|
|
566
|
-
async resolveDynamicWithSearchInput({
|
|
567
|
-
resolver,
|
|
568
|
-
context,
|
|
569
|
-
promptLabel,
|
|
570
|
-
isOptional
|
|
571
|
-
}) {
|
|
572
|
-
const parenParts = [];
|
|
573
|
-
if (isOptional) parenParts.push("optional");
|
|
574
|
-
if (resolver.placeholder) parenParts.push(resolver.placeholder);
|
|
575
|
-
const parens = parenParts.length > 0 ? ` (${parenParts.join(", ")})` : "";
|
|
576
|
-
const message = `Enter or search ${promptLabel}${parens}:`;
|
|
577
|
-
const SKIP_SENTINEL = Symbol("SKIP");
|
|
578
|
-
const USE_AS_IS_SENTINEL = Symbol("USE_AS_IS");
|
|
579
|
-
const TRY_AGAIN_SENTINEL = Symbol("TRY_AGAIN");
|
|
580
|
-
let lastNote;
|
|
581
|
-
while (true) {
|
|
582
|
-
this.stopSpinner();
|
|
583
|
-
if (lastNote) {
|
|
584
|
-
console.log(chalk__default.default.yellow(lastNote));
|
|
585
|
-
lastNote = void 0;
|
|
586
|
-
}
|
|
587
|
-
const answers = await inquirer__default.default.prompt([
|
|
588
|
-
{ type: "input", name: "search", message }
|
|
589
|
-
]);
|
|
590
|
-
const rawInput = answers.search;
|
|
591
|
-
const searchInput = typeof rawInput === "string" ? rawInput.trim() : "";
|
|
592
|
-
if (!searchInput) {
|
|
593
|
-
if (isOptional) return void 0;
|
|
594
|
-
lastNote = `${promptLabel} is required.`;
|
|
595
|
-
continue;
|
|
596
|
-
}
|
|
597
|
-
const searchParams = {
|
|
598
|
-
...context.resolvedParams,
|
|
599
|
-
search: searchInput
|
|
600
|
-
};
|
|
601
|
-
this.startSpinner();
|
|
602
|
-
this.debugLog(`Searching ${promptLabel} for "${searchInput}"`);
|
|
603
|
-
let fetchResult;
|
|
604
|
-
try {
|
|
605
|
-
fetchResult = await resolver.fetch(context.sdk, searchParams);
|
|
606
|
-
} finally {
|
|
607
|
-
this.stopSpinner();
|
|
608
|
-
}
|
|
609
|
-
if (typeof fetchResult === "string" || typeof fetchResult === "number") {
|
|
610
|
-
return fetchResult;
|
|
611
|
-
}
|
|
612
|
-
const { items } = await this.unpackFetchResult(fetchResult, promptLabel);
|
|
613
|
-
const choicesConfig = resolver.prompt(items, searchParams);
|
|
614
|
-
const dataChoices = (choicesConfig.choices ?? []).map(renderChoiceLabel);
|
|
615
|
-
const capabilityHintMessages = await this.computeCapabilityHints(
|
|
616
|
-
resolver,
|
|
617
|
-
context
|
|
618
|
-
);
|
|
619
|
-
const selected = await search__default.default({
|
|
620
|
-
message: choicesConfig.message,
|
|
621
|
-
validate: this.wrapPromptValidate(choicesConfig.validate),
|
|
622
|
-
// @inquirer/search passes an AbortSignal as the second arg for
|
|
623
|
-
// cancelling async sources. All three of our source callbacks are
|
|
624
|
-
// pure-local (filter an already-fetched array), so we intentionally
|
|
625
|
-
// ignore the signal. A future server-side filter implementation
|
|
626
|
-
// would need to honor it.
|
|
627
|
-
source: (term) => {
|
|
628
|
-
const trimmed = (term ?? "").trim();
|
|
629
|
-
const lower = trimmed.toLowerCase();
|
|
630
|
-
const matches = trimmed ? dataChoices.filter((c) => c.name.toLowerCase().includes(lower)) : dataChoices;
|
|
631
|
-
const orderedMatches = trimmed ? matches : this.reorderForDefault(matches, choicesConfig.default);
|
|
632
|
-
const skipChoice = isOptional ? [{ name: chalk__default.default.dim("(Skip)"), value: SKIP_SENTINEL }] : [];
|
|
633
|
-
const useAsIsChoice = {
|
|
634
|
-
name: chalk__default.default.dim(`(Use ${JSON.stringify(searchInput)} as-is)`),
|
|
635
|
-
value: USE_AS_IS_SENTINEL
|
|
636
|
-
};
|
|
637
|
-
const tryAgainChoice = {
|
|
638
|
-
name: chalk__default.default.dim("(Try a different search)"),
|
|
639
|
-
value: TRY_AGAIN_SENTINEL
|
|
640
|
-
};
|
|
641
|
-
const out2 = [];
|
|
642
|
-
if (orderedMatches.length === 0) {
|
|
643
|
-
out2.push(useAsIsChoice);
|
|
644
|
-
out2.push(tryAgainChoice);
|
|
645
|
-
out2.push(...skipChoice);
|
|
646
|
-
} else {
|
|
647
|
-
out2.push(...orderedMatches);
|
|
648
|
-
out2.push(...skipChoice);
|
|
649
|
-
out2.push(useAsIsChoice);
|
|
650
|
-
out2.push(tryAgainChoice);
|
|
651
|
-
}
|
|
652
|
-
for (const message2 of capabilityHintMessages) {
|
|
653
|
-
out2.push({
|
|
654
|
-
name: chalk__default.default.dim(message2),
|
|
655
|
-
value: SKIP_SENTINEL,
|
|
656
|
-
disabled: true
|
|
657
|
-
});
|
|
658
|
-
}
|
|
659
|
-
return out2;
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
if (selected === SKIP_SENTINEL) return void 0;
|
|
663
|
-
if (selected === USE_AS_IS_SENTINEL) {
|
|
664
|
-
const validationResult = choicesConfig.validate?.(searchInput);
|
|
665
|
-
if (validationResult === false) {
|
|
666
|
-
lastNote = `${promptLabel}: invalid value.`;
|
|
667
|
-
continue;
|
|
668
|
-
}
|
|
669
|
-
if (typeof validationResult === "string") {
|
|
670
|
-
lastNote = validationResult;
|
|
671
|
-
continue;
|
|
672
|
-
}
|
|
673
|
-
return this.applyPromptFilter(choicesConfig.filter, searchInput);
|
|
674
|
-
}
|
|
675
|
-
if (selected === TRY_AGAIN_SENTINEL) continue;
|
|
676
|
-
return this.applyPromptFilter(choicesConfig.filter, selected);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
async resolveParameter(param, context, functionName, options) {
|
|
680
|
-
const resolver = this.getResolver(
|
|
681
|
-
param.name,
|
|
682
|
-
context.sdk,
|
|
683
|
-
functionName
|
|
684
|
-
);
|
|
685
|
-
if (!resolver) {
|
|
686
|
-
throw new Error(`No resolver found for parameter: ${param.name}`);
|
|
687
|
-
}
|
|
688
|
-
return this.resolveWithResolver(resolver, param, context, {
|
|
689
|
-
isOptional: options?.isOptional
|
|
690
|
-
});
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Run a resolver to obtain a value for one parameter, prompting the
|
|
694
|
-
* user when necessary. Routes to one of several prompt backends and
|
|
695
|
-
* has to keep the `PromptConfig` contract honest across each one.
|
|
696
|
-
*
|
|
697
|
-
* `PromptConfig` field × prompt-backend handling:
|
|
698
|
-
*
|
|
699
|
-
* | field | list (search()) | checkbox/confirm (inquirer.prompt) | search-mode dropdown (search()) |
|
|
700
|
-
* | -------- | --------------- | ---------------------------------- | ------------------------------- |
|
|
701
|
-
* | type | required | required | required |
|
|
702
|
-
* | name | (set internally)| forwarded | (set internally) |
|
|
703
|
-
* | message | forwarded | forwarded | forwarded |
|
|
704
|
-
* | choices | filtered in src | passed to inquirer | filtered in src |
|
|
705
|
-
* | default | reorder matches | passed (also internal cursor jump) | reorder matches |
|
|
706
|
-
* | validate | wrapped | passed (inquirer native) | wrapped + manual for (Use as-is)|
|
|
707
|
-
* | filter | manual once | inquirer native (do NOT double) | manual once |
|
|
708
|
-
*
|
|
709
|
-
* Escape-hatch sentinels (Skip / Custom value / Use as-is / Load more
|
|
710
|
-
* / Try again) bypass the resolver's validate/filter because they
|
|
711
|
-
* aren't real user values — they're CLI control-flow.
|
|
712
|
-
*/
|
|
713
|
-
async resolveWithResolver(resolver, param, context, options = {}) {
|
|
714
|
-
const { arrayIndex, isOptional } = options;
|
|
715
|
-
const inArrayContext = arrayIndex != null;
|
|
716
|
-
const promptLabel = inArrayContext ? `${param.name}[${arrayIndex}]` : param.name;
|
|
717
|
-
const promptName = inArrayContext ? "value" : param.name;
|
|
718
|
-
this.debugLog(`Resolving ${promptLabel}${isOptional ? " (optional)" : ""}`);
|
|
719
|
-
if (resolver.type === "constant") {
|
|
720
|
-
const constantResolver = resolver;
|
|
721
|
-
this.stopSpinner();
|
|
722
|
-
return constantResolver.value;
|
|
723
|
-
} else if (resolver.type === "static") {
|
|
724
|
-
const staticResolver = resolver;
|
|
725
|
-
const promptConfig = {
|
|
726
|
-
type: staticResolver.inputType === "password" ? "password" : "input",
|
|
727
|
-
name: promptName,
|
|
728
|
-
message: `Enter ${promptLabel}${isOptional ? " (optional)" : ""}:`,
|
|
729
|
-
...staticResolver.placeholder && {
|
|
730
|
-
default: staticResolver.placeholder
|
|
731
|
-
}
|
|
732
|
-
};
|
|
733
|
-
this.stopSpinner();
|
|
734
|
-
const answers = await inquirer__default.default.prompt([promptConfig]);
|
|
735
|
-
const value = answers[promptName];
|
|
736
|
-
if (isOptional && (value === void 0 || value === "" || value === staticResolver.placeholder)) {
|
|
737
|
-
return void 0;
|
|
738
|
-
}
|
|
739
|
-
return coerceToSchemaType(value, param.schema);
|
|
740
|
-
} else if (resolver.type === "dynamic") {
|
|
741
|
-
const dynamicResolver = resolver;
|
|
742
|
-
this.startSpinner();
|
|
743
|
-
const autoResolution = await this.tryAutoResolve(
|
|
744
|
-
dynamicResolver,
|
|
745
|
-
context
|
|
746
|
-
);
|
|
747
|
-
if (autoResolution != null) {
|
|
748
|
-
this.stopSpinner();
|
|
749
|
-
return autoResolution.resolvedValue;
|
|
750
|
-
}
|
|
751
|
-
if (dynamicResolver.inputType === "search") {
|
|
752
|
-
this.stopSpinner();
|
|
753
|
-
return await this.resolveDynamicWithSearchInput({
|
|
754
|
-
resolver: dynamicResolver,
|
|
755
|
-
context,
|
|
756
|
-
promptLabel,
|
|
757
|
-
isOptional: isOptional ?? false
|
|
758
|
-
});
|
|
759
|
-
}
|
|
760
|
-
this.debugLog(`Fetching options for ${promptLabel}`);
|
|
761
|
-
let fetchResult;
|
|
762
|
-
try {
|
|
763
|
-
fetchResult = await dynamicResolver.fetch(
|
|
764
|
-
context.sdk,
|
|
765
|
-
context.resolvedParams
|
|
766
|
-
);
|
|
767
|
-
} finally {
|
|
768
|
-
this.stopSpinner();
|
|
769
|
-
}
|
|
770
|
-
if (typeof fetchResult === "string" || typeof fetchResult === "number") {
|
|
771
|
-
console.error(
|
|
772
|
-
chalk__default.default.yellow(
|
|
773
|
-
`Resolver for ${promptLabel} returned a primitive value but is not in search mode. Set inputType: "search" on the resolver if you want exact-match short-circuit. Falling back to manual entry.`
|
|
774
|
-
)
|
|
775
|
-
);
|
|
776
|
-
const fallbackAnswers = await inquirer__default.default.prompt([
|
|
777
|
-
{
|
|
778
|
-
type: "input",
|
|
779
|
-
name: promptName,
|
|
780
|
-
message: `Enter ${promptLabel}${isOptional ? " (optional)" : ""}:`
|
|
781
|
-
}
|
|
782
|
-
]);
|
|
783
|
-
const fallbackValue = fallbackAnswers[promptName];
|
|
784
|
-
if (isOptional && (fallbackValue === void 0 || fallbackValue === "")) {
|
|
785
|
-
return void 0;
|
|
786
|
-
}
|
|
787
|
-
return fallbackValue;
|
|
788
|
-
}
|
|
789
|
-
const unpacked = await this.unpackFetchResult(fetchResult, promptLabel);
|
|
790
|
-
let pageIterator = unpacked.pageIterator;
|
|
791
|
-
let items = unpacked.items;
|
|
792
|
-
let hasMore = unpacked.hasMore;
|
|
793
|
-
const LOAD_MORE_SENTINEL = Symbol("LOAD_MORE");
|
|
794
|
-
const SKIP_SENTINEL = Symbol("SKIP");
|
|
795
|
-
const CUSTOM_VALUE_SENTINEL = Symbol("CUSTOM_VALUE");
|
|
796
|
-
let newItemsStartIndex = -1;
|
|
797
|
-
while (true) {
|
|
798
|
-
const promptConfig = dynamicResolver.prompt(
|
|
799
|
-
items,
|
|
800
|
-
context.resolvedParams
|
|
801
|
-
);
|
|
802
|
-
promptConfig.name = promptName;
|
|
803
|
-
const renderedChoices = promptConfig.choices ? promptConfig.choices.map(renderChoiceLabel) : [];
|
|
804
|
-
if (promptConfig.choices) {
|
|
805
|
-
promptConfig.choices = renderedChoices;
|
|
806
|
-
}
|
|
807
|
-
const hasSelectableChoice = promptConfig.choices?.some(
|
|
808
|
-
(c) => !c.disabled
|
|
809
|
-
);
|
|
810
|
-
if (!hasSelectableChoice && !hasMore) {
|
|
811
|
-
throw new ZapierCliValidationError(
|
|
812
|
-
`No ${promptLabel} available to select.`
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
const capabilityHints = [];
|
|
816
|
-
if (!hasMore) {
|
|
817
|
-
const hintMessages = await this.computeCapabilityHints(
|
|
818
|
-
dynamicResolver,
|
|
819
|
-
context
|
|
820
|
-
);
|
|
821
|
-
for (const message of hintMessages) {
|
|
822
|
-
capabilityHints.push({
|
|
823
|
-
name: chalk__default.default.dim(message),
|
|
824
|
-
value: SKIP_SENTINEL,
|
|
825
|
-
disabled: true
|
|
826
|
-
});
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
let selected;
|
|
830
|
-
if (promptConfig.type === "list") {
|
|
831
|
-
const dataChoices = renderedChoices;
|
|
832
|
-
selected = await search__default.default({
|
|
833
|
-
message: promptConfig.message,
|
|
834
|
-
validate: this.wrapPromptValidate(promptConfig.validate),
|
|
835
|
-
source: (term) => {
|
|
836
|
-
const trimmed = (term ?? "").trim();
|
|
837
|
-
const lower = trimmed.toLowerCase();
|
|
838
|
-
const matches = trimmed ? dataChoices.filter(
|
|
839
|
-
(c) => c.name.toLowerCase().includes(lower)
|
|
840
|
-
) : dataChoices;
|
|
841
|
-
const out2 = [];
|
|
842
|
-
const skipChoice = isOptional ? [
|
|
843
|
-
{
|
|
844
|
-
name: chalk__default.default.dim("(Skip)"),
|
|
845
|
-
value: SKIP_SENTINEL
|
|
846
|
-
}
|
|
847
|
-
] : [];
|
|
848
|
-
const customValueChoice = {
|
|
849
|
-
name: chalk__default.default.dim("(Enter custom value)"),
|
|
850
|
-
value: CUSTOM_VALUE_SENTINEL
|
|
851
|
-
};
|
|
852
|
-
const orderedMatches = trimmed ? matches : this.reorderForDefault(matches, promptConfig.default);
|
|
853
|
-
const matchesFirst = trimmed || promptConfig.default !== void 0;
|
|
854
|
-
const loadMoreChoice = hasMore && pageIterator ? {
|
|
855
|
-
name: chalk__default.default.dim("(Load more...)"),
|
|
856
|
-
value: LOAD_MORE_SENTINEL
|
|
857
|
-
} : null;
|
|
858
|
-
if (matchesFirst && orderedMatches.length > 0) {
|
|
859
|
-
out2.push(...orderedMatches);
|
|
860
|
-
out2.push(...skipChoice);
|
|
861
|
-
out2.push(customValueChoice);
|
|
862
|
-
if (loadMoreChoice) out2.push(loadMoreChoice);
|
|
863
|
-
} else if (matchesFirst) {
|
|
864
|
-
out2.push(customValueChoice);
|
|
865
|
-
if (loadMoreChoice) out2.push(loadMoreChoice);
|
|
866
|
-
out2.push(...skipChoice);
|
|
867
|
-
} else {
|
|
868
|
-
out2.push(...skipChoice);
|
|
869
|
-
out2.push(customValueChoice);
|
|
870
|
-
out2.push(...orderedMatches);
|
|
871
|
-
if (loadMoreChoice) out2.push(loadMoreChoice);
|
|
872
|
-
}
|
|
873
|
-
if (capabilityHints.length > 0 && (!trimmed || matches.length > 0)) {
|
|
874
|
-
out2.push(...capabilityHints);
|
|
875
|
-
}
|
|
876
|
-
return out2;
|
|
877
|
-
}
|
|
878
|
-
});
|
|
879
|
-
} else {
|
|
880
|
-
if (isOptional && promptConfig.choices) {
|
|
881
|
-
promptConfig.choices.unshift({
|
|
882
|
-
name: chalk__default.default.dim("(Skip)"),
|
|
883
|
-
value: SKIP_SENTINEL
|
|
884
|
-
});
|
|
885
|
-
}
|
|
886
|
-
if (hasMore && pageIterator && promptConfig.choices) {
|
|
887
|
-
promptConfig.choices.push({
|
|
888
|
-
name: chalk__default.default.dim("(Load more...)"),
|
|
889
|
-
value: LOAD_MORE_SENTINEL
|
|
890
|
-
});
|
|
891
|
-
}
|
|
892
|
-
if (capabilityHints.length > 0 && promptConfig.choices) {
|
|
893
|
-
promptConfig.choices.push(...capabilityHints);
|
|
894
|
-
}
|
|
895
|
-
if (newItemsStartIndex >= 0 && promptConfig.choices) {
|
|
896
|
-
const injectedBefore = isOptional ? 1 : 0;
|
|
897
|
-
const adjustedIndex = newItemsStartIndex + injectedBefore;
|
|
898
|
-
if (promptConfig.choices[adjustedIndex]) {
|
|
899
|
-
promptConfig.default = promptConfig.choices[adjustedIndex].value;
|
|
900
|
-
}
|
|
901
|
-
newItemsStartIndex = -1;
|
|
902
|
-
}
|
|
903
|
-
const answers = await inquirer__default.default.prompt([promptConfig]);
|
|
904
|
-
selected = answers[promptName];
|
|
905
|
-
}
|
|
906
|
-
if (selected === SKIP_SENTINEL) {
|
|
907
|
-
return void 0;
|
|
908
|
-
}
|
|
909
|
-
if (selected === CUSTOM_VALUE_SENTINEL) {
|
|
910
|
-
const customAnswer = await inquirer__default.default.prompt([
|
|
911
|
-
{
|
|
912
|
-
type: "input",
|
|
913
|
-
name: promptName,
|
|
914
|
-
message: `Enter ${promptLabel}${isOptional ? " (optional)" : ""}:`
|
|
915
|
-
}
|
|
916
|
-
]);
|
|
917
|
-
const value = customAnswer[promptName];
|
|
918
|
-
if (isOptional && (value === void 0 || value === "")) {
|
|
919
|
-
return void 0;
|
|
920
|
-
}
|
|
921
|
-
return value;
|
|
922
|
-
}
|
|
923
|
-
const wantsMore = Array.isArray(selected) ? selected.includes(LOAD_MORE_SENTINEL) : selected === LOAD_MORE_SENTINEL;
|
|
924
|
-
if (wantsMore && pageIterator) {
|
|
925
|
-
if (Array.isArray(selected)) {
|
|
926
|
-
selected = selected.filter(
|
|
927
|
-
(v) => v !== LOAD_MORE_SENTINEL
|
|
928
|
-
);
|
|
929
|
-
}
|
|
930
|
-
const prevLength = items.length;
|
|
931
|
-
this.startSpinner();
|
|
932
|
-
this.debugLog("Fetching more options...");
|
|
933
|
-
const next = await pageIterator.next();
|
|
934
|
-
this.stopSpinner();
|
|
935
|
-
if (!next.done && next.value) {
|
|
936
|
-
items = [...items, ...next.value.data];
|
|
937
|
-
hasMore = next.value.nextCursor != null;
|
|
938
|
-
newItemsStartIndex = prevLength;
|
|
939
|
-
} else {
|
|
940
|
-
hasMore = false;
|
|
941
|
-
}
|
|
942
|
-
continue;
|
|
943
|
-
}
|
|
944
|
-
return promptConfig.type === "list" ? this.applyPromptFilter(promptConfig.filter, selected) : selected;
|
|
945
|
-
}
|
|
946
|
-
} else if (resolver.type === "fields") {
|
|
947
|
-
if (isOptional && !inArrayContext) {
|
|
948
|
-
this.stopSpinner();
|
|
949
|
-
const { confirm } = await inquirer__default.default.prompt([
|
|
950
|
-
{
|
|
951
|
-
type: "confirm",
|
|
952
|
-
name: "confirm",
|
|
953
|
-
message: `Add ${promptLabel}?`,
|
|
954
|
-
default: false
|
|
955
|
-
}
|
|
956
|
-
]);
|
|
957
|
-
if (!confirm) {
|
|
958
|
-
return void 0;
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
return await this.resolveFieldsRecursively(
|
|
962
|
-
resolver,
|
|
963
|
-
context,
|
|
964
|
-
param,
|
|
965
|
-
{ inArrayContext }
|
|
966
|
-
);
|
|
967
|
-
} else if (resolver.type === "array") {
|
|
968
|
-
return await this.resolveArrayRecursively(
|
|
969
|
-
resolver,
|
|
970
|
-
context,
|
|
971
|
-
param
|
|
972
|
-
);
|
|
973
|
-
}
|
|
974
|
-
throw new Error(`Unknown resolver type for ${promptLabel}`);
|
|
975
|
-
}
|
|
976
|
-
async resolveFieldsRecursively(resolver, context, param, options = {}) {
|
|
977
|
-
const inputs = {};
|
|
978
|
-
let processedFieldKeys = /* @__PURE__ */ new Set();
|
|
979
|
-
let iteration = 0;
|
|
980
|
-
const maxIterations = 10;
|
|
981
|
-
while (iteration < maxIterations) {
|
|
982
|
-
iteration++;
|
|
983
|
-
const updatedContext = {
|
|
984
|
-
...context,
|
|
985
|
-
resolvedParams: {
|
|
986
|
-
...context.resolvedParams,
|
|
987
|
-
inputs
|
|
988
|
-
}
|
|
989
|
-
};
|
|
990
|
-
this.debugLog(
|
|
991
|
-
`Fetching input fields for ${param.name}${iteration > 1 ? ` (iteration ${iteration})` : ""}`
|
|
992
|
-
);
|
|
993
|
-
this.startSpinner();
|
|
994
|
-
const rootFieldItems = await resolver.fetch(
|
|
995
|
-
updatedContext.sdk,
|
|
996
|
-
updatedContext.resolvedParams
|
|
997
|
-
);
|
|
998
|
-
this.stopSpinner();
|
|
999
|
-
if (!rootFieldItems || rootFieldItems.length === 0) {
|
|
1000
|
-
if (iteration === 1) {
|
|
1001
|
-
console.log(
|
|
1002
|
-
chalk__default.default.yellow(`No input fields required for this action.`)
|
|
1003
|
-
);
|
|
1004
|
-
}
|
|
1005
|
-
break;
|
|
1006
|
-
}
|
|
1007
|
-
const fieldStats = await this.processFieldItems(
|
|
1008
|
-
rootFieldItems,
|
|
1009
|
-
inputs,
|
|
1010
|
-
processedFieldKeys,
|
|
1011
|
-
[],
|
|
1012
|
-
iteration,
|
|
1013
|
-
updatedContext,
|
|
1014
|
-
{ inArrayContext: options.inArrayContext }
|
|
1015
|
-
);
|
|
1016
|
-
if (fieldStats.newRequired === 0 && fieldStats.newOptional === 0) {
|
|
1017
|
-
break;
|
|
1018
|
-
}
|
|
1019
|
-
if (fieldStats.newRequired === 0 && fieldStats.optionalSkipped) {
|
|
1020
|
-
break;
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
if (iteration >= maxIterations) {
|
|
1024
|
-
console.log(
|
|
1025
|
-
chalk__default.default.yellow(
|
|
1026
|
-
`
|
|
1027
|
-
\u26A0\uFE0F Maximum field resolution iterations reached. Some dynamic fields may not have been discovered.`
|
|
1028
|
-
)
|
|
1029
|
-
);
|
|
1030
|
-
}
|
|
1031
|
-
if (resolver.transform) {
|
|
1032
|
-
return resolver.transform(inputs);
|
|
1033
|
-
}
|
|
1034
|
-
return inputs;
|
|
1035
|
-
}
|
|
1036
|
-
/**
|
|
1037
|
-
* Resolves an array parameter by repeatedly prompting for items until user says no
|
|
1038
|
-
*/
|
|
1039
|
-
async resolveArrayRecursively(resolver, context, param) {
|
|
1040
|
-
const items = [];
|
|
1041
|
-
const minItems = resolver.minItems ?? 0;
|
|
1042
|
-
const maxItems = resolver.maxItems ?? Infinity;
|
|
1043
|
-
while (items.length < maxItems) {
|
|
1044
|
-
const currentIndex = items.length;
|
|
1045
|
-
if (currentIndex >= minItems) {
|
|
1046
|
-
this.stopSpinner();
|
|
1047
|
-
const confirmAnswer = await inquirer__default.default.prompt([
|
|
1048
|
-
{
|
|
1049
|
-
type: "confirm",
|
|
1050
|
-
name: "addItem",
|
|
1051
|
-
message: `Add ${param.name}[${currentIndex}]?`,
|
|
1052
|
-
default: false
|
|
1053
|
-
}
|
|
1054
|
-
]);
|
|
1055
|
-
if (!confirmAnswer.addItem) {
|
|
1056
|
-
break;
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
const innerResolver = await resolver.fetch(
|
|
1060
|
-
context.sdk,
|
|
1061
|
-
context.resolvedParams
|
|
1062
|
-
);
|
|
1063
|
-
const itemValue = await this.resolveWithResolver(
|
|
1064
|
-
innerResolver,
|
|
1065
|
-
param,
|
|
1066
|
-
context,
|
|
1067
|
-
{ arrayIndex: currentIndex }
|
|
1068
|
-
);
|
|
1069
|
-
items.push(itemValue);
|
|
1070
|
-
context.resolvedParams = {
|
|
1071
|
-
...context.resolvedParams,
|
|
1072
|
-
[param.name]: items
|
|
1073
|
-
};
|
|
1074
|
-
}
|
|
1075
|
-
if (items.length >= maxItems) {
|
|
1076
|
-
console.log(chalk__default.default.gray(`Maximum of ${maxItems} items reached.`));
|
|
1077
|
-
}
|
|
1078
|
-
return items;
|
|
1079
|
-
}
|
|
1080
|
-
/**
|
|
1081
|
-
* Recursively processes fieldsets and their fields, maintaining natural structure
|
|
1082
|
-
* and creating nested inputs as needed (e.g., fieldset "foo" becomes inputs.foo = [{}])
|
|
1083
|
-
*/
|
|
1084
|
-
async processFieldItems(items, targetInputs, processedFieldKeys, fieldsetPath = [], iteration = 1, context, options = {}) {
|
|
1085
|
-
let newRequiredCount = 0;
|
|
1086
|
-
let newOptionalCount = 0;
|
|
1087
|
-
let optionalSkipped = false;
|
|
1088
|
-
for (const item of items) {
|
|
1089
|
-
const typedItem = item;
|
|
1090
|
-
if (typedItem.type === "fieldset" && typedItem.fields && typedItem.key) {
|
|
1091
|
-
const fieldsetTitle = typedItem.title || typedItem.key;
|
|
1092
|
-
const pathDisplay = fieldsetPath.length > 0 ? ` (in ${fieldsetPath.join(" > ")})` : "";
|
|
1093
|
-
console.log(
|
|
1094
|
-
chalk__default.default.cyan(
|
|
1095
|
-
`
|
|
1096
|
-
\u{1F4C1} Processing fieldset: ${fieldsetTitle}${pathDisplay}`
|
|
1097
|
-
)
|
|
1098
|
-
);
|
|
1099
|
-
if (!targetInputs[typedItem.key]) {
|
|
1100
|
-
targetInputs[typedItem.key] = [{}];
|
|
1101
|
-
}
|
|
1102
|
-
const fieldsetTarget = targetInputs[typedItem.key][0];
|
|
1103
|
-
const nestedPath = [...fieldsetPath, fieldsetTitle];
|
|
1104
|
-
const nestedStats = await this.processFieldItems(
|
|
1105
|
-
typedItem.fields,
|
|
1106
|
-
fieldsetTarget,
|
|
1107
|
-
processedFieldKeys,
|
|
1108
|
-
nestedPath,
|
|
1109
|
-
iteration,
|
|
1110
|
-
context,
|
|
1111
|
-
options
|
|
1112
|
-
);
|
|
1113
|
-
newRequiredCount += nestedStats.newRequired;
|
|
1114
|
-
newOptionalCount += nestedStats.newOptional;
|
|
1115
|
-
if (nestedStats.optionalSkipped) {
|
|
1116
|
-
optionalSkipped = true;
|
|
1117
|
-
}
|
|
1118
|
-
} else if (typedItem.type === "input_field" && typedItem.key) {
|
|
1119
|
-
if (processedFieldKeys.has(typedItem.key)) {
|
|
1120
|
-
continue;
|
|
1121
|
-
}
|
|
1122
|
-
const isRequired = typedItem.is_required || false;
|
|
1123
|
-
if (isRequired) {
|
|
1124
|
-
newRequiredCount++;
|
|
1125
|
-
if (typedItem.resolver && context) {
|
|
1126
|
-
const param = {
|
|
1127
|
-
name: typedItem.key,
|
|
1128
|
-
path: [typedItem.key],
|
|
1129
|
-
schema: zod.z.unknown(),
|
|
1130
|
-
isRequired: true
|
|
1131
|
-
};
|
|
1132
|
-
targetInputs[typedItem.key] = await this.resolveWithResolver(
|
|
1133
|
-
typedItem.resolver,
|
|
1134
|
-
param,
|
|
1135
|
-
context,
|
|
1136
|
-
{ isOptional: false }
|
|
1137
|
-
);
|
|
1138
|
-
} else {
|
|
1139
|
-
await this.promptForField(typedItem, targetInputs, context);
|
|
1140
|
-
}
|
|
1141
|
-
processedFieldKeys.add(typedItem.key);
|
|
1142
|
-
} else {
|
|
1143
|
-
newOptionalCount++;
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
if (newOptionalCount > 0) {
|
|
1148
|
-
const optionalFields = items.filter((item) => {
|
|
1149
|
-
const typedItem = item;
|
|
1150
|
-
return typedItem.type === "input_field" && typedItem.key && !typedItem.is_required && !processedFieldKeys.has(typedItem.key);
|
|
1151
|
-
});
|
|
1152
|
-
if (optionalFields.length > 0) {
|
|
1153
|
-
const pathContext = fieldsetPath.length > 0 ? ` in ${fieldsetPath.join(" > ")}` : "";
|
|
1154
|
-
if (options.inArrayContext) {
|
|
1155
|
-
for (const field of optionalFields) {
|
|
1156
|
-
await this.promptForField(field, targetInputs, context);
|
|
1157
|
-
const typedField = field;
|
|
1158
|
-
processedFieldKeys.add(typedField.key);
|
|
1159
|
-
}
|
|
1160
|
-
} else {
|
|
1161
|
-
console.log(
|
|
1162
|
-
chalk__default.default.gray(
|
|
1163
|
-
`
|
|
1164
|
-
There are ${optionalFields.length} ${iteration === 1 ? "" : "additional "}optional field(s) available${pathContext}.`
|
|
1165
|
-
)
|
|
1166
|
-
);
|
|
1167
|
-
try {
|
|
1168
|
-
const shouldConfigureOptional = await inquirer__default.default.prompt([
|
|
1169
|
-
{
|
|
1170
|
-
type: "confirm",
|
|
1171
|
-
name: "configure",
|
|
1172
|
-
message: `Would you like to configure ${iteration === 1 ? "" : "these additional "}optional fields${pathContext}?`,
|
|
1173
|
-
default: false
|
|
1174
|
-
}
|
|
1175
|
-
]);
|
|
1176
|
-
if (shouldConfigureOptional.configure) {
|
|
1177
|
-
console.log(chalk__default.default.cyan(`
|
|
1178
|
-
Optional fields${pathContext}:`));
|
|
1179
|
-
for (const field of optionalFields) {
|
|
1180
|
-
await this.promptForField(field, targetInputs, context);
|
|
1181
|
-
const typedField = field;
|
|
1182
|
-
processedFieldKeys.add(typedField.key);
|
|
1183
|
-
}
|
|
1184
|
-
} else {
|
|
1185
|
-
optionalSkipped = true;
|
|
1186
|
-
optionalFields.forEach((field) => {
|
|
1187
|
-
const typedField = field;
|
|
1188
|
-
processedFieldKeys.add(typedField.key);
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
|
-
} catch (error) {
|
|
1192
|
-
if (this.isUserCancellation(error)) {
|
|
1193
|
-
console.log(chalk__default.default.yellow("\n\nOperation cancelled by user"));
|
|
1194
|
-
throw new ZapierCliUserCancellationError();
|
|
1195
|
-
}
|
|
1196
|
-
throw error;
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
return {
|
|
1202
|
-
newRequired: newRequiredCount,
|
|
1203
|
-
newOptional: newOptionalCount,
|
|
1204
|
-
optionalSkipped
|
|
1205
|
-
};
|
|
1206
|
-
}
|
|
1207
|
-
getNestedValue(obj, path2) {
|
|
1208
|
-
return path2.reduce(
|
|
1209
|
-
(current, key) => current?.[key],
|
|
1210
|
-
obj
|
|
1211
|
-
);
|
|
1212
|
-
}
|
|
1213
|
-
setNestedValue(obj, path2, value) {
|
|
1214
|
-
const lastKey = path2[path2.length - 1];
|
|
1215
|
-
const parent = path2.slice(0, -1).reduce((current, key) => {
|
|
1216
|
-
const currentObj = current;
|
|
1217
|
-
if (!(key in currentObj)) {
|
|
1218
|
-
currentObj[key] = {};
|
|
1219
|
-
}
|
|
1220
|
-
return currentObj[key];
|
|
1221
|
-
}, obj);
|
|
1222
|
-
parent[lastKey] = value;
|
|
1223
|
-
}
|
|
1224
|
-
/**
|
|
1225
|
-
* Extract and normalize field metadata from raw field object
|
|
1226
|
-
*/
|
|
1227
|
-
extractFieldMetadata(field) {
|
|
1228
|
-
const fieldObj = field;
|
|
1229
|
-
const valueType = fieldObj.value_type || "string";
|
|
1230
|
-
return {
|
|
1231
|
-
key: fieldObj.key,
|
|
1232
|
-
title: fieldObj.title || fieldObj.label || fieldObj.key,
|
|
1233
|
-
description: fieldObj.description || fieldObj.helpText,
|
|
1234
|
-
isRequired: fieldObj.is_required || false,
|
|
1235
|
-
defaultValue: fieldObj.default_value ?? fieldObj.default,
|
|
1236
|
-
valueType,
|
|
1237
|
-
hasDropdown: fieldObj.format === "SELECT" || Boolean(fieldObj.choices),
|
|
1238
|
-
isMultiSelect: Boolean(
|
|
1239
|
-
valueType === "array" || fieldObj.items && fieldObj.items.type !== void 0
|
|
1240
|
-
),
|
|
1241
|
-
inlineChoices: fieldObj.choices
|
|
1242
|
-
};
|
|
1243
|
-
}
|
|
1244
|
-
/**
|
|
1245
|
-
* Fetch a page of choices for a dropdown field
|
|
1246
|
-
*/
|
|
1247
|
-
async fetchChoices(fieldMeta, inputs, context, cursor) {
|
|
1248
|
-
try {
|
|
1249
|
-
this.debugLog(
|
|
1250
|
-
cursor ? `Fetching more choices for ${fieldMeta.title}` : `Fetching choices for ${fieldMeta.title}`
|
|
1251
|
-
);
|
|
1252
|
-
this.startSpinner();
|
|
1253
|
-
const page = await context.sdk.listActionInputFieldChoices({
|
|
1254
|
-
app: context.resolvedParams.app,
|
|
1255
|
-
action: context.resolvedParams.action,
|
|
1256
|
-
actionType: context.resolvedParams.actionType,
|
|
1257
|
-
connection: context.resolvedParams.connection,
|
|
1258
|
-
inputField: fieldMeta.key,
|
|
1259
|
-
inputs,
|
|
1260
|
-
...cursor && { cursor }
|
|
1261
|
-
});
|
|
1262
|
-
this.stopSpinner();
|
|
1263
|
-
const choices = page.data.map((choice) => ({
|
|
1264
|
-
label: choice.label || choice.key || String(choice.value),
|
|
1265
|
-
value: choice.value ?? choice.key
|
|
1266
|
-
}));
|
|
1267
|
-
if (choices.length === 0 && !cursor) {
|
|
1268
|
-
console.log(
|
|
1269
|
-
chalk__default.default.yellow(`No choices available for ${fieldMeta.title}`)
|
|
1270
|
-
);
|
|
1271
|
-
}
|
|
1272
|
-
return {
|
|
1273
|
-
choices,
|
|
1274
|
-
nextCursor: page.nextCursor
|
|
1275
|
-
};
|
|
1276
|
-
} catch (error) {
|
|
1277
|
-
this.stopSpinner();
|
|
1278
|
-
console.warn(
|
|
1279
|
-
chalk__default.default.yellow(`Failed to fetch choices for ${fieldMeta.title}:`),
|
|
1280
|
-
error
|
|
1281
|
-
);
|
|
1282
|
-
return { choices: [] };
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
/**
|
|
1286
|
-
* Prompt user with choices (handles both single and multi-select with pagination).
|
|
1287
|
-
* Single-select goes through @inquirer/search so users can type-to-filter long
|
|
1288
|
-
* dropdowns (SELECT fields); multi-select stays on inquirer.prompt since search
|
|
1289
|
-
* is single-select only.
|
|
1290
|
-
*/
|
|
1291
|
-
async promptWithChoices({
|
|
1292
|
-
fieldMeta,
|
|
1293
|
-
choices: initialChoices,
|
|
1294
|
-
nextCursor: initialCursor,
|
|
1295
|
-
inputs,
|
|
1296
|
-
context
|
|
1297
|
-
}) {
|
|
1298
|
-
this.stopSpinner();
|
|
1299
|
-
const choices = [...initialChoices];
|
|
1300
|
-
let nextCursor = initialCursor;
|
|
1301
|
-
const LOAD_MORE_SENTINEL = Symbol("LOAD_MORE");
|
|
1302
|
-
const SKIP_SENTINEL = Symbol("SKIP");
|
|
1303
|
-
const CUSTOM_VALUE_SENTINEL = Symbol("CUSTOM_VALUE");
|
|
1304
|
-
const message = `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"}:`;
|
|
1305
|
-
while (true) {
|
|
1306
|
-
let selectedValue;
|
|
1307
|
-
if (!fieldMeta.isMultiSelect) {
|
|
1308
|
-
const dataChoices = choices.map((c) => ({
|
|
1309
|
-
name: c.label,
|
|
1310
|
-
value: c.value
|
|
1311
|
-
}));
|
|
1312
|
-
selectedValue = await search__default.default({
|
|
1313
|
-
message,
|
|
1314
|
-
source: (term) => {
|
|
1315
|
-
const trimmed = (term ?? "").trim();
|
|
1316
|
-
const lower = trimmed.toLowerCase();
|
|
1317
|
-
const matches = trimmed ? dataChoices.filter((c) => c.name.toLowerCase().includes(lower)) : dataChoices;
|
|
1318
|
-
const out2 = [];
|
|
1319
|
-
const skipChoice = !fieldMeta.isRequired ? [{ name: chalk__default.default.dim("(Skip)"), value: SKIP_SENTINEL }] : [];
|
|
1320
|
-
const customValueChoice = {
|
|
1321
|
-
name: chalk__default.default.dim("(Enter custom value)"),
|
|
1322
|
-
value: CUSTOM_VALUE_SENTINEL
|
|
1323
|
-
};
|
|
1324
|
-
const loadMoreChoice = nextCursor && context ? {
|
|
1325
|
-
name: chalk__default.default.dim("(Load more...)"),
|
|
1326
|
-
value: LOAD_MORE_SENTINEL
|
|
1327
|
-
} : null;
|
|
1328
|
-
if (trimmed && matches.length > 0) {
|
|
1329
|
-
out2.push(...matches);
|
|
1330
|
-
out2.push(...skipChoice);
|
|
1331
|
-
out2.push(customValueChoice);
|
|
1332
|
-
if (loadMoreChoice) out2.push(loadMoreChoice);
|
|
1333
|
-
} else if (trimmed) {
|
|
1334
|
-
out2.push(customValueChoice);
|
|
1335
|
-
if (loadMoreChoice) out2.push(loadMoreChoice);
|
|
1336
|
-
out2.push(...skipChoice);
|
|
1337
|
-
} else {
|
|
1338
|
-
out2.push(...skipChoice);
|
|
1339
|
-
out2.push(customValueChoice);
|
|
1340
|
-
out2.push(...matches);
|
|
1341
|
-
if (loadMoreChoice) out2.push(loadMoreChoice);
|
|
1342
|
-
}
|
|
1343
|
-
return out2;
|
|
1344
|
-
}
|
|
8
|
+
var chalk8 = require('chalk');
|
|
9
|
+
var core = require('@inquirer/core');
|
|
10
|
+
var ora = require('ora');
|
|
11
|
+
var util = require('util');
|
|
12
|
+
var wrapAnsi3 = require('wrap-ansi');
|
|
13
|
+
var jwt = require('jsonwebtoken');
|
|
14
|
+
var crossKeychain = require('cross-keychain');
|
|
15
|
+
var Conf = require('conf');
|
|
16
|
+
var fs = require('fs');
|
|
17
|
+
var crypto = require('crypto');
|
|
18
|
+
var path = require('path');
|
|
19
|
+
var lockfile = require('proper-lockfile');
|
|
20
|
+
var os = require('os');
|
|
21
|
+
var express = require('express');
|
|
22
|
+
var promises$1 = require('readline/promises');
|
|
23
|
+
var open = require('open');
|
|
24
|
+
var pkceChallenge = require('pkce-challenge');
|
|
25
|
+
var zapierSdkMcp = require('@zapier/zapier-sdk-mcp');
|
|
26
|
+
var esbuild = require('esbuild');
|
|
27
|
+
var promises = require('fs/promises');
|
|
28
|
+
var ts = require('typescript');
|
|
29
|
+
var isInstalledGlobally = require('is-installed-globally');
|
|
30
|
+
var child_process = require('child_process');
|
|
31
|
+
var Handlebars = require('handlebars');
|
|
32
|
+
var url = require('url');
|
|
33
|
+
var experimental = require('@zapier/zapier-sdk/experimental');
|
|
34
|
+
var packageJsonLib = require('package-json');
|
|
35
|
+
var semver = require('semver');
|
|
36
|
+
var readline = require('readline');
|
|
37
|
+
|
|
38
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
39
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
40
|
+
|
|
41
|
+
function _interopNamespace(e) {
|
|
42
|
+
if (e && e.__esModule) return e;
|
|
43
|
+
var n = Object.create(null);
|
|
44
|
+
if (e) {
|
|
45
|
+
Object.keys(e).forEach(function (k) {
|
|
46
|
+
if (k !== 'default') {
|
|
47
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
48
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () { return e[k]; }
|
|
1345
51
|
});
|
|
1346
|
-
if (selectedValue === SKIP_SENTINEL) {
|
|
1347
|
-
return void 0;
|
|
1348
|
-
}
|
|
1349
|
-
if (selectedValue === CUSTOM_VALUE_SENTINEL) {
|
|
1350
|
-
return await this.promptFreeForm(fieldMeta);
|
|
1351
|
-
}
|
|
1352
|
-
} else {
|
|
1353
|
-
const promptChoices = choices.map((c) => ({
|
|
1354
|
-
name: c.label,
|
|
1355
|
-
value: c.value
|
|
1356
|
-
}));
|
|
1357
|
-
if (nextCursor) {
|
|
1358
|
-
promptChoices.push({
|
|
1359
|
-
name: chalk__default.default.dim("(Load more...)"),
|
|
1360
|
-
value: LOAD_MORE_SENTINEL
|
|
1361
|
-
});
|
|
1362
|
-
}
|
|
1363
|
-
const promptConfig = {
|
|
1364
|
-
type: "checkbox",
|
|
1365
|
-
name: fieldMeta.key,
|
|
1366
|
-
message,
|
|
1367
|
-
choices: promptChoices,
|
|
1368
|
-
validate: (input) => {
|
|
1369
|
-
if (fieldMeta.isRequired && (!input || input.length === 0)) {
|
|
1370
|
-
return "At least one selection is required";
|
|
1371
|
-
}
|
|
1372
|
-
return true;
|
|
1373
|
-
}
|
|
1374
|
-
};
|
|
1375
|
-
const answer = await inquirer__default.default.prompt([promptConfig]);
|
|
1376
|
-
selectedValue = answer[fieldMeta.key];
|
|
1377
|
-
}
|
|
1378
|
-
const wantsMore = fieldMeta.isMultiSelect ? Array.isArray(selectedValue) && selectedValue.includes(LOAD_MORE_SENTINEL) : selectedValue === LOAD_MORE_SENTINEL;
|
|
1379
|
-
if (wantsMore && nextCursor && context) {
|
|
1380
|
-
if (fieldMeta.isMultiSelect && Array.isArray(selectedValue)) {
|
|
1381
|
-
selectedValue = selectedValue.filter((v) => v !== LOAD_MORE_SENTINEL);
|
|
1382
|
-
}
|
|
1383
|
-
const result = await this.fetchChoices(
|
|
1384
|
-
fieldMeta,
|
|
1385
|
-
inputs,
|
|
1386
|
-
context,
|
|
1387
|
-
nextCursor
|
|
1388
|
-
);
|
|
1389
|
-
choices.push(...result.choices);
|
|
1390
|
-
nextCursor = result.nextCursor;
|
|
1391
|
-
continue;
|
|
1392
|
-
}
|
|
1393
|
-
return selectedValue;
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
/**
|
|
1397
|
-
* Prompt user for free-form input (text or boolean)
|
|
1398
|
-
*/
|
|
1399
|
-
async promptFreeForm(fieldMeta) {
|
|
1400
|
-
const promptConfig = {
|
|
1401
|
-
name: fieldMeta.key,
|
|
1402
|
-
message: `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"}:`
|
|
1403
|
-
};
|
|
1404
|
-
if (fieldMeta.valueType === "boolean") {
|
|
1405
|
-
promptConfig.type = "confirm";
|
|
1406
|
-
promptConfig.default = fieldMeta.defaultValue !== void 0 ? Boolean(fieldMeta.defaultValue) : void 0;
|
|
1407
|
-
} else if (fieldMeta.valueType === "array") {
|
|
1408
|
-
promptConfig.type = "input";
|
|
1409
|
-
promptConfig.default = fieldMeta.defaultValue;
|
|
1410
|
-
promptConfig.message = `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"} (JSON array or comma-separated):`;
|
|
1411
|
-
promptConfig.validate = (input) => {
|
|
1412
|
-
if (fieldMeta.isRequired && !input) {
|
|
1413
|
-
return "This field is required";
|
|
1414
|
-
}
|
|
1415
|
-
return true;
|
|
1416
|
-
};
|
|
1417
|
-
promptConfig.filter = (input) => {
|
|
1418
|
-
if (!input) return input;
|
|
1419
|
-
const trimmed = input.trim();
|
|
1420
|
-
if (trimmed.startsWith("[")) {
|
|
1421
|
-
try {
|
|
1422
|
-
return JSON.parse(trimmed);
|
|
1423
|
-
} catch {
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
return trimmed.split(",").map((s) => s.trim());
|
|
1427
|
-
};
|
|
1428
|
-
} else {
|
|
1429
|
-
promptConfig.type = "input";
|
|
1430
|
-
promptConfig.default = fieldMeta.defaultValue;
|
|
1431
|
-
promptConfig.validate = (input) => {
|
|
1432
|
-
if (fieldMeta.isRequired && !input) {
|
|
1433
|
-
return "This field is required";
|
|
1434
|
-
}
|
|
1435
|
-
return true;
|
|
1436
|
-
};
|
|
1437
|
-
}
|
|
1438
|
-
if (fieldMeta.description) {
|
|
1439
|
-
promptConfig.prefix = chalk__default.default.gray(`\u2139 ${fieldMeta.description}
|
|
1440
|
-
`);
|
|
1441
|
-
}
|
|
1442
|
-
try {
|
|
1443
|
-
const answer = await inquirer__default.default.prompt([promptConfig]);
|
|
1444
|
-
return answer[fieldMeta.key];
|
|
1445
|
-
} catch (error) {
|
|
1446
|
-
if (this.isUserCancellation(error)) {
|
|
1447
|
-
console.log(chalk__default.default.yellow("\n\nOperation cancelled by user"));
|
|
1448
|
-
throw new ZapierCliUserCancellationError();
|
|
1449
|
-
}
|
|
1450
|
-
throw error;
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
1453
|
-
/**
|
|
1454
|
-
* Store field value in inputs object with validation
|
|
1455
|
-
*/
|
|
1456
|
-
storeFieldValue(inputs, key, value, isRequired) {
|
|
1457
|
-
try {
|
|
1458
|
-
if (value !== void 0 && value !== "") {
|
|
1459
|
-
inputs[key] = value;
|
|
1460
|
-
} else if (isRequired) {
|
|
1461
|
-
throw new Error(`Required field ${key} cannot be empty`);
|
|
1462
|
-
}
|
|
1463
|
-
} catch (error) {
|
|
1464
|
-
if (this.isUserCancellation(error)) {
|
|
1465
|
-
console.log(chalk__default.default.yellow("\n\nOperation cancelled by user"));
|
|
1466
|
-
throw new ZapierCliUserCancellationError();
|
|
1467
|
-
}
|
|
1468
|
-
throw error;
|
|
1469
|
-
}
|
|
1470
|
-
}
|
|
1471
|
-
async promptForField(field, inputs, context) {
|
|
1472
|
-
const fieldMeta = this.extractFieldMetadata(field);
|
|
1473
|
-
let choices = [];
|
|
1474
|
-
let nextCursor;
|
|
1475
|
-
if (fieldMeta.inlineChoices) {
|
|
1476
|
-
choices = fieldMeta.inlineChoices;
|
|
1477
|
-
} else if (fieldMeta.hasDropdown && context) {
|
|
1478
|
-
const result = await this.fetchChoices(fieldMeta, inputs, context);
|
|
1479
|
-
choices = result.choices;
|
|
1480
|
-
nextCursor = result.nextCursor;
|
|
1481
|
-
}
|
|
1482
|
-
let selectedValue;
|
|
1483
|
-
if (choices.length > 0) {
|
|
1484
|
-
selectedValue = await this.promptWithChoices({
|
|
1485
|
-
fieldMeta,
|
|
1486
|
-
choices,
|
|
1487
|
-
nextCursor,
|
|
1488
|
-
inputs,
|
|
1489
|
-
context
|
|
1490
|
-
});
|
|
1491
|
-
} else {
|
|
1492
|
-
selectedValue = await this.promptFreeForm(fieldMeta);
|
|
1493
|
-
}
|
|
1494
|
-
this.storeFieldValue(
|
|
1495
|
-
inputs,
|
|
1496
|
-
fieldMeta.key,
|
|
1497
|
-
selectedValue,
|
|
1498
|
-
fieldMeta.isRequired
|
|
1499
|
-
);
|
|
1500
|
-
}
|
|
1501
|
-
isUserCancellation(error) {
|
|
1502
|
-
const errorObj = error;
|
|
1503
|
-
return errorObj?.name === "ExitPromptError" || errorObj?.message?.includes("User force closed") || errorObj?.isTTYError === true;
|
|
1504
|
-
}
|
|
1505
|
-
hasResolver(paramName, sdk, functionName) {
|
|
1506
|
-
if (functionName && typeof sdk.getRegistry === "function") {
|
|
1507
|
-
const registry = sdk.getRegistry({ package: "cli" });
|
|
1508
|
-
const functionInfo = registry.functions.find(
|
|
1509
|
-
(f) => f.name === functionName
|
|
1510
|
-
);
|
|
1511
|
-
if (functionInfo && functionInfo.resolvers?.[paramName]) {
|
|
1512
|
-
return true;
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
return false;
|
|
1516
|
-
}
|
|
1517
|
-
getResolver(paramName, sdk, functionName) {
|
|
1518
|
-
if (functionName && typeof sdk.getRegistry === "function") {
|
|
1519
|
-
const registry = sdk.getRegistry({ package: "cli" });
|
|
1520
|
-
const functionInfo = registry.functions.find(
|
|
1521
|
-
(f) => f.name === functionName
|
|
1522
|
-
);
|
|
1523
|
-
if (functionInfo && functionInfo.resolvers?.[paramName]) {
|
|
1524
|
-
return functionInfo.resolvers[paramName];
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
return null;
|
|
1528
|
-
}
|
|
1529
|
-
getLocalResolvers(sdk, functionName) {
|
|
1530
|
-
if (!functionName || typeof sdk.getRegistry !== "function") {
|
|
1531
|
-
return {};
|
|
1532
|
-
}
|
|
1533
|
-
const registry = sdk.getRegistry();
|
|
1534
|
-
const functionInfo = registry.functions.find(
|
|
1535
|
-
(f) => f.name === functionName
|
|
1536
|
-
);
|
|
1537
|
-
return functionInfo?.resolvers || {};
|
|
1538
|
-
}
|
|
1539
|
-
getResolverConstants(sdk, functionName) {
|
|
1540
|
-
if (!functionName || typeof sdk.getRegistry !== "function") {
|
|
1541
|
-
return {};
|
|
1542
|
-
}
|
|
1543
|
-
const registry = sdk.getRegistry();
|
|
1544
|
-
const functionInfo = registry.functions.find(
|
|
1545
|
-
(f) => f.name === functionName
|
|
1546
|
-
);
|
|
1547
|
-
const resolvers = functionInfo?.resolvers ?? {};
|
|
1548
|
-
const constants = {};
|
|
1549
|
-
for (const [key, resolver] of Object.entries(resolvers)) {
|
|
1550
|
-
if (resolver && typeof resolver === "object" && resolver.type === "constant") {
|
|
1551
|
-
constants[key] = resolver.value;
|
|
1552
52
|
}
|
|
1553
|
-
}
|
|
1554
|
-
return constants;
|
|
53
|
+
});
|
|
1555
54
|
}
|
|
55
|
+
n.default = e;
|
|
56
|
+
return Object.freeze(n);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
60
|
+
var chalk8__default = /*#__PURE__*/_interopDefault(chalk8);
|
|
61
|
+
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
62
|
+
var util__default = /*#__PURE__*/_interopDefault(util);
|
|
63
|
+
var wrapAnsi3__default = /*#__PURE__*/_interopDefault(wrapAnsi3);
|
|
64
|
+
var jwt__namespace = /*#__PURE__*/_interopNamespace(jwt);
|
|
65
|
+
var Conf__default = /*#__PURE__*/_interopDefault(Conf);
|
|
66
|
+
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
67
|
+
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
68
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
69
|
+
var lockfile__namespace = /*#__PURE__*/_interopNamespace(lockfile);
|
|
70
|
+
var express__default = /*#__PURE__*/_interopDefault(express);
|
|
71
|
+
var open__default = /*#__PURE__*/_interopDefault(open);
|
|
72
|
+
var pkceChallenge__default = /*#__PURE__*/_interopDefault(pkceChallenge);
|
|
73
|
+
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
74
|
+
var isInstalledGlobally__default = /*#__PURE__*/_interopDefault(isInstalledGlobally);
|
|
75
|
+
var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
|
|
76
|
+
var packageJsonLib__default = /*#__PURE__*/_interopDefault(packageJsonLib);
|
|
77
|
+
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
78
|
+
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
79
|
+
|
|
80
|
+
var __defProp = Object.defineProperty;
|
|
81
|
+
var __export = (target, all) => {
|
|
82
|
+
for (var name in all)
|
|
83
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
1556
84
|
};
|
|
1557
85
|
function isSelectable(item) {
|
|
1558
86
|
return !core.Separator.isSeparator(item) && !item.disabled;
|
|
@@ -1572,9 +100,9 @@ function normalizeChoices(choices) {
|
|
|
1572
100
|
var theme = core.makeTheme({
|
|
1573
101
|
icon: { cursor: "\u276F" },
|
|
1574
102
|
style: {
|
|
1575
|
-
disabled: (text) =>
|
|
1576
|
-
searchTerm: (text) =>
|
|
1577
|
-
keysHelpTip: (keys) => keys.map(([key, action]) => `${
|
|
103
|
+
disabled: (text) => chalk8__default.default.dim(`- ${text}`),
|
|
104
|
+
searchTerm: (text) => chalk8__default.default.cyan(text),
|
|
105
|
+
keysHelpTip: (keys) => keys.map(([key, action]) => `${chalk8__default.default.bold(key)} ${chalk8__default.default.dim(action)}`).join(chalk8__default.default.dim(" \u2022 "))
|
|
1578
106
|
}
|
|
1579
107
|
});
|
|
1580
108
|
var searchSelect = core.createPrompt(
|
|
@@ -1712,7 +240,7 @@ async function promptText({
|
|
|
1712
240
|
]);
|
|
1713
241
|
return value;
|
|
1714
242
|
}
|
|
1715
|
-
var display = (c) => c.hint ? `${c.label} ${
|
|
243
|
+
var display = (c) => c.hint ? `${c.label} ${chalk8__default.default.dim(`(${c.hint})`)}` : c.label;
|
|
1716
244
|
function buildSelectRows(question, term) {
|
|
1717
245
|
const row = (name, action) => ({
|
|
1718
246
|
name,
|
|
@@ -1726,8 +254,8 @@ function buildSelectRows(question, term) {
|
|
|
1726
254
|
name: display(c),
|
|
1727
255
|
value: c.value
|
|
1728
256
|
}));
|
|
1729
|
-
const skipRow = offers(question, "skip") ? [row(
|
|
1730
|
-
const customRow = offers(question, "custom") ? [row(
|
|
257
|
+
const skipRow = offers(question, "skip") ? [row(chalk8__default.default.dim("Skip (optional)"), "skip")] : [];
|
|
258
|
+
const customRow = offers(question, "custom") ? [row(chalk8__default.default.dim("Enter a value manually\u2026"), "custom")] : [];
|
|
1731
259
|
const committed = !!t || question.search !== void 0;
|
|
1732
260
|
let rows;
|
|
1733
261
|
if (!committed) {
|
|
@@ -1738,13 +266,13 @@ function buildSelectRows(question, term) {
|
|
|
1738
266
|
rows = [...customRow, ...skipRow];
|
|
1739
267
|
}
|
|
1740
268
|
if (offers(question, "search"))
|
|
1741
|
-
rows.push(row(
|
|
269
|
+
rows.push(row(chalk8__default.default.cyan("Search again\u2026"), "search"));
|
|
1742
270
|
if (offers(question, "next_page"))
|
|
1743
|
-
rows.push(row(
|
|
1744
|
-
if (offers(question, "retry")) rows.push(row(
|
|
1745
|
-
if (offers(question, "cancel")) rows.push(row(
|
|
271
|
+
rows.push(row(chalk8__default.default.dim("Load more\u2026"), "next_page"));
|
|
272
|
+
if (offers(question, "retry")) rows.push(row(chalk8__default.default.yellow("Retry"), "retry"));
|
|
273
|
+
if (offers(question, "cancel")) rows.push(row(chalk8__default.default.dim("Cancel"), "cancel"));
|
|
1746
274
|
for (const note of question.notes ?? [])
|
|
1747
|
-
rows.push({ name:
|
|
275
|
+
rows.push({ name: chalk8__default.default.dim(note), value: note, disabled: true });
|
|
1748
276
|
return rows;
|
|
1749
277
|
}
|
|
1750
278
|
function foldPage(acc, question, field) {
|
|
@@ -1794,12 +322,12 @@ async function answerSelect(question, field, box, failed = false) {
|
|
|
1794
322
|
})),
|
|
1795
323
|
...offers(question, "next_page") ? [
|
|
1796
324
|
{
|
|
1797
|
-
name:
|
|
325
|
+
name: chalk8__default.default.dim("Load more\u2026"),
|
|
1798
326
|
value: { action: "next_page" }
|
|
1799
327
|
}
|
|
1800
328
|
] : [],
|
|
1801
329
|
...(question.notes ?? []).map((note) => ({
|
|
1802
|
-
name:
|
|
330
|
+
name: chalk8__default.default.dim(note),
|
|
1803
331
|
value: note,
|
|
1804
332
|
disabled: true
|
|
1805
333
|
}))
|
|
@@ -1870,14 +398,14 @@ async function answerSelect(question, field, box, failed = false) {
|
|
|
1870
398
|
case "retry":
|
|
1871
399
|
return { type: "retry" };
|
|
1872
400
|
case "skip":
|
|
1873
|
-
printAnswered(view.message,
|
|
401
|
+
printAnswered(view.message, chalk8__default.default.dim("(skipped)"));
|
|
1874
402
|
return { type: "skip" };
|
|
1875
403
|
case "cancel":
|
|
1876
404
|
return { type: "cancel" };
|
|
1877
405
|
}
|
|
1878
406
|
}
|
|
1879
407
|
function printAnswered(message, label) {
|
|
1880
|
-
console.log(`${
|
|
408
|
+
console.log(`${chalk8__default.default.green("\u2714")} ${message} ${chalk8__default.default.cyan(label)}`);
|
|
1881
409
|
}
|
|
1882
410
|
async function answerInput(question) {
|
|
1883
411
|
const message = question.placeholder ? question.message.replace(/:?\s*$/, ` (${question.placeholder}):`) : question.message;
|
|
@@ -1920,7 +448,7 @@ function createCliAnswer() {
|
|
|
1920
448
|
return ({ result }) => {
|
|
1921
449
|
if (result.error !== void 0) {
|
|
1922
450
|
const message = typeof result.error === "string" ? result.error : result.error.message;
|
|
1923
|
-
console.log(
|
|
451
|
+
console.log(chalk8__default.default.yellow(`! ${message}`));
|
|
1924
452
|
}
|
|
1925
453
|
const question = result.question;
|
|
1926
454
|
const field = question.path.length ? question.path.join(".") : "value";
|
|
@@ -1934,6 +462,49 @@ function createCliAnswer() {
|
|
|
1934
462
|
}
|
|
1935
463
|
};
|
|
1936
464
|
}
|
|
465
|
+
var ZapierCliError = class extends zapierSdk.ZapierError {
|
|
466
|
+
};
|
|
467
|
+
var ZapierCliUserCancellationError = class extends ZapierCliError {
|
|
468
|
+
constructor(message = "Operation cancelled by user") {
|
|
469
|
+
super(message);
|
|
470
|
+
this.name = "ZapierCliUserCancellationError";
|
|
471
|
+
this.code = "ZAPIER_CLI_USER_CANCELLATION";
|
|
472
|
+
this.exitCode = 0;
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
var ZapierCliExitError = class extends ZapierCliError {
|
|
476
|
+
constructor(message, exitCode = 1) {
|
|
477
|
+
super(message);
|
|
478
|
+
this.name = "ZapierCliExitError";
|
|
479
|
+
this.code = "ZAPIER_CLI_EXIT";
|
|
480
|
+
this.exitCode = exitCode;
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
var ZapierCliValidationError = class _ZapierCliValidationError extends ZapierCliError {
|
|
484
|
+
constructor(message, options = {}) {
|
|
485
|
+
super(message);
|
|
486
|
+
this.exitCode = 1;
|
|
487
|
+
this.name = options.name ?? "ZapierCliValidationError";
|
|
488
|
+
this.code = options.code ?? "ZAPIER_CLI_VALIDATION_ERROR";
|
|
489
|
+
}
|
|
490
|
+
withMessage(message) {
|
|
491
|
+
return new _ZapierCliValidationError(message, {
|
|
492
|
+
name: this.name,
|
|
493
|
+
code: this.code
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
var ZapierCliMissingParametersError = class extends ZapierCliError {
|
|
498
|
+
constructor(params) {
|
|
499
|
+
super(
|
|
500
|
+
`Missing required parameters: ${params.map((p) => p.name).join(", ")}`
|
|
501
|
+
);
|
|
502
|
+
this.name = "ZapierCliMissingParametersError";
|
|
503
|
+
this.code = "ZAPIER_CLI_MISSING_PARAMETERS";
|
|
504
|
+
this.exitCode = 1;
|
|
505
|
+
this.params = params;
|
|
506
|
+
}
|
|
507
|
+
};
|
|
1937
508
|
|
|
1938
509
|
// src/utils/cli-options.ts
|
|
1939
510
|
var RESERVED_CLI_OPTIONS = [
|
|
@@ -1965,7 +536,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
1965
536
|
|
|
1966
537
|
// package.json
|
|
1967
538
|
var package_default = {
|
|
1968
|
-
version: "0.66.
|
|
539
|
+
version: "0.66.3"};
|
|
1969
540
|
|
|
1970
541
|
// src/telemetry/builders.ts
|
|
1971
542
|
function createCliBaseEvent(context = {}) {
|
|
@@ -2052,7 +623,7 @@ async function formatItemsFromSchema(_functionInfo, items, startingNumber = 0, o
|
|
|
2052
623
|
formatItemsGeneric(items, startingNumber);
|
|
2053
624
|
}
|
|
2054
625
|
function formatSingleItem(formatted, itemNumber) {
|
|
2055
|
-
let titleLine = `${
|
|
626
|
+
let titleLine = `${chalk8__default.default.gray(`${itemNumber + 1}.`)} ${chalk8__default.default.cyan(formatted.title)}`;
|
|
2056
627
|
const subtitleParts = [];
|
|
2057
628
|
if (formatted.hint !== void 0) {
|
|
2058
629
|
subtitleParts.push(
|
|
@@ -2070,11 +641,11 @@ function formatSingleItem(formatted, itemNumber) {
|
|
|
2070
641
|
}
|
|
2071
642
|
const uniqueParts = [...new Set(subtitleParts)];
|
|
2072
643
|
if (uniqueParts.length > 0) {
|
|
2073
|
-
titleLine += ` ${
|
|
644
|
+
titleLine += ` ${chalk8__default.default.gray(`(${uniqueParts.join(", ")})`)}`;
|
|
2074
645
|
}
|
|
2075
646
|
console.log(titleLine);
|
|
2076
647
|
if (formatted.description) {
|
|
2077
|
-
console.log(` ${
|
|
648
|
+
console.log(` ${chalk8__default.default.dim(formatted.description)}`);
|
|
2078
649
|
}
|
|
2079
650
|
if (formatted.raw !== void 0) {
|
|
2080
651
|
formatJsonOutput(formatted.raw);
|
|
@@ -2085,7 +656,7 @@ function formatSingleItem(formatted, itemNumber) {
|
|
|
2085
656
|
if (detail.label) {
|
|
2086
657
|
const isMultiline = detail.text.includes("\n");
|
|
2087
658
|
if (isMultiline) {
|
|
2088
|
-
console.log(` ${
|
|
659
|
+
console.log(` ${chalk8__default.default.gray(detail.label + ":")}`);
|
|
2089
660
|
const displayText = formatDetailText(
|
|
2090
661
|
detail.text,
|
|
2091
662
|
DETAIL_INDENT + " "
|
|
@@ -2094,7 +665,7 @@ function formatSingleItem(formatted, itemNumber) {
|
|
|
2094
665
|
console.log(`${DETAIL_INDENT} ${styledText}`);
|
|
2095
666
|
} else {
|
|
2096
667
|
const styledValue = applyStyle(detail.text, detail.style);
|
|
2097
|
-
console.log(` ${
|
|
668
|
+
console.log(` ${chalk8__default.default.gray(detail.label + ":")} ${styledValue}`);
|
|
2098
669
|
}
|
|
2099
670
|
} else {
|
|
2100
671
|
const displayText = formatDetailText(detail.text, DETAIL_INDENT);
|
|
@@ -2118,16 +689,16 @@ function formatDetailText(text, indent = DETAIL_INDENT) {
|
|
|
2118
689
|
function applyStyle(value, style) {
|
|
2119
690
|
switch (style) {
|
|
2120
691
|
case "dim":
|
|
2121
|
-
return
|
|
692
|
+
return chalk8__default.default.dim(value);
|
|
2122
693
|
case "accent":
|
|
2123
|
-
return
|
|
694
|
+
return chalk8__default.default.magenta(value);
|
|
2124
695
|
case "warning":
|
|
2125
|
-
return
|
|
696
|
+
return chalk8__default.default.red(value);
|
|
2126
697
|
case "success":
|
|
2127
|
-
return
|
|
698
|
+
return chalk8__default.default.green(value);
|
|
2128
699
|
case "normal":
|
|
2129
700
|
default:
|
|
2130
|
-
return
|
|
701
|
+
return chalk8__default.default.blue(value);
|
|
2131
702
|
}
|
|
2132
703
|
}
|
|
2133
704
|
function convertGenericItemToFormattedItem(item) {
|
|
@@ -2155,15 +726,15 @@ function formatMissingParamsError(error) {
|
|
|
2155
726
|
return [
|
|
2156
727
|
"Missing required parameters:",
|
|
2157
728
|
...error.params.map(
|
|
2158
|
-
({ name, isPositional:
|
|
729
|
+
({ name, isPositional: isPositional2 }) => isPositional2 ? ` \u2022 <${toKebabCase(name)}>` : ` \u2022 --${toKebabCase(name)}`
|
|
2159
730
|
)
|
|
2160
731
|
].join("\n");
|
|
2161
732
|
}
|
|
2162
733
|
function buildJsonErrors(error) {
|
|
2163
734
|
if (error instanceof ZapierCliMissingParametersError) {
|
|
2164
|
-
return error.params.map(({ name, isPositional:
|
|
735
|
+
return error.params.map(({ name, isPositional: isPositional2 }) => ({
|
|
2165
736
|
code: error.code,
|
|
2166
|
-
message:
|
|
737
|
+
message: isPositional2 ? `<${toKebabCase(name)}> is required in non-interactive mode` : `--${toKebabCase(name)} is required in non-interactive mode`
|
|
2167
738
|
}));
|
|
2168
739
|
}
|
|
2169
740
|
const code = error instanceof zapierSdk.ZapierError ? error.code : "UNKNOWN_ERROR";
|
|
@@ -2271,10 +842,10 @@ function createInteractiveRenderer(context = {}) {
|
|
|
2271
842
|
const obj = item;
|
|
2272
843
|
const name = obj?.name || obj?.key || obj?.id || "Item";
|
|
2273
844
|
console.log(
|
|
2274
|
-
`${
|
|
845
|
+
`${chalk8__default.default.gray(`${startingNumber + index + 1}.`)} ${chalk8__default.default.cyan(String(name))}`
|
|
2275
846
|
);
|
|
2276
847
|
if (obj?.description)
|
|
2277
|
-
console.log(` ${
|
|
848
|
+
console.log(` ${chalk8__default.default.dim(String(obj.description))}`);
|
|
2278
849
|
console.log();
|
|
2279
850
|
});
|
|
2280
851
|
}
|
|
@@ -2285,35 +856,35 @@ function createInteractiveRenderer(context = {}) {
|
|
|
2285
856
|
if (!(Symbol.asyncIterator in Object(source))) {
|
|
2286
857
|
const items = source?.data;
|
|
2287
858
|
if (!Array.isArray(items) || items.length === 0) {
|
|
2288
|
-
console.log(
|
|
859
|
+
console.log(chalk8__default.default.yellow(`No ${itemName} found.`));
|
|
2289
860
|
return;
|
|
2290
861
|
}
|
|
2291
862
|
await renderItemsForDisplay(items, functionInfo, 0);
|
|
2292
|
-
console.log(
|
|
863
|
+
console.log(chalk8__default.default.green(`
|
|
2293
864
|
\u2705 Showing ${items.length} ${itemName}`));
|
|
2294
865
|
return;
|
|
2295
866
|
}
|
|
2296
867
|
let totalShown = 0;
|
|
2297
868
|
let pageCount = 0;
|
|
2298
|
-
console.log(
|
|
869
|
+
console.log(chalk8__default.default.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
|
|
2299
870
|
`));
|
|
2300
871
|
for await (const page of source) {
|
|
2301
872
|
const items = page.data ?? [];
|
|
2302
873
|
pageCount++;
|
|
2303
874
|
if (items.length === 0 && pageCount === 1) {
|
|
2304
|
-
console.log(
|
|
875
|
+
console.log(chalk8__default.default.yellow(`No ${itemName} found.`));
|
|
2305
876
|
return;
|
|
2306
877
|
}
|
|
2307
878
|
if (items.length === 0) break;
|
|
2308
879
|
if (pageCount > 1) {
|
|
2309
880
|
console.clear();
|
|
2310
|
-
console.log(
|
|
881
|
+
console.log(chalk8__default.default.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
|
|
2311
882
|
`));
|
|
2312
883
|
}
|
|
2313
884
|
await renderItemsForDisplay(items, functionInfo, totalShown);
|
|
2314
885
|
totalShown += items.length;
|
|
2315
886
|
console.log(
|
|
2316
|
-
|
|
887
|
+
chalk8__default.default.green(
|
|
2317
888
|
`
|
|
2318
889
|
\u2705 Showing ${totalShown} ${itemName} (page ${pageCount})`
|
|
2319
890
|
)
|
|
@@ -2332,7 +903,7 @@ function createInteractiveRenderer(context = {}) {
|
|
|
2332
903
|
break;
|
|
2333
904
|
}
|
|
2334
905
|
}
|
|
2335
|
-
console.log(
|
|
906
|
+
console.log(chalk8__default.default.gray(`
|
|
2336
907
|
\u{1F4C4} Finished browsing ${itemName}`));
|
|
2337
908
|
},
|
|
2338
909
|
async renderCollectedList(items, { maxItems, userSpecifiedMaxItems, functionInfo } = {}) {
|
|
@@ -2342,30 +913,30 @@ function createInteractiveRenderer(context = {}) {
|
|
|
2342
913
|
}
|
|
2343
914
|
const itemName = getItemName(functionInfo);
|
|
2344
915
|
if (items.length === 0) {
|
|
2345
|
-
console.log(
|
|
916
|
+
console.log(chalk8__default.default.yellow(`No ${itemName} found.`));
|
|
2346
917
|
return;
|
|
2347
918
|
}
|
|
2348
|
-
console.log(
|
|
919
|
+
console.log(chalk8__default.default.green(`
|
|
2349
920
|
\u2705 Found ${items.length} ${itemName}:
|
|
2350
921
|
`));
|
|
2351
922
|
await renderItemsForDisplay(items, functionInfo);
|
|
2352
923
|
if (userSpecifiedMaxItems && maxItems) {
|
|
2353
924
|
console.log(
|
|
2354
|
-
|
|
925
|
+
chalk8__default.default.gray(
|
|
2355
926
|
`
|
|
2356
927
|
\u{1F4C4} Showing up to ${maxItems} ${itemName} (--max-items ${maxItems})`
|
|
2357
928
|
)
|
|
2358
929
|
);
|
|
2359
930
|
} else {
|
|
2360
|
-
console.log(
|
|
931
|
+
console.log(chalk8__default.default.gray(`
|
|
2361
932
|
\u{1F4C4} All available ${itemName} shown`));
|
|
2362
933
|
}
|
|
2363
934
|
},
|
|
2364
935
|
renderItem(value, options) {
|
|
2365
936
|
if (options?.outputFile) {
|
|
2366
937
|
const label = options.commandName ? `\u2705 ${options.commandName} completed successfully!` : "\u2705 Done!";
|
|
2367
|
-
console.log(
|
|
2368
|
-
console.log(
|
|
938
|
+
console.log(chalk8__default.default.green(label));
|
|
939
|
+
console.log(chalk8__default.default.gray(`Output written to: ${options.outputFile}`));
|
|
2369
940
|
} else {
|
|
2370
941
|
formatJsonOutput(value);
|
|
2371
942
|
}
|
|
@@ -2375,17 +946,17 @@ function createInteractiveRenderer(context = {}) {
|
|
|
2375
946
|
},
|
|
2376
947
|
renderError(error) {
|
|
2377
948
|
if (error instanceof ZapierCliMissingParametersError) {
|
|
2378
|
-
console.error(
|
|
2379
|
-
console.error("\n" +
|
|
949
|
+
console.error(chalk8__default.default.red("\u274C " + formatMissingParamsError(error)));
|
|
950
|
+
console.error("\n" + chalk8__default.default.dim("Use --help to see available options"));
|
|
2380
951
|
throw new ZapierCliExitError(error.message, 1);
|
|
2381
952
|
}
|
|
2382
953
|
if (error instanceof zapierSdk.ZapierError) {
|
|
2383
954
|
const formattedMessage = zapierSdk.formatErrorMessage(error);
|
|
2384
|
-
console.error(
|
|
955
|
+
console.error(chalk8__default.default.red("\u274C Error:"), formattedMessage);
|
|
2385
956
|
throw new ZapierCliExitError(formattedMessage, 1);
|
|
2386
957
|
}
|
|
2387
958
|
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
2388
|
-
console.error(
|
|
959
|
+
console.error(chalk8__default.default.red("\u274C Error:"), msg);
|
|
2389
960
|
throw new ZapierCliExitError(msg, 1);
|
|
2390
961
|
}
|
|
2391
962
|
};
|
|
@@ -2501,7 +1072,7 @@ async function promptConfirm(confirmType, itemType) {
|
|
|
2501
1072
|
}
|
|
2502
1073
|
const configOrFn = CONFIRM_MESSAGES[confirmType];
|
|
2503
1074
|
const { messageBefore, messageAfter } = typeof configOrFn === "function" ? configOrFn(itemType) : configOrFn;
|
|
2504
|
-
console.log(
|
|
1075
|
+
console.log(chalk8__default.default.yellow(`
|
|
2505
1076
|
${messageBefore}
|
|
2506
1077
|
`));
|
|
2507
1078
|
const { confirmed } = await inquirer__default.default.prompt([
|
|
@@ -2525,12 +1096,12 @@ function emitParamDeprecationWarnings({
|
|
|
2525
1096
|
if (Array.isArray(value) && value.length === 0) continue;
|
|
2526
1097
|
console.warn();
|
|
2527
1098
|
console.warn(
|
|
2528
|
-
|
|
1099
|
+
chalk8__default.default.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8__default.default.yellow(
|
|
2529
1100
|
` - \`${toKebabCase(param.name)}\` is deprecated and may be removed in a future release.`
|
|
2530
1101
|
)
|
|
2531
1102
|
);
|
|
2532
1103
|
if (param.deprecationMessage) {
|
|
2533
|
-
console.warn(
|
|
1104
|
+
console.warn(chalk8__default.default.yellow(` ${param.deprecationMessage}`));
|
|
2534
1105
|
}
|
|
2535
1106
|
console.warn();
|
|
2536
1107
|
}
|
|
@@ -2569,20 +1140,16 @@ function getAuthFlowIsHeadless({
|
|
|
2569
1140
|
if (isCallbackResume && !isHeadless) return null;
|
|
2570
1141
|
return isHeadless;
|
|
2571
1142
|
}
|
|
2572
|
-
function analyzeZodSchema(schema
|
|
1143
|
+
function analyzeZodSchema(schema) {
|
|
2573
1144
|
const parameters = [];
|
|
2574
1145
|
const schemaDef = schema._zod?.def;
|
|
2575
1146
|
if (schemaDef?.type === "effect" && schemaDef.innerType) {
|
|
2576
|
-
return analyzeZodSchema(schemaDef.innerType
|
|
1147
|
+
return analyzeZodSchema(schemaDef.innerType);
|
|
2577
1148
|
}
|
|
2578
1149
|
if (schema instanceof zod.z.ZodObject) {
|
|
2579
1150
|
const shape = schema.shape;
|
|
2580
1151
|
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
2581
|
-
const param = analyzeZodField(
|
|
2582
|
-
key,
|
|
2583
|
-
fieldSchema,
|
|
2584
|
-
functionInfo
|
|
2585
|
-
);
|
|
1152
|
+
const param = analyzeZodField(key, fieldSchema);
|
|
2586
1153
|
if (param) {
|
|
2587
1154
|
parameters.push(param);
|
|
2588
1155
|
}
|
|
@@ -2590,7 +1157,7 @@ function analyzeZodSchema(schema, functionInfo) {
|
|
|
2590
1157
|
}
|
|
2591
1158
|
return parameters;
|
|
2592
1159
|
}
|
|
2593
|
-
function analyzeZodField(name, schema
|
|
1160
|
+
function analyzeZodField(name, schema) {
|
|
2594
1161
|
let baseSchema = schema;
|
|
2595
1162
|
let required = true;
|
|
2596
1163
|
let defaultValue = void 0;
|
|
@@ -2650,10 +1217,6 @@ function analyzeZodField(name, schema, functionInfo) {
|
|
|
2650
1217
|
} else if (baseSchema instanceof zod.z.ZodObject || baseSchema instanceof zod.z.ZodRecord) {
|
|
2651
1218
|
paramType = "object";
|
|
2652
1219
|
}
|
|
2653
|
-
let paramHasResolver = false;
|
|
2654
|
-
if (functionInfo?.resolvers?.[name] || functionInfo?.boundResolvers?.[name]) {
|
|
2655
|
-
paramHasResolver = true;
|
|
2656
|
-
}
|
|
2657
1220
|
return {
|
|
2658
1221
|
name,
|
|
2659
1222
|
type: paramType,
|
|
@@ -2661,16 +1224,21 @@ function analyzeZodField(name, schema, functionInfo) {
|
|
|
2661
1224
|
description: schema.description,
|
|
2662
1225
|
default: defaultValue,
|
|
2663
1226
|
choices,
|
|
2664
|
-
hasResolver: paramHasResolver,
|
|
2665
1227
|
isPositional: zapierSdk.isPositional(schema),
|
|
2666
1228
|
elementType,
|
|
2667
1229
|
deprecationMessage,
|
|
2668
1230
|
isDeprecated
|
|
2669
1231
|
};
|
|
2670
1232
|
}
|
|
2671
|
-
function
|
|
1233
|
+
function positionalProjection(schema, positional) {
|
|
1234
|
+
if (!positional?.length || !schema) return [];
|
|
1235
|
+
const shape = schema.shape;
|
|
1236
|
+
if (!shape) return [];
|
|
1237
|
+
return positional.filter((name) => name in shape).map((name) => ({ name, schema: shape[name] }));
|
|
1238
|
+
}
|
|
1239
|
+
function analyzePositionalProjection(projection) {
|
|
2672
1240
|
const cliParams = [];
|
|
2673
|
-
for (const param of
|
|
1241
|
+
for (const param of projection) {
|
|
2674
1242
|
let schema = param.schema;
|
|
2675
1243
|
let isOptional = false;
|
|
2676
1244
|
if (schema instanceof zod.z.ZodOptional) {
|
|
@@ -2680,11 +1248,7 @@ function analyzeInputParameters(inputParameters, functionInfo) {
|
|
|
2680
1248
|
if (schema instanceof zod.z.ZodObject) {
|
|
2681
1249
|
const shape = schema.shape;
|
|
2682
1250
|
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
2683
|
-
const analyzed = analyzeZodField(
|
|
2684
|
-
key,
|
|
2685
|
-
fieldSchema,
|
|
2686
|
-
functionInfo
|
|
2687
|
-
);
|
|
1251
|
+
const analyzed = analyzeZodField(key, fieldSchema);
|
|
2688
1252
|
if (analyzed) {
|
|
2689
1253
|
if (isOptional) {
|
|
2690
1254
|
analyzed.required = false;
|
|
@@ -2693,7 +1257,7 @@ function analyzeInputParameters(inputParameters, functionInfo) {
|
|
|
2693
1257
|
}
|
|
2694
1258
|
}
|
|
2695
1259
|
} else {
|
|
2696
|
-
const analyzed = analyzeZodField(param.name, param.schema
|
|
1260
|
+
const analyzed = analyzeZodField(param.name, param.schema);
|
|
2697
1261
|
if (analyzed) {
|
|
2698
1262
|
analyzed.required = !isOptional;
|
|
2699
1263
|
analyzed.isPositional = true;
|
|
@@ -2703,29 +1267,25 @@ function analyzeInputParameters(inputParameters, functionInfo) {
|
|
|
2703
1267
|
}
|
|
2704
1268
|
return cliParams;
|
|
2705
1269
|
}
|
|
2706
|
-
function
|
|
2707
|
-
const
|
|
2708
|
-
for (const
|
|
2709
|
-
|
|
2710
|
-
if (
|
|
2711
|
-
schema = schema._zod.def.innerType;
|
|
2712
|
-
}
|
|
2713
|
-
if (schema instanceof zod.z.ZodObject) {
|
|
2714
|
-
const shape = schema.shape;
|
|
1270
|
+
function nestPositionalParams(projection, flatParams) {
|
|
1271
|
+
const out2 = {};
|
|
1272
|
+
for (const { name, schema } of projection) {
|
|
1273
|
+
const inner = schema instanceof zod.z.ZodOptional ? schema._zod.def.innerType : schema;
|
|
1274
|
+
if (inner instanceof zod.z.ZodObject) {
|
|
2715
1275
|
const obj = {};
|
|
2716
1276
|
let hasValues = false;
|
|
2717
|
-
for (const key of Object.keys(shape)) {
|
|
1277
|
+
for (const key of Object.keys(inner.shape)) {
|
|
2718
1278
|
if (key in flatParams && flatParams[key] !== void 0) {
|
|
2719
1279
|
obj[key] = flatParams[key];
|
|
2720
1280
|
hasValues = true;
|
|
2721
1281
|
}
|
|
2722
1282
|
}
|
|
2723
|
-
|
|
2724
|
-
} else {
|
|
2725
|
-
|
|
1283
|
+
if (hasValues) out2[name] = obj;
|
|
1284
|
+
} else if (flatParams[name] !== void 0) {
|
|
1285
|
+
out2[name] = flatParams[name];
|
|
2726
1286
|
}
|
|
2727
1287
|
}
|
|
2728
|
-
return
|
|
1288
|
+
return out2;
|
|
2729
1289
|
}
|
|
2730
1290
|
function methodNameToCliCommand(methodName) {
|
|
2731
1291
|
return toKebabCase(methodName);
|
|
@@ -2737,7 +1297,7 @@ function generateCliCommands(program2, sdk) {
|
|
|
2737
1297
|
}
|
|
2738
1298
|
const registry = sdk.getRegistry({ package: "cli" });
|
|
2739
1299
|
registry.functions.forEach((fnInfo) => {
|
|
2740
|
-
if (!fnInfo.inputSchema
|
|
1300
|
+
if (!fnInfo.inputSchema) {
|
|
2741
1301
|
console.warn(`Schema not found for ${fnInfo.name}`);
|
|
2742
1302
|
return;
|
|
2743
1303
|
}
|
|
@@ -2807,12 +1367,11 @@ function generateCliCommands(program2, sdk) {
|
|
|
2807
1367
|
});
|
|
2808
1368
|
}
|
|
2809
1369
|
function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
2810
|
-
const usesInputParameters = !!functionInfo.inputParameters;
|
|
2811
1370
|
const schema = functionInfo.inputSchema;
|
|
2812
|
-
const
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
1371
|
+
const projection = positionalProjection(schema, functionInfo.positional);
|
|
1372
|
+
const usesPositionalProjection = projection.length > 0;
|
|
1373
|
+
const parameters = usesPositionalProjection ? analyzePositionalProjection(projection) : analyzeZodSchema(schema);
|
|
1374
|
+
for (const param of parameters) param.promptable = true;
|
|
2816
1375
|
const schemaAliases = getSchemaAliases(schema);
|
|
2817
1376
|
if (schemaAliases) {
|
|
2818
1377
|
const aliasedNames = new Set(Object.keys(schemaAliases));
|
|
@@ -2862,72 +1421,55 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2862
1421
|
}
|
|
2863
1422
|
}
|
|
2864
1423
|
}
|
|
2865
|
-
const
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
const
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
missing.set(p.name, isRegisteredPositional(p.name));
|
|
2895
|
-
}
|
|
1424
|
+
const resolvers = functionInfo.resolvers;
|
|
1425
|
+
const seedInput = usesPositionalProjection ? nestPositionalParams(projection, rawParams) : Object.fromEntries(
|
|
1426
|
+
Object.entries(rawParams).filter(([, v]) => v !== void 0)
|
|
1427
|
+
);
|
|
1428
|
+
const controller = zapierSdk.createController(sdk);
|
|
1429
|
+
const spinner = promptingEnabled && !options.debug ? ora__default.default({ text: "", spinner: "dots" }) : void 0;
|
|
1430
|
+
let resolved;
|
|
1431
|
+
try {
|
|
1432
|
+
const isRegisteredPositional = (name) => {
|
|
1433
|
+
const p = parameters.find((param) => param.name === name);
|
|
1434
|
+
return !!p && takesPositionalSlot(p);
|
|
1435
|
+
};
|
|
1436
|
+
spinner?.start();
|
|
1437
|
+
resolved = await controller.resolve({
|
|
1438
|
+
method: functionInfo.name,
|
|
1439
|
+
input: seedInput,
|
|
1440
|
+
answer: spinner ? withEngineSpinner(createCliAnswer(), spinner) : promptingEnabled ? createCliAnswer() : ({ state }) => {
|
|
1441
|
+
const missing = /* @__PURE__ */ new Map();
|
|
1442
|
+
missing.set(
|
|
1443
|
+
state.current?.join(".") ?? "value",
|
|
1444
|
+
isRegisteredPositional(String(state.current?.[0] ?? ""))
|
|
1445
|
+
);
|
|
1446
|
+
for (const p of parameters) {
|
|
1447
|
+
if (!p.required || p.isDeprecated || p.isAlias) continue;
|
|
1448
|
+
if (p.name in state.resolved) continue;
|
|
1449
|
+
if (state.settled.includes(p.name)) continue;
|
|
1450
|
+
if (resolvers?.[p.name]?.type === "constant") continue;
|
|
1451
|
+
if (!missing.has(p.name)) {
|
|
1452
|
+
missing.set(p.name, isRegisteredPositional(p.name));
|
|
2896
1453
|
}
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
)
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
}
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
throw err;
|
|
2911
|
-
} finally {
|
|
2912
|
-
spinner?.stop();
|
|
1454
|
+
}
|
|
1455
|
+
throw new ZapierCliMissingParametersError(
|
|
1456
|
+
[...missing].map(([name, isPositional2]) => ({
|
|
1457
|
+
name,
|
|
1458
|
+
isPositional: isPositional2
|
|
1459
|
+
}))
|
|
1460
|
+
);
|
|
1461
|
+
},
|
|
1462
|
+
interactive: promptingEnabled
|
|
1463
|
+
});
|
|
1464
|
+
} catch (err) {
|
|
1465
|
+
if (err instanceof zapierSdk.CoreCancelledSignal) {
|
|
1466
|
+
throw new ZapierCliUserCancellationError();
|
|
2913
1467
|
}
|
|
2914
|
-
|
|
2915
|
-
}
|
|
2916
|
-
|
|
2917
|
-
const resolved = await resolver.resolveParameters(
|
|
2918
|
-
schema,
|
|
2919
|
-
rawParams,
|
|
2920
|
-
sdk,
|
|
2921
|
-
functionInfo.name,
|
|
2922
|
-
{
|
|
2923
|
-
interactiveMode,
|
|
2924
|
-
debug: !!options.debug || process.env.DEBUG === "true" || process.argv.includes("--debug")
|
|
2925
|
-
}
|
|
2926
|
-
);
|
|
2927
|
-
Object.assign(resolvedParams, resolved);
|
|
2928
|
-
} else {
|
|
2929
|
-
Object.assign(resolvedParams, rawParams);
|
|
1468
|
+
throw err;
|
|
1469
|
+
} finally {
|
|
1470
|
+
spinner?.stop();
|
|
2930
1471
|
}
|
|
1472
|
+
Object.assign(resolvedParams, resolved);
|
|
2931
1473
|
const confirm = functionInfo.confirm;
|
|
2932
1474
|
let confirmMessageAfter;
|
|
2933
1475
|
if (confirm && interactiveMode) {
|
|
@@ -2936,7 +1478,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2936
1478
|
functionInfo.itemType
|
|
2937
1479
|
);
|
|
2938
1480
|
if (!confirmResult.confirmed) {
|
|
2939
|
-
console.log(
|
|
1481
|
+
console.log(chalk8__default.default.yellow("Operation cancelled."));
|
|
2940
1482
|
return;
|
|
2941
1483
|
}
|
|
2942
1484
|
confirmMessageAfter = confirmResult.messageAfter;
|
|
@@ -2964,10 +1506,9 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2964
1506
|
}
|
|
2965
1507
|
case "single": {
|
|
2966
1508
|
const callSdkMethod = () => {
|
|
2967
|
-
if (
|
|
2968
|
-
const positionalArgs =
|
|
2969
|
-
|
|
2970
|
-
resolvedParams
|
|
1509
|
+
if (usesPositionalProjection) {
|
|
1510
|
+
const positionalArgs = (functionInfo.positional ?? []).map(
|
|
1511
|
+
(name) => resolvedParams[name]
|
|
2971
1512
|
);
|
|
2972
1513
|
return sdkMethod(...positionalArgs);
|
|
2973
1514
|
}
|
|
@@ -2998,7 +1539,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2998
1539
|
renderer.renderItem(normalizedResult.value);
|
|
2999
1540
|
}
|
|
3000
1541
|
if (confirmMessageAfter) {
|
|
3001
|
-
console.log(
|
|
1542
|
+
console.log(chalk8__default.default.yellow(`
|
|
3002
1543
|
${confirmMessageAfter}`));
|
|
3003
1544
|
}
|
|
3004
1545
|
break;
|
|
@@ -3075,7 +1616,7 @@ function addCommand(program2, commandName, config2) {
|
|
|
3075
1616
|
let hasPositionalArray = false;
|
|
3076
1617
|
config2.parameters.forEach((param) => {
|
|
3077
1618
|
const kebabName = toKebabCase(param.name);
|
|
3078
|
-
if (param.
|
|
1619
|
+
if (param.promptable && param.required) {
|
|
3079
1620
|
command.argument(
|
|
3080
1621
|
`[${kebabName}]`,
|
|
3081
1622
|
param.description || `${kebabName} parameter`
|
|
@@ -4194,20 +2735,20 @@ var getCallablePromise = () => {
|
|
|
4194
2735
|
var getCallablePromise_default = getCallablePromise;
|
|
4195
2736
|
var log = {
|
|
4196
2737
|
info: (message, ...args) => {
|
|
4197
|
-
console.error(
|
|
2738
|
+
console.error(chalk8__default.default.blue("\u2139"), message, ...args);
|
|
4198
2739
|
},
|
|
4199
2740
|
error: (message, ...args) => {
|
|
4200
|
-
console.error(
|
|
2741
|
+
console.error(chalk8__default.default.red("\u2716"), message, ...args);
|
|
4201
2742
|
},
|
|
4202
2743
|
success: (message, ...args) => {
|
|
4203
|
-
console.error(
|
|
2744
|
+
console.error(chalk8__default.default.green("\u2713"), message, ...args);
|
|
4204
2745
|
},
|
|
4205
2746
|
warn: (message, ...args) => {
|
|
4206
|
-
console.error(
|
|
2747
|
+
console.error(chalk8__default.default.yellow("\u26A0"), message, ...args);
|
|
4207
2748
|
},
|
|
4208
2749
|
debug: (message, ...args) => {
|
|
4209
2750
|
if (process.env.DEBUG === "true" || process.argv.includes("--debug")) {
|
|
4210
|
-
console.error(
|
|
2751
|
+
console.error(chalk8__default.default.gray("\u{1F41B}"), message, ...args);
|
|
4211
2752
|
}
|
|
4212
2753
|
}
|
|
4213
2754
|
};
|
|
@@ -7364,7 +5905,7 @@ function buildTemplateVariables({
|
|
|
7364
5905
|
};
|
|
7365
5906
|
}
|
|
7366
5907
|
function cleanupProject({ projectDir }) {
|
|
7367
|
-
console.log("\n" +
|
|
5908
|
+
console.log("\n" + chalk8__default.default.yellow("!") + " Cleaning up...");
|
|
7368
5909
|
fs.rmSync(projectDir, { recursive: true, force: true });
|
|
7369
5910
|
}
|
|
7370
5911
|
async function withInterruptCleanup(cleanup, fn) {
|
|
@@ -7574,8 +6115,8 @@ function buildNextSteps({
|
|
|
7574
6115
|
}
|
|
7575
6116
|
function createConsoleDisplayHooks() {
|
|
7576
6117
|
return {
|
|
7577
|
-
onItemComplete: (message) => console.log(" " +
|
|
7578
|
-
onWarn: (message) => console.warn(
|
|
6118
|
+
onItemComplete: (message) => console.log(" " + chalk8__default.default.green("\u2713") + " " + chalk8__default.default.dim(message)),
|
|
6119
|
+
onWarn: (message) => console.warn(chalk8__default.default.yellow("!") + " " + message),
|
|
7579
6120
|
onStepStart: ({
|
|
7580
6121
|
description,
|
|
7581
6122
|
stepNumber,
|
|
@@ -7584,31 +6125,31 @@ function createConsoleDisplayHooks() {
|
|
|
7584
6125
|
nonInteractive
|
|
7585
6126
|
}) => {
|
|
7586
6127
|
const progressMessage = `${description}...`;
|
|
7587
|
-
const stepCounter =
|
|
6128
|
+
const stepCounter = chalk8__default.default.dim(`${stepNumber}/${totalSteps}`);
|
|
7588
6129
|
if (nonInteractive) {
|
|
7589
6130
|
console.log(
|
|
7590
|
-
"\n" +
|
|
6131
|
+
"\n" + chalk8__default.default.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
|
|
7591
6132
|
);
|
|
7592
6133
|
} else {
|
|
7593
6134
|
console.log(
|
|
7594
|
-
|
|
6135
|
+
chalk8__default.default.dim("\u2192") + " " + progressMessage + " " + stepCounter
|
|
7595
6136
|
);
|
|
7596
6137
|
}
|
|
7597
6138
|
if (command) {
|
|
7598
|
-
console.log(" " +
|
|
6139
|
+
console.log(" " + chalk8__default.default.cyan(`$ ${command}`));
|
|
7599
6140
|
}
|
|
7600
6141
|
},
|
|
7601
6142
|
onStepSuccess: ({ stepNumber, totalSteps }) => console.log(
|
|
7602
|
-
"\n" +
|
|
6143
|
+
"\n" + chalk8__default.default.green("\u2713") + " " + chalk8__default.default.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
|
|
7603
6144
|
),
|
|
7604
6145
|
onStepError: ({ description, command, err }) => {
|
|
7605
6146
|
const detail = err instanceof Error && err.message ? `
|
|
7606
|
-
${
|
|
6147
|
+
${chalk8__default.default.dim(err.message)}` : "";
|
|
7607
6148
|
const hint = command ? `
|
|
7608
|
-
${
|
|
6149
|
+
${chalk8__default.default.dim("run manually:")} ${chalk8__default.default.cyan(`$ ${command}`)}` : "";
|
|
7609
6150
|
console.error(
|
|
7610
6151
|
`
|
|
7611
|
-
${
|
|
6152
|
+
${chalk8__default.default.red("\u2716")} ${chalk8__default.default.bold(description)}${chalk8__default.default.dim(" failed")}${detail}${hint}`
|
|
7612
6153
|
);
|
|
7613
6154
|
}
|
|
7614
6155
|
};
|
|
@@ -7620,22 +6161,22 @@ function displaySummaryAndNextSteps({
|
|
|
7620
6161
|
packageManager
|
|
7621
6162
|
}) {
|
|
7622
6163
|
const formatStatus = (complete) => ({
|
|
7623
|
-
icon: complete ?
|
|
7624
|
-
text: complete ?
|
|
6164
|
+
icon: complete ? chalk8__default.default.green("\u2713") : chalk8__default.default.yellow("!"),
|
|
6165
|
+
text: complete ? chalk8__default.default.green("Setup complete") : chalk8__default.default.yellow("Setup interrupted")
|
|
7625
6166
|
});
|
|
7626
|
-
const formatNextStep = (step, i) => " " +
|
|
7627
|
-
const formatCommand = (cmd) => " " +
|
|
7628
|
-
const formatCompletedStep = (step) => " " +
|
|
6167
|
+
const formatNextStep = (step, i) => " " + chalk8__default.default.dim(`${i + 1}.`) + " " + chalk8__default.default.bold(step.description);
|
|
6168
|
+
const formatCommand = (cmd) => " " + chalk8__default.default.cyan(`$ ${cmd}`);
|
|
6169
|
+
const formatCompletedStep = (step) => " " + chalk8__default.default.green("\u2713") + " " + step.description;
|
|
7629
6170
|
const { execCmd } = getPackageManagerCommands({ packageManager });
|
|
7630
6171
|
const leftoverSteps = steps.filter(
|
|
7631
6172
|
(s) => !completedSetupStepIds.includes(s.id)
|
|
7632
6173
|
);
|
|
7633
6174
|
const isComplete = leftoverSteps.length === 0;
|
|
7634
6175
|
const status = formatStatus(isComplete);
|
|
7635
|
-
console.log("\n" +
|
|
7636
|
-
console.log(" " +
|
|
6176
|
+
console.log("\n" + chalk8__default.default.bold("\u276F Summary") + "\n");
|
|
6177
|
+
console.log(" " + chalk8__default.default.dim("Project") + " " + chalk8__default.default.bold(projectName));
|
|
7637
6178
|
console.log(
|
|
7638
|
-
" " +
|
|
6179
|
+
" " + chalk8__default.default.dim("Status") + " " + status.icon + " " + status.text
|
|
7639
6180
|
);
|
|
7640
6181
|
const completedSteps = steps.filter(
|
|
7641
6182
|
(s) => completedSetupStepIds.includes(s.id)
|
|
@@ -7645,7 +6186,7 @@ function displaySummaryAndNextSteps({
|
|
|
7645
6186
|
for (const step of completedSteps) console.log(formatCompletedStep(step));
|
|
7646
6187
|
}
|
|
7647
6188
|
const nextSteps = buildNextSteps({ projectName, leftoverSteps, execCmd });
|
|
7648
|
-
console.log("\n" +
|
|
6189
|
+
console.log("\n" + chalk8__default.default.bold("\u276F Next Steps") + "\n");
|
|
7649
6190
|
nextSteps.forEach((step, i) => {
|
|
7650
6191
|
console.log(formatNextStep(step, i));
|
|
7651
6192
|
if (step.command) console.log(formatCommand(step.command));
|
|
@@ -7722,13 +6263,13 @@ function createInteractiveCallback() {
|
|
|
7722
6263
|
const attrs = message.message_attributes;
|
|
7723
6264
|
console.log(
|
|
7724
6265
|
`
|
|
7725
|
-
${
|
|
6266
|
+
${chalk8__default.default.bold(`Message #${messageNumber}`)} ${chalk8__default.default.dim(message.id)} ${chalk8__default.default.dim(`(lease #${attrs.lease_count})`)}`
|
|
7726
6267
|
);
|
|
7727
6268
|
if (attrs.error_message) {
|
|
7728
|
-
console.log(
|
|
6269
|
+
console.log(chalk8__default.default.yellow(` upstream error: ${attrs.error_message}`));
|
|
7729
6270
|
}
|
|
7730
6271
|
if (attrs.possible_duplicate_data) {
|
|
7731
|
-
console.log(
|
|
6272
|
+
console.log(chalk8__default.default.yellow(" possible duplicate data"));
|
|
7732
6273
|
}
|
|
7733
6274
|
while (true) {
|
|
7734
6275
|
let action;
|
|
@@ -7758,7 +6299,7 @@ ${chalk__default.default.bold(`Message #${messageNumber}`)} ${chalk__default.def
|
|
|
7758
6299
|
throw error;
|
|
7759
6300
|
}
|
|
7760
6301
|
if (action === "view") {
|
|
7761
|
-
console.log(
|
|
6302
|
+
console.log(chalk8__default.default.dim(JSON.stringify(message.payload, null, 2)));
|
|
7762
6303
|
continue;
|
|
7763
6304
|
}
|
|
7764
6305
|
if (action === "ack") {
|
|
@@ -7861,7 +6402,7 @@ function describeReason(reason) {
|
|
|
7861
6402
|
}
|
|
7862
6403
|
function printDrainError(reason, message) {
|
|
7863
6404
|
console.error(
|
|
7864
|
-
|
|
6405
|
+
chalk8__default.default.red(`Error processing ${message.id}: ${describeReason(reason)}`)
|
|
7865
6406
|
);
|
|
7866
6407
|
}
|
|
7867
6408
|
function printDrainSummary(counts) {
|
|
@@ -7871,7 +6412,7 @@ function printDrainSummary(counts) {
|
|
|
7871
6412
|
if (skipped > 0) parts.push(`${skipped} skipped`);
|
|
7872
6413
|
parts.push(`${counts.rejected} rejected`);
|
|
7873
6414
|
console.log(
|
|
7874
|
-
|
|
6415
|
+
chalk8__default.default.dim(
|
|
7875
6416
|
`
|
|
7876
6417
|
Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
|
|
7877
6418
|
)
|
|
@@ -7879,7 +6420,7 @@ Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
|
|
|
7879
6420
|
}
|
|
7880
6421
|
function warnInteractiveContinueOnErrorOverride() {
|
|
7881
6422
|
console.warn(
|
|
7882
|
-
|
|
6423
|
+
chalk8__default.default.yellow(
|
|
7883
6424
|
'Note: continueOnError=false is overridden to true in interactive mode (the "Skip (let lease expire)" choice would otherwise terminate the drain).'
|
|
7884
6425
|
)
|
|
7885
6426
|
);
|
|
@@ -8205,7 +6746,7 @@ function renderDeprecationNotices() {
|
|
|
8205
6746
|
console.error();
|
|
8206
6747
|
for (const message of messages) {
|
|
8207
6748
|
for (const line of buildBoxLines(message)) {
|
|
8208
|
-
console.error(
|
|
6749
|
+
console.error(chalk8__default.default.red.bold(line));
|
|
8209
6750
|
}
|
|
8210
6751
|
console.error();
|
|
8211
6752
|
}
|
|
@@ -8226,7 +6767,7 @@ function buildBoxLines(message) {
|
|
|
8226
6767
|
// package.json with { type: 'json' }
|
|
8227
6768
|
var package_default2 = {
|
|
8228
6769
|
name: "@zapier/zapier-sdk-cli",
|
|
8229
|
-
version: "0.66.
|
|
6770
|
+
version: "0.66.3"};
|
|
8230
6771
|
|
|
8231
6772
|
// src/sdk.ts
|
|
8232
6773
|
var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
|
|
@@ -8237,9 +6778,9 @@ var cliCoreOptions = {
|
|
|
8237
6778
|
warnedDeprecatedMethods.add(methodName);
|
|
8238
6779
|
console.warn();
|
|
8239
6780
|
console.warn(
|
|
8240
|
-
|
|
6781
|
+
chalk8__default.default.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8__default.default.yellow(` - \`${toKebabCase(methodName)}\` is deprecated.`)
|
|
8241
6782
|
);
|
|
8242
|
-
console.warn(
|
|
6783
|
+
console.warn(chalk8__default.default.yellow(` ${deprecation.message}`));
|
|
8243
6784
|
console.warn();
|
|
8244
6785
|
}
|
|
8245
6786
|
};
|
|
@@ -8529,26 +7070,26 @@ function displayUpdateNotification(versionInfo, packageName) {
|
|
|
8529
7070
|
if (versionInfo.isDeprecated) {
|
|
8530
7071
|
console.error();
|
|
8531
7072
|
console.error(
|
|
8532
|
-
|
|
7073
|
+
chalk8__default.default.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8__default.default.red(
|
|
8533
7074
|
` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
|
|
8534
7075
|
)
|
|
8535
7076
|
);
|
|
8536
7077
|
if (versionInfo.deprecationMessage) {
|
|
8537
|
-
console.error(
|
|
7078
|
+
console.error(chalk8__default.default.red(` ${versionInfo.deprecationMessage}`));
|
|
8538
7079
|
}
|
|
8539
|
-
console.error(
|
|
7080
|
+
console.error(chalk8__default.default.red(` Please update to the latest version.`));
|
|
8540
7081
|
console.error();
|
|
8541
7082
|
}
|
|
8542
7083
|
if (versionInfo.hasUpdate) {
|
|
8543
7084
|
console.error();
|
|
8544
7085
|
console.error(
|
|
8545
|
-
|
|
7086
|
+
chalk8__default.default.yellow.bold("\u{1F4E6} Update available!") + chalk8__default.default.yellow(
|
|
8546
7087
|
` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
|
|
8547
7088
|
)
|
|
8548
7089
|
);
|
|
8549
7090
|
console.error(
|
|
8550
|
-
|
|
8551
|
-
` Run ${
|
|
7091
|
+
chalk8__default.default.yellow(
|
|
7092
|
+
` Run ${chalk8__default.default.bold(getUpdateCommand(packageName))} to update.`
|
|
8552
7093
|
)
|
|
8553
7094
|
);
|
|
8554
7095
|
console.error();
|
|
@@ -8656,11 +7197,11 @@ function buildFrameLines(state, frameIndex) {
|
|
|
8656
7197
|
const bodyWidth = width - 2;
|
|
8657
7198
|
const bodyTextWidth = innerWidth - 2;
|
|
8658
7199
|
const content = [];
|
|
8659
|
-
content.push(
|
|
7200
|
+
content.push(chalk8__default.default.bold.cyan("Approval review"));
|
|
8660
7201
|
content.push("");
|
|
8661
7202
|
if (!state.verdict) {
|
|
8662
7203
|
content.push(
|
|
8663
|
-
|
|
7204
|
+
chalk8__default.default.yellow(`${SPINNER_FRAMES[frameIndex]} Checking approval...`)
|
|
8664
7205
|
);
|
|
8665
7206
|
}
|
|
8666
7207
|
const recentMessages = state.messages.slice(-5);
|
|
@@ -8671,13 +7212,13 @@ function buildFrameLines(state, frameIndex) {
|
|
|
8671
7212
|
"\n"
|
|
8672
7213
|
);
|
|
8673
7214
|
segments.forEach((segment, segmentIndex) => {
|
|
8674
|
-
const prefix = segmentIndex === 0 ?
|
|
8675
|
-
content.push(`${prefix}${dimmed ?
|
|
7215
|
+
const prefix = segmentIndex === 0 ? chalk8__default.default.cyan("> ") : " ";
|
|
7216
|
+
content.push(`${prefix}${dimmed ? chalk8__default.default.dim(segment) : segment}`);
|
|
8676
7217
|
});
|
|
8677
7218
|
});
|
|
8678
7219
|
if (state.streamError) {
|
|
8679
7220
|
if (hasMessages || !state.verdict) content.push("");
|
|
8680
|
-
content.push(
|
|
7221
|
+
content.push(chalk8__default.default.bold.red("Approval stream error"));
|
|
8681
7222
|
for (const segment of wrapAnsi3__default.default(state.streamError, bodyTextWidth, {
|
|
8682
7223
|
hard: true
|
|
8683
7224
|
}).split("\n")) {
|
|
@@ -8687,7 +7228,7 @@ function buildFrameLines(state, frameIndex) {
|
|
|
8687
7228
|
if (state.verdict) {
|
|
8688
7229
|
if (hasMessages || state.streamError) content.push("");
|
|
8689
7230
|
content.push(
|
|
8690
|
-
|
|
7231
|
+
chalk8__default.default.bold.green(`${state.verdict.icon} ${state.verdict.label}`)
|
|
8691
7232
|
);
|
|
8692
7233
|
if (state.verdict.reason) {
|
|
8693
7234
|
for (const segment of wrapAnsi3__default.default(state.verdict.reason, bodyTextWidth, {
|
|
@@ -8699,12 +7240,12 @@ function buildFrameLines(state, frameIndex) {
|
|
|
8699
7240
|
}
|
|
8700
7241
|
const pad = (line) => {
|
|
8701
7242
|
const padding = " ".repeat(Math.max(0, innerWidth - displayWidth(line)));
|
|
8702
|
-
return `${
|
|
7243
|
+
return `${chalk8__default.default.cyan("\u2502")} ${line}${padding} ${chalk8__default.default.cyan("\u2502")}`;
|
|
8703
7244
|
};
|
|
8704
7245
|
return [
|
|
8705
|
-
|
|
7246
|
+
chalk8__default.default.cyan(`\u256D${"\u2500".repeat(bodyWidth)}\u256E`),
|
|
8706
7247
|
...content.map(pad),
|
|
8707
|
-
|
|
7248
|
+
chalk8__default.default.cyan(`\u2570${"\u2500".repeat(bodyWidth)}\u256F`)
|
|
8708
7249
|
];
|
|
8709
7250
|
}
|
|
8710
7251
|
function createApprovalProgressRenderer({
|