@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/dist/cli.mjs CHANGED
@@ -1,1515 +1,44 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command, CommanderError, Option } from 'commander';
3
- import { getConnectionPlugin, defineMethod, apiPluginRef, resolveCredentialsPluginRef, eventEmissionPluginRef, sdkOptionsPluginRef, declareOptionalProperty, OutputPropertySchema, ZapierBundleError, DEFAULT_CONFIG_PATH, declareMethod, ZapierValidationError, ZapierUnknownError, manifestPluginRef, defineResolver, defineMethodOverride, zapierCoreOptions, injectCliLogin, definePlugin, omitExports, zapierSdkPlugin, BaseSdkOptionsSchema, disposeSdk, isPermanentHttpError, invalidateCachedToken, batch, toSnakeCase, ZapierError, ZapierReleaseTriggerMessageSignal, createSdk as createSdk$1, CORE_OPTIONS_ID as CORE_OPTIONS_ID$1, SDK_OPTIONS_ID as SDK_OPTIONS_ID$1, addPlugin as addPlugin$1, getOrCreateApiClient, isCredentialsObject, ZapierAuthenticationError, ZapierAbortDrainSignal, buildApplicationLifecycleEvent, AuthMechanism, DEPRECATION_NOTICE_EVENT, runWithCallerContext, isPositional, createController, CoreCancelledSignal, resolvePlugin, runWithTelemetryContext, buildCapabilityMessage, formatErrorMessage, getOsInfo, getPlatformVersions, getAgent, getTtyContext, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId, ZapierApprovalError } from '@zapier/zapier-sdk';
3
+ import { getConnectionPlugin, defineMethod, apiPluginRef, resolveCredentialsPluginRef, eventEmissionPluginRef, sdkOptionsPluginRef, declareOptionalProperty, OutputPropertySchema, ZapierBundleError, DEFAULT_CONFIG_PATH, declareMethod, ZapierValidationError, ZapierUnknownError, manifestPluginRef, defineResolver, defineMethodOverride, zapierCoreOptions, injectCliLogin, definePlugin, omitExports, zapierSdkPlugin, BaseSdkOptionsSchema, disposeSdk, isPermanentHttpError, invalidateCachedToken, batch, toSnakeCase, ZapierError, ZapierReleaseTriggerMessageSignal, createSdk as createSdk$1, CORE_OPTIONS_ID as CORE_OPTIONS_ID$1, SDK_OPTIONS_ID as SDK_OPTIONS_ID$1, addPlugin as addPlugin$1, getOrCreateApiClient, isCredentialsObject, ZapierAuthenticationError, ZapierAbortDrainSignal, buildApplicationLifecycleEvent, AuthMechanism, DEPRECATION_NOTICE_EVENT, runWithCallerContext, isPositional, createController, CoreCancelledSignal, resolvePlugin, formatErrorMessage, getOsInfo, getPlatformVersions, getAgent, getTtyContext, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId, ZapierApprovalError } from '@zapier/zapier-sdk';
4
4
  import { z } from 'zod';
5
5
  import inquirer from 'inquirer';
