@zapier/zapier-sdk-cli 0.48.1 → 0.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +20 -0
- package/dist/cli.cjs +562 -191
- package/dist/cli.mjs +560 -190
- 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/dist/package.json +2 -1
- package/dist/src/utils/parameter-resolver.d.ts +91 -1
- package/dist/src/utils/parameter-resolver.js +593 -120
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -3
package/dist/cli.mjs
CHANGED
|
@@ -3,7 +3,8 @@ import { Command, CommanderError, Option } from 'commander';
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { definePlugin, createPluginMethod, getOrCreateApiClient, OutputPropertySchema, ZapierBundleError, DEFAULT_CONFIG_PATH, ZapierValidationError, ZapierUnknownError, ZapierReleaseTriggerMessageSignal, injectCliLogin, BaseSdkOptionsSchema, isCredentialsObject, invalidateCachedToken, buildApplicationLifecycleEvent, batch, toSnakeCase, ZapierAbortDrainSignal, createZapierSdk as createZapierSdk$1, ZapierError, isPositional, runWithTelemetryContext, buildCapabilityMessage, formatErrorMessage, getOsInfo, getPlatformVersions, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId } from '@zapier/zapier-sdk';
|
|
5
5
|
import inquirer from 'inquirer';
|
|
6
|
-
import
|
|
6
|
+
import search from '@inquirer/search';
|
|
7
|
+
import chalk from 'chalk';
|
|
7
8
|
import ora from 'ora';
|
|
8
9
|
import util from 'util';
|
|
9
10
|
import wrapAnsi from 'wrap-ansi';
|
|
@@ -115,6 +116,26 @@ function getLocalResolutionOrderForParams(paramNames, resolvers) {
|
|
|
115
116
|
}
|
|
116
117
|
return order;
|
|
117
118
|
}
|
|
119
|
+
function unwrapSchema(schema) {
|
|
120
|
+
let current = schema;
|
|
121
|
+
while (current instanceof z.ZodOptional || current instanceof z.ZodDefault || current instanceof z.ZodNullable) {
|
|
122
|
+
current = current._zod.def.innerType;
|
|
123
|
+
}
|
|
124
|
+
return current;
|
|
125
|
+
}
|
|
126
|
+
function coerceToSchemaType(value, schema) {
|
|
127
|
+
if (typeof value !== "string") return value;
|
|
128
|
+
const base = unwrapSchema(schema);
|
|
129
|
+
if (base instanceof z.ZodNumber) {
|
|
130
|
+
const n = Number(value);
|
|
131
|
+
return Number.isNaN(n) ? value : n;
|
|
132
|
+
}
|
|
133
|
+
if (base instanceof z.ZodBoolean) {
|
|
134
|
+
if (value === "true") return true;
|
|
135
|
+
if (value === "false") return false;
|
|
136
|
+
}
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
118
139
|
var SchemaParameterResolver = class {
|
|
119
140
|
constructor() {
|
|
120
141
|
this.debug = false;
|
|
@@ -123,7 +144,7 @@ var SchemaParameterResolver = class {
|
|
|
123
144
|
debugLog(message) {
|
|
124
145
|
if (this.debug) {
|
|
125
146
|
this.stopSpinner();
|
|
126
|
-
console.log(
|
|
147
|
+
console.log(chalk.gray(`[Zapier CLI] ${message}`));
|
|
127
148
|
}
|
|
128
149
|
}
|
|
129
150
|
startSpinner() {
|
|
@@ -214,7 +235,7 @@ var SchemaParameterResolver = class {
|
|
|
214
235
|
}
|
|
215
236
|
} catch (error) {
|
|
216
237
|
if (this.isUserCancellation(error)) {
|
|
217
|
-
console.log(
|
|
238
|
+
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
218
239
|
throw new ZapierCliUserCancellationError();
|
|
219
240
|
}
|
|
220
241
|
throw error;
|
|
@@ -251,7 +272,7 @@ var SchemaParameterResolver = class {
|
|
|
251
272
|
}
|
|
252
273
|
} catch (error) {
|
|
253
274
|
if (this.isUserCancellation(error)) {
|
|
254
|
-
console.log(
|
|
275
|
+
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
255
276
|
throw new ZapierCliUserCancellationError();
|
|
256
277
|
}
|
|
257
278
|
throw error;
|
|
@@ -362,6 +383,237 @@ var SchemaParameterResolver = class {
|
|
|
362
383
|
throw new ZapierCliMissingParametersError(missingParams);
|
|
363
384
|
}
|
|
364
385
|
}
|
|
386
|
+
/**
|
|
387
|
+
* Wrap a PromptConfig.validate so internal sentinels (Symbols) bypass
|
|
388
|
+
* it. The resolver's validator is intended for actual user values; our
|
|
389
|
+
* Skip / Custom / Load-more sentinels are internal control-flow and
|
|
390
|
+
* should pass through. Returns `undefined` when the resolver didn't
|
|
391
|
+
* supply a validator (so `await search({ ...rest })` doesn't get a
|
|
392
|
+
* pass-through identity function).
|
|
393
|
+
*/
|
|
394
|
+
wrapPromptValidate(validate) {
|
|
395
|
+
if (!validate) return void 0;
|
|
396
|
+
return (value) => typeof value === "symbol" ? true : validate(value);
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Apply a PromptConfig.filter to a selected value, but only when the
|
|
400
|
+
* value is a real data choice (not an internal sentinel). @inquirer/search
|
|
401
|
+
* has no built-in filter hook, so the search-backed paths call this
|
|
402
|
+
* explicitly before returning.
|
|
403
|
+
*/
|
|
404
|
+
applyPromptFilter(filter, value) {
|
|
405
|
+
if (!filter || typeof value === "symbol") return value;
|
|
406
|
+
return filter(value);
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* If the resolver's PromptConfig sets a `default` value, move the
|
|
410
|
+
* matching choice to the front so it's the first selectable item in
|
|
411
|
+
* the rendered source. @inquirer/search has no built-in `default`
|
|
412
|
+
* option; first-selectable is what Enter picks, so reordering achieves
|
|
413
|
+
* the same semantics inquirer.prompt's list had natively.
|
|
414
|
+
*
|
|
415
|
+
* Returns the original array if no default is set or the default
|
|
416
|
+
* doesn't match any current choice.
|
|
417
|
+
*/
|
|
418
|
+
reorderForDefault(matches, defaultValue) {
|
|
419
|
+
if (defaultValue === void 0) return matches;
|
|
420
|
+
const idx = matches.findIndex((c) => c.value === defaultValue);
|
|
421
|
+
if (idx <= 0) return matches;
|
|
422
|
+
return [matches[idx], ...matches.slice(0, idx), ...matches.slice(idx + 1)];
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Build the disabled "if you had X capability, more results would show"
|
|
426
|
+
* hints for any unmet capabilities the resolver declared. Returns the
|
|
427
|
+
* raw hint strings — callers wrap them into choice objects with whatever
|
|
428
|
+
* sentinel value they prefer (disabled choices' values are inert).
|
|
429
|
+
*/
|
|
430
|
+
async computeCapabilityHints(resolver, context) {
|
|
431
|
+
if (!resolver.requireCapabilities) return [];
|
|
432
|
+
const capContext = context.sdk.context;
|
|
433
|
+
if (!capContext.hasCapability) return [];
|
|
434
|
+
const messages = [];
|
|
435
|
+
for (const cap of resolver.requireCapabilities) {
|
|
436
|
+
const enabled = await capContext.hasCapability(cap);
|
|
437
|
+
if (!enabled) messages.push(buildCapabilityMessage(cap));
|
|
438
|
+
}
|
|
439
|
+
return messages;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Unpack a DynamicResolver.fetch result into the three shapes the caller
|
|
443
|
+
* cares about: a flat items array, an optional AsyncIterator for further
|
|
444
|
+
* pagination, and a hasMore flag. Centralizing keeps the AsyncIterable /
|
|
445
|
+
* `{data, nextCursor}` / `TItem[]` discrimination in one place — both
|
|
446
|
+
* the main dropdown loop and the search-mode flow consume it.
|
|
447
|
+
*
|
|
448
|
+
* The function is `async` for the AsyncIterable branch only (we eagerly
|
|
449
|
+
* consume the first page so callers don't have to discriminate). The
|
|
450
|
+
* other two branches return synchronously; an explicit Promise.resolve
|
|
451
|
+
* is unnecessary because async automatically wraps.
|
|
452
|
+
*
|
|
453
|
+
* Note: callers in search mode intentionally drop `pageIterator` /
|
|
454
|
+
* `hasMore` because each search() invocation re-prompts from scratch;
|
|
455
|
+
* pagination only matters when the prompt is the dropdown itself.
|
|
456
|
+
*/
|
|
457
|
+
async unpackFetchResult(fetchResult, promptLabel) {
|
|
458
|
+
if (fetchResult != null && typeof fetchResult === "object" && Symbol.asyncIterator in fetchResult) {
|
|
459
|
+
const pageIterator = fetchResult[Symbol.asyncIterator]();
|
|
460
|
+
const first = await pageIterator.next();
|
|
461
|
+
if (!first.done && first.value) {
|
|
462
|
+
return {
|
|
463
|
+
items: Array.isArray(first.value.data) ? first.value.data : [],
|
|
464
|
+
pageIterator,
|
|
465
|
+
hasMore: first.value.nextCursor != null
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
return { items: [], pageIterator, hasMore: false };
|
|
469
|
+
}
|
|
470
|
+
if (fetchResult != null && typeof fetchResult === "object" && "data" in fetchResult) {
|
|
471
|
+
const page = fetchResult;
|
|
472
|
+
const hasMore = page.nextCursor != null;
|
|
473
|
+
if (hasMore) {
|
|
474
|
+
this.debugLog(
|
|
475
|
+
`Resolver for ${promptLabel} has more pages but no iterator. Use toIterable() to enable "Load more..." support.`
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
return {
|
|
479
|
+
items: Array.isArray(page.data) ? page.data : [],
|
|
480
|
+
pageIterator: null,
|
|
481
|
+
hasMore
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
return {
|
|
485
|
+
items: Array.isArray(fetchResult) ? fetchResult : [],
|
|
486
|
+
pageIterator: null,
|
|
487
|
+
hasMore: false
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Search-mode dynamic resolver: prompts the user for free-form text, passes
|
|
492
|
+
* it to fetch via `search`, and either short-circuits on a primitive return
|
|
493
|
+
* (exact match) or renders the results as a search-filterable dropdown.
|
|
494
|
+
* Empty results still render the dropdown so the user can fall through to
|
|
495
|
+
* "(Use 'foo' as-is)" or "(Try a different search)" rather than being
|
|
496
|
+
* stuck.
|
|
497
|
+
*
|
|
498
|
+
* Known limitation: pagination beyond the first page is dropped. Each
|
|
499
|
+
* search() invocation re-prompts from scratch and the user is expected
|
|
500
|
+
* to refine their query if too many results came back. If a future
|
|
501
|
+
* high-cardinality search resolver needs Load-more here, the
|
|
502
|
+
* `pageIterator` / `hasMore` from `unpackFetchResult` is what to wire in.
|
|
503
|
+
*/
|
|
504
|
+
async resolveDynamicWithSearchInput({
|
|
505
|
+
resolver,
|
|
506
|
+
context,
|
|
507
|
+
promptLabel,
|
|
508
|
+
isOptional
|
|
509
|
+
}) {
|
|
510
|
+
const parenParts = [];
|
|
511
|
+
if (isOptional) parenParts.push("optional");
|
|
512
|
+
if (resolver.placeholder) parenParts.push(resolver.placeholder);
|
|
513
|
+
const parens = parenParts.length > 0 ? ` (${parenParts.join(", ")})` : "";
|
|
514
|
+
const message = `Enter or search ${promptLabel}${parens}:`;
|
|
515
|
+
const SKIP_SENTINEL = Symbol("SKIP");
|
|
516
|
+
const USE_AS_IS_SENTINEL = Symbol("USE_AS_IS");
|
|
517
|
+
const TRY_AGAIN_SENTINEL = Symbol("TRY_AGAIN");
|
|
518
|
+
let lastNote;
|
|
519
|
+
while (true) {
|
|
520
|
+
this.stopSpinner();
|
|
521
|
+
if (lastNote) {
|
|
522
|
+
console.log(chalk.yellow(lastNote));
|
|
523
|
+
lastNote = void 0;
|
|
524
|
+
}
|
|
525
|
+
const answers = await inquirer.prompt([
|
|
526
|
+
{ type: "input", name: "search", message }
|
|
527
|
+
]);
|
|
528
|
+
const rawInput = answers.search;
|
|
529
|
+
const searchInput = typeof rawInput === "string" ? rawInput.trim() : "";
|
|
530
|
+
if (!searchInput) {
|
|
531
|
+
if (isOptional) return void 0;
|
|
532
|
+
lastNote = `${promptLabel} is required.`;
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
const searchParams = {
|
|
536
|
+
...context.resolvedParams,
|
|
537
|
+
search: searchInput
|
|
538
|
+
};
|
|
539
|
+
this.startSpinner();
|
|
540
|
+
this.debugLog(`Searching ${promptLabel} for "${searchInput}"`);
|
|
541
|
+
let fetchResult;
|
|
542
|
+
try {
|
|
543
|
+
fetchResult = await resolver.fetch(context.sdk, searchParams);
|
|
544
|
+
} finally {
|
|
545
|
+
this.stopSpinner();
|
|
546
|
+
}
|
|
547
|
+
if (typeof fetchResult === "string" || typeof fetchResult === "number") {
|
|
548
|
+
return fetchResult;
|
|
549
|
+
}
|
|
550
|
+
const { items } = await this.unpackFetchResult(fetchResult, promptLabel);
|
|
551
|
+
const choicesConfig = resolver.prompt(items, searchParams);
|
|
552
|
+
const dataChoices = choicesConfig.choices ?? [];
|
|
553
|
+
const capabilityHintMessages = await this.computeCapabilityHints(
|
|
554
|
+
resolver,
|
|
555
|
+
context
|
|
556
|
+
);
|
|
557
|
+
const selected = await search({
|
|
558
|
+
message: choicesConfig.message,
|
|
559
|
+
validate: this.wrapPromptValidate(choicesConfig.validate),
|
|
560
|
+
// @inquirer/search passes an AbortSignal as the second arg for
|
|
561
|
+
// cancelling async sources. All three of our source callbacks are
|
|
562
|
+
// pure-local (filter an already-fetched array), so we intentionally
|
|
563
|
+
// ignore the signal. A future server-side filter implementation
|
|
564
|
+
// would need to honor it.
|
|
565
|
+
source: (term) => {
|
|
566
|
+
const trimmed = (term ?? "").trim();
|
|
567
|
+
const lower = trimmed.toLowerCase();
|
|
568
|
+
const matches = trimmed ? dataChoices.filter((c) => c.name.toLowerCase().includes(lower)) : dataChoices;
|
|
569
|
+
const orderedMatches = trimmed ? matches : this.reorderForDefault(matches, choicesConfig.default);
|
|
570
|
+
const skipChoice = isOptional ? [{ name: chalk.dim("(Skip)"), value: SKIP_SENTINEL }] : [];
|
|
571
|
+
const useAsIsChoice = {
|
|
572
|
+
name: chalk.dim(`(Use ${JSON.stringify(searchInput)} as-is)`),
|
|
573
|
+
value: USE_AS_IS_SENTINEL
|
|
574
|
+
};
|
|
575
|
+
const tryAgainChoice = {
|
|
576
|
+
name: chalk.dim("(Try a different search)"),
|
|
577
|
+
value: TRY_AGAIN_SENTINEL
|
|
578
|
+
};
|
|
579
|
+
const out = [];
|
|
580
|
+
if (orderedMatches.length === 0) {
|
|
581
|
+
out.push(useAsIsChoice);
|
|
582
|
+
out.push(tryAgainChoice);
|
|
583
|
+
out.push(...skipChoice);
|
|
584
|
+
} else {
|
|
585
|
+
out.push(...orderedMatches);
|
|
586
|
+
out.push(...skipChoice);
|
|
587
|
+
out.push(useAsIsChoice);
|
|
588
|
+
out.push(tryAgainChoice);
|
|
589
|
+
}
|
|
590
|
+
for (const message2 of capabilityHintMessages) {
|
|
591
|
+
out.push({
|
|
592
|
+
name: chalk.dim(message2),
|
|
593
|
+
value: SKIP_SENTINEL,
|
|
594
|
+
disabled: true
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
return out;
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
if (selected === SKIP_SENTINEL) return void 0;
|
|
601
|
+
if (selected === USE_AS_IS_SENTINEL) {
|
|
602
|
+
const validationResult = choicesConfig.validate?.(searchInput);
|
|
603
|
+
if (validationResult === false) {
|
|
604
|
+
lastNote = `${promptLabel}: invalid value.`;
|
|
605
|
+
continue;
|
|
606
|
+
}
|
|
607
|
+
if (typeof validationResult === "string") {
|
|
608
|
+
lastNote = validationResult;
|
|
609
|
+
continue;
|
|
610
|
+
}
|
|
611
|
+
return this.applyPromptFilter(choicesConfig.filter, searchInput);
|
|
612
|
+
}
|
|
613
|
+
if (selected === TRY_AGAIN_SENTINEL) continue;
|
|
614
|
+
return this.applyPromptFilter(choicesConfig.filter, selected);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
365
617
|
async resolveParameter(param, context, functionName, options) {
|
|
366
618
|
const resolver = this.getResolver(
|
|
367
619
|
param.name,
|
|
@@ -375,6 +627,27 @@ var SchemaParameterResolver = class {
|
|
|
375
627
|
isOptional: options?.isOptional
|
|
376
628
|
});
|
|
377
629
|
}
|
|
630
|
+
/**
|
|
631
|
+
* Run a resolver to obtain a value for one parameter, prompting the
|
|
632
|
+
* user when necessary. Routes to one of several prompt backends and
|
|
633
|
+
* has to keep the `PromptConfig` contract honest across each one.
|
|
634
|
+
*
|
|
635
|
+
* `PromptConfig` field × prompt-backend handling:
|
|
636
|
+
*
|
|
637
|
+
* | field | list (search()) | checkbox/confirm (inquirer.prompt) | search-mode dropdown (search()) |
|
|
638
|
+
* | -------- | --------------- | ---------------------------------- | ------------------------------- |
|
|
639
|
+
* | type | required | required | required |
|
|
640
|
+
* | name | (set internally)| forwarded | (set internally) |
|
|
641
|
+
* | message | forwarded | forwarded | forwarded |
|
|
642
|
+
* | choices | filtered in src | passed to inquirer | filtered in src |
|
|
643
|
+
* | default | reorder matches | passed (also internal cursor jump) | reorder matches |
|
|
644
|
+
* | validate | wrapped | passed (inquirer native) | wrapped + manual for (Use as-is)|
|
|
645
|
+
* | filter | manual once | inquirer native (do NOT double) | manual once |
|
|
646
|
+
*
|
|
647
|
+
* Escape-hatch sentinels (Skip / Custom value / Use as-is / Load more
|
|
648
|
+
* / Try again) bypass the resolver's validate/filter because they
|
|
649
|
+
* aren't real user values — they're CLI control-flow.
|
|
650
|
+
*/
|
|
378
651
|
async resolveWithResolver(resolver, param, context, options = {}) {
|
|
379
652
|
const { arrayIndex, isOptional } = options;
|
|
380
653
|
const inArrayContext = arrayIndex != null;
|
|
@@ -401,7 +674,7 @@ var SchemaParameterResolver = class {
|
|
|
401
674
|
if (isOptional && (value === void 0 || value === "" || value === staticResolver.placeholder)) {
|
|
402
675
|
return void 0;
|
|
403
676
|
}
|
|
404
|
-
return value;
|
|
677
|
+
return coerceToSchemaType(value, param.schema);
|
|
405
678
|
} else if (resolver.type === "dynamic") {
|
|
406
679
|
const dynamicResolver = resolver;
|
|
407
680
|
this.startSpinner();
|
|
@@ -413,41 +686,52 @@ var SchemaParameterResolver = class {
|
|
|
413
686
|
this.stopSpinner();
|
|
414
687
|
return autoResolution.resolvedValue;
|
|
415
688
|
}
|
|
689
|
+
if (dynamicResolver.inputType === "search") {
|
|
690
|
+
this.stopSpinner();
|
|
691
|
+
return await this.resolveDynamicWithSearchInput({
|
|
692
|
+
resolver: dynamicResolver,
|
|
693
|
+
context,
|
|
694
|
+
promptLabel,
|
|
695
|
+
isOptional: isOptional ?? false
|
|
696
|
+
});
|
|
697
|
+
}
|
|
416
698
|
this.debugLog(`Fetching options for ${promptLabel}`);
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
699
|
+
let fetchResult;
|
|
700
|
+
try {
|
|
701
|
+
fetchResult = await dynamicResolver.fetch(
|
|
702
|
+
context.sdk,
|
|
703
|
+
context.resolvedParams
|
|
704
|
+
);
|
|
705
|
+
} finally {
|
|
706
|
+
this.stopSpinner();
|
|
707
|
+
}
|
|
708
|
+
if (typeof fetchResult === "string" || typeof fetchResult === "number") {
|
|
709
|
+
console.error(
|
|
710
|
+
chalk.yellow(
|
|
711
|
+
`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.`
|
|
712
|
+
)
|
|
713
|
+
);
|
|
714
|
+
const fallbackAnswers = await inquirer.prompt([
|
|
715
|
+
{
|
|
716
|
+
type: "input",
|
|
717
|
+
name: promptName,
|
|
718
|
+
message: `Enter ${promptLabel}${isOptional ? " (optional)" : ""}:`
|
|
719
|
+
}
|
|
720
|
+
]);
|
|
721
|
+
const fallbackValue = fallbackAnswers[promptName];
|
|
722
|
+
if (isOptional && (fallbackValue === void 0 || fallbackValue === "")) {
|
|
723
|
+
return void 0;
|
|
441
724
|
}
|
|
442
|
-
|
|
443
|
-
items = fetchResult || [];
|
|
444
|
-
pageIterator = null;
|
|
725
|
+
return fallbackValue;
|
|
445
726
|
}
|
|
727
|
+
const unpacked = await this.unpackFetchResult(fetchResult, promptLabel);
|
|
728
|
+
let pageIterator = unpacked.pageIterator;
|
|
729
|
+
let items = unpacked.items;
|
|
730
|
+
let hasMore = unpacked.hasMore;
|
|
446
731
|
const LOAD_MORE_SENTINEL = Symbol("LOAD_MORE");
|
|
447
732
|
const SKIP_SENTINEL = Symbol("SKIP");
|
|
448
733
|
const CUSTOM_VALUE_SENTINEL = Symbol("CUSTOM_VALUE");
|
|
449
734
|
let newItemsStartIndex = -1;
|
|
450
|
-
this.stopSpinner();
|
|
451
735
|
while (true) {
|
|
452
736
|
const promptConfig = dynamicResolver.prompt(
|
|
453
737
|
items,
|
|
@@ -462,50 +746,97 @@ var SchemaParameterResolver = class {
|
|
|
462
746
|
`No ${promptLabel} available to select.`
|
|
463
747
|
);
|
|
464
748
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
if (hasMore && pageIterator && promptConfig.choices) {
|
|
479
|
-
promptConfig.choices.push({
|
|
480
|
-
name: chalk7.dim("(Load more...)"),
|
|
481
|
-
value: LOAD_MORE_SENTINEL
|
|
482
|
-
});
|
|
749
|
+
const capabilityHints = [];
|
|
750
|
+
if (!hasMore) {
|
|
751
|
+
const hintMessages = await this.computeCapabilityHints(
|
|
752
|
+
dynamicResolver,
|
|
753
|
+
context
|
|
754
|
+
);
|
|
755
|
+
for (const message of hintMessages) {
|
|
756
|
+
capabilityHints.push({
|
|
757
|
+
name: chalk.dim(message),
|
|
758
|
+
value: SKIP_SENTINEL,
|
|
759
|
+
disabled: true
|
|
760
|
+
});
|
|
761
|
+
}
|
|
483
762
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
763
|
+
let selected;
|
|
764
|
+
if (promptConfig.type === "list") {
|
|
765
|
+
const dataChoices = promptConfig.choices ?? [];
|
|
766
|
+
selected = await search({
|
|
767
|
+
message: promptConfig.message,
|
|
768
|
+
validate: this.wrapPromptValidate(promptConfig.validate),
|
|
769
|
+
source: (term) => {
|
|
770
|
+
const trimmed = (term ?? "").trim();
|
|
771
|
+
const lower = trimmed.toLowerCase();
|
|
772
|
+
const matches = trimmed ? dataChoices.filter(
|
|
773
|
+
(c) => c.name.toLowerCase().includes(lower)
|
|
774
|
+
) : dataChoices;
|
|
775
|
+
const out = [];
|
|
776
|
+
const skipChoice = isOptional ? [
|
|
777
|
+
{
|
|
778
|
+
name: chalk.dim("(Skip)"),
|
|
779
|
+
value: SKIP_SENTINEL
|
|
780
|
+
}
|
|
781
|
+
] : [];
|
|
782
|
+
const customValueChoice = {
|
|
783
|
+
name: chalk.dim("(Enter custom value)"),
|
|
784
|
+
value: CUSTOM_VALUE_SENTINEL
|
|
785
|
+
};
|
|
786
|
+
const orderedMatches = trimmed ? matches : this.reorderForDefault(matches, promptConfig.default);
|
|
787
|
+
const matchesFirst = trimmed || promptConfig.default !== void 0;
|
|
788
|
+
const loadMoreChoice = hasMore && pageIterator ? {
|
|
789
|
+
name: chalk.dim("(Load more...)"),
|
|
790
|
+
value: LOAD_MORE_SENTINEL
|
|
791
|
+
} : null;
|
|
792
|
+
if (matchesFirst && orderedMatches.length > 0) {
|
|
793
|
+
out.push(...orderedMatches);
|
|
794
|
+
out.push(...skipChoice);
|
|
795
|
+
out.push(customValueChoice);
|
|
796
|
+
if (loadMoreChoice) out.push(loadMoreChoice);
|
|
797
|
+
} else if (matchesFirst) {
|
|
798
|
+
out.push(customValueChoice);
|
|
799
|
+
if (loadMoreChoice) out.push(loadMoreChoice);
|
|
800
|
+
out.push(...skipChoice);
|
|
801
|
+
} else {
|
|
802
|
+
out.push(...skipChoice);
|
|
803
|
+
out.push(customValueChoice);
|
|
804
|
+
out.push(...orderedMatches);
|
|
805
|
+
if (loadMoreChoice) out.push(loadMoreChoice);
|
|
495
806
|
}
|
|
807
|
+
if (capabilityHints.length > 0 && (!trimmed || matches.length > 0)) {
|
|
808
|
+
out.push(...capabilityHints);
|
|
809
|
+
}
|
|
810
|
+
return out;
|
|
496
811
|
}
|
|
812
|
+
});
|
|
813
|
+
} else {
|
|
814
|
+
if (isOptional && promptConfig.choices) {
|
|
815
|
+
promptConfig.choices.unshift({
|
|
816
|
+
name: chalk.dim("(Skip)"),
|
|
817
|
+
value: SKIP_SENTINEL
|
|
818
|
+
});
|
|
497
819
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
promptConfig.default = promptConfig.choices[adjustedIndex].value;
|
|
820
|
+
if (hasMore && pageIterator && promptConfig.choices) {
|
|
821
|
+
promptConfig.choices.push({
|
|
822
|
+
name: chalk.dim("(Load more...)"),
|
|
823
|
+
value: LOAD_MORE_SENTINEL
|
|
824
|
+
});
|
|
504
825
|
}
|
|
505
|
-
|
|
826
|
+
if (capabilityHints.length > 0 && promptConfig.choices) {
|
|
827
|
+
promptConfig.choices.push(...capabilityHints);
|
|
828
|
+
}
|
|
829
|
+
if (newItemsStartIndex >= 0 && promptConfig.choices) {
|
|
830
|
+
const injectedBefore = isOptional ? 1 : 0;
|
|
831
|
+
const adjustedIndex = newItemsStartIndex + injectedBefore;
|
|
832
|
+
if (promptConfig.choices[adjustedIndex]) {
|
|
833
|
+
promptConfig.default = promptConfig.choices[adjustedIndex].value;
|
|
834
|
+
}
|
|
835
|
+
newItemsStartIndex = -1;
|
|
836
|
+
}
|
|
837
|
+
const answers = await inquirer.prompt([promptConfig]);
|
|
838
|
+
selected = answers[promptName];
|
|
506
839
|
}
|
|
507
|
-
const answers = await inquirer.prompt([promptConfig]);
|
|
508
|
-
let selected = answers[promptName];
|
|
509
840
|
if (selected === SKIP_SENTINEL) {
|
|
510
841
|
return void 0;
|
|
511
842
|
}
|
|
@@ -544,7 +875,7 @@ var SchemaParameterResolver = class {
|
|
|
544
875
|
}
|
|
545
876
|
continue;
|
|
546
877
|
}
|
|
547
|
-
return selected;
|
|
878
|
+
return promptConfig.type === "list" ? this.applyPromptFilter(promptConfig.filter, selected) : selected;
|
|
548
879
|
}
|
|
549
880
|
} else if (resolver.type === "fields") {
|
|
550
881
|
if (isOptional && !inArrayContext) {
|
|
@@ -602,7 +933,7 @@ var SchemaParameterResolver = class {
|
|
|
602
933
|
if (!rootFieldItems || rootFieldItems.length === 0) {
|
|
603
934
|
if (iteration === 1) {
|
|
604
935
|
console.log(
|
|
605
|
-
|
|
936
|
+
chalk.yellow(`No input fields required for this action.`)
|
|
606
937
|
);
|
|
607
938
|
}
|
|
608
939
|
break;
|
|
@@ -625,7 +956,7 @@ var SchemaParameterResolver = class {
|
|
|
625
956
|
}
|
|
626
957
|
if (iteration >= maxIterations) {
|
|
627
958
|
console.log(
|
|
628
|
-
|
|
959
|
+
chalk.yellow(
|
|
629
960
|
`
|
|
630
961
|
\u26A0\uFE0F Maximum field resolution iterations reached. Some dynamic fields may not have been discovered.`
|
|
631
962
|
)
|
|
@@ -676,7 +1007,7 @@ var SchemaParameterResolver = class {
|
|
|
676
1007
|
};
|
|
677
1008
|
}
|
|
678
1009
|
if (items.length >= maxItems) {
|
|
679
|
-
console.log(
|
|
1010
|
+
console.log(chalk.gray(`Maximum of ${maxItems} items reached.`));
|
|
680
1011
|
}
|
|
681
1012
|
return items;
|
|
682
1013
|
}
|
|
@@ -694,7 +1025,7 @@ var SchemaParameterResolver = class {
|
|
|
694
1025
|
const fieldsetTitle = typedItem.title || typedItem.key;
|
|
695
1026
|
const pathDisplay = fieldsetPath.length > 0 ? ` (in ${fieldsetPath.join(" > ")})` : "";
|
|
696
1027
|
console.log(
|
|
697
|
-
|
|
1028
|
+
chalk.cyan(
|
|
698
1029
|
`
|
|
699
1030
|
\u{1F4C1} Processing fieldset: ${fieldsetTitle}${pathDisplay}`
|
|
700
1031
|
)
|
|
@@ -762,7 +1093,7 @@ var SchemaParameterResolver = class {
|
|
|
762
1093
|
}
|
|
763
1094
|
} else {
|
|
764
1095
|
console.log(
|
|
765
|
-
|
|
1096
|
+
chalk.gray(
|
|
766
1097
|
`
|
|
767
1098
|
There are ${optionalFields.length} ${iteration === 1 ? "" : "additional "}optional field(s) available${pathContext}.`
|
|
768
1099
|
)
|
|
@@ -777,7 +1108,7 @@ There are ${optionalFields.length} ${iteration === 1 ? "" : "additional "}option
|
|
|
777
1108
|
}
|
|
778
1109
|
]);
|
|
779
1110
|
if (shouldConfigureOptional.configure) {
|
|
780
|
-
console.log(
|
|
1111
|
+
console.log(chalk.cyan(`
|
|
781
1112
|
Optional fields${pathContext}:`));
|
|
782
1113
|
for (const field of optionalFields) {
|
|
783
1114
|
await this.promptForField(field, targetInputs, context);
|
|
@@ -793,7 +1124,7 @@ Optional fields${pathContext}:`));
|
|
|
793
1124
|
}
|
|
794
1125
|
} catch (error) {
|
|
795
1126
|
if (this.isUserCancellation(error)) {
|
|
796
|
-
console.log(
|
|
1127
|
+
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
797
1128
|
throw new ZapierCliUserCancellationError();
|
|
798
1129
|
}
|
|
799
1130
|
throw error;
|
|
@@ -869,7 +1200,7 @@ Optional fields${pathContext}:`));
|
|
|
869
1200
|
}));
|
|
870
1201
|
if (choices.length === 0 && !cursor) {
|
|
871
1202
|
console.log(
|
|
872
|
-
|
|
1203
|
+
chalk.yellow(`No choices available for ${fieldMeta.title}`)
|
|
873
1204
|
);
|
|
874
1205
|
}
|
|
875
1206
|
return {
|
|
@@ -879,14 +1210,17 @@ Optional fields${pathContext}:`));
|
|
|
879
1210
|
} catch (error) {
|
|
880
1211
|
this.stopSpinner();
|
|
881
1212
|
console.warn(
|
|
882
|
-
|
|
1213
|
+
chalk.yellow(`Failed to fetch choices for ${fieldMeta.title}:`),
|
|
883
1214
|
error
|
|
884
1215
|
);
|
|
885
1216
|
return { choices: [] };
|
|
886
1217
|
}
|
|
887
1218
|
}
|
|
888
1219
|
/**
|
|
889
|
-
* Prompt user with choices (handles both single and multi-select with pagination)
|
|
1220
|
+
* Prompt user with choices (handles both single and multi-select with pagination).
|
|
1221
|
+
* Single-select goes through @inquirer/search so users can type-to-filter long
|
|
1222
|
+
* dropdowns (SELECT fields); multi-select stays on inquirer.prompt since search
|
|
1223
|
+
* is single-select only.
|
|
890
1224
|
*/
|
|
891
1225
|
async promptWithChoices({
|
|
892
1226
|
fieldMeta,
|
|
@@ -899,45 +1233,81 @@ Optional fields${pathContext}:`));
|
|
|
899
1233
|
const choices = [...initialChoices];
|
|
900
1234
|
let nextCursor = initialCursor;
|
|
901
1235
|
const LOAD_MORE_SENTINEL = Symbol("LOAD_MORE");
|
|
1236
|
+
const SKIP_SENTINEL = Symbol("SKIP");
|
|
902
1237
|
const CUSTOM_VALUE_SENTINEL = Symbol("CUSTOM_VALUE");
|
|
1238
|
+
const message = `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"}:`;
|
|
903
1239
|
while (true) {
|
|
904
|
-
|
|
905
|
-
name: choice.label,
|
|
906
|
-
value: choice.value
|
|
907
|
-
}));
|
|
1240
|
+
let selectedValue;
|
|
908
1241
|
if (!fieldMeta.isMultiSelect) {
|
|
909
|
-
|
|
910
|
-
name:
|
|
911
|
-
value:
|
|
912
|
-
});
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
1242
|
+
const dataChoices = choices.map((c) => ({
|
|
1243
|
+
name: c.label,
|
|
1244
|
+
value: c.value
|
|
1245
|
+
}));
|
|
1246
|
+
selectedValue = await search({
|
|
1247
|
+
message,
|
|
1248
|
+
source: (term) => {
|
|
1249
|
+
const trimmed = (term ?? "").trim();
|
|
1250
|
+
const lower = trimmed.toLowerCase();
|
|
1251
|
+
const matches = trimmed ? dataChoices.filter((c) => c.name.toLowerCase().includes(lower)) : dataChoices;
|
|
1252
|
+
const out = [];
|
|
1253
|
+
const skipChoice = !fieldMeta.isRequired ? [{ name: chalk.dim("(Skip)"), value: SKIP_SENTINEL }] : [];
|
|
1254
|
+
const customValueChoice = {
|
|
1255
|
+
name: chalk.dim("(Enter custom value)"),
|
|
1256
|
+
value: CUSTOM_VALUE_SENTINEL
|
|
1257
|
+
};
|
|
1258
|
+
const loadMoreChoice = nextCursor && context ? {
|
|
1259
|
+
name: chalk.dim("(Load more...)"),
|
|
1260
|
+
value: LOAD_MORE_SENTINEL
|
|
1261
|
+
} : null;
|
|
1262
|
+
if (trimmed && matches.length > 0) {
|
|
1263
|
+
out.push(...matches);
|
|
1264
|
+
out.push(...skipChoice);
|
|
1265
|
+
out.push(customValueChoice);
|
|
1266
|
+
if (loadMoreChoice) out.push(loadMoreChoice);
|
|
1267
|
+
} else if (trimmed) {
|
|
1268
|
+
out.push(customValueChoice);
|
|
1269
|
+
if (loadMoreChoice) out.push(loadMoreChoice);
|
|
1270
|
+
out.push(...skipChoice);
|
|
1271
|
+
} else {
|
|
1272
|
+
out.push(...skipChoice);
|
|
1273
|
+
out.push(customValueChoice);
|
|
1274
|
+
out.push(...matches);
|
|
1275
|
+
if (loadMoreChoice) out.push(loadMoreChoice);
|
|
1276
|
+
}
|
|
1277
|
+
return out;
|
|
1278
|
+
}
|
|
918
1279
|
});
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
1280
|
+
if (selectedValue === SKIP_SENTINEL) {
|
|
1281
|
+
return void 0;
|
|
1282
|
+
}
|
|
1283
|
+
if (selectedValue === CUSTOM_VALUE_SENTINEL) {
|
|
1284
|
+
return await this.promptFreeForm(fieldMeta);
|
|
1285
|
+
}
|
|
1286
|
+
} else {
|
|
1287
|
+
const promptChoices = choices.map((c) => ({
|
|
1288
|
+
name: c.label,
|
|
1289
|
+
value: c.value
|
|
1290
|
+
}));
|
|
1291
|
+
if (nextCursor) {
|
|
1292
|
+
promptChoices.push({
|
|
1293
|
+
name: chalk.dim("(Load more...)"),
|
|
1294
|
+
value: LOAD_MORE_SENTINEL
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
const promptConfig = {
|
|
1298
|
+
type: "checkbox",
|
|
1299
|
+
name: fieldMeta.key,
|
|
1300
|
+
message,
|
|
1301
|
+
choices: promptChoices,
|
|
929
1302
|
validate: (input) => {
|
|
930
1303
|
if (fieldMeta.isRequired && (!input || input.length === 0)) {
|
|
931
1304
|
return "At least one selection is required";
|
|
932
1305
|
}
|
|
933
1306
|
return true;
|
|
934
1307
|
}
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
let selectedValue = answer[fieldMeta.key];
|
|
939
|
-
if (selectedValue === CUSTOM_VALUE_SENTINEL) {
|
|
940
|
-
return await this.promptFreeForm(fieldMeta);
|
|
1308
|
+
};
|
|
1309
|
+
const answer = await inquirer.prompt([promptConfig]);
|
|
1310
|
+
selectedValue = answer[fieldMeta.key];
|
|
941
1311
|
}
|
|
942
1312
|
const wantsMore = fieldMeta.isMultiSelect ? Array.isArray(selectedValue) && selectedValue.includes(LOAD_MORE_SENTINEL) : selectedValue === LOAD_MORE_SENTINEL;
|
|
943
1313
|
if (wantsMore && nextCursor && context) {
|
|
@@ -1000,7 +1370,7 @@ Optional fields${pathContext}:`));
|
|
|
1000
1370
|
};
|
|
1001
1371
|
}
|
|
1002
1372
|
if (fieldMeta.description) {
|
|
1003
|
-
promptConfig.prefix =
|
|
1373
|
+
promptConfig.prefix = chalk.gray(`\u2139 ${fieldMeta.description}
|
|
1004
1374
|
`);
|
|
1005
1375
|
}
|
|
1006
1376
|
try {
|
|
@@ -1008,7 +1378,7 @@ Optional fields${pathContext}:`));
|
|
|
1008
1378
|
return answer[fieldMeta.key];
|
|
1009
1379
|
} catch (error) {
|
|
1010
1380
|
if (this.isUserCancellation(error)) {
|
|
1011
|
-
console.log(
|
|
1381
|
+
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
1012
1382
|
throw new ZapierCliUserCancellationError();
|
|
1013
1383
|
}
|
|
1014
1384
|
throw error;
|
|
@@ -1026,7 +1396,7 @@ Optional fields${pathContext}:`));
|
|
|
1026
1396
|
}
|
|
1027
1397
|
} catch (error) {
|
|
1028
1398
|
if (this.isUserCancellation(error)) {
|
|
1029
|
-
console.log(
|
|
1399
|
+
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
1030
1400
|
throw new ZapierCliUserCancellationError();
|
|
1031
1401
|
}
|
|
1032
1402
|
throw error;
|
|
@@ -1149,7 +1519,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
1149
1519
|
|
|
1150
1520
|
// package.json
|
|
1151
1521
|
var package_default = {
|
|
1152
|
-
version: "0.
|
|
1522
|
+
version: "0.49.0"};
|
|
1153
1523
|
|
|
1154
1524
|
// src/telemetry/builders.ts
|
|
1155
1525
|
function createCliBaseEvent(context = {}) {
|
|
@@ -1234,7 +1604,7 @@ async function formatItemsFromSchema(functionInfo, items, startingNumber = 0, op
|
|
|
1234
1604
|
});
|
|
1235
1605
|
}
|
|
1236
1606
|
function formatSingleItem(formatted, itemNumber) {
|
|
1237
|
-
let titleLine = `${
|
|
1607
|
+
let titleLine = `${chalk.gray(`${itemNumber + 1}.`)} ${chalk.cyan(formatted.title)}`;
|
|
1238
1608
|
const subtitleParts = [];
|
|
1239
1609
|
if (formatted.keys) {
|
|
1240
1610
|
subtitleParts.push(...formatted.keys);
|
|
@@ -1246,11 +1616,11 @@ function formatSingleItem(formatted, itemNumber) {
|
|
|
1246
1616
|
}
|
|
1247
1617
|
const uniqueParts = [...new Set(subtitleParts)];
|
|
1248
1618
|
if (uniqueParts.length > 0) {
|
|
1249
|
-
titleLine += ` ${
|
|
1619
|
+
titleLine += ` ${chalk.gray(`(${uniqueParts.join(", ")})`)}`;
|
|
1250
1620
|
}
|
|
1251
1621
|
console.log(titleLine);
|
|
1252
1622
|
if (formatted.description) {
|
|
1253
|
-
console.log(` ${
|
|
1623
|
+
console.log(` ${chalk.dim(formatted.description)}`);
|
|
1254
1624
|
}
|
|
1255
1625
|
if (formatted.data !== void 0) {
|
|
1256
1626
|
formatJsonOutput(formatted.data);
|
|
@@ -1261,7 +1631,7 @@ function formatSingleItem(formatted, itemNumber) {
|
|
|
1261
1631
|
if (detail.label) {
|
|
1262
1632
|
const isMultiline = detail.text.includes("\n");
|
|
1263
1633
|
if (isMultiline) {
|
|
1264
|
-
console.log(` ${
|
|
1634
|
+
console.log(` ${chalk.gray(detail.label + ":")}`);
|
|
1265
1635
|
const displayText = formatDetailText(
|
|
1266
1636
|
detail.text,
|
|
1267
1637
|
DETAIL_INDENT + " "
|
|
@@ -1270,7 +1640,7 @@ function formatSingleItem(formatted, itemNumber) {
|
|
|
1270
1640
|
console.log(`${DETAIL_INDENT} ${styledText}`);
|
|
1271
1641
|
} else {
|
|
1272
1642
|
const styledValue = applyStyle(detail.text, detail.style);
|
|
1273
|
-
console.log(` ${
|
|
1643
|
+
console.log(` ${chalk.gray(detail.label + ":")} ${styledValue}`);
|
|
1274
1644
|
}
|
|
1275
1645
|
} else {
|
|
1276
1646
|
const displayText = formatDetailText(detail.text, DETAIL_INDENT);
|
|
@@ -1294,16 +1664,16 @@ function formatDetailText(text, indent = DETAIL_INDENT) {
|
|
|
1294
1664
|
function applyStyle(value, style) {
|
|
1295
1665
|
switch (style) {
|
|
1296
1666
|
case "dim":
|
|
1297
|
-
return
|
|
1667
|
+
return chalk.dim(value);
|
|
1298
1668
|
case "accent":
|
|
1299
|
-
return
|
|
1669
|
+
return chalk.magenta(value);
|
|
1300
1670
|
case "warning":
|
|
1301
|
-
return
|
|
1671
|
+
return chalk.red(value);
|
|
1302
1672
|
case "success":
|
|
1303
|
-
return
|
|
1673
|
+
return chalk.green(value);
|
|
1304
1674
|
case "normal":
|
|
1305
1675
|
default:
|
|
1306
|
-
return
|
|
1676
|
+
return chalk.blue(value);
|
|
1307
1677
|
}
|
|
1308
1678
|
}
|
|
1309
1679
|
function convertGenericItemToFormattedItem(item) {
|
|
@@ -1435,10 +1805,10 @@ function renderItemsForDisplay(items, functionInfo, startingNumber = 0) {
|
|
|
1435
1805
|
const obj = item;
|
|
1436
1806
|
const name = obj?.name || obj?.key || obj?.id || "Item";
|
|
1437
1807
|
console.log(
|
|
1438
|
-
`${
|
|
1808
|
+
`${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(String(name))}`
|
|
1439
1809
|
);
|
|
1440
1810
|
if (obj?.description)
|
|
1441
|
-
console.log(` ${
|
|
1811
|
+
console.log(` ${chalk.dim(String(obj.description))}`);
|
|
1442
1812
|
console.log();
|
|
1443
1813
|
});
|
|
1444
1814
|
}
|
|
@@ -1450,35 +1820,35 @@ function createInteractiveRenderer() {
|
|
|
1450
1820
|
if (!(Symbol.asyncIterator in Object(source))) {
|
|
1451
1821
|
const items = source?.data;
|
|
1452
1822
|
if (!Array.isArray(items) || items.length === 0) {
|
|
1453
|
-
console.log(
|
|
1823
|
+
console.log(chalk.yellow(`No ${itemName} found.`));
|
|
1454
1824
|
return;
|
|
1455
1825
|
}
|
|
1456
1826
|
renderItemsForDisplay(items, functionInfo, 0);
|
|
1457
|
-
console.log(
|
|
1827
|
+
console.log(chalk.green(`
|
|
1458
1828
|
\u2705 Showing ${items.length} ${itemName}`));
|
|
1459
1829
|
return;
|
|
1460
1830
|
}
|
|
1461
1831
|
let totalShown = 0;
|
|
1462
1832
|
let pageCount = 0;
|
|
1463
|
-
console.log(
|
|
1833
|
+
console.log(chalk.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
|
|
1464
1834
|
`));
|
|
1465
1835
|
for await (const page of source) {
|
|
1466
1836
|
const items = page.data ?? [];
|
|
1467
1837
|
pageCount++;
|
|
1468
1838
|
if (items.length === 0 && pageCount === 1) {
|
|
1469
|
-
console.log(
|
|
1839
|
+
console.log(chalk.yellow(`No ${itemName} found.`));
|
|
1470
1840
|
return;
|
|
1471
1841
|
}
|
|
1472
1842
|
if (items.length === 0) break;
|
|
1473
1843
|
if (pageCount > 1) {
|
|
1474
1844
|
console.clear();
|
|
1475
|
-
console.log(
|
|
1845
|
+
console.log(chalk.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
|
|
1476
1846
|
`));
|
|
1477
1847
|
}
|
|
1478
1848
|
renderItemsForDisplay(items, functionInfo, totalShown);
|
|
1479
1849
|
totalShown += items.length;
|
|
1480
1850
|
console.log(
|
|
1481
|
-
|
|
1851
|
+
chalk.green(
|
|
1482
1852
|
`
|
|
1483
1853
|
\u2705 Showing ${totalShown} ${itemName} (page ${pageCount})`
|
|
1484
1854
|
)
|
|
@@ -1497,7 +1867,7 @@ function createInteractiveRenderer() {
|
|
|
1497
1867
|
break;
|
|
1498
1868
|
}
|
|
1499
1869
|
}
|
|
1500
|
-
console.log(
|
|
1870
|
+
console.log(chalk.gray(`
|
|
1501
1871
|
\u{1F4C4} Finished browsing ${itemName}`));
|
|
1502
1872
|
},
|
|
1503
1873
|
renderCollectedList(items, { maxItems, userSpecifiedMaxItems, functionInfo } = {}) {
|
|
@@ -1507,30 +1877,30 @@ function createInteractiveRenderer() {
|
|
|
1507
1877
|
}
|
|
1508
1878
|
const itemName = getItemName(functionInfo);
|
|
1509
1879
|
if (items.length === 0) {
|
|
1510
|
-
console.log(
|
|
1880
|
+
console.log(chalk.yellow(`No ${itemName} found.`));
|
|
1511
1881
|
return;
|
|
1512
1882
|
}
|
|
1513
|
-
console.log(
|
|
1883
|
+
console.log(chalk.green(`
|
|
1514
1884
|
\u2705 Found ${items.length} ${itemName}:
|
|
1515
1885
|
`));
|
|
1516
1886
|
renderItemsForDisplay(items, functionInfo);
|
|
1517
1887
|
if (userSpecifiedMaxItems && maxItems) {
|
|
1518
1888
|
console.log(
|
|
1519
|
-
|
|
1889
|
+
chalk.gray(
|
|
1520
1890
|
`
|
|
1521
1891
|
\u{1F4C4} Showing up to ${maxItems} ${itemName} (--max-items ${maxItems})`
|
|
1522
1892
|
)
|
|
1523
1893
|
);
|
|
1524
1894
|
} else {
|
|
1525
|
-
console.log(
|
|
1895
|
+
console.log(chalk.gray(`
|
|
1526
1896
|
\u{1F4C4} All available ${itemName} shown`));
|
|
1527
1897
|
}
|
|
1528
1898
|
},
|
|
1529
1899
|
renderItem(value, options) {
|
|
1530
1900
|
if (options?.outputFile) {
|
|
1531
1901
|
const label = options.commandName ? `\u2705 ${options.commandName} completed successfully!` : "\u2705 Done!";
|
|
1532
|
-
console.log(
|
|
1533
|
-
console.log(
|
|
1902
|
+
console.log(chalk.green(label));
|
|
1903
|
+
console.log(chalk.gray(`Output written to: ${options.outputFile}`));
|
|
1534
1904
|
} else {
|
|
1535
1905
|
formatJsonOutput(value);
|
|
1536
1906
|
}
|
|
@@ -1540,17 +1910,17 @@ function createInteractiveRenderer() {
|
|
|
1540
1910
|
},
|
|
1541
1911
|
renderError(error) {
|
|
1542
1912
|
if (error instanceof ZapierCliMissingParametersError) {
|
|
1543
|
-
console.error(
|
|
1544
|
-
console.error("\n" +
|
|
1913
|
+
console.error(chalk.red("\u274C " + formatMissingParamsError(error)));
|
|
1914
|
+
console.error("\n" + chalk.dim("Use --help to see available options"));
|
|
1545
1915
|
throw new ZapierCliExitError(error.message, 1);
|
|
1546
1916
|
}
|
|
1547
1917
|
if (error instanceof ZapierError) {
|
|
1548
1918
|
const formattedMessage = formatErrorMessage(error);
|
|
1549
|
-
console.error(
|
|
1919
|
+
console.error(chalk.red("\u274C Error:"), formattedMessage);
|
|
1550
1920
|
throw new ZapierCliExitError(formattedMessage, 1);
|
|
1551
1921
|
}
|
|
1552
1922
|
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
1553
|
-
console.error(
|
|
1923
|
+
console.error(chalk.red("\u274C Error:"), msg);
|
|
1554
1924
|
throw new ZapierCliExitError(msg, 1);
|
|
1555
1925
|
}
|
|
1556
1926
|
};
|
|
@@ -1660,7 +2030,7 @@ async function promptConfirm(confirmType, itemType) {
|
|
|
1660
2030
|
}
|
|
1661
2031
|
const configOrFn = CONFIRM_MESSAGES[confirmType];
|
|
1662
2032
|
const { messageBefore, messageAfter } = typeof configOrFn === "function" ? configOrFn(itemType) : configOrFn;
|
|
1663
|
-
console.log(
|
|
2033
|
+
console.log(chalk.yellow(`
|
|
1664
2034
|
${messageBefore}
|
|
1665
2035
|
`));
|
|
1666
2036
|
const { confirmed } = await inquirer.prompt([
|
|
@@ -1682,9 +2052,9 @@ function emitDeprecationWarning({
|
|
|
1682
2052
|
}
|
|
1683
2053
|
console.warn();
|
|
1684
2054
|
console.warn(
|
|
1685
|
-
|
|
2055
|
+
chalk.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk.yellow(` - \`${cliCommandName}\` is deprecated.`)
|
|
1686
2056
|
);
|
|
1687
|
-
console.warn(
|
|
2057
|
+
console.warn(chalk.yellow(` ${deprecation.message}`));
|
|
1688
2058
|
console.warn();
|
|
1689
2059
|
}
|
|
1690
2060
|
function emitParamDeprecationWarnings({
|
|
@@ -1698,12 +2068,12 @@ function emitParamDeprecationWarnings({
|
|
|
1698
2068
|
if (Array.isArray(value) && value.length === 0) continue;
|
|
1699
2069
|
console.warn();
|
|
1700
2070
|
console.warn(
|
|
1701
|
-
|
|
2071
|
+
chalk.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk.yellow(
|
|
1702
2072
|
` - \`${toKebabCase(param.name)}\` is deprecated and may be removed in a future release.`
|
|
1703
2073
|
)
|
|
1704
2074
|
);
|
|
1705
2075
|
if (param.deprecationMessage) {
|
|
1706
|
-
console.warn(
|
|
2076
|
+
console.warn(chalk.yellow(` ${param.deprecationMessage}`));
|
|
1707
2077
|
}
|
|
1708
2078
|
console.warn();
|
|
1709
2079
|
}
|
|
@@ -2034,7 +2404,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2034
2404
|
functionInfo.itemType
|
|
2035
2405
|
);
|
|
2036
2406
|
if (!confirmResult.confirmed) {
|
|
2037
|
-
console.log(
|
|
2407
|
+
console.log(chalk.yellow("Operation cancelled."));
|
|
2038
2408
|
return;
|
|
2039
2409
|
}
|
|
2040
2410
|
confirmMessageAfter = confirmResult.messageAfter;
|
|
@@ -2096,7 +2466,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2096
2466
|
renderer.renderItem(normalizedResult.value);
|
|
2097
2467
|
}
|
|
2098
2468
|
if (confirmMessageAfter) {
|
|
2099
|
-
console.log(
|
|
2469
|
+
console.log(chalk.yellow(`
|
|
2100
2470
|
${confirmMessageAfter}`));
|
|
2101
2471
|
}
|
|
2102
2472
|
break;
|
|
@@ -3139,20 +3509,20 @@ var spinPromise = async (promise, text) => {
|
|
|
3139
3509
|
};
|
|
3140
3510
|
var log = {
|
|
3141
3511
|
info: (message, ...args) => {
|
|
3142
|
-
console.log(
|
|
3512
|
+
console.log(chalk.blue("\u2139"), message, ...args);
|
|
3143
3513
|
},
|
|
3144
3514
|
error: (message, ...args) => {
|
|
3145
|
-
console.error(
|
|
3515
|
+
console.error(chalk.red("\u2716"), message, ...args);
|
|
3146
3516
|
},
|
|
3147
3517
|
success: (message, ...args) => {
|
|
3148
|
-
console.log(
|
|
3518
|
+
console.log(chalk.green("\u2713"), message, ...args);
|
|
3149
3519
|
},
|
|
3150
3520
|
warn: (message, ...args) => {
|
|
3151
|
-
console.log(
|
|
3521
|
+
console.log(chalk.yellow("\u26A0"), message, ...args);
|
|
3152
3522
|
},
|
|
3153
3523
|
debug: (message, ...args) => {
|
|
3154
3524
|
if (process.env.DEBUG === "true" || process.argv.includes("--debug")) {
|
|
3155
|
-
console.log(
|
|
3525
|
+
console.log(chalk.gray("\u{1F41B}"), message, ...args);
|
|
3156
3526
|
}
|
|
3157
3527
|
}
|
|
3158
3528
|
};
|
|
@@ -5362,7 +5732,7 @@ function buildTemplateVariables({
|
|
|
5362
5732
|
};
|
|
5363
5733
|
}
|
|
5364
5734
|
function cleanupProject({ projectDir }) {
|
|
5365
|
-
console.log("\n" +
|
|
5735
|
+
console.log("\n" + chalk.yellow("!") + " Cleaning up...");
|
|
5366
5736
|
rmSync(projectDir, { recursive: true, force: true });
|
|
5367
5737
|
}
|
|
5368
5738
|
async function withInterruptCleanup(cleanup, fn) {
|
|
@@ -5572,8 +5942,8 @@ function buildNextSteps({
|
|
|
5572
5942
|
}
|
|
5573
5943
|
function createConsoleDisplayHooks() {
|
|
5574
5944
|
return {
|
|
5575
|
-
onItemComplete: (message) => console.log(" " +
|
|
5576
|
-
onWarn: (message) => console.warn(
|
|
5945
|
+
onItemComplete: (message) => console.log(" " + chalk.green("\u2713") + " " + chalk.dim(message)),
|
|
5946
|
+
onWarn: (message) => console.warn(chalk.yellow("!") + " " + message),
|
|
5577
5947
|
onStepStart: ({
|
|
5578
5948
|
description,
|
|
5579
5949
|
stepNumber,
|
|
@@ -5582,31 +5952,31 @@ function createConsoleDisplayHooks() {
|
|
|
5582
5952
|
skipPrompts
|
|
5583
5953
|
}) => {
|
|
5584
5954
|
const progressMessage = `${description}...`;
|
|
5585
|
-
const stepCounter =
|
|
5955
|
+
const stepCounter = chalk.dim(`${stepNumber}/${totalSteps}`);
|
|
5586
5956
|
if (skipPrompts) {
|
|
5587
5957
|
console.log(
|
|
5588
|
-
"\n" +
|
|
5958
|
+
"\n" + chalk.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
|
|
5589
5959
|
);
|
|
5590
5960
|
} else {
|
|
5591
5961
|
console.log(
|
|
5592
|
-
|
|
5962
|
+
chalk.dim("\u2192") + " " + progressMessage + " " + stepCounter
|
|
5593
5963
|
);
|
|
5594
5964
|
}
|
|
5595
5965
|
if (command) {
|
|
5596
|
-
console.log(" " +
|
|
5966
|
+
console.log(" " + chalk.cyan(`$ ${command}`));
|
|
5597
5967
|
}
|
|
5598
5968
|
},
|
|
5599
5969
|
onStepSuccess: ({ stepNumber, totalSteps }) => console.log(
|
|
5600
|
-
"\n" +
|
|
5970
|
+
"\n" + chalk.green("\u2713") + " " + chalk.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
|
|
5601
5971
|
),
|
|
5602
5972
|
onStepError: ({ description, command, err }) => {
|
|
5603
5973
|
const detail = err instanceof Error && err.message ? `
|
|
5604
|
-
${
|
|
5974
|
+
${chalk.dim(err.message)}` : "";
|
|
5605
5975
|
const hint = command ? `
|
|
5606
|
-
${
|
|
5976
|
+
${chalk.dim("run manually:")} ${chalk.cyan(`$ ${command}`)}` : "";
|
|
5607
5977
|
console.error(
|
|
5608
5978
|
`
|
|
5609
|
-
${
|
|
5979
|
+
${chalk.red("\u2716")} ${chalk.bold(description)}${chalk.dim(" failed")}${detail}${hint}`
|
|
5610
5980
|
);
|
|
5611
5981
|
}
|
|
5612
5982
|
};
|
|
@@ -5618,22 +5988,22 @@ function displaySummaryAndNextSteps({
|
|
|
5618
5988
|
packageManager
|
|
5619
5989
|
}) {
|
|
5620
5990
|
const formatStatus = (complete) => ({
|
|
5621
|
-
icon: complete ?
|
|
5622
|
-
text: complete ?
|
|
5991
|
+
icon: complete ? chalk.green("\u2713") : chalk.yellow("!"),
|
|
5992
|
+
text: complete ? chalk.green("Setup complete") : chalk.yellow("Setup interrupted")
|
|
5623
5993
|
});
|
|
5624
|
-
const formatNextStep = (step, i) => " " +
|
|
5625
|
-
const formatCommand = (cmd) => " " +
|
|
5626
|
-
const formatCompletedStep = (step) => " " +
|
|
5994
|
+
const formatNextStep = (step, i) => " " + chalk.dim(`${i + 1}.`) + " " + chalk.bold(step.description);
|
|
5995
|
+
const formatCommand = (cmd) => " " + chalk.cyan(`$ ${cmd}`);
|
|
5996
|
+
const formatCompletedStep = (step) => " " + chalk.green("\u2713") + " " + step.description;
|
|
5627
5997
|
const { execCmd } = getPackageManagerCommands({ packageManager });
|
|
5628
5998
|
const leftoverSteps = steps.filter(
|
|
5629
5999
|
(s) => !completedSetupStepIds.includes(s.id)
|
|
5630
6000
|
);
|
|
5631
6001
|
const isComplete = leftoverSteps.length === 0;
|
|
5632
6002
|
const status = formatStatus(isComplete);
|
|
5633
|
-
console.log("\n" +
|
|
5634
|
-
console.log(" " +
|
|
6003
|
+
console.log("\n" + chalk.bold("\u276F Summary") + "\n");
|
|
6004
|
+
console.log(" " + chalk.dim("Project") + " " + chalk.bold(projectName));
|
|
5635
6005
|
console.log(
|
|
5636
|
-
" " +
|
|
6006
|
+
" " + chalk.dim("Status") + " " + status.icon + " " + status.text
|
|
5637
6007
|
);
|
|
5638
6008
|
const completedSteps = steps.filter(
|
|
5639
6009
|
(s) => completedSetupStepIds.includes(s.id)
|
|
@@ -5643,7 +6013,7 @@ function displaySummaryAndNextSteps({
|
|
|
5643
6013
|
for (const step of completedSteps) console.log(formatCompletedStep(step));
|
|
5644
6014
|
}
|
|
5645
6015
|
const nextSteps = buildNextSteps({ projectName, leftoverSteps, execCmd });
|
|
5646
|
-
console.log("\n" +
|
|
6016
|
+
console.log("\n" + chalk.bold("\u276F Next Steps") + "\n");
|
|
5647
6017
|
nextSteps.forEach((step, i) => {
|
|
5648
6018
|
console.log(formatNextStep(step, i));
|
|
5649
6019
|
if (step.command) console.log(formatCommand(step.command));
|
|
@@ -5719,13 +6089,13 @@ function createInteractiveCallback() {
|
|
|
5719
6089
|
const attrs = message.message_attributes;
|
|
5720
6090
|
console.log(
|
|
5721
6091
|
`
|
|
5722
|
-
${
|
|
6092
|
+
${chalk.bold(`Message #${messageNumber}`)} ${chalk.dim(message.id)} ${chalk.dim(`(lease #${attrs.lease_count})`)}`
|
|
5723
6093
|
);
|
|
5724
6094
|
if (attrs.error_message) {
|
|
5725
|
-
console.log(
|
|
6095
|
+
console.log(chalk.yellow(` upstream error: ${attrs.error_message}`));
|
|
5726
6096
|
}
|
|
5727
6097
|
if (attrs.possible_duplicate_data) {
|
|
5728
|
-
console.log(
|
|
6098
|
+
console.log(chalk.yellow(" possible duplicate data"));
|
|
5729
6099
|
}
|
|
5730
6100
|
while (true) {
|
|
5731
6101
|
let action;
|
|
@@ -5755,7 +6125,7 @@ ${chalk7.bold(`Message #${messageNumber}`)} ${chalk7.dim(message.id)} ${chalk7.d
|
|
|
5755
6125
|
throw error;
|
|
5756
6126
|
}
|
|
5757
6127
|
if (action === "view") {
|
|
5758
|
-
console.log(
|
|
6128
|
+
console.log(chalk.dim(JSON.stringify(message.payload, null, 2)));
|
|
5759
6129
|
continue;
|
|
5760
6130
|
}
|
|
5761
6131
|
if (action === "ack") {
|
|
@@ -5858,7 +6228,7 @@ function describeReason(reason) {
|
|
|
5858
6228
|
}
|
|
5859
6229
|
function printDrainError(reason, message) {
|
|
5860
6230
|
console.error(
|
|
5861
|
-
|
|
6231
|
+
chalk.red(`Error processing ${message.id}: ${describeReason(reason)}`)
|
|
5862
6232
|
);
|
|
5863
6233
|
}
|
|
5864
6234
|
function printDrainSummary(counts) {
|
|
@@ -5868,7 +6238,7 @@ function printDrainSummary(counts) {
|
|
|
5868
6238
|
if (skipped > 0) parts.push(`${skipped} skipped`);
|
|
5869
6239
|
parts.push(`${counts.rejected} rejected`);
|
|
5870
6240
|
console.log(
|
|
5871
|
-
|
|
6241
|
+
chalk.dim(
|
|
5872
6242
|
`
|
|
5873
6243
|
Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
|
|
5874
6244
|
)
|
|
@@ -5876,7 +6246,7 @@ Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
|
|
|
5876
6246
|
}
|
|
5877
6247
|
function warnInteractiveContinueOnErrorOverride() {
|
|
5878
6248
|
console.warn(
|
|
5879
|
-
|
|
6249
|
+
chalk.yellow(
|
|
5880
6250
|
'Note: continueOnError=false is overridden to true in interactive mode (the "Skip (let lease expire)" choice would otherwise terminate the drain).'
|
|
5881
6251
|
)
|
|
5882
6252
|
);
|
|
@@ -6180,7 +6550,7 @@ var watchTriggerInboxCliPlugin = definePlugin(
|
|
|
6180
6550
|
// package.json with { type: 'json' }
|
|
6181
6551
|
var package_default2 = {
|
|
6182
6552
|
name: "@zapier/zapier-sdk-cli",
|
|
6183
|
-
version: "0.
|
|
6553
|
+
version: "0.49.0"};
|
|
6184
6554
|
|
|
6185
6555
|
// src/sdk.ts
|
|
6186
6556
|
injectCliLogin(login_exports);
|
|
@@ -6387,26 +6757,26 @@ function displayUpdateNotification(versionInfo, packageName) {
|
|
|
6387
6757
|
if (versionInfo.isDeprecated) {
|
|
6388
6758
|
console.error();
|
|
6389
6759
|
console.error(
|
|
6390
|
-
|
|
6760
|
+
chalk.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk.red(
|
|
6391
6761
|
` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
|
|
6392
6762
|
)
|
|
6393
6763
|
);
|
|
6394
6764
|
if (versionInfo.deprecationMessage) {
|
|
6395
|
-
console.error(
|
|
6765
|
+
console.error(chalk.red(` ${versionInfo.deprecationMessage}`));
|
|
6396
6766
|
}
|
|
6397
|
-
console.error(
|
|
6767
|
+
console.error(chalk.red(` Please update to the latest version.`));
|
|
6398
6768
|
console.error();
|
|
6399
6769
|
}
|
|
6400
6770
|
if (versionInfo.hasUpdate) {
|
|
6401
6771
|
console.error();
|
|
6402
6772
|
console.error(
|
|
6403
|
-
|
|
6773
|
+
chalk.yellow.bold("\u{1F4E6} Update available!") + chalk.yellow(
|
|
6404
6774
|
` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
|
|
6405
6775
|
)
|
|
6406
6776
|
);
|
|
6407
6777
|
console.error(
|
|
6408
|
-
|
|
6409
|
-
` Run ${
|
|
6778
|
+
chalk.yellow(
|
|
6779
|
+
` Run ${chalk.bold(getUpdateCommand(packageName))} to update.`
|
|
6410
6780
|
)
|
|
6411
6781
|
);
|
|
6412
6782
|
console.error();
|