6
- import search from '@inquirer/search';
7
- import chalk from 'chalk';
8
- import ora from 'ora';
9
- import { makeTheme, createPrompt, useState, usePrefix, useMemo, useEffect, useKeypress, isEnterKey, isTabKey, isUpKey, isDownKey, usePagination, Separator } from '@inquirer/core';
10
- import util, { stripVTControlCharacters } from 'util';
11
- import wrapAnsi3 from 'wrap-ansi';
12
- import * as jwt from 'jsonwebtoken';
13
- import { deletePassword, getKeyring, setPassword, getPassword } from 'cross-keychain';
14
- import Conf from 'conf';
15
- import * as fs from 'fs';
16
- import { promises, createWriteStream, existsSync, readdirSync, rmSync, mkdirSync, writeFileSync, copyFileSync, readFileSync } from 'fs';
17
- import crypto, { createHash } from 'crypto';
18
- import * as path from 'path';
19
- import { resolve, join, dirname, basename, relative, extname } from 'path';
20
- import * as lockfile from 'proper-lockfile';
21
- import { hostname } from 'os';
22
- import express from 'express';
23
- import { createInterface } from 'readline/promises';
24
- import open from 'open';
25
- import pkceChallenge from 'pkce-challenge';
26
- import { startMcpServer } from '@zapier/zapier-sdk-mcp';
27
- import { buildSync } from 'esbuild';
28
- import { mkdir, writeFile, access } from 'fs/promises';
29
- import * as ts from 'typescript';
30
- import isInstalledGlobally from 'is-installed-globally';
31
- import { execSync, spawn } from 'child_process';
32
- import Handlebars from 'handlebars';
33
- import { fileURLToPath } from 'url';
34
- import { triggerInboxResolver, DrainTriggerInboxSchema, WatchTriggerInboxSchema, injectCliLogin as injectCliLogin$1, definePlugin as definePlugin$1, omitExports as omitExports$1, zapierExperimentalSdkPlugin, createSdk, CORE_OPTIONS_ID, SDK_OPTIONS_ID, addPlugin } from '@zapier/zapier-sdk/experimental';
35
- import packageJsonLib, { VersionNotFoundError } from 'package-json';
36
- import semver from 'semver';
37
- import * as readline from 'readline';
38
-
39
- var __defProp = Object.defineProperty;
40
- var __export = (target, all) => {
41
- for (var name in all)
42
- __defProp(target, name, { get: all[name], enumerable: true });
43
- };
44
- var ZapierCliError = class extends ZapierError {
45
- };
46
- var ZapierCliUserCancellationError = class extends ZapierCliError {
47
- constructor(message = "Operation cancelled by user") {
48
- super(message);
49
- this.name = "ZapierCliUserCancellationError";
50
- this.code = "ZAPIER_CLI_USER_CANCELLATION";
51
- this.exitCode = 0;
52
- }
53
- };
54
- var ZapierCliExitError = class extends ZapierCliError {
55
- constructor(message, exitCode = 1) {
56
- super(message);
57
- this.name = "ZapierCliExitError";
58
- this.code = "ZAPIER_CLI_EXIT";
59
- this.exitCode = exitCode;
60
- }
61
- };
62
- var ZapierCliValidationError = class _ZapierCliValidationError extends ZapierCliError {
63
- constructor(message, options = {}) {
64
- super(message);
65
- this.exitCode = 1;
66
- this.name = options.name ?? "ZapierCliValidationError";
67
- this.code = options.code ?? "ZAPIER_CLI_VALIDATION_ERROR";
68
- }
69
- withMessage(message) {
70
- return new _ZapierCliValidationError(message, {
71
- name: this.name,
72
- code: this.code
73
- });
74
- }
75
- };
76
- var ZapierCliMissingParametersError = class extends ZapierCliError {
77
- constructor(params) {
78
- super(
79
- `Missing required parameters: ${params.map((p) => p.name).join(", ")}`
80
- );
81
- this.name = "ZapierCliMissingParametersError";
82
- this.code = "ZAPIER_CLI_MISSING_PARAMETERS";
83
- this.exitCode = 1;
84
- this.params = params;
85
- }
86
- };
87
-
88
- // src/utils/parameter-resolver.ts
89
- function formatZodError(error) {
90
- return error.issues.map((issue) => {
91
- const field = issue.path.length > 0 ? issue.path.join(".") : "input";
92
- return `${field}: ${issue.message}`;
93
- }).join(", ");
94
- }
95
- function getLocalResolutionOrder(paramName, resolvers, resolved = /* @__PURE__ */ new Set()) {
96
- const resolver = resolvers[paramName];
97
- if (!resolver || resolver.type === "static" || resolver.type === "constant") {
98
- return [paramName];
99
- }
100
- const order = [];
101
- if ("depends" in resolver && resolver.depends) {
102
- for (const dependency of resolver.depends) {
103
- if (!resolved.has(dependency)) {
104
- order.push(...getLocalResolutionOrder(dependency, resolvers, resolved));
105
- resolved.add(dependency);
106
- }
107
- }
108
- }
109
- if (!resolved.has(paramName)) {
110
- order.push(paramName);
111
- resolved.add(paramName);
112
- }
113
- return order;
114
- }
115
- function getLocalResolutionOrderForParams(paramNames, resolvers) {
116
- const resolved = /* @__PURE__ */ new Set();
117
- const order = [];
118
- for (const paramName of paramNames) {
119
- const paramOrder = getLocalResolutionOrder(paramName, resolvers, resolved);
120
- for (const param of paramOrder) {
121
- if (!order.includes(param)) {
122
- order.push(param);
123
- }
124
- }
125
- }
126
- return order;
127
- }
128
- function unwrapSchema(schema) {
129
- let current = schema;
130
- while (current instanceof z.ZodOptional || current instanceof z.ZodDefault || current instanceof z.ZodNullable) {
131
- current = current._zod.def.innerType;
132
- }
133
- return current;
134
- }
135
- function coerceToSchemaType(value, schema) {
136
- if (typeof value !== "string") return value;
137
- const base = unwrapSchema(schema);
138
- if (base instanceof z.ZodNumber) {
139
- const n = Number(value);
140
- return Number.isNaN(n) ? value : n;
141
- }
142
- if (base instanceof z.ZodBoolean) {
143
- if (value === "true") return true;
144
- if (value === "false") return false;
145
- }
146
- return value;
147
- }
148
- function renderChoiceLabel(choice) {
149
- const baseName = choice.label ?? choice.name ?? "";
150
- const alreadyNamed = choice.name === baseName;
151
- let effectiveHint = choice.hint;
152
- if (effectiveHint === void 0 && (typeof choice.value === "string" || typeof choice.value === "number")) {
153
- effectiveHint = String(choice.value);
154
- }
155
- if (!effectiveHint || Array.isArray(effectiveHint) && effectiveHint.length === 0) {
156
- return alreadyNamed ? choice : { ...choice, name: baseName };
157
- }
158
- const hintText = Array.isArray(effectiveHint) ? effectiveHint.join(", ") : effectiveHint;
159
- if (hintText === baseName) {
160
- return alreadyNamed ? choice : { ...choice, name: baseName };
161
- }
162
- return { ...choice, name: `${baseName} ${chalk.dim(`(${hintText})`)}` };
163
- }
164
- var SchemaParameterResolver = class {
165
- constructor() {
166
- this.debug = false;
167
- this.spinner = null;
168
- }
169
- debugLog(message) {
170
- if (this.debug) {
171
- this.stopSpinner();
172
- console.error(chalk.gray(`[Zapier CLI] ${message}`));
173
- }
174
- }
175
- startSpinner() {
176
- if (!this.debug && !this.spinner) {
177
- this.spinner = ora({ text: "", spinner: "dots" }).start();
178
- }
179
- }
180
- stopSpinner() {
181
- if (this.spinner) {
182
- this.spinner.stop();
183
- this.spinner = null;
184
- }
185
- }
186
- async resolveParameters(schema, providedParams, sdk, functionName, options) {
187
- return runWithTelemetryContext(async () => {
188
- this.debug = options?.debug ?? false;
189
- const interactiveMode = (options?.interactiveMode ?? true) && !!process.stdin.isTTY;
190
- const parseResult = schema.safeParse(providedParams);
191
- const allParams = this.extractParametersFromSchema(schema);
192
- const resolvableParams = allParams.filter(
193
- (param) => this.hasResolver(param.name, sdk, functionName)
194
- );
195
- const missingResolvable = resolvableParams.filter((param) => {
196
- const hasValue = this.getNestedValue(providedParams, param.path) !== void 0;
197
- return !hasValue;
198
- });
199
- const required = missingResolvable.filter((param) => param.isRequired);
200
- const optional = missingResolvable.filter((param) => !param.isRequired);
201
- if (parseResult.success && required.length === 0 && optional.length === 0) {
202
- return parseResult.data;
203
- }
204
- if (required.length === 0 && optional.length === 0) {
205
- if (!parseResult.success) {
206
- throw new ZapierCliValidationError(formatZodError(parseResult.error));
207
- }
208
- return parseResult.data;
209
- }
210
- const resolverConstants = this.getResolverConstants(sdk, functionName);
211
- const resolvedParams = {
212
- ...resolverConstants,
213
- ...providedParams
214
- };
215
- const context = {
216
- sdk,
217
- currentParams: providedParams,
218
- resolvedParams,
219
- functionName
220
- };
221
- const localResolvers = this.getLocalResolvers(sdk, functionName);
222
- if (required.length > 0) {
223
- const requiredParamNames = required.map((p) => p.name);
224
- const requiredResolutionOrder = getLocalResolutionOrderForParams(
225
- requiredParamNames,
226
- localResolvers
227
- );
228
- const orderedRequiredParams = requiredResolutionOrder.map((paramName) => {
229
- let param = required.find((p) => p.name === paramName);
230
- if (!param) {
231
- param = optional.find((p) => p.name === paramName);
232
- }
233
- return param;
234
- }).filter((param) => param !== void 0);
235
- if (!interactiveMode) {
236
- await this.resolveRequiredParamsNonInteractive(
237
- orderedRequiredParams,
238
- context,
239
- resolvedParams,
240
- functionName
241
- );
242
- } else {
243
- for (const param of orderedRequiredParams) {
244
- try {
245
- const value = await this.resolveParameter(
246
- param,
247
- context,
248
- functionName,
249
- { isOptional: !param.isRequired }
250
- );
251
- if (param.isRequired || value !== void 0) {
252
- this.setNestedValue(resolvedParams, param.path, value);
253
- context.resolvedParams = resolvedParams;
254
- }
255
- } catch (error) {
256
- if (this.isUserCancellation(error)) {
257
- console.log(chalk.yellow("\n\nOperation cancelled by user"));
258
- throw new ZapierCliUserCancellationError();
259
- }
260
- throw error;
261
- }
262
- }
263
- }
264
- const resolvedParamNames = new Set(
265
- orderedRequiredParams.map((p) => p.name)
266
- );
267
- optional.splice(
268
- 0,
269
- optional.length,
270
- ...optional.filter((p) => !resolvedParamNames.has(p.name))
271
- );
272
- }
273
- if (interactiveMode && optional.length > 0) {
274
- const optionalParamNames = optional.map((p) => p.name);
275
- const optionalResolutionOrder = getLocalResolutionOrderForParams(
276
- optionalParamNames,
277
- localResolvers
278
- );
279
- const orderedOptionalParams = optionalResolutionOrder.map((paramName) => optional.find((p) => p.name === paramName)).filter((param) => param !== void 0);
280
- for (const param of orderedOptionalParams) {
281
- try {
282
- const value = await this.resolveParameter(
283
- param,
284
- context,
285
- functionName,
286
- { isOptional: true }
287
- );
288
- if (value !== void 0) {
289
- this.setNestedValue(resolvedParams, param.path, value);
290
- context.resolvedParams = resolvedParams;
291
- }
292
- } catch (error) {
293
- if (this.isUserCancellation(error)) {
294
- console.log(chalk.yellow("\n\nOperation cancelled by user"));
295
- throw new ZapierCliUserCancellationError();
296
- }
297
- throw error;
298
- }
299
- }
300
- }
301
- const finalResult = schema.safeParse(resolvedParams);
302
- if (!finalResult.success) {
303
- throw new ZapierCliValidationError(
304
- `Parameter validation failed: ${formatZodError(finalResult.error)}`
305
- );
306
- }
307
- return finalResult.data;
308
- });
309
- }
310
- extractParametersFromSchema(schema) {
311
- const parameters = [];
312
- if (schema instanceof z.ZodObject) {
313
- const shape = schema.shape;
314
- for (const [key, fieldSchema] of Object.entries(shape)) {
315
- const param = this.analyzeFieldSchema(key, fieldSchema);
316
- if (param) {
317
- parameters.push(param);
318
- }
319
- }
320
- }
321
- return parameters;
322
- }
323
- analyzeFieldSchema(fieldName, fieldSchema) {
324
- let baseSchema = fieldSchema;
325
- let isRequired = true;
326
- if (baseSchema instanceof z.ZodOptional) {
327
- isRequired = false;
328
- baseSchema = baseSchema._zod.def.innerType;
329
- }
330
- if (baseSchema instanceof z.ZodDefault) {
331
- isRequired = false;
332
- baseSchema = baseSchema._zod.def.innerType;
333
- }
334
- return this.createResolvableParameter([fieldName], baseSchema, isRequired);
335
- }
336
- createResolvableParameter(path2, schema, isRequired) {
337
- if (path2.length === 0) return null;
338
- const name = path2[path2.length - 1];
339
- return {
340
- name,
341
- path: path2,
342
- schema,
343
- description: schema.description,
344
- isRequired
345
- };
346
- }
347
- /**
348
- * Calls `tryResolveWithoutPrompt` on a dynamic resolver.
349
- * Returns the resolution result object, or null if unresolvable / throws.
350
- * Note: { resolvedValue: undefined } is a valid result (e.g. connection when app has no auth);
351
- * only a null return from the resolver itself means "could not auto-resolve".
352
- */
353
- async tryAutoResolve(dynamicResolver, context) {
354
- if (!dynamicResolver.tryResolveWithoutPrompt) return null;
355
- try {
356
- return await dynamicResolver.tryResolveWithoutPrompt(
357
- context.sdk,
358
- context.resolvedParams
359
- );
360
- } catch (err) {
361
- console.warn(
362
- `Auto-resolver threw unexpectedly; treating as unresolved. Error: ${err instanceof Error ? err.message : String(err)}`
363
- );
364
- return null;
365
- }
366
- }
367
- /**
368
- * Non-interactive resolution: auto-resolves what it can via tryAutoResolve,
369
- * throws ZapierCliMissingParametersError for anything that requires user input.
370
- */
371
- async resolveRequiredParamsNonInteractive(params, context, resolvedParams, functionName) {
372
- const missingParams = [];
373
- for (const param of params) {
374
- const resolver = this.getResolver(param.name, context.sdk, functionName);
375
- let autoResolved = null;
376
- if (resolver?.type === "constant") {
377
- autoResolved = {
378
- resolvedValue: resolver.value
379
- };
380
- } else if (resolver?.type === "dynamic") {
381
- autoResolved = await this.tryAutoResolve(
382
- resolver,
383
- context
384
- );
385
- }
386
- if (autoResolved != null) {
387
- this.setNestedValue(
388
- resolvedParams,
389
- param.path,
390
- autoResolved.resolvedValue
391
- );
392
- context.resolvedParams = resolvedParams;
393
- } else {
394
- missingParams.push({
395
- name: param.name,
396
- // Required params render as positional CLI args (<name>); so do explicitly positional optional params.
397
- isPositional: param.isRequired || isPositional(param.schema)
398
- });
399
- }
400
- }
401
- if (missingParams.length > 0) {
402
- throw new ZapierCliMissingParametersError(missingParams);
403
- }
404
- }
405
- /**
406
- * Wrap a PromptConfig.validate so internal sentinels (Symbols) bypass
407
- * it. The resolver's validator is intended for actual user values; our
408
- * Skip / Custom / Load-more sentinels are internal control-flow and
409
- * should pass through. Returns `undefined` when the resolver didn't
410
- * supply a validator (so `await search({ ...rest })` doesn't get a
411
- * pass-through identity function).
412
- */
413
- wrapPromptValidate(validate) {
414
- if (!validate) return void 0;
415
- return (value) => typeof value === "symbol" ? true : validate(value);
416
- }
417
- /**
418
- * Apply a PromptConfig.filter to a selected value, but only when the
419
- * value is a real data choice (not an internal sentinel). @inquirer/search
420
- * has no built-in filter hook, so the search-backed paths call this
421
- * explicitly before returning.
422
- */
423
- applyPromptFilter(filter, value) {
424
- if (!filter || typeof value === "symbol") return value;
425
- return filter(value);
426
- }
427
- /**
428
- * If the resolver's PromptConfig sets a `default` value, move the
429
- * matching choice to the front so it's the first selectable item in
430
- * the rendered source. @inquirer/search has no built-in `default`
431
- * option; first-selectable is what Enter picks, so reordering achieves
432
- * the same semantics inquirer.prompt's list had natively.
433
- *
434
- * Returns the original array if no default is set or the default
435
- * doesn't match any current choice.
436
- */
437
- reorderForDefault(matches, defaultValue) {
438
- if (defaultValue === void 0) return matches;
439
- const idx = matches.findIndex((c) => c.value === defaultValue);
440
- if (idx <= 0) return matches;
441
- return [matches[idx], ...matches.slice(0, idx), ...matches.slice(idx + 1)];
442
- }
443
- /**
444
- * Build the disabled "if you had X capability, more results would show"
445
- * hints for any unmet capabilities the resolver declared. Returns the
446
- * raw hint strings — callers wrap them into choice objects with whatever
447
- * sentinel value they prefer (disabled choices' values are inert).
448
- */
449
- async computeCapabilityHints(resolver, context) {
450
- if (!resolver.requireCapabilities) return [];
451
- const capContext = context.sdk.context;
452
- if (!capContext.hasCapability) return [];
453
- const messages = [];
454
- for (const cap of resolver.requireCapabilities) {
455
- const enabled = await capContext.hasCapability(cap);
456
- if (!enabled) messages.push(buildCapabilityMessage(cap));
457
- }
458
- return messages;
459
- }
460
- /**
461
- * Unpack a DynamicResolver.fetch result into the three shapes the caller
462
- * cares about: a flat items array, an optional AsyncIterator for further
463
- * pagination, and a hasMore flag. Centralizing keeps the AsyncIterable /
464
- * `{data, nextCursor}` / `TItem[]` discrimination in one place — both
465
- * the main dropdown loop and the search-mode flow consume it.
466
- *
467
- * The function is `async` for the AsyncIterable branch only (we eagerly
468
- * consume the first page so callers don't have to discriminate). The
469
- * other two branches return synchronously; an explicit Promise.resolve
470
- * is unnecessary because async automatically wraps.
471
- *
472
- * Note: callers in search mode intentionally drop `pageIterator` /
473
- * `hasMore` because each search() invocation re-prompts from scratch;
474
- * pagination only matters when the prompt is the dropdown itself.
475
- */
476
- async unpackFetchResult(fetchResult, promptLabel) {
477
- if (fetchResult != null && typeof fetchResult === "object" && Symbol.asyncIterator in fetchResult) {
478
- const pageIterator = fetchResult[Symbol.asyncIterator]();
479
- const first = await pageIterator.next();
480
- if (!first.done && first.value) {
481
- return {
482
- items: Array.isArray(first.value.data) ? first.value.data : [],
483
- pageIterator,
484
- hasMore: first.value.nextCursor != null
485
- };
486
- }
487
- return { items: [], pageIterator, hasMore: false };
488
- }
489
- if (fetchResult != null && typeof fetchResult === "object" && "data" in fetchResult) {
490
- const page = fetchResult;
491
- const hasMore = page.nextCursor != null;
492
- if (hasMore) {
493
- this.debugLog(
494
- `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.`
495
- );
496
- }
497
- return {
498
- items: Array.isArray(page.data) ? page.data : [],
499
- pageIterator: null,
500
- hasMore
501
- };
502
- }
503
- return {
504
- items: Array.isArray(fetchResult) ? fetchResult : [],
505
- pageIterator: null,
506
- hasMore: false
507
- };
508
- }
509
- /**
510
- * Search-mode dynamic resolver: prompts the user for free-form text, passes
511
- * it to fetch via `search`, and either short-circuits on a primitive return
512
- * (exact match) or renders the results as a search-filterable dropdown.
513
- * Empty results still render the dropdown so the user can fall through to
514
- * "(Use 'foo' as-is)" or "(Try a different search)" rather than being
515
- * stuck.
516
- *
517
- * Known limitation: pagination beyond the first page is dropped. Each
518
- * search() invocation re-prompts from scratch and the user is expected
519
- * to refine their query if too many results came back. If a future
520
- * high-cardinality search resolver needs Load-more here, the
521
- * `pageIterator` / `hasMore` from `unpackFetchResult` is what to wire in.
522
- */
523
- async resolveDynamicWithSearchInput({
524
- resolver,
525
- context,
526
- promptLabel,
527
- isOptional
528
- }) {
529
- const parenParts = [];
530
- if (isOptional) parenParts.push("optional");
531
- if (resolver.placeholder) parenParts.push(resolver.placeholder);
532
- const parens = parenParts.length > 0 ? ` (${parenParts.join(", ")})` : "";
533
- const message = `Enter or search ${promptLabel}${parens}:`;
534
- const SKIP_SENTINEL = Symbol("SKIP");
535
- const USE_AS_IS_SENTINEL = Symbol("USE_AS_IS");
536
- const TRY_AGAIN_SENTINEL = Symbol("TRY_AGAIN");
537
- let lastNote;
538
- while (true) {
539
- this.stopSpinner();
540
- if (lastNote) {
541
- console.log(chalk.yellow(lastNote));
542
- lastNote = void 0;
543
- }
544
- const answers = await inquirer.prompt([
545
- { type: "input", name: "search", message }
546
- ]);
547
- const rawInput = answers.search;
548
- const searchInput = typeof rawInput === "string" ? rawInput.trim() : "";
549
- if (!searchInput) {
550
- if (isOptional) return void 0;
551
- lastNote = `${promptLabel} is required.`;
552
- continue;
553
- }
554
- const searchParams = {
555
- ...context.resolvedParams,
556
- search: searchInput
557
- };
558
- this.startSpinner();
559
- this.debugLog(`Searching ${promptLabel} for "${searchInput}"`);
560
- let fetchResult;
561
- try {
562
- fetchResult = await resolver.fetch(context.sdk, searchParams);
563
- } finally {
564
- this.stopSpinner();
565
- }
566
- if (typeof fetchResult === "string" || typeof fetchResult === "number") {
567
- return fetchResult;
568
- }
569
- const { items } = await this.unpackFetchResult(fetchResult, promptLabel);
570
- const choicesConfig = resolver.prompt(items, searchParams);
571
- const dataChoices = (choicesConfig.choices ?? []).map(renderChoiceLabel);
572
- const capabilityHintMessages = await this.computeCapabilityHints(
573
- resolver,
574
- context
575
- );
576
- const selected = await search({
577
- message: choicesConfig.message,
578
- validate: this.wrapPromptValidate(choicesConfig.validate),
579
- // @inquirer/search passes an AbortSignal as the second arg for
580
- // cancelling async sources. All three of our source callbacks are
581
- // pure-local (filter an already-fetched array), so we intentionally
582
- // ignore the signal. A future server-side filter implementation
583
- // would need to honor it.
584
- source: (term) => {
585
- const trimmed = (term ?? "").trim();
586
- const lower = trimmed.toLowerCase();
587
- const matches = trimmed ? dataChoices.filter((c) => c.name.toLowerCase().includes(lower)) : dataChoices;
588
- const orderedMatches = trimmed ? matches : this.reorderForDefault(matches, choicesConfig.default);
589
- const skipChoice = isOptional ? [{ name: chalk.dim("(Skip)"), value: SKIP_SENTINEL }] : [];
590
- const useAsIsChoice = {
591
- name: chalk.dim(`(Use ${JSON.stringify(searchInput)} as-is)`),
592
- value: USE_AS_IS_SENTINEL
593
- };
594
- const tryAgainChoice = {
595
- name: chalk.dim("(Try a different search)"),
596
- value: TRY_AGAIN_SENTINEL
597
- };
598
- const out2 = [];
599
- if (orderedMatches.length === 0) {
600
- out2.push(useAsIsChoice);
601
- out2.push(tryAgainChoice);
602
- out2.push(...skipChoice);
603
- } else {
604
- out2.push(...orderedMatches);
605
- out2.push(...skipChoice);
606
- out2.push(useAsIsChoice);
607
- out2.push(tryAgainChoice);
608
- }
609
- for (const message2 of capabilityHintMessages) {
610
- out2.push({
611
- name: chalk.dim(message2),
612
- value: SKIP_SENTINEL,
613
- disabled: true
614
- });
615
- }
616
- return out2;
617
- }
618
- });
619
- if (selected === SKIP_SENTINEL) return void 0;
620
- if (selected === USE_AS_IS_SENTINEL) {
621
- const validationResult = choicesConfig.validate?.(searchInput);
622
- if (validationResult === false) {
623
- lastNote = `${promptLabel}: invalid value.`;
624
- continue;
625
- }
626
- if (typeof validationResult === "string") {
627
- lastNote = validationResult;
628
- continue;
629
- }
630
- return this.applyPromptFilter(choicesConfig.filter, searchInput);
631
- }
632
- if (selected === TRY_AGAIN_SENTINEL) continue;
633
- return this.applyPromptFilter(choicesConfig.filter, selected);
634
- }
635
- }
636
- async resolveParameter(param, context, functionName, options) {
637
- const resolver = this.getResolver(
638
- param.name,
639
- context.sdk,
640
- functionName
641
- );
642
- if (!resolver) {
643
- throw new Error(`No resolver found for parameter: ${param.name}`);
644
- }
645
- return this.resolveWithResolver(resolver, param, context, {
646
- isOptional: options?.isOptional
647
- });
648
- }
649
- /**
650
- * Run a resolver to obtain a value for one parameter, prompting the
651
- * user when necessary. Routes to one of several prompt backends and
652
- * has to keep the `PromptConfig` contract honest across each one.
653
- *
654
- * `PromptConfig` field × prompt-backend handling:
655
- *
656
- * | field | list (search()) | checkbox/confirm (inquirer.prompt) | search-mode dropdown (search()) |
657
- * | -------- | --------------- | ---------------------------------- | ------------------------------- |
658
- * | type | required | required | required |
659
- * | name | (set internally)| forwarded | (set internally) |
660
- * | message | forwarded | forwarded | forwarded |
661
- * | choices | filtered in src | passed to inquirer | filtered in src |
662
- * | default | reorder matches | passed (also internal cursor jump) | reorder matches |
663
- * | validate | wrapped | passed (inquirer native) | wrapped + manual for (Use as-is)|
664
- * | filter | manual once | inquirer native (do NOT double) | manual once |
665
- *
666
- * Escape-hatch sentinels (Skip / Custom value / Use as-is / Load more
667
- * / Try again) bypass the resolver's validate/filter because they
668
- * aren't real user values — they're CLI control-flow.
669
- */
670
- async resolveWithResolver(resolver, param, context, options = {}) {
671
- const { arrayIndex, isOptional } = options;
672
- const inArrayContext = arrayIndex != null;
673
- const promptLabel = inArrayContext ? `${param.name}[${arrayIndex}]` : param.name;
674
- const promptName = inArrayContext ? "value" : param.name;
675
- this.debugLog(`Resolving ${promptLabel}${isOptional ? " (optional)" : ""}`);
676
- if (resolver.type === "constant") {
677
- const constantResolver = resolver;
678
- this.stopSpinner();
679
- return constantResolver.value;
680
- } else if (resolver.type === "static") {
681
- const staticResolver = resolver;
682
- const promptConfig = {
683
- type: staticResolver.inputType === "password" ? "password" : "input",
684
- name: promptName,
685
- message: `Enter ${promptLabel}${isOptional ? " (optional)" : ""}:`,
686
- ...staticResolver.placeholder && {
687
- default: staticResolver.placeholder
688
- }
689
- };
690
- this.stopSpinner();
691
- const answers = await inquirer.prompt([promptConfig]);
692
- const value = answers[promptName];
693
- if (isOptional && (value === void 0 || value === "" || value === staticResolver.placeholder)) {
694
- return void 0;
695
- }
696
- return coerceToSchemaType(value, param.schema);
697
- } else if (resolver.type === "dynamic") {
698
- const dynamicResolver = resolver;
699
- this.startSpinner();
700
- const autoResolution = await this.tryAutoResolve(
701
- dynamicResolver,
702
- context
703
- );
704
- if (autoResolution != null) {
705
- this.stopSpinner();
706
- return autoResolution.resolvedValue;
707
- }
708
- if (dynamicResolver.inputType === "search") {
709
- this.stopSpinner();
710
- return await this.resolveDynamicWithSearchInput({
711
- resolver: dynamicResolver,
712
- context,
713
- promptLabel,
714
- isOptional: isOptional ?? false
715
- });
716
- }
717
- this.debugLog(`Fetching options for ${promptLabel}`);
718
- let fetchResult;
719
- try {
720
- fetchResult = await dynamicResolver.fetch(
721
- context.sdk,
722
- context.resolvedParams
723
- );
724
- } finally {
725
- this.stopSpinner();
726
- }
727
- if (typeof fetchResult === "string" || typeof fetchResult === "number") {
728
- console.error(
729
- chalk.yellow(
730
- `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.`
731
- )
732
- );
733
- const fallbackAnswers = await inquirer.prompt([
734
- {
735
- type: "input",
736
- name: promptName,
737
- message: `Enter ${promptLabel}${isOptional ? " (optional)" : ""}:`
738
- }
739
- ]);
740
- const fallbackValue = fallbackAnswers[promptName];
741
- if (isOptional && (fallbackValue === void 0 || fallbackValue === "")) {
742
- return void 0;
743
- }
744
- return fallbackValue;
745
- }
746
- const unpacked = await this.unpackFetchResult(fetchResult, promptLabel);
747
- let pageIterator = unpacked.pageIterator;
748
- let items = unpacked.items;
749
- let hasMore = unpacked.hasMore;
750
- const LOAD_MORE_SENTINEL = Symbol("LOAD_MORE");
751
- const SKIP_SENTINEL = Symbol("SKIP");
752
- const CUSTOM_VALUE_SENTINEL = Symbol("CUSTOM_VALUE");
753
- let newItemsStartIndex = -1;
754
- while (true) {
755
- const promptConfig = dynamicResolver.prompt(
756
- items,
757
- context.resolvedParams
758
- );
759
- promptConfig.name = promptName;
760
- const renderedChoices = promptConfig.choices ? promptConfig.choices.map(renderChoiceLabel) : [];
761
- if (promptConfig.choices) {
762
- promptConfig.choices = renderedChoices;
763
- }
764
- const hasSelectableChoice = promptConfig.choices?.some(
765
- (c) => !c.disabled
766
- );
767
- if (!hasSelectableChoice && !hasMore) {
768
- throw new ZapierCliValidationError(
769
- `No ${promptLabel} available to select.`
770
- );
771
- }
772
- const capabilityHints = [];
773
- if (!hasMore) {
774
- const hintMessages = await this.computeCapabilityHints(
775
- dynamicResolver,
776
- context
777
- );
778
- for (const message of hintMessages) {
779
- capabilityHints.push({
780
- name: chalk.dim(message),
781
- value: SKIP_SENTINEL,
782
- disabled: true
783
- });
784
- }
785
- }
786
- let selected;
787
- if (promptConfig.type === "list") {
788
- const dataChoices = renderedChoices;
789
- selected = await search({
790
- message: promptConfig.message,
791
- validate: this.wrapPromptValidate(promptConfig.validate),
792
- source: (term) => {
793
- const trimmed = (term ?? "").trim();
794
- const lower = trimmed.toLowerCase();
795
- const matches = trimmed ? dataChoices.filter(
796
- (c) => c.name.toLowerCase().includes(lower)
797
- ) : dataChoices;
798
- const out2 = [];
799
- const skipChoice = isOptional ? [
800
- {
801
- name: chalk.dim("(Skip)"),
802
- value: SKIP_SENTINEL
803
- }
804
- ] : [];
805
- const customValueChoice = {
806
- name: chalk.dim("(Enter custom value)"),
807
- value: CUSTOM_VALUE_SENTINEL
808
- };
809
- const orderedMatches = trimmed ? matches : this.reorderForDefault(matches, promptConfig.default);
810
- const matchesFirst = trimmed || promptConfig.default !== void 0;
811
- const loadMoreChoice = hasMore && pageIterator ? {
812
- name: chalk.dim("(Load more...)"),
813
- value: LOAD_MORE_SENTINEL
814
- } : null;
815
- if (matchesFirst && orderedMatches.length > 0) {
816
- out2.push(...orderedMatches);
817
- out2.push(...skipChoice);
818
- out2.push(customValueChoice);
819
- if (loadMoreChoice) out2.push(loadMoreChoice);
820
- } else if (matchesFirst) {
821
- out2.push(customValueChoice);
822
- if (loadMoreChoice) out2.push(loadMoreChoice);
823
- out2.push(...skipChoice);
824
- } else {
825
- out2.push(...skipChoice);
826
- out2.push(customValueChoice);
827
- out2.push(...orderedMatches);
828
- if (loadMoreChoice) out2.push(loadMoreChoice);
829
- }
830
- if (capabilityHints.length > 0 && (!trimmed || matches.length > 0)) {
831
- out2.push(...capabilityHints);
832
- }
833
- return out2;
834
- }
835
- });
836
- } else {
837
- if (isOptional && promptConfig.choices) {
838
- promptConfig.choices.unshift({
839
- name: chalk.dim("(Skip)"),
840
- value: SKIP_SENTINEL
841
- });
842
- }
843
- if (hasMore && pageIterator && promptConfig.choices) {
844
- promptConfig.choices.push({
845
- name: chalk.dim("(Load more...)"),
846
- value: LOAD_MORE_SENTINEL
847
- });
848
- }
849
- if (capabilityHints.length > 0 && promptConfig.choices) {
850
- promptConfig.choices.push(...capabilityHints);
851
- }
852
- if (newItemsStartIndex >= 0 && promptConfig.choices) {
853
- const injectedBefore = isOptional ? 1 : 0;
854
- const adjustedIndex = newItemsStartIndex + injectedBefore;
855
- if (promptConfig.choices[adjustedIndex]) {
856
- promptConfig.default = promptConfig.choices[adjustedIndex].value;
857
- }
858
- newItemsStartIndex = -1;
859
- }
860
- const answers = await inquirer.prompt([promptConfig]);
861
- selected = answers[promptName];
862
- }
863
- if (selected === SKIP_SENTINEL) {
864
- return void 0;
865
- }
866
- if (selected === CUSTOM_VALUE_SENTINEL) {
867
- const customAnswer = await inquirer.prompt([
868
- {
869
- type: "input",
870
- name: promptName,
871
- message: `Enter ${promptLabel}${isOptional ? " (optional)" : ""}:`
872
- }
873
- ]);
874
- const value = customAnswer[promptName];
875
- if (isOptional && (value === void 0 || value === "")) {
876
- return void 0;
877
- }
878
- return value;
879
- }
880
- const wantsMore = Array.isArray(selected) ? selected.includes(LOAD_MORE_SENTINEL) : selected === LOAD_MORE_SENTINEL;
881
- if (wantsMore && pageIterator) {
882
- if (Array.isArray(selected)) {
883
- selected = selected.filter(
884
- (v) => v !== LOAD_MORE_SENTINEL
885
- );
886
- }
887
- const prevLength = items.length;
888
- this.startSpinner();
889
- this.debugLog("Fetching more options...");
890
- const next = await pageIterator.next();
891
- this.stopSpinner();
892
- if (!next.done && next.value) {
893
- items = [...items, ...next.value.data];
894
- hasMore = next.value.nextCursor != null;
895
- newItemsStartIndex = prevLength;
896
- } else {
897
- hasMore = false;
898
- }
899
- continue;
900
- }
901
- return promptConfig.type === "list" ? this.applyPromptFilter(promptConfig.filter, selected) : selected;
902
- }
903
- } else if (resolver.type === "fields") {
904
- if (isOptional && !inArrayContext) {
905
- this.stopSpinner();
906
- const { confirm } = await inquirer.prompt([
907
- {
908
- type: "confirm",
909
- name: "confirm",
910
- message: `Add ${promptLabel}?`,
911
- default: false
912
- }
913
- ]);
914
- if (!confirm) {
915
- return void 0;
916
- }
917
- }
918
- return await this.resolveFieldsRecursively(
919
- resolver,
920
- context,
921
- param,
922
- { inArrayContext }
923
- );
924
- } else if (resolver.type === "array") {
925
- return await this.resolveArrayRecursively(
926
- resolver,
927
- context,
928
- param
929
- );
930
- }
931
- throw new Error(`Unknown resolver type for ${promptLabel}`);
932
- }
933
- async resolveFieldsRecursively(resolver, context, param, options = {}) {
934
- const inputs = {};
935
- let processedFieldKeys = /* @__PURE__ */ new Set();
936
- let iteration = 0;
937
- const maxIterations = 10;
938
- while (iteration < maxIterations) {
939
- iteration++;
940
- const updatedContext = {
941
- ...context,
942
- resolvedParams: {
943
- ...context.resolvedParams,
944
- inputs
945
- }
946
- };
947
- this.debugLog(
948
- `Fetching input fields for ${param.name}${iteration > 1 ? ` (iteration ${iteration})` : ""}`
949
- );
950
- this.startSpinner();
951
- const rootFieldItems = await resolver.fetch(
952
- updatedContext.sdk,
953
- updatedContext.resolvedParams
954
- );
955
- this.stopSpinner();
956
- if (!rootFieldItems || rootFieldItems.length === 0) {
957
- if (iteration === 1) {
958
- console.log(
959
- chalk.yellow(`No input fields required for this action.`)
960
- );
961
- }
962
- break;
963
- }
964
- const fieldStats = await this.processFieldItems(
965
- rootFieldItems,
966
- inputs,
967
- processedFieldKeys,
968
- [],
969
- iteration,
970
- updatedContext,
971
- { inArrayContext: options.inArrayContext }
972
- );
973
- if (fieldStats.newRequired === 0 && fieldStats.newOptional === 0) {
974
- break;
975
- }
976
- if (fieldStats.newRequired === 0 && fieldStats.optionalSkipped) {
977
- break;
978
- }
979
- }
980
- if (iteration >= maxIterations) {
981
- console.log(
982
- chalk.yellow(
983
- `
984
- \u26A0\uFE0F Maximum field resolution iterations reached. Some dynamic fields may not have been discovered.`
985
- )
986
- );
987
- }
988
- if (resolver.transform) {
989
- return resolver.transform(inputs);
990
- }
991
- return inputs;
992
- }
993
- /**
994
- * Resolves an array parameter by repeatedly prompting for items until user says no
995
- */
996
- async resolveArrayRecursively(resolver, context, param) {
997
- const items = [];
998
- const minItems = resolver.minItems ?? 0;
999
- const maxItems = resolver.maxItems ?? Infinity;
1000
- while (items.length < maxItems) {
1001
- const currentIndex = items.length;
1002
- if (currentIndex >= minItems) {
1003
- this.stopSpinner();
1004
- const confirmAnswer = await inquirer.prompt([
1005
- {
1006
- type: "confirm",
1007
- name: "addItem",
1008
- message: `Add ${param.name}[${currentIndex}]?`,
1009
- default: false
1010
- }
1011
- ]);
1012
- if (!confirmAnswer.addItem) {
1013
- break;
1014
- }
1015
- }
1016
- const innerResolver = await resolver.fetch(
1017
- context.sdk,
1018
- context.resolvedParams
1019
- );
1020
- const itemValue = await this.resolveWithResolver(
1021
- innerResolver,
1022
- param,
1023
- context,
1024
- { arrayIndex: currentIndex }
1025
- );
1026
- items.push(itemValue);
1027
- context.resolvedParams = {
1028
- ...context.resolvedParams,
1029
- [param.name]: items
1030
- };
1031
- }
1032
- if (items.length >= maxItems) {
1033
- console.log(chalk.gray(`Maximum of ${maxItems} items reached.`));
1034
- }
1035
- return items;
1036
- }
1037
- /**
1038
- * Recursively processes fieldsets and their fields, maintaining natural structure
1039
- * and creating nested inputs as needed (e.g., fieldset "foo" becomes inputs.foo = [{}])
1040
- */
1041
- async processFieldItems(items, targetInputs, processedFieldKeys, fieldsetPath = [], iteration = 1, context, options = {}) {
1042
- let newRequiredCount = 0;
1043
- let newOptionalCount = 0;
1044
- let optionalSkipped = false;
1045
- for (const item of items) {
1046
- const typedItem = item;
1047
- if (typedItem.type === "fieldset" && typedItem.fields && typedItem.key) {
1048
- const fieldsetTitle = typedItem.title || typedItem.key;
1049
- const pathDisplay = fieldsetPath.length > 0 ? ` (in ${fieldsetPath.join(" > ")})` : "";
1050
- console.log(
1051
- chalk.cyan(
1052
- `
1053
- \u{1F4C1} Processing fieldset: ${fieldsetTitle}${pathDisplay}`
1054
- )
1055
- );
1056
- if (!targetInputs[typedItem.key]) {
1057
- targetInputs[typedItem.key] = [{}];
1058
- }
1059
- const fieldsetTarget = targetInputs[typedItem.key][0];
1060
- const nestedPath = [...fieldsetPath, fieldsetTitle];
1061
- const nestedStats = await this.processFieldItems(
1062
- typedItem.fields,
1063
- fieldsetTarget,
1064
- processedFieldKeys,
1065
- nestedPath,
1066
- iteration,
1067
- context,
1068
- options
1069
- );
1070
- newRequiredCount += nestedStats.newRequired;
1071
- newOptionalCount += nestedStats.newOptional;
1072
- if (nestedStats.optionalSkipped) {
1073
- optionalSkipped = true;
1074
- }
1075
- } else if (typedItem.type === "input_field" && typedItem.key) {
1076
- if (processedFieldKeys.has(typedItem.key)) {
1077
- continue;
1078
- }
1079
- const isRequired = typedItem.is_required || false;
1080
- if (isRequired) {
1081
- newRequiredCount++;
1082
- if (typedItem.resolver && context) {
1083
- const param = {
1084
- name: typedItem.key,
1085
- path: [typedItem.key],
1086
- schema: z.unknown(),
1087
- isRequired: true
1088
- };
1089
- targetInputs[typedItem.key] = await this.resolveWithResolver(
1090
- typedItem.resolver,
1091
- param,
1092
- context,
1093
- { isOptional: false }
1094
- );
1095
- } else {
1096
- await this.promptForField(typedItem, targetInputs, context);
1097
- }
1098
- processedFieldKeys.add(typedItem.key);
1099
- } else {
1100
- newOptionalCount++;
1101
- }
1102
- }
1103
- }
1104
- if (newOptionalCount > 0) {
1105
- const optionalFields = items.filter((item) => {
1106
- const typedItem = item;
1107
- return typedItem.type === "input_field" && typedItem.key && !typedItem.is_required && !processedFieldKeys.has(typedItem.key);
1108
- });
1109
- if (optionalFields.length > 0) {
1110
- const pathContext = fieldsetPath.length > 0 ? ` in ${fieldsetPath.join(" > ")}` : "";
1111
- if (options.inArrayContext) {
1112
- for (const field of optionalFields) {
1113
- await this.promptForField(field, targetInputs, context);
1114
- const typedField = field;
1115
- processedFieldKeys.add(typedField.key);
1116
- }
1117
- } else {
1118
- console.log(
1119
- chalk.gray(
1120
- `
1121
- There are ${optionalFields.length} ${iteration === 1 ? "" : "additional "}optional field(s) available${pathContext}.`
1122
- )
1123
- );
1124
- try {
1125
- const shouldConfigureOptional = await inquirer.prompt([
1126
- {
1127
- type: "confirm",
1128
- name: "configure",
1129
- message: `Would you like to configure ${iteration === 1 ? "" : "these additional "}optional fields${pathContext}?`,
1130
- default: false
1131
- }
1132
- ]);
1133
- if (shouldConfigureOptional.configure) {
1134
- console.log(chalk.cyan(`
1135
- Optional fields${pathContext}:`));
1136
- for (const field of optionalFields) {
1137
- await this.promptForField(field, targetInputs, context);
1138
- const typedField = field;
1139
- processedFieldKeys.add(typedField.key);
1140
- }
1141
- } else {
1142
- optionalSkipped = true;
1143
- optionalFields.forEach((field) => {
1144
- const typedField = field;
1145
- processedFieldKeys.add(typedField.key);
1146
- });
1147
- }
1148
- } catch (error) {
1149
- if (this.isUserCancellation(error)) {
1150
- console.log(chalk.yellow("\n\nOperation cancelled by user"));
1151
- throw new ZapierCliUserCancellationError();
1152
- }
1153
- throw error;
1154
- }
1155
- }
1156
- }
1157
- }
1158
- return {
1159
- newRequired: newRequiredCount,
1160
- newOptional: newOptionalCount,
1161
- optionalSkipped
1162
- };
1163
- }
1164
- getNestedValue(obj, path2) {
1165
- return path2.reduce(
1166
- (current, key) => current?.[key],
1167
- obj
1168
- );
1169
- }
1170
- setNestedValue(obj, path2, value) {
1171
- const lastKey = path2[path2.length - 1];
1172
- const parent = path2.slice(0, -1).reduce((current, key) => {
1173
- const currentObj = current;
1174
- if (!(key in currentObj)) {
1175
- currentObj[key] = {};
1176
- }
1177
- return currentObj[key];
1178
- }, obj);
1179
- parent[lastKey] = value;
1180
- }
1181
- /**
1182
- * Extract and normalize field metadata from raw field object
1183
- */
1184
- extractFieldMetadata(field) {
1185
- const fieldObj = field;
1186
- const valueType = fieldObj.value_type || "string";
1187
- return {
1188
- key: fieldObj.key,
1189
- title: fieldObj.title || fieldObj.label || fieldObj.key,
1190
- description: fieldObj.description || fieldObj.helpText,
1191
- isRequired: fieldObj.is_required || false,
1192
- defaultValue: fieldObj.default_value ?? fieldObj.default,
1193
- valueType,
1194
- hasDropdown: fieldObj.format === "SELECT" || Boolean(fieldObj.choices),
1195
- isMultiSelect: Boolean(
1196
- valueType === "array" || fieldObj.items && fieldObj.items.type !== void 0
1197
- ),
1198
- inlineChoices: fieldObj.choices
1199
- };
1200
- }
1201
- /**
1202
- * Fetch a page of choices for a dropdown field
1203
- */
1204
- async fetchChoices(fieldMeta, inputs, context, cursor) {
1205
- try {
1206
- this.debugLog(
1207
- cursor ? `Fetching more choices for ${fieldMeta.title}` : `Fetching choices for ${fieldMeta.title}`
1208
- );
1209
- this.startSpinner();
1210
- const page = await context.sdk.listActionInputFieldChoices({
1211
- app: context.resolvedParams.app,
1212
- action: context.resolvedParams.action,
1213
- actionType: context.resolvedParams.actionType,
1214
- connection: context.resolvedParams.connection,
1215
- inputField: fieldMeta.key,
1216
- inputs,
1217
- ...cursor && { cursor }
1218
- });
1219
- this.stopSpinner();
1220
- const choices = page.data.map((choice) => ({
1221
- label: choice.label || choice.key || String(choice.value),
1222
- value: choice.value ?? choice.key
1223
- }));
1224
- if (choices.length === 0 && !cursor) {
1225
- console.log(
1226
- chalk.yellow(`No choices available for ${fieldMeta.title}`)
1227
- );
1228
- }
1229
- return {
1230
- choices,
1231
- nextCursor: page.nextCursor
1232
- };
1233
- } catch (error) {
1234
- this.stopSpinner();
1235
- console.warn(
1236
- chalk.yellow(`Failed to fetch choices for ${fieldMeta.title}:`),
1237
- error
1238
- );
1239
- return { choices: [] };
1240
- }
1241
- }
1242
- /**
1243
- * Prompt user with choices (handles both single and multi-select with pagination).
1244
- * Single-select goes through @inquirer/search so users can type-to-filter long
1245
- * dropdowns (SELECT fields); multi-select stays on inquirer.prompt since search
1246
- * is single-select only.
1247
- */
1248
- async promptWithChoices({
1249
- fieldMeta,
1250
- choices: initialChoices,
1251
- nextCursor: initialCursor,
1252
- inputs,
1253
- context
1254
- }) {
1255
- this.stopSpinner();
1256
- const choices = [...initialChoices];
1257
- let nextCursor = initialCursor;
1258
- const LOAD_MORE_SENTINEL = Symbol("LOAD_MORE");
1259
- const SKIP_SENTINEL = Symbol("SKIP");
1260
- const CUSTOM_VALUE_SENTINEL = Symbol("CUSTOM_VALUE");
1261
- const message = `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"}:`;
1262
- while (true) {
1263
- let selectedValue;
1264
- if (!fieldMeta.isMultiSelect) {
1265
- const dataChoices = choices.map((c) => ({
1266
- name: c.label,
1267
- value: c.value
1268
- }));
1269
- selectedValue = await search({
1270
- message,
1271
- source: (term) => {
1272
- const trimmed = (term ?? "").trim();
1273
- const lower = trimmed.toLowerCase();
1274
- const matches = trimmed ? dataChoices.filter((c) => c.name.toLowerCase().includes(lower)) : dataChoices;
1275
- const out2 = [];
1276
- const skipChoice = !fieldMeta.isRequired ? [{ name: chalk.dim("(Skip)"), value: SKIP_SENTINEL }] : [];
1277
- const customValueChoice = {
1278
- name: chalk.dim("(Enter custom value)"),
1279
- value: CUSTOM_VALUE_SENTINEL
1280
- };
1281
- const loadMoreChoice = nextCursor && context ? {
1282
- name: chalk.dim("(Load more...)"),
1283
- value: LOAD_MORE_SENTINEL
1284
- } : null;
1285
- if (trimmed && matches.length > 0) {
1286
- out2.push(...matches);
1287
- out2.push(...skipChoice);
1288
- out2.push(customValueChoice);
1289
- if (loadMoreChoice) out2.push(loadMoreChoice);
1290
- } else if (trimmed) {
1291
- out2.push(customValueChoice);
1292
- if (loadMoreChoice) out2.push(loadMoreChoice);
1293
- out2.push(...skipChoice);
1294
- } else {
1295
- out2.push(...skipChoice);
1296
- out2.push(customValueChoice);
1297
- out2.push(...matches);
1298
- if (loadMoreChoice) out2.push(loadMoreChoice);
1299
- }
1300
- return out2;
1301
- }
1302
- });
1303
- if (selectedValue === SKIP_SENTINEL) {
1304
- return void 0;
1305
- }
1306
- if (selectedValue === CUSTOM_VALUE_SENTINEL) {
1307
- return await this.promptFreeForm(fieldMeta);
1308
- }
1309
- } else {
1310
- const promptChoices = choices.map((c) => ({
1311
- name: c.label,
1312
- value: c.value
1313
- }));
1314
- if (nextCursor) {
1315
- promptChoices.push({
1316
- name: chalk.dim("(Load more...)"),
1317
- value: LOAD_MORE_SENTINEL
1318
- });
1319
- }
1320
- const promptConfig = {
1321
- type: "checkbox",
1322
- name: fieldMeta.key,
1323
- message,
1324
- choices: promptChoices,
1325
- validate: (input) => {
1326
- if (fieldMeta.isRequired && (!input || input.length === 0)) {
1327
- return "At least one selection is required";
1328
- }
1329
- return true;
1330
- }
1331
- };
1332
- const answer = await inquirer.prompt([promptConfig]);
1333
- selectedValue = answer[fieldMeta.key];
1334
- }
1335
- const wantsMore = fieldMeta.isMultiSelect ? Array.isArray(selectedValue) && selectedValue.includes(LOAD_MORE_SENTINEL) : selectedValue === LOAD_MORE_SENTINEL;
1336
- if (wantsMore && nextCursor && context) {
1337
- if (fieldMeta.isMultiSelect && Array.isArray(selectedValue)) {
1338
- selectedValue = selectedValue.filter((v) => v !== LOAD_MORE_SENTINEL);
1339
- }
1340
- const result = await this.fetchChoices(
1341
- fieldMeta,
1342
- inputs,
1343
- context,
1344
- nextCursor
1345
- );
1346
- choices.push(...result.choices);
1347
- nextCursor = result.nextCursor;
1348
- continue;
1349
- }
1350
- return selectedValue;
1351
- }
1352
- }
1353
- /**
1354
- * Prompt user for free-form input (text or boolean)
1355
- */
1356
- async promptFreeForm(fieldMeta) {
1357
- const promptConfig = {
1358
- name: fieldMeta.key,
1359
- message: `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"}:`
1360
- };
1361
- if (fieldMeta.valueType === "boolean") {
1362
- promptConfig.type = "confirm";
1363
- promptConfig.default = fieldMeta.defaultValue !== void 0 ? Boolean(fieldMeta.defaultValue) : void 0;
1364
- } else if (fieldMeta.valueType === "array") {
1365
- promptConfig.type = "input";
1366
- promptConfig.default = fieldMeta.defaultValue;
1367
- promptConfig.message = `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"} (JSON array or comma-separated):`;
1368
- promptConfig.validate = (input) => {
1369
- if (fieldMeta.isRequired && !input) {
1370
- return "This field is required";
1371
- }
1372
- return true;
1373
- };
1374
- promptConfig.filter = (input) => {
1375
- if (!input) return input;
1376
- const trimmed = input.trim();
1377
- if (trimmed.startsWith("[")) {
1378
- try {
1379
- return JSON.parse(trimmed);
1380
- } catch {
1381
- }
1382
- }
1383
- return trimmed.split(",").map((s) => s.trim());
1384
- };
1385
- } else {
1386
- promptConfig.type = "input";
1387
- promptConfig.default = fieldMeta.defaultValue;
1388
- promptConfig.validate = (input) => {
1389
- if (fieldMeta.isRequired && !input) {
1390
- return "This field is required";
1391
- }
1392
- return true;
1393
- };
1394
- }
1395
- if (fieldMeta.description) {
1396
- promptConfig.prefix = chalk.gray(`\u2139 ${fieldMeta.description}
1397
- `);
1398
- }
1399
- try {
1400
- const answer = await inquirer.prompt([promptConfig]);
1401
- return answer[fieldMeta.key];
1402
- } catch (error) {
1403
- if (this.isUserCancellation(error)) {
1404
- console.log(chalk.yellow("\n\nOperation cancelled by user"));
1405
- throw new ZapierCliUserCancellationError();
1406
- }
1407
- throw error;
1408
- }
1409
- }
1410
- /**
1411
- * Store field value in inputs object with validation
1412
- */
1413
- storeFieldValue(inputs, key, value, isRequired) {
1414
- try {
1415
- if (value !== void 0 && value !== "") {
1416
- inputs[key] = value;
1417
- } else if (isRequired) {
1418
- throw new Error(`Required field ${key} cannot be empty`);
1419
- }
1420
- } catch (error) {
1421
- if (this.isUserCancellation(error)) {
1422
- console.log(chalk.yellow("\n\nOperation cancelled by user"));
1423
- throw new ZapierCliUserCancellationError();
1424
- }
1425
- throw error;
1426
- }
1427
- }
1428
- async promptForField(field, inputs, context) {
1429
- const fieldMeta = this.extractFieldMetadata(field);
1430
- let choices = [];
1431
- let nextCursor;
1432
- if (fieldMeta.inlineChoices) {
1433
- choices = fieldMeta.inlineChoices;
1434
- } else if (fieldMeta.hasDropdown && context) {
1435
- const result = await this.fetchChoices(fieldMeta, inputs, context);
1436
- choices = result.choices;
1437
- nextCursor = result.nextCursor;
1438
- }
1439
- let selectedValue;
1440
- if (choices.length > 0) {
1441
- selectedValue = await this.promptWithChoices({
1442
- fieldMeta,
1443
- choices,
1444
- nextCursor,
1445
- inputs,
1446
- context
1447
- });
1448
- } else {
1449
- selectedValue = await this.promptFreeForm(fieldMeta);
1450
- }
1451
- this.storeFieldValue(
1452
- inputs,
1453
- fieldMeta.key,
1454
- selectedValue,
1455
- fieldMeta.isRequired
1456
- );
1457
- }
1458
- isUserCancellation(error) {
1459
- const errorObj = error;
1460
- return errorObj?.name === "ExitPromptError" || errorObj?.message?.includes("User force closed") || errorObj?.isTTYError === true;
1461
- }
1462
- hasResolver(paramName, sdk, functionName) {
1463
- if (functionName && typeof sdk.getRegistry === "function") {
1464
- const registry = sdk.getRegistry({ package: "cli" });
1465
- const functionInfo = registry.functions.find(
1466
- (f) => f.name === functionName
1467
- );
1468
- if (functionInfo && functionInfo.resolvers?.[paramName]) {
1469
- return true;
1470
- }
1471
- }
1472
- return false;
1473
- }
1474
- getResolver(paramName, sdk, functionName) {
1475
- if (functionName && typeof sdk.getRegistry === "function") {
1476
- const registry = sdk.getRegistry({ package: "cli" });
1477
- const functionInfo = registry.functions.find(
1478
- (f) => f.name === functionName
1479
- );
1480
- if (functionInfo && functionInfo.resolvers?.[paramName]) {
1481
- return functionInfo.resolvers[paramName];
1482
- }
1483
- }
1484
- return null;
1485
- }
1486
- getLocalResolvers(sdk, functionName) {
1487
- if (!functionName || typeof sdk.getRegistry !== "function") {
1488
- return {};
1489
- }
1490
- const registry = sdk.getRegistry();
1491
- const functionInfo = registry.functions.find(
1492
- (f) => f.name === functionName
1493
- );
1494
- return functionInfo?.resolvers || {};
1495
- }
1496
- getResolverConstants(sdk, functionName) {
1497
- if (!functionName || typeof sdk.getRegistry !== "function") {
1498
- return {};
1499
- }
1500
- const registry = sdk.getRegistry();
1501
- const functionInfo = registry.functions.find(
1502
- (f) => f.name === functionName
1503
- );
1504
- const resolvers = functionInfo?.resolvers ?? {};
1505
- const constants = {};
1506
- for (const [key, resolver] of Object.entries(resolvers)) {
1507
- if (resolver && typeof resolver === "object" && resolver.type === "constant") {
1508
- constants[key] = resolver.value;
1509
- }
1510
- }
1511
- return constants;
1512
- }
6
+ import chalk8 from 'chalk';
7
+ import { makeTheme, createPrompt, useState, usePrefix, useMemo, useEffect, useKeypress, isEnterKey, isTabKey, isUpKey, isDownKey, usePagination, Separator } from '@inquirer/core';
8
+ import ora from 'ora';
9
+ import util, { stripVTControlCharacters } from 'util';
10
+ import wrapAnsi3 from 'wrap-ansi';
11
+ import * as jwt from 'jsonwebtoken';
12
+ import { deletePassword, getKeyring, setPassword, getPassword } from 'cross-keychain';
13
+ import Conf from 'conf';
14
+ import * as fs from 'fs';
15
+ import { promises, createWriteStream, existsSync, readdirSync, rmSync, mkdirSync, writeFileSync, copyFileSync, readFileSync } from 'fs';
16
+ import crypto, { createHash } from 'crypto';
17
+ import * as path from 'path';
18
+ import { resolve, join, dirname, basename, relative, extname } from 'path';
19
+ import * as lockfile from 'proper-lockfile';
20
+ import { hostname } from 'os';
21
+ import express from 'express';
22
+ import { createInterface } from 'readline/promises';
23
+ import open from 'open';
24
+ import pkceChallenge from 'pkce-challenge';
25
+ import { startMcpServer } from '@zapier/zapier-sdk-mcp';
26
+ import { buildSync } from 'esbuild';
27
+ import { mkdir, writeFile, access } from 'fs/promises';
28
+ import * as ts from 'typescript';
29
+ import isInstalledGlobally from 'is-installed-globally';
30
+ import { execSync, spawn } from 'child_process';
31
+ import Handlebars from 'handlebars';
32
+ import { fileURLToPath } from 'url';
33
+ import { triggerInboxResolver, DrainTriggerInboxSchema, WatchTriggerInboxSchema, injectCliLogin as injectCliLogin$1, definePlugin as definePlugin$1, omitExports as omitExports$1, zapierExperimentalSdkPlugin, createSdk, CORE_OPTIONS_ID, SDK_OPTIONS_ID, addPlugin } from '@zapier/zapier-sdk/experimental';
34
+ import packageJsonLib, { VersionNotFoundError } from 'package-json';
35
+ import semver from 'semver';
36
+ import * as readline from 'readline';
37
+
38
+ var __defProp = Object.defineProperty;
39
+ var __export = (target, all) => {
40
+ for (var name in all)
41
+ __defProp(target, name, { get: all[name], enumerable: true });
1513
42
  };
1514
43
  function isSelectable(item) {
1515
44
  return !Separator.isSeparator(item) && !item.disabled;
@@ -1529,9 +58,9 @@ function normalizeChoices(choices) {
1529
58
  var theme = makeTheme({
1530
59
  icon: { cursor: "\u276F" },
1531
60
  style: {
1532
- disabled: (text) => chalk.dim(`- ${text}`),
1533
- searchTerm: (text) => chalk.cyan(text),
1534
- keysHelpTip: (keys) => keys.map(([key, action]) => `${chalk.bold(key)} ${chalk.dim(action)}`).join(chalk.dim(" \u2022 "))
61
+ disabled: (text) => chalk8.dim(`- ${text}`),
62
+ searchTerm: (text) => chalk8.cyan(text),
63
+ keysHelpTip: (keys) => keys.map(([key, action]) => `${chalk8.bold(key)} ${chalk8.dim(action)}`).join(chalk8.dim(" \u2022 "))
1535
64
  }
1536
65
  });
1537
66
  var searchSelect = createPrompt(
@@ -1669,7 +198,7 @@ async function promptText({
1669
198
  ]);
1670
199
  return value;
1671
200
  }
1672
- var display = (c) => c.hint ? `${c.label} ${chalk.dim(`(${c.hint})`)}` : c.label;
201
+ var display = (c) => c.hint ? `${c.label} ${chalk8.dim(`(${c.hint})`)}` : c.label;
1673
202
  function buildSelectRows(question, term) {
1674
203
  const row = (name, action) => ({
1675
204
  name,
@@ -1683,8 +212,8 @@ function buildSelectRows(question, term) {
1683
212
  name: display(c),
1684
213
  value: c.value
1685
214
  }));
1686
- const skipRow = offers(question, "skip") ? [row(chalk.dim("Skip (optional)"), "skip")] : [];
1687
- const customRow = offers(question, "custom") ? [row(chalk.dim("Enter a value manually\u2026"), "custom")] : [];
215
+ const skipRow = offers(question, "skip") ? [row(chalk8.dim("Skip (optional)"), "skip")] : [];
216
+ const customRow = offers(question, "custom") ? [row(chalk8.dim("Enter a value manually\u2026"), "custom")] : [];
1688
217
  const committed = !!t || question.search !== void 0;
1689
218
  let rows;
1690
219
  if (!committed) {
@@ -1695,13 +224,13 @@ function buildSelectRows(question, term) {
1695
224
  rows = [...customRow, ...skipRow];
1696
225
  }
1697
226
  if (offers(question, "search"))
1698
- rows.push(row(chalk.cyan("Search again\u2026"), "search"));
227
+ rows.push(row(chalk8.cyan("Search again\u2026"), "search"));
1699
228
  if (offers(question, "next_page"))
1700
- rows.push(row(chalk.dim("Load more\u2026"), "next_page"));
1701
- if (offers(question, "retry")) rows.push(row(chalk.yellow("Retry"), "retry"));
1702
- if (offers(question, "cancel")) rows.push(row(chalk.dim("Cancel"), "cancel"));
229
+ rows.push(row(chalk8.dim("Load more\u2026"), "next_page"));
230
+ if (offers(question, "retry")) rows.push(row(chalk8.yellow("Retry"), "retry"));
231
+ if (offers(question, "cancel")) rows.push(row(chalk8.dim("Cancel"), "cancel"));
1703
232
  for (const note of question.notes ?? [])
1704
- rows.push({ name: chalk.dim(note), value: note, disabled: true });
233
+ rows.push({ name: chalk8.dim(note), value: note, disabled: true });
1705
234
  return rows;
1706
235
  }
1707
236
  function foldPage(acc, question, field) {
@@ -1751,12 +280,12 @@ async function answerSelect(question, field, box, failed = false) {
1751
280
  })),
1752
281
  ...offers(question, "next_page") ? [
1753
282
  {
1754
- name: chalk.dim("Load more\u2026"),
283
+ name: chalk8.dim("Load more\u2026"),
1755
284
  value: { action: "next_page" }
1756
285
  }
1757
286
  ] : [],
1758
287
  ...(question.notes ?? []).map((note) => ({
1759
- name: chalk.dim(note),
288
+ name: chalk8.dim(note),
1760
289
  value: note,
1761
290
  disabled: true
1762
291
  }))
@@ -1827,14 +356,14 @@ async function answerSelect(question, field, box, failed = false) {
1827
356
  case "retry":
1828
357
  return { type: "retry" };
1829
358
  case "skip":
1830
- printAnswered(view.message, chalk.dim("(skipped)"));
359
+ printAnswered(view.message, chalk8.dim("(skipped)"));
1831
360
  return { type: "skip" };
1832
361
  case "cancel":
1833
362
  return { type: "cancel" };
1834
363
  }
1835
364
  }
1836
365
  function printAnswered(message, label) {
1837
- console.log(`${chalk.green("\u2714")} ${message} ${chalk.cyan(label)}`);
366
+ console.log(`${chalk8.green("\u2714")} ${message} ${chalk8.cyan(label)}`);
1838
367
  }
1839
368
  async function answerInput(question) {
1840
369
  const message = question.placeholder ? question.message.replace(/:?\s*$/, ` (${question.placeholder}):`) : question.message;
@@ -1877,7 +406,7 @@ function createCliAnswer() {
1877
406
  return ({ result }) => {
1878
407
  if (result.error !== void 0) {
1879
408
  const message = typeof result.error === "string" ? result.error : result.error.message;
1880
- console.log(chalk.yellow(`! ${message}`));
409
+ console.log(chalk8.yellow(`! ${message}`));
1881
410
  }
1882
411
  const question = result.question;
1883
412
  const field = question.path.length ? question.path.join(".") : "value";
@@ -1891,6 +420,49 @@ function createCliAnswer() {
1891
420
  }
1892
421
  };
1893
422
  }
423
+ var ZapierCliError = class extends ZapierError {
424
+ };
425
+ var ZapierCliUserCancellationError = class extends ZapierCliError {
426
+ constructor(message = "Operation cancelled by user") {
427
+ super(message);
428
+ this.name = "ZapierCliUserCancellationError";
429
+ this.code = "ZAPIER_CLI_USER_CANCELLATION";
430
+ this.exitCode = 0;
431
+ }
432
+ };
433
+ var ZapierCliExitError = class extends ZapierCliError {
434
+ constructor(message, exitCode = 1) {
435
+ super(message);
436
+ this.name = "ZapierCliExitError";
437
+ this.code = "ZAPIER_CLI_EXIT";
438
+ this.exitCode = exitCode;
439
+ }
440
+ };
441
+ var ZapierCliValidationError = class _ZapierCliValidationError extends ZapierCliError {
442
+ constructor(message, options = {}) {
443
+ super(message);
444
+ this.exitCode = 1;
445
+ this.name = options.name ?? "ZapierCliValidationError";
446
+ this.code = options.code ?? "ZAPIER_CLI_VALIDATION_ERROR";
447
+ }
448
+ withMessage(message) {
449
+ return new _ZapierCliValidationError(message, {
450
+ name: this.name,
451
+ code: this.code
452
+ });
453
+ }
454
+ };
455
+ var ZapierCliMissingParametersError = class extends ZapierCliError {
456
+ constructor(params) {
457
+ super(
458
+ `Missing required parameters: ${params.map((p) => p.name).join(", ")}`
459
+ );
460
+ this.name = "ZapierCliMissingParametersError";
461
+ this.code = "ZAPIER_CLI_MISSING_PARAMETERS";
462
+ this.exitCode = 1;
463
+ this.params = params;
464
+ }
465
+ };
1894
466
 
1895
467
  // src/utils/cli-options.ts
1896
468
  var RESERVED_CLI_OPTIONS = [
@@ -1922,7 +494,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
1922
494
 
1923
495
  // package.json
1924
496
  var package_default = {
1925
- version: "0.66.2"};
497
+ version: "0.66.3"};
1926
498
 
1927
499
  // src/telemetry/builders.ts
1928
500
  function createCliBaseEvent(context = {}) {
@@ -2009,7 +581,7 @@ async function formatItemsFromSchema(_functionInfo, items, startingNumber = 0, o
2009
581
  formatItemsGeneric(items, startingNumber);
2010
582
  }
2011
583
  function formatSingleItem(formatted, itemNumber) {
2012
- let titleLine = `${chalk.gray(`${itemNumber + 1}.`)} ${chalk.cyan(formatted.title)}`;
584
+ let titleLine = `${chalk8.gray(`${itemNumber + 1}.`)} ${chalk8.cyan(formatted.title)}`;
2013
585
  const subtitleParts = [];
2014
586
  if (formatted.hint !== void 0) {
2015
587
  subtitleParts.push(
@@ -2027,11 +599,11 @@ function formatSingleItem(formatted, itemNumber) {
2027
599
  }
2028
600
  const uniqueParts = [...new Set(subtitleParts)];
2029
601
  if (uniqueParts.length > 0) {
2030
- titleLine += ` ${chalk.gray(`(${uniqueParts.join(", ")})`)}`;
602
+ titleLine += ` ${chalk8.gray(`(${uniqueParts.join(", ")})`)}`;
2031
603
  }
2032
604
  console.log(titleLine);
2033
605
  if (formatted.description) {
2034
- console.log(` ${chalk.dim(formatted.description)}`);
606
+ console.log(` ${chalk8.dim(formatted.description)}`);
2035
607
  }
2036
608
  if (formatted.raw !== void 0) {
2037
609
  formatJsonOutput(formatted.raw);
@@ -2042,7 +614,7 @@ function formatSingleItem(formatted, itemNumber) {
2042
614
  if (detail.label) {
2043
615
  const isMultiline = detail.text.includes("\n");
2044
616
  if (isMultiline) {
2045
- console.log(` ${chalk.gray(detail.label + ":")}`);
617
+ console.log(` ${chalk8.gray(detail.label + ":")}`);
2046
618
  const displayText = formatDetailText(
2047
619
  detail.text,
2048
620
  DETAIL_INDENT + " "
@@ -2051,7 +623,7 @@ function formatSingleItem(formatted, itemNumber) {
2051
623
  console.log(`${DETAIL_INDENT} ${styledText}`);
2052
624
  } else {
2053
625
  const styledValue = applyStyle(detail.text, detail.style);
2054
- console.log(` ${chalk.gray(detail.label + ":")} ${styledValue}`);
626
+ console.log(` ${chalk8.gray(detail.label + ":")} ${styledValue}`);
2055
627
  }
2056
628
  } else {
2057
629
  const displayText = formatDetailText(detail.text, DETAIL_INDENT);
@@ -2075,16 +647,16 @@ function formatDetailText(text, indent = DETAIL_INDENT) {
2075
647
  function applyStyle(value, style) {
2076
648
  switch (style) {
2077
649
  case "dim":
2078
- return chalk.dim(value);
650
+ return chalk8.dim(value);
2079
651
  case "accent":
2080
- return chalk.magenta(value);
652
+ return chalk8.magenta(value);
2081
653
  case "warning":
2082
- return chalk.red(value);
654
+ return chalk8.red(value);
2083
655
  case "success":
2084
- return chalk.green(value);
656
+ return chalk8.green(value);
2085
657
  case "normal":
2086
658
  default:
2087
- return chalk.blue(value);
659
+ return chalk8.blue(value);
2088
660
  }
2089
661
  }
2090
662
  function convertGenericItemToFormattedItem(item) {
@@ -2112,15 +684,15 @@ function formatMissingParamsError(error) {
2112
684
  return [
2113
685
  "Missing required parameters:",
2114
686
  ...error.params.map(
2115
- ({ name, isPositional: isPositional3 }) => isPositional3 ? ` \u2022 <${toKebabCase(name)}>` : ` \u2022 --${toKebabCase(name)}`
687
+ ({ name, isPositional: isPositional2 }) => isPositional2 ? ` \u2022 <${toKebabCase(name)}>` : ` \u2022 --${toKebabCase(name)}`
2116
688
  )
2117
689
  ].join("\n");
2118
690
  }
2119
691
  function buildJsonErrors(error) {
2120
692
  if (error instanceof ZapierCliMissingParametersError) {
2121
- return error.params.map(({ name, isPositional: isPositional3 }) => ({
693
+ return error.params.map(({ name, isPositional: isPositional2 }) => ({
2122
694
  code: error.code,
2123
- message: isPositional3 ? `<${toKebabCase(name)}> is required in non-interactive mode` : `--${toKebabCase(name)} is required in non-interactive mode`
695
+ message: isPositional2 ? `<${toKebabCase(name)}> is required in non-interactive mode` : `--${toKebabCase(name)} is required in non-interactive mode`
2124
696
  }));
2125
697
  }
2126
698
  const code = error instanceof ZapierError ? error.code : "UNKNOWN_ERROR";
@@ -2228,10 +800,10 @@ function createInteractiveRenderer(context = {}) {
2228
800
  const obj = item;
2229
801
  const name = obj?.name || obj?.key || obj?.id || "Item";
2230
802
  console.log(
2231
- `${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(String(name))}`
803
+ `${chalk8.gray(`${startingNumber + index + 1}.`)} ${chalk8.cyan(String(name))}`
2232
804
  );
2233
805
  if (obj?.description)
2234
- console.log(` ${chalk.dim(String(obj.description))}`);
806
+ console.log(` ${chalk8.dim(String(obj.description))}`);
2235
807
  console.log();
2236
808
  });
2237
809
  }
@@ -2242,35 +814,35 @@ function createInteractiveRenderer(context = {}) {
2242
814
  if (!(Symbol.asyncIterator in Object(source))) {
2243
815
  const items = source?.data;
2244
816
  if (!Array.isArray(items) || items.length === 0) {
2245
- console.log(chalk.yellow(`No ${itemName} found.`));
817
+ console.log(chalk8.yellow(`No ${itemName} found.`));
2246
818
  return;
2247
819
  }
2248
820
  await renderItemsForDisplay(items, functionInfo, 0);
2249
- console.log(chalk.green(`
821
+ console.log(chalk8.green(`
2250
822
  \u2705 Showing ${items.length} ${itemName}`));
2251
823
  return;
2252
824
  }
2253
825
  let totalShown = 0;
2254
826
  let pageCount = 0;
2255
- console.log(chalk.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
827
+ console.log(chalk8.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
2256
828
  `));
2257
829
  for await (const page of source) {
2258
830
  const items = page.data ?? [];
2259
831
  pageCount++;
2260
832
  if (items.length === 0 && pageCount === 1) {
2261
- console.log(chalk.yellow(`No ${itemName} found.`));
833
+ console.log(chalk8.yellow(`No ${itemName} found.`));
2262
834
  return;
2263
835
  }
2264
836
  if (items.length === 0) break;
2265
837
  if (pageCount > 1) {
2266
838
  console.clear();
2267
- console.log(chalk.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
839
+ console.log(chalk8.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
2268
840
  `));
2269
841
  }
2270
842
  await renderItemsForDisplay(items, functionInfo, totalShown);
2271
843
  totalShown += items.length;
2272
844
  console.log(
2273
- chalk.green(
845
+ chalk8.green(
2274
846
  `
2275
847
  \u2705 Showing ${totalShown} ${itemName} (page ${pageCount})`
2276
848
  )
@@ -2289,7 +861,7 @@ function createInteractiveRenderer(context = {}) {
2289
861
  break;
2290
862
  }
2291
863
  }
2292
- console.log(chalk.gray(`
864
+ console.log(chalk8.gray(`
2293
865
  \u{1F4C4} Finished browsing ${itemName}`));
2294
866
  },
2295
867
  async renderCollectedList(items, { maxItems, userSpecifiedMaxItems, functionInfo } = {}) {
@@ -2299,30 +871,30 @@ function createInteractiveRenderer(context = {}) {
2299
871
  }
2300
872
  const itemName = getItemName(functionInfo);
2301
873
  if (items.length === 0) {
2302
- console.log(chalk.yellow(`No ${itemName} found.`));
874
+ console.log(chalk8.yellow(`No ${itemName} found.`));
2303
875
  return;
2304
876
  }
2305
- console.log(chalk.green(`
877
+ console.log(chalk8.green(`
2306
878
  \u2705 Found ${items.length} ${itemName}:
2307
879
  `));
2308
880
  await renderItemsForDisplay(items, functionInfo);
2309
881
  if (userSpecifiedMaxItems && maxItems) {
2310
882
  console.log(
2311
- chalk.gray(
883
+ chalk8.gray(
2312
884
  `
2313
885
  \u{1F4C4} Showing up to ${maxItems} ${itemName} (--max-items ${maxItems})`
2314
886
  )
2315
887
  );
2316
888
  } else {
2317
- console.log(chalk.gray(`
889
+ console.log(chalk8.gray(`
2318
890
  \u{1F4C4} All available ${itemName} shown`));
2319
891
  }
2320
892
  },
2321
893
  renderItem(value, options) {
2322
894
  if (options?.outputFile) {
2323
895
  const label = options.commandName ? `\u2705 ${options.commandName} completed successfully!` : "\u2705 Done!";
2324
- console.log(chalk.green(label));
2325
- console.log(chalk.gray(`Output written to: ${options.outputFile}`));
896
+ console.log(chalk8.green(label));
897
+ console.log(chalk8.gray(`Output written to: ${options.outputFile}`));
2326
898
  } else {
2327
899
  formatJsonOutput(value);
2328
900
  }
@@ -2332,17 +904,17 @@ function createInteractiveRenderer(context = {}) {
2332
904
  },
2333
905
  renderError(error) {
2334
906
  if (error instanceof ZapierCliMissingParametersError) {
2335
- console.error(chalk.red("\u274C " + formatMissingParamsError(error)));
2336
- console.error("\n" + chalk.dim("Use --help to see available options"));
907
+ console.error(chalk8.red("\u274C " + formatMissingParamsError(error)));
908
+ console.error("\n" + chalk8.dim("Use --help to see available options"));
2337
909
  throw new ZapierCliExitError(error.message, 1);
2338
910
  }
2339
911
  if (error instanceof ZapierError) {
2340
912
  const formattedMessage = formatErrorMessage(error);
2341
- console.error(chalk.red("\u274C Error:"), formattedMessage);
913
+ console.error(chalk8.red("\u274C Error:"), formattedMessage);
2342
914
  throw new ZapierCliExitError(formattedMessage, 1);
2343
915
  }
2344
916
  const msg = error instanceof Error ? error.message : "Unknown error";
2345
- console.error(chalk.red("\u274C Error:"), msg);
917
+ console.error(chalk8.red("\u274C Error:"), msg);
2346
918
  throw new ZapierCliExitError(msg, 1);
2347
919
  }
2348
920
  };
@@ -2458,7 +1030,7 @@ async function promptConfirm(confirmType, itemType) {
2458
1030
  }
2459
1031
  const configOrFn = CONFIRM_MESSAGES[confirmType];
2460
1032
  const { messageBefore, messageAfter } = typeof configOrFn === "function" ? configOrFn(itemType) : configOrFn;
2461
- console.log(chalk.yellow(`
1033
+ console.log(chalk8.yellow(`
2462
1034
  ${messageBefore}
2463
1035
  `));
2464
1036
  const { confirmed } = await inquirer.prompt([
@@ -2482,12 +1054,12 @@ function emitParamDeprecationWarnings({
2482
1054
  if (Array.isArray(value) && value.length === 0) continue;
2483
1055
  console.warn();
2484
1056
  console.warn(
2485
- chalk.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk.yellow(
1057
+ chalk8.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8.yellow(
2486
1058
  ` - \`${toKebabCase(param.name)}\` is deprecated and may be removed in a future release.`
2487
1059
  )
2488
1060
  );
2489
1061
  if (param.deprecationMessage) {
2490
- console.warn(chalk.yellow(` ${param.deprecationMessage}`));
1062
+ console.warn(chalk8.yellow(` ${param.deprecationMessage}`));
2491
1063
  }
2492
1064
  console.warn();
2493
1065
  }
@@ -2526,20 +1098,16 @@ function getAuthFlowIsHeadless({
2526
1098
  if (isCallbackResume && !isHeadless) return null;
2527
1099
  return isHeadless;
2528
1100
  }
2529
- function analyzeZodSchema(schema, functionInfo) {
1101
+ function analyzeZodSchema(schema) {
2530
1102
  const parameters = [];
2531
1103
  const schemaDef = schema._zod?.def;
2532
1104
  if (schemaDef?.type === "effect" && schemaDef.innerType) {
2533
- return analyzeZodSchema(schemaDef.innerType, functionInfo);
1105
+ return analyzeZodSchema(schemaDef.innerType);
2534
1106
  }
2535
1107
  if (schema instanceof z.ZodObject) {
2536
1108
  const shape = schema.shape;
2537
1109
  for (const [key, fieldSchema] of Object.entries(shape)) {
2538
- const param = analyzeZodField(
2539
- key,
2540
- fieldSchema,
2541
- functionInfo
2542
- );
1110
+ const param = analyzeZodField(key, fieldSchema);
2543
1111
  if (param) {
2544
1112
  parameters.push(param);
2545
1113
  }
@@ -2547,7 +1115,7 @@ function analyzeZodSchema(schema, functionInfo) {
2547
1115
  }
2548
1116
  return parameters;
2549
1117
  }
2550
- function analyzeZodField(name, schema, functionInfo) {
1118
+ function analyzeZodField(name, schema) {
2551
1119
  let baseSchema = schema;
2552
1120
  let required = true;
2553
1121
  let defaultValue = void 0;
@@ -2607,10 +1175,6 @@ function analyzeZodField(name, schema, functionInfo) {
2607
1175
  } else if (baseSchema instanceof z.ZodObject || baseSchema instanceof z.ZodRecord) {
2608
1176
  paramType = "object";
2609
1177
  }
2610
- let paramHasResolver = false;
2611
- if (functionInfo?.resolvers?.[name] || functionInfo?.boundResolvers?.[name]) {
2612
- paramHasResolver = true;
2613
- }
2614
1178
  return {
2615
1179
  name,
2616
1180
  type: paramType,
@@ -2618,16 +1182,21 @@ function analyzeZodField(name, schema, functionInfo) {
2618
1182
  description: schema.description,
2619
1183
  default: defaultValue,
2620
1184
  choices,
2621
- hasResolver: paramHasResolver,
2622
1185
  isPositional: isPositional(schema),
2623
1186
  elementType,
2624
1187
  deprecationMessage,
2625
1188
  isDeprecated
2626
1189
  };
2627
1190
  }
2628
- function analyzeInputParameters(inputParameters, functionInfo) {
1191
+ function positionalProjection(schema, positional) {
1192
+ if (!positional?.length || !schema) return [];
1193
+ const shape = schema.shape;
1194
+ if (!shape) return [];
1195
+ return positional.filter((name) => name in shape).map((name) => ({ name, schema: shape[name] }));
1196
+ }
1197
+ function analyzePositionalProjection(projection) {
2629
1198
  const cliParams = [];
2630
- for (const param of inputParameters) {
1199
+ for (const param of projection) {
2631
1200
  let schema = param.schema;
2632
1201
  let isOptional = false;
2633
1202
  if (schema instanceof z.ZodOptional) {
@@ -2637,11 +1206,7 @@ function analyzeInputParameters(inputParameters, functionInfo) {
2637
1206
  if (schema instanceof z.ZodObject) {
2638
1207
  const shape = schema.shape;
2639
1208
  for (const [key, fieldSchema] of Object.entries(shape)) {
2640
- const analyzed = analyzeZodField(
2641
- key,
2642
- fieldSchema,
2643
- functionInfo
2644
- );
1209
+ const analyzed = analyzeZodField(key, fieldSchema);
2645
1210
  if (analyzed) {
2646
1211
  if (isOptional) {
2647
1212
  analyzed.required = false;
@@ -2650,7 +1215,7 @@ function analyzeInputParameters(inputParameters, functionInfo) {
2650
1215
  }
2651
1216
  }
2652
1217
  } else {
2653
- const analyzed = analyzeZodField(param.name, param.schema, functionInfo);
1218
+ const analyzed = analyzeZodField(param.name, param.schema);
2654
1219
  if (analyzed) {
2655
1220
  analyzed.required = !isOptional;
2656
1221
  analyzed.isPositional = true;
@@ -2660,29 +1225,25 @@ function analyzeInputParameters(inputParameters, functionInfo) {
2660
1225
  }
2661
1226
  return cliParams;
2662
1227
  }
2663
- function reconstructPositionalArgs(inputParameters, flatParams) {
2664
- const args = [];
2665
- for (const param of inputParameters) {
2666
- let schema = param.schema;
2667
- if (schema instanceof z.ZodOptional) {
2668
- schema = schema._zod.def.innerType;
2669
- }
2670
- if (schema instanceof z.ZodObject) {
2671
- const shape = schema.shape;
1228
+ function nestPositionalParams(projection, flatParams) {
1229
+ const out2 = {};
1230
+ for (const { name, schema } of projection) {
1231
+ const inner = schema instanceof z.ZodOptional ? schema._zod.def.innerType : schema;
1232
+ if (inner instanceof z.ZodObject) {
2672
1233
  const obj = {};
2673
1234
  let hasValues = false;
2674
- for (const key of Object.keys(shape)) {
1235
+ for (const key of Object.keys(inner.shape)) {
2675
1236
  if (key in flatParams && flatParams[key] !== void 0) {
2676
1237
  obj[key] = flatParams[key];
2677
1238
  hasValues = true;
2678
1239
  }
2679
1240
  }
2680
- args.push(hasValues ? obj : void 0);
2681
- } else {
2682
- args.push(flatParams[param.name]);
1241
+ if (hasValues) out2[name] = obj;
1242
+ } else if (flatParams[name] !== void 0) {
1243
+ out2[name] = flatParams[name];
2683
1244
  }
2684
1245
  }
2685
- return args;
1246
+ return out2;
2686
1247
  }
2687
1248
  function methodNameToCliCommand(methodName) {
2688
1249
  return toKebabCase(methodName);
@@ -2694,7 +1255,7 @@ function generateCliCommands(program2, sdk) {
2694
1255
  }
2695
1256
  const registry = sdk.getRegistry({ package: "cli" });
2696
1257
  registry.functions.forEach((fnInfo) => {
2697
- if (!fnInfo.inputSchema && !fnInfo.inputParameters) {
1258
+ if (!fnInfo.inputSchema) {
2698
1259
  console.warn(`Schema not found for ${fnInfo.name}`);
2699
1260
  return;
2700
1261
  }
@@ -2764,12 +1325,11 @@ function generateCliCommands(program2, sdk) {
2764
1325
  });
2765
1326
  }
2766
1327
  function createCommandConfig(cliCommandName, functionInfo, sdk) {
2767
- const usesInputParameters = !!functionInfo.inputParameters;
2768
1328
  const schema = functionInfo.inputSchema;
2769
- const parameters = usesInputParameters ? analyzeInputParameters(functionInfo.inputParameters, functionInfo) : analyzeZodSchema(schema, functionInfo);
2770
- if (functionInfo.boundResolvers && Object.keys(functionInfo.boundResolvers).length > 0) {
2771
- for (const param of parameters) param.hasResolver = true;
2772
- }
1329
+ const projection = positionalProjection(schema, functionInfo.positional);
1330
+ const usesPositionalProjection = projection.length > 0;
1331
+ const parameters = usesPositionalProjection ? analyzePositionalProjection(projection) : analyzeZodSchema(schema);
1332
+ for (const param of parameters) param.promptable = true;
2773
1333
  const schemaAliases = getSchemaAliases(schema);
2774
1334
  if (schemaAliases) {
2775
1335
  const aliasedNames = new Set(Object.keys(schemaAliases));
@@ -2819,72 +1379,55 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
2819
1379
  }
2820
1380
  }
2821
1381
  }
2822
- const boundResolvers = functionInfo.boundResolvers;
2823
- if (boundResolvers && Object.keys(boundResolvers).length > 0) {
2824
- const seedInput = Object.fromEntries(
2825
- Object.entries(rawParams).filter(([, v]) => v !== void 0)
2826
- );
2827
- const controller = createController(sdk);
2828
- const spinner = promptingEnabled && !options.debug ? ora({ text: "", spinner: "dots" }) : void 0;
2829
- let resolved;
2830
- try {
2831
- const isRegisteredPositional = (name) => {
2832
- const p = parameters.find((param) => param.name === name);
2833
- return !!p && takesPositionalSlot(p);
2834
- };
2835
- spinner?.start();
2836
- resolved = await controller.resolve({
2837
- method: functionInfo.name,
2838
- input: seedInput,
2839
- answer: spinner ? withEngineSpinner(createCliAnswer(), spinner) : promptingEnabled ? createCliAnswer() : ({ state }) => {
2840
- const missing = /* @__PURE__ */ new Map();
2841
- missing.set(
2842
- state.current?.join(".") ?? "value",
2843
- isRegisteredPositional(String(state.current?.[0] ?? ""))
2844
- );
2845
- for (const p of parameters) {
2846
- if (!p.required || p.isDeprecated || p.isAlias) continue;
2847
- if (p.name in state.resolved) continue;
2848
- if (state.settled.includes(p.name)) continue;
2849
- if (boundResolvers[p.name]?.type === "constant") continue;
2850
- if (!missing.has(p.name)) {
2851
- missing.set(p.name, isRegisteredPositional(p.name));
2852
- }
1382
+ const resolvers = functionInfo.resolvers;
1383
+ const seedInput = usesPositionalProjection ? nestPositionalParams(projection, rawParams) : Object.fromEntries(
1384
+ Object.entries(rawParams).filter(([, v]) => v !== void 0)
1385
+ );
1386
+ const controller = createController(sdk);
1387
+ const spinner = promptingEnabled && !options.debug ? ora({ text: "", spinner: "dots" }) : void 0;
1388
+ let resolved;
1389
+ try {
1390
+ const isRegisteredPositional = (name) => {
1391
+ const p = parameters.find((param) => param.name === name);
1392
+ return !!p && takesPositionalSlot(p);
1393
+ };
1394
+ spinner?.start();
1395
+ resolved = await controller.resolve({
1396
+ method: functionInfo.name,
1397
+ input: seedInput,
1398
+ answer: spinner ? withEngineSpinner(createCliAnswer(), spinner) : promptingEnabled ? createCliAnswer() : ({ state }) => {
1399
+ const missing = /* @__PURE__ */ new Map();
1400
+ missing.set(
1401
+ state.current?.join(".") ?? "value",
1402
+ isRegisteredPositional(String(state.current?.[0] ?? ""))
1403
+ );
1404
+ for (const p of parameters) {
1405
+ if (!p.required || p.isDeprecated || p.isAlias) continue;
1406
+ if (p.name in state.resolved) continue;
1407
+ if (state.settled.includes(p.name)) continue;
1408
+ if (resolvers?.[p.name]?.type === "constant") continue;
1409
+ if (!missing.has(p.name)) {
1410
+ missing.set(p.name, isRegisteredPositional(p.name));
2853
1411
  }
2854
- throw new ZapierCliMissingParametersError(
2855
- [...missing].map(([name, isPositional3]) => ({
2856
- name,
2857
- isPositional: isPositional3
2858
- }))
2859
- );
2860
- },
2861
- interactive: promptingEnabled
2862
- });
2863
- } catch (err) {
2864
- if (err instanceof CoreCancelledSignal) {
2865
- throw new ZapierCliUserCancellationError();
2866
- }
2867
- throw err;
2868
- } finally {
2869
- spinner?.stop();
1412
+ }
1413
+ throw new ZapierCliMissingParametersError(
1414
+ [...missing].map(([name, isPositional2]) => ({
1415
+ name,
1416
+ isPositional: isPositional2
1417
+ }))
1418
+ );
1419
+ },
1420
+ interactive: promptingEnabled
1421
+ });
1422
+ } catch (err) {
1423
+ if (err instanceof CoreCancelledSignal) {
1424
+ throw new ZapierCliUserCancellationError();
2870
1425
  }
2871
- Object.assign(resolvedParams, resolved);
2872
- } else if (schema && !usesInputParameters) {
2873
- const resolver = new SchemaParameterResolver();
2874
- const resolved = await resolver.resolveParameters(
2875
- schema,
2876
- rawParams,
2877
- sdk,
2878
- functionInfo.name,
2879
- {
2880
- interactiveMode,
2881
- debug: !!options.debug || process.env.DEBUG === "true" || process.argv.includes("--debug")
2882
- }
2883
- );
2884
- Object.assign(resolvedParams, resolved);
2885
- } else {
2886
- Object.assign(resolvedParams, rawParams);
1426
+ throw err;
1427
+ } finally {
1428
+ spinner?.stop();
2887
1429
  }
1430
+ Object.assign(resolvedParams, resolved);
2888
1431
  const confirm = functionInfo.confirm;
2889
1432
  let confirmMessageAfter;
2890
1433
  if (confirm && interactiveMode) {
@@ -2893,7 +1436,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
2893
1436
  functionInfo.itemType
2894
1437
  );
2895
1438
  if (!confirmResult.confirmed) {
2896
- console.log(chalk.yellow("Operation cancelled."));
1439
+ console.log(chalk8.yellow("Operation cancelled."));
2897
1440
  return;
2898
1441
  }
2899
1442
  confirmMessageAfter = confirmResult.messageAfter;
@@ -2921,10 +1464,9 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
2921
1464
  }
2922
1465
  case "single": {
2923
1466
  const callSdkMethod = () => {
2924
- if (usesInputParameters) {
2925
- const positionalArgs = reconstructPositionalArgs(
2926
- functionInfo.inputParameters,
2927
- resolvedParams
1467
+ if (usesPositionalProjection) {
1468
+ const positionalArgs = (functionInfo.positional ?? []).map(
1469
+ (name) => resolvedParams[name]
2928
1470
  );
2929
1471
  return sdkMethod(...positionalArgs);
2930
1472
  }
@@ -2955,7 +1497,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
2955
1497
  renderer.renderItem(normalizedResult.value);
2956
1498
  }
2957
1499
  if (confirmMessageAfter) {
2958
- console.log(chalk.yellow(`
1500
+ console.log(chalk8.yellow(`
2959
1501
  ${confirmMessageAfter}`));
2960
1502
  }
2961
1503
  break;
@@ -3032,7 +1574,7 @@ function addCommand(program2, commandName, config2) {
3032
1574
  let hasPositionalArray = false;
3033
1575
  config2.parameters.forEach((param) => {
3034
1576
  const kebabName = toKebabCase(param.name);
3035
- if (param.hasResolver && param.required) {
1577
+ if (param.promptable && param.required) {
3036
1578
  command.argument(
3037
1579
  `[${kebabName}]`,
3038
1580
  param.description || `${kebabName} parameter`
@@ -4151,20 +2693,20 @@ var getCallablePromise = () => {
4151
2693
  var getCallablePromise_default = getCallablePromise;
4152
2694
  var log = {
4153
2695
  info: (message, ...args) => {
4154
- console.error(chalk.blue("\u2139"), message, ...args);
2696
+ console.error(chalk8.blue("\u2139"), message, ...args);
4155
2697
  },
4156
2698
  error: (message, ...args) => {
4157
- console.error(chalk.red("\u2716"), message, ...args);
2699
+ console.error(chalk8.red("\u2716"), message, ...args);
4158
2700
  },
4159
2701
  success: (message, ...args) => {
4160
- console.error(chalk.green("\u2713"), message, ...args);
2702
+ console.error(chalk8.green("\u2713"), message, ...args);
4161
2703
  },
4162
2704
  warn: (message, ...args) => {
4163
- console.error(chalk.yellow("\u26A0"), message, ...args);
2705
+ console.error(chalk8.yellow("\u26A0"), message, ...args);
4164
2706
  },
4165
2707
  debug: (message, ...args) => {
4166
2708
  if (process.env.DEBUG === "true" || process.argv.includes("--debug")) {
4167
- console.error(chalk.gray("\u{1F41B}"), message, ...args);
2709
+ console.error(chalk8.gray("\u{1F41B}"), message, ...args);
4168
2710
  }
4169
2711
  }
4170
2712
  };
@@ -7321,7 +5863,7 @@ function buildTemplateVariables({
7321
5863
  };
7322
5864
  }
7323
5865
  function cleanupProject({ projectDir }) {
7324
- console.log("\n" + chalk.yellow("!") + " Cleaning up...");
5866
+ console.log("\n" + chalk8.yellow("!") + " Cleaning up...");
7325
5867
  rmSync(projectDir, { recursive: true, force: true });
7326
5868
  }
7327
5869
  async function withInterruptCleanup(cleanup, fn) {
@@ -7531,8 +6073,8 @@ function buildNextSteps({
7531
6073
  }
7532
6074
  function createConsoleDisplayHooks() {
7533
6075
  return {
7534
- onItemComplete: (message) => console.log(" " + chalk.green("\u2713") + " " + chalk.dim(message)),
7535
- onWarn: (message) => console.warn(chalk.yellow("!") + " " + message),
6076
+ onItemComplete: (message) => console.log(" " + chalk8.green("\u2713") + " " + chalk8.dim(message)),
6077
+ onWarn: (message) => console.warn(chalk8.yellow("!") + " " + message),
7536
6078
  onStepStart: ({
7537
6079
  description,
7538
6080
  stepNumber,
@@ -7541,31 +6083,31 @@ function createConsoleDisplayHooks() {
7541
6083
  nonInteractive
7542
6084
  }) => {
7543
6085
  const progressMessage = `${description}...`;
7544
- const stepCounter = chalk.dim(`${stepNumber}/${totalSteps}`);
6086
+ const stepCounter = chalk8.dim(`${stepNumber}/${totalSteps}`);
7545
6087
  if (nonInteractive) {
7546
6088
  console.log(
7547
- "\n" + chalk.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
6089
+ "\n" + chalk8.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
7548
6090
  );
7549
6091
  } else {
7550
6092
  console.log(
7551
- chalk.dim("\u2192") + " " + progressMessage + " " + stepCounter
6093
+ chalk8.dim("\u2192") + " " + progressMessage + " " + stepCounter
7552
6094
  );
7553
6095
  }
7554
6096
  if (command) {
7555
- console.log(" " + chalk.cyan(`$ ${command}`));
6097
+ console.log(" " + chalk8.cyan(`$ ${command}`));
7556
6098
  }
7557
6099
  },
7558
6100
  onStepSuccess: ({ stepNumber, totalSteps }) => console.log(
7559
- "\n" + chalk.green("\u2713") + " " + chalk.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
6101
+ "\n" + chalk8.green("\u2713") + " " + chalk8.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
7560
6102
  ),
7561
6103
  onStepError: ({ description, command, err }) => {
7562
6104
  const detail = err instanceof Error && err.message ? `
7563
- ${chalk.dim(err.message)}` : "";
6105
+ ${chalk8.dim(err.message)}` : "";
7564
6106
  const hint = command ? `
7565
- ${chalk.dim("run manually:")} ${chalk.cyan(`$ ${command}`)}` : "";
6107
+ ${chalk8.dim("run manually:")} ${chalk8.cyan(`$ ${command}`)}` : "";
7566
6108
  console.error(
7567
6109
  `
7568
- ${chalk.red("\u2716")} ${chalk.bold(description)}${chalk.dim(" failed")}${detail}${hint}`
6110
+ ${chalk8.red("\u2716")} ${chalk8.bold(description)}${chalk8.dim(" failed")}${detail}${hint}`
7569
6111
  );
7570
6112
  }
7571
6113
  };
@@ -7577,22 +6119,22 @@ function displaySummaryAndNextSteps({
7577
6119
  packageManager
7578
6120
  }) {
7579
6121
  const formatStatus = (complete) => ({
7580
- icon: complete ? chalk.green("\u2713") : chalk.yellow("!"),
7581
- text: complete ? chalk.green("Setup complete") : chalk.yellow("Setup interrupted")
6122
+ icon: complete ? chalk8.green("\u2713") : chalk8.yellow("!"),
6123
+ text: complete ? chalk8.green("Setup complete") : chalk8.yellow("Setup interrupted")
7582
6124
  });
7583
- const formatNextStep = (step, i) => " " + chalk.dim(`${i + 1}.`) + " " + chalk.bold(step.description);
7584
- const formatCommand = (cmd) => " " + chalk.cyan(`$ ${cmd}`);
7585
- const formatCompletedStep = (step) => " " + chalk.green("\u2713") + " " + step.description;
6125
+ const formatNextStep = (step, i) => " " + chalk8.dim(`${i + 1}.`) + " " + chalk8.bold(step.description);
6126
+ const formatCommand = (cmd) => " " + chalk8.cyan(`$ ${cmd}`);
6127
+ const formatCompletedStep = (step) => " " + chalk8.green("\u2713") + " " + step.description;
7586
6128
  const { execCmd } = getPackageManagerCommands({ packageManager });
7587
6129
  const leftoverSteps = steps.filter(
7588
6130
  (s) => !completedSetupStepIds.includes(s.id)
7589
6131
  );
7590
6132
  const isComplete = leftoverSteps.length === 0;
7591
6133
  const status = formatStatus(isComplete);
7592
- console.log("\n" + chalk.bold("\u276F Summary") + "\n");
7593
- console.log(" " + chalk.dim("Project") + " " + chalk.bold(projectName));
6134
+ console.log("\n" + chalk8.bold("\u276F Summary") + "\n");
6135
+ console.log(" " + chalk8.dim("Project") + " " + chalk8.bold(projectName));
7594
6136
  console.log(
7595
- " " + chalk.dim("Status") + " " + status.icon + " " + status.text
6137
+ " " + chalk8.dim("Status") + " " + status.icon + " " + status.text
7596
6138
  );
7597
6139
  const completedSteps = steps.filter(
7598
6140
  (s) => completedSetupStepIds.includes(s.id)
@@ -7602,7 +6144,7 @@ function displaySummaryAndNextSteps({
7602
6144
  for (const step of completedSteps) console.log(formatCompletedStep(step));
7603
6145
  }
7604
6146
  const nextSteps = buildNextSteps({ projectName, leftoverSteps, execCmd });
7605
- console.log("\n" + chalk.bold("\u276F Next Steps") + "\n");
6147
+ console.log("\n" + chalk8.bold("\u276F Next Steps") + "\n");
7606
6148
  nextSteps.forEach((step, i) => {
7607
6149
  console.log(formatNextStep(step, i));
7608
6150
  if (step.command) console.log(formatCommand(step.command));
@@ -7679,13 +6221,13 @@ function createInteractiveCallback() {
7679
6221
  const attrs = message.message_attributes;
7680
6222
  console.log(
7681
6223
  `
7682
- ${chalk.bold(`Message #${messageNumber}`)} ${chalk.dim(message.id)} ${chalk.dim(`(lease #${attrs.lease_count})`)}`
6224
+ ${chalk8.bold(`Message #${messageNumber}`)} ${chalk8.dim(message.id)} ${chalk8.dim(`(lease #${attrs.lease_count})`)}`
7683
6225
  );
7684
6226
  if (attrs.error_message) {
7685
- console.log(chalk.yellow(` upstream error: ${attrs.error_message}`));
6227
+ console.log(chalk8.yellow(` upstream error: ${attrs.error_message}`));
7686
6228
  }
7687
6229
  if (attrs.possible_duplicate_data) {
7688
- console.log(chalk.yellow(" possible duplicate data"));
6230
+ console.log(chalk8.yellow(" possible duplicate data"));
7689
6231
  }
7690
6232
  while (true) {
7691
6233
  let action;
@@ -7715,7 +6257,7 @@ ${chalk.bold(`Message #${messageNumber}`)} ${chalk.dim(message.id)} ${chalk.dim(
7715
6257
  throw error;
7716
6258
  }
7717
6259
  if (action === "view") {
7718
- console.log(chalk.dim(JSON.stringify(message.payload, null, 2)));
6260
+ console.log(chalk8.dim(JSON.stringify(message.payload, null, 2)));
7719
6261
  continue;
7720
6262
  }
7721
6263
  if (action === "ack") {
@@ -7818,7 +6360,7 @@ function describeReason(reason) {
7818
6360
  }
7819
6361
  function printDrainError(reason, message) {
7820
6362
  console.error(
7821
- chalk.red(`Error processing ${message.id}: ${describeReason(reason)}`)
6363
+ chalk8.red(`Error processing ${message.id}: ${describeReason(reason)}`)
7822
6364
  );
7823
6365
  }
7824
6366
  function printDrainSummary(counts) {
@@ -7828,7 +6370,7 @@ function printDrainSummary(counts) {
7828
6370
  if (skipped > 0) parts.push(`${skipped} skipped`);
7829
6371
  parts.push(`${counts.rejected} rejected`);
7830
6372
  console.log(
7831
- chalk.dim(
6373
+ chalk8.dim(
7832
6374
  `
7833
6375
  Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
7834
6376
  )
@@ -7836,7 +6378,7 @@ Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
7836
6378
  }
7837
6379
  function warnInteractiveContinueOnErrorOverride() {
7838
6380
  console.warn(
7839
- chalk.yellow(
6381
+ chalk8.yellow(
7840
6382
  'Note: continueOnError=false is overridden to true in interactive mode (the "Skip (let lease expire)" choice would otherwise terminate the drain).'
7841
6383
  )
7842
6384
  );
@@ -8162,7 +6704,7 @@ function renderDeprecationNotices() {
8162
6704
  console.error();
8163
6705
  for (const message of messages) {
8164
6706
  for (const line of buildBoxLines(message)) {
8165
- console.error(chalk.red.bold(line));
6707
+ console.error(chalk8.red.bold(line));
8166
6708
  }
8167
6709
  console.error();
8168
6710
  }
@@ -8183,7 +6725,7 @@ function buildBoxLines(message) {
8183
6725
  // package.json with { type: 'json' }
8184
6726
  var package_default2 = {
8185
6727
  name: "@zapier/zapier-sdk-cli",
8186
- version: "0.66.2"};
6728
+ version: "0.66.3"};
8187
6729
 
8188
6730
  // src/sdk.ts
8189
6731
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
@@ -8194,9 +6736,9 @@ var cliCoreOptions = {
8194
6736
  warnedDeprecatedMethods.add(methodName);
8195
6737
  console.warn();
8196
6738
  console.warn(
8197
- chalk.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk.yellow(` - \`${toKebabCase(methodName)}\` is deprecated.`)
6739
+ chalk8.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8.yellow(` - \`${toKebabCase(methodName)}\` is deprecated.`)
8198
6740
  );
8199
- console.warn(chalk.yellow(` ${deprecation.message}`));
6741
+ console.warn(chalk8.yellow(` ${deprecation.message}`));
8200
6742
  console.warn();
8201
6743
  }
8202
6744
  };
@@ -8486,26 +7028,26 @@ function displayUpdateNotification(versionInfo, packageName) {
8486
7028
  if (versionInfo.isDeprecated) {
8487
7029
  console.error();
8488
7030
  console.error(
8489
- chalk.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk.red(
7031
+ chalk8.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8.red(
8490
7032
  ` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
8491
7033
  )
8492
7034
  );
8493
7035
  if (versionInfo.deprecationMessage) {
8494
- console.error(chalk.red(` ${versionInfo.deprecationMessage}`));
7036
+ console.error(chalk8.red(` ${versionInfo.deprecationMessage}`));
8495
7037
  }
8496
- console.error(chalk.red(` Please update to the latest version.`));
7038
+ console.error(chalk8.red(` Please update to the latest version.`));
8497
7039
  console.error();
8498
7040
  }
8499
7041
  if (versionInfo.hasUpdate) {
8500
7042
  console.error();
8501
7043
  console.error(
8502
- chalk.yellow.bold("\u{1F4E6} Update available!") + chalk.yellow(
7044
+ chalk8.yellow.bold("\u{1F4E6} Update available!") + chalk8.yellow(
8503
7045
  ` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
8504
7046
  )
8505
7047
  );
8506
7048
  console.error(
8507
- chalk.yellow(
8508
- ` Run ${chalk.bold(getUpdateCommand(packageName))} to update.`
7049
+ chalk8.yellow(
7050
+ ` Run ${chalk8.bold(getUpdateCommand(packageName))} to update.`
8509
7051
  )
8510
7052
  );
8511
7053
  console.error();
@@ -8613,11 +7155,11 @@ function buildFrameLines(state, frameIndex) {
8613
7155
  const bodyWidth = width - 2;
8614
7156
  const bodyTextWidth = innerWidth - 2;
8615
7157
  const content = [];
8616
- content.push(chalk.bold.cyan("Approval review"));
7158
+ content.push(chalk8.bold.cyan("Approval review"));
8617
7159
  content.push("");
8618
7160
  if (!state.verdict) {
8619
7161
  content.push(
8620
- chalk.yellow(`${SPINNER_FRAMES[frameIndex]} Checking approval...`)
7162
+ chalk8.yellow(`${SPINNER_FRAMES[frameIndex]} Checking approval...`)
8621
7163
  );
8622
7164
  }
8623
7165
  const recentMessages = state.messages.slice(-5);
@@ -8628,13 +7170,13 @@ function buildFrameLines(state, frameIndex) {
8628
7170
  "\n"
8629
7171
  );
8630
7172
  segments.forEach((segment, segmentIndex) => {
8631
- const prefix = segmentIndex === 0 ? chalk.cyan("> ") : " ";
8632
- content.push(`${prefix}${dimmed ? chalk.dim(segment) : segment}`);
7173
+ const prefix = segmentIndex === 0 ? chalk8.cyan("> ") : " ";
7174
+ content.push(`${prefix}${dimmed ? chalk8.dim(segment) : segment}`);
8633
7175
  });
8634
7176
  });
8635
7177
  if (state.streamError) {
8636
7178
  if (hasMessages || !state.verdict) content.push("");
8637
- content.push(chalk.bold.red("Approval stream error"));
7179
+ content.push(chalk8.bold.red("Approval stream error"));
8638
7180
  for (const segment of wrapAnsi3(state.streamError, bodyTextWidth, {
8639
7181
  hard: true
8640
7182
  }).split("\n")) {
@@ -8644,7 +7186,7 @@ function buildFrameLines(state, frameIndex) {
8644
7186
  if (state.verdict) {
8645
7187
  if (hasMessages || state.streamError) content.push("");
8646
7188
  content.push(
8647
- chalk.bold.green(`${state.verdict.icon} ${state.verdict.label}`)
7189
+ chalk8.bold.green(`${state.verdict.icon} ${state.verdict.label}`)
8648
7190
  );
8649
7191
  if (state.verdict.reason) {
8650
7192
  for (const segment of wrapAnsi3(state.verdict.reason, bodyTextWidth, {
@@ -8656,12 +7198,12 @@ function buildFrameLines(state, frameIndex) {
8656
7198
  }
8657
7199
  const pad = (line) => {
8658
7200
  const padding = " ".repeat(Math.max(0, innerWidth - displayWidth(line)));
8659
- return `${chalk.cyan("\u2502")} ${line}${padding} ${chalk.cyan("\u2502")}`;
7201
+ return `${chalk8.cyan("\u2502")} ${line}${padding} ${chalk8.cyan("\u2502")}`;
8660
7202
  };
8661
7203
  return [
8662
- chalk.cyan(`\u256D${"\u2500".repeat(bodyWidth)}\u256E`),
7204
+ chalk8.cyan(`\u256D${"\u2500".repeat(bodyWidth)}\u256E`),
8663
7205
  ...content.map(pad),
8664
- chalk.cyan(`\u2570${"\u2500".repeat(bodyWidth)}\u256F`)
7206
+ chalk8.cyan(`\u2570${"\u2500".repeat(bodyWidth)}\u256F`)
8665
7207
  ];
8666
7208
  }
8667
7209
  function createApprovalProgressRenderer({