@zapier/zapier-sdk 0.85.0 → 0.86.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -32,6 +32,33 @@ function pluralizeLastWord(title) {
32
32
  const words = title.split(" ");
33
33
  return [...words.slice(0, -1), pluralize(words[words.length - 1])].join(" ");
34
34
  }
35
+ function canonicalInputSchema(schema) {
36
+ if (schema instanceof z.ZodUnion) {
37
+ return schema.options[0];
38
+ }
39
+ return schema;
40
+ }
41
+ function withPositional(schema) {
42
+ Object.assign(schema._zod.def, {
43
+ positionalMeta: { positional: true }
44
+ });
45
+ return schema;
46
+ }
47
+ function schemaHasPositionalMeta(schema) {
48
+ return "positionalMeta" in schema._zod.def;
49
+ }
50
+ function isPositional(schema) {
51
+ if (schemaHasPositionalMeta(schema) && schema._zod.def.positionalMeta?.positional) {
52
+ return true;
53
+ }
54
+ if (schema instanceof z.ZodOptional) {
55
+ return isPositional(schema._zod.def.innerType);
56
+ }
57
+ if (schema instanceof z.ZodDefault) {
58
+ return isPositional(schema._zod.def.innerType);
59
+ }
60
+ return false;
61
+ }
35
62
  function resolveCategoryDefinition(ref) {
36
63
  const def = typeof ref === "string" ? { key: ref } : ref;
37
64
  const title = def.title ?? toTitleCase(def.key);
@@ -41,30 +68,25 @@ function resolveCategoryDefinition(ref) {
41
68
  titlePlural: def.titlePlural ?? pluralizeLastWord(title)
42
69
  };
43
70
  }
44
- function canonicalInputSchema(schema) {
45
- if (schema instanceof z.ZodUnion) {
46
- return schema.options[0];
47
- }
48
- return schema;
49
- }
50
71
  function buildRegistry({
51
72
  sdk,
52
73
  meta,
53
74
  formatters,
54
- boundResolvers,
75
+ resolvers,
55
76
  positional,
77
+ skipInputValidation,
56
78
  packageFilter
57
79
  }) {
58
80
  const definitionsByKey = /* @__PURE__ */ new Map();
59
81
  const objectDeclaredKeys = /* @__PURE__ */ new Set();
60
82
  for (const m of Object.values(meta)) {
61
83
  for (const ref of m.categories ?? []) {
62
- const key2 = typeof ref === "string" ? ref : ref.key;
84
+ const key = typeof ref === "string" ? ref : ref.key;
63
85
  if (typeof ref === "object") {
64
- objectDeclaredKeys.add(key2);
65
- definitionsByKey.set(key2, resolveCategoryDefinition(ref));
66
- } else if (!objectDeclaredKeys.has(key2)) {
67
- definitionsByKey.set(key2, resolveCategoryDefinition(ref));
86
+ objectDeclaredKeys.add(key);
87
+ definitionsByKey.set(key, resolveCategoryDefinition(ref));
88
+ } else if (!objectDeclaredKeys.has(key)) {
89
+ definitionsByKey.set(key, resolveCategoryDefinition(ref));
68
90
  }
69
91
  }
70
92
  }
@@ -72,30 +94,29 @@ function buildRegistry({
72
94
  definitionsByKey.set("other", resolveCategoryDefinition("other"));
73
95
  }
74
96
  const knownCategories = Array.from(definitionsByKey.keys());
75
- const functions = Object.keys(meta).filter((key2) => {
76
- const property = sdk[key2];
97
+ const functions = Object.keys(meta).filter((key) => {
98
+ const property = sdk[key];
77
99
  if (typeof property === "function") return true;
78
- const [rootKey] = key2.split(".");
100
+ const [rootKey] = key.split(".");
79
101
  const rootProperty = sdk[rootKey];
80
102
  return typeof rootProperty === "object" && rootProperty !== null;
81
- }).map((key2) => {
82
- const m = meta[key2];
103
+ }).map((key) => {
104
+ const m = meta[key];
83
105
  return {
84
- name: key2,
106
+ name: key,
85
107
  description: m.description,
86
108
  type: m.type,
87
109
  itemType: m.itemType,
88
110
  returnType: m.returnType,
89
111
  inputSchema: canonicalInputSchema(m.inputSchema),
90
- inputParameters: m.inputParameters,
91
112
  outputSchema: m.outputSchema,
92
- positional: positional?.[key2],
113
+ positional: positional?.[key],
114
+ skipInputValidation: skipInputValidation?.[key],
93
115
  categories: (m.categories ?? []).map(
94
116
  (c) => typeof c === "string" ? c : c.key
95
117
  ),
96
- resolvers: m.resolvers,
97
- boundResolvers: boundResolvers?.[key2],
98
- formatter: formatters?.[key2],
118
+ resolvers: resolvers?.[key],
119
+ formatter: formatters?.[key],
99
120
  experimental: m.experimental,
100
121
  packages: m.packages,
101
122
  confirm: m.confirm ?? (m.type === "delete" ? "delete" : void 0),
@@ -510,6 +531,50 @@ function runInMethodScope(fn) {
510
531
  return scope.run({ depth: currentDepth + 1 }, fn);
511
532
  }
512
533
  var runWithTelemetryContext = runInMethodScope;
534
+ var CALL_CONTEXT_BRAND = Symbol("kitcore.callContext");
535
+ function isCallContext(value) {
536
+ return typeof value === "object" && value !== null && value[CALL_CONTEXT_BRAND] === true;
537
+ }
538
+ function generateCallId() {
539
+ try {
540
+ const webCrypto = globalThis.crypto;
541
+ if (webCrypto?.randomUUID) {
542
+ return webCrypto.randomUUID();
543
+ }
544
+ if (webCrypto?.getRandomValues) {
545
+ const bytes = webCrypto.getRandomValues(new Uint8Array(16));
546
+ const hex = Array.from(bytes, (byte, i) => {
547
+ const value = i === 6 ? byte & 15 | 64 : i === 8 ? byte & 63 | 128 : byte;
548
+ return value.toString(16).padStart(2, "0");
549
+ });
550
+ return [
551
+ hex.slice(0, 4).join(""),
552
+ hex.slice(4, 6).join(""),
553
+ hex.slice(6, 8).join(""),
554
+ hex.slice(8, 10).join(""),
555
+ hex.slice(10, 16).join("")
556
+ ].join("-");
557
+ }
558
+ } catch {
559
+ }
560
+ return null;
561
+ }
562
+ function rootCallContext() {
563
+ return {
564
+ callId: generateCallId(),
565
+ depth: 0,
566
+ annotations: {},
567
+ [CALL_CONTEXT_BRAND]: true
568
+ };
569
+ }
570
+ function childCallContext(parent) {
571
+ return {
572
+ callId: parent.callId,
573
+ depth: parent.depth + 1,
574
+ annotations: {},
575
+ [CALL_CONTEXT_BRAND]: true
576
+ };
577
+ }
513
578
  function defaultLogDeprecation({
514
579
  methodName,
515
580
  deprecation
@@ -525,6 +590,9 @@ function resolveCoreOptions(context) {
525
590
  return context.core;
526
591
  }
527
592
  var INTERNAL_CALL = Symbol("kitcore.internalCall");
593
+ function resolveCallContext(secondArg) {
594
+ return isCallContext(secondArg) ? secondArg : rootCallContext();
595
+ }
528
596
  function signalDeprecation(context, methodName, getDeprecation) {
529
597
  if (isInsideObserver()) return;
530
598
  const deprecation = getDeprecation?.();
@@ -554,14 +622,16 @@ function createFunction(coreFn, options) {
554
622
  const functionName = name || coreFn.name;
555
623
  const namedFunctions = {
556
624
  [functionName]: async function(callOptions) {
557
- if (arguments[1] !== INTERNAL_CALL) {
625
+ const internal = arguments[1];
626
+ const context = resolveCallContext(internal);
627
+ if (!isCallContext(internal) && internal !== INTERNAL_CALL) {
558
628
  signalDeprecation(sdk.context, functionName, getDeprecation);
559
629
  }
560
630
  return runInMethodScope(async () => {
561
631
  const startTime = Date.now();
562
632
  const normalizedOptions = callOptions ?? {};
563
633
  const args = [normalizedOptions];
564
- const depth = getCurrentDepth();
634
+ const depth = Math.max(context.depth, getCurrentDepth());
565
635
  const hooks = isInsideObserver() ? void 0 : sdk.context.hooks;
566
636
  const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
567
637
  hooks?.onMethodStart?.({
@@ -580,12 +650,15 @@ function createFunction(coreFn, options) {
580
650
  adaptError
581
651
  }
582
652
  );
583
- result = await coreFn({
584
- ...normalizedOptions,
585
- ...validatedOptions
586
- });
653
+ result = await coreFn(
654
+ {
655
+ ...normalizedOptions,
656
+ ...validatedOptions
657
+ },
658
+ context
659
+ );
587
660
  } else {
588
- result = await coreFn(normalizedOptions);
661
+ result = await coreFn(normalizedOptions, context);
589
662
  }
590
663
  hooks?.onMethodEnd?.({
591
664
  methodName: functionName,
@@ -615,17 +688,19 @@ function createFunction(coreFn, options) {
615
688
  function createRawFunction(coreFn, options) {
616
689
  const { sdk, name, schema, positional, getDeprecation } = options;
617
690
  return function(rawInput) {
618
- if (arguments[1] !== INTERNAL_CALL) {
691
+ const internal = arguments[1];
692
+ const context = resolveCallContext(internal);
693
+ if (!isCallContext(internal) && internal !== INTERNAL_CALL) {
619
694
  signalDeprecation(sdk.context, name, getDeprecation);
620
695
  }
621
696
  return runInMethodScope(() => {
622
697
  const startTime = Date.now();
623
- const depth = getCurrentDepth();
698
+ const depth = Math.max(context.depth, getCurrentDepth());
624
699
  const hooks = isInsideObserver() ? void 0 : sdk.context.hooks;
625
700
  const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
626
701
  const input = schema ? rawInput ?? {} : rawInput;
627
702
  const record = input;
628
- const args = positional ? positional.filter((key2) => record?.[key2] !== void 0).map((key2) => record?.[key2]) : [input];
703
+ const args = positional ? positional.filter((key) => record?.[key] !== void 0).map((key) => record?.[key]) : [input];
629
704
  hooks?.onMethodStart?.({
630
705
  methodName: name,
631
706
  args,
@@ -644,7 +719,7 @@ function createRawFunction(coreFn, options) {
644
719
  };
645
720
  try {
646
721
  const parsed = schema ? validateOptions(schema, input, { adaptError }) : input;
647
- const result = coreFn(parsed);
722
+ const result = coreFn(parsed, context);
648
723
  if (result !== null && typeof result === "object" && typeof result.then === "function") {
649
724
  return result.then(
650
725
  (value) => {
@@ -683,9 +758,9 @@ function createPageFunction(coreFn, {
683
758
  }) {
684
759
  const functionName = coreFn.name + "Page";
685
760
  const namedFunctions = {
686
- [functionName]: async function(options) {
761
+ [functionName]: async function(options, callContext) {
687
762
  try {
688
- const response = await coreFn(options);
763
+ const response = await coreFn(options, callContext);
689
764
  const page = adaptPage ? adaptPage(response) : response;
690
765
  if (!isSdkPage(page)) {
691
766
  throw new Error(
@@ -709,14 +784,16 @@ function createPaginatedFunction(coreFn, options) {
709
784
  const functionName = name || coreFn.name;
710
785
  const namedFunctions = {
711
786
  [functionName]: function(callOptions) {
712
- if (arguments[1] !== INTERNAL_CALL) {
787
+ const internal = arguments[1];
788
+ const context = resolveCallContext(internal);
789
+ if (!isCallContext(internal) && internal !== INTERNAL_CALL) {
713
790
  signalDeprecation(sdk.context, functionName, getDeprecation);
714
791
  }
715
792
  return runInMethodScope(() => {
716
793
  const startTime = Date.now();
717
794
  const normalizedOptions = callOptions ?? {};
718
795
  const args = [normalizedOptions];
719
- const depth = getCurrentDepth();
796
+ const depth = Math.max(context.depth, getCurrentDepth());
720
797
  const hooks = isInsideObserver() ? void 0 : sdk.context.hooks;
721
798
  const adaptError = resolveCoreOptions(sdk.context)?.adaptError;
722
799
  hooks?.onMethodStart?.({
@@ -735,7 +812,11 @@ function createPaginatedFunction(coreFn, options) {
735
812
  ...validatedOptions,
736
813
  pageSize
737
814
  };
738
- const iterator = paginate(pageFunction, optimizedOptions);
815
+ const iterator = paginate(
816
+ (pageOptions) => pageFunction(pageOptions, context),
817
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
818
+ optimizedOptions
819
+ );
739
820
  const firstPagePromise = iterator.next().then((result) => {
740
821
  if (result.done) {
741
822
  throw new Error("Paginate should always iterate at least once");
@@ -884,11 +965,11 @@ var RESERVED_ROOT_KEYS = /* @__PURE__ */ new Set([
884
965
  "context",
885
966
  "getRegistry"
886
967
  ]);
887
- function hasOwn(obj, key2) {
888
- return Object.prototype.hasOwnProperty.call(obj, key2);
968
+ function hasOwn(obj, key) {
969
+ return Object.prototype.hasOwnProperty.call(obj, key);
889
970
  }
890
- function setOwn(target, key2, value) {
891
- Object.defineProperty(target, key2, {
971
+ function setOwn(target, key, value) {
972
+ Object.defineProperty(target, key, {
892
973
  value,
893
974
  enumerable: true,
894
975
  configurable: true,
@@ -900,31 +981,31 @@ function checkCollisions(target, source, kind, callerLabel, override) {
900
981
  checkRootKeyCollisions(target, Object.keys(source), override, callerLabel);
901
982
  return;
902
983
  }
903
- for (const key2 of Object.keys(source)) {
904
- if (!override && hasOwn(target, key2)) {
984
+ for (const key of Object.keys(source)) {
985
+ if (!override && hasOwn(target, key)) {
905
986
  throw new Error(
906
- `${callerLabel}: duplicate ${kind} "${key2}". If the override is intentional, pass { override: true } in the options.`
987
+ `${callerLabel}: duplicate ${kind} "${key}". If the override is intentional, pass { override: true } in the options.`
907
988
  );
908
989
  }
909
990
  }
910
991
  }
911
992
  function checkRootKeyCollisions(target, keys, override, callerLabel) {
912
- for (const key2 of keys) {
913
- if (RESERVED_ROOT_KEYS.has(key2)) {
993
+ for (const key of keys) {
994
+ if (RESERVED_ROOT_KEYS.has(key)) {
914
995
  throw new Error(
915
- `${callerLabel}: plugin attempted to register reserved root key "${key2}". The SDK uses this key for its own accessor; rename the plugin's method.`
996
+ `${callerLabel}: plugin attempted to register reserved root key "${key}". The SDK uses this key for its own accessor; rename the plugin's method.`
916
997
  );
917
998
  }
918
- if (!override && hasOwn(target, key2)) {
999
+ if (!override && hasOwn(target, key)) {
919
1000
  throw new Error(
920
- `${callerLabel}: duplicate root key "${key2}". If the override is intentional, pass { override: true } in the options.`
1001
+ `${callerLabel}: duplicate root key "${key}". If the override is intentional, pass { override: true } in the options.`
921
1002
  );
922
1003
  }
923
1004
  }
924
1005
  }
925
1006
  function applyOwnProperties(target, source) {
926
- for (const key2 of Object.keys(source)) {
927
- setOwn(target, key2, source[key2]);
1007
+ for (const key of Object.keys(source)) {
1008
+ setOwn(target, key, source[key]);
928
1009
  }
929
1010
  }
930
1011
  function createPluginAccumulator(initialProperties = {}, initialContext = {}) {
@@ -1138,7 +1219,6 @@ var LEAF_META_KEYS = [
1138
1219
  "itemType",
1139
1220
  "returnType",
1140
1221
  "outputSchema",
1141
- "inputParameters",
1142
1222
  "packages",
1143
1223
  "experimental",
1144
1224
  "confirm",
@@ -1175,8 +1255,8 @@ function normalizeImports(deps) {
1175
1255
  }
1176
1256
  function collectLeafMeta(config) {
1177
1257
  let meta;
1178
- for (const key2 of LEAF_META_KEYS) {
1179
- if (config[key2] !== void 0) (meta ?? (meta = {}))[key2] = config[key2];
1258
+ for (const key of LEAF_META_KEYS) {
1259
+ if (config[key] !== void 0) (meta ?? (meta = {}))[key] = config[key];
1180
1260
  }
1181
1261
  return meta;
1182
1262
  }
@@ -1259,7 +1339,8 @@ function defineResolver(config) {
1259
1339
  type: "object",
1260
1340
  properties: config.properties,
1261
1341
  definitions: config.definitions,
1262
- getProperties: config.getProperties
1342
+ getProperties: config.getProperties,
1343
+ additionalKeys: config.additionalKeys
1263
1344
  };
1264
1345
  case "array":
1265
1346
  return {
@@ -1562,7 +1643,7 @@ function normalizeFormatter(entry, sdk) {
1562
1643
  const legacy = entry.meta?.formatter;
1563
1644
  return legacy ? adaptLegacyFormatter(legacy, sdk) : void 0;
1564
1645
  }
1565
- function normalizeBoundResolvers(entry) {
1646
+ function normalizeResolvers(entry) {
1566
1647
  if (entry.pluginType !== "method") return void 0;
1567
1648
  return entry.resolvers;
1568
1649
  }
@@ -1603,17 +1684,20 @@ function collectSurfaceProjection(context, formatterSdk) {
1603
1684
  foldDynamicMembers(entry, surfaceBindings, meta);
1604
1685
  }
1605
1686
  const formatters = {};
1606
- const boundResolvers = {};
1687
+ const resolvers = {};
1607
1688
  const positional = {};
1689
+ const skipInputValidation = {};
1608
1690
  for (const [binding, entry] of Object.entries(entries)) {
1609
1691
  const f = normalizeFormatter(entry, formatterSdk);
1610
1692
  if (f) formatters[binding] = f;
1611
- const r = normalizeBoundResolvers(entry);
1612
- if (r) boundResolvers[binding] = r;
1693
+ const r = normalizeResolvers(entry);
1694
+ if (r) resolvers[binding] = r;
1613
1695
  const p = methodPositional(entry);
1614
1696
  if (p) positional[binding] = p;
1697
+ if (entry.pluginType === "method" && entry.skipInputValidation)
1698
+ skipInputValidation[binding] = true;
1615
1699
  }
1616
- return { meta, formatters, boundResolvers, positional };
1700
+ return { meta, formatters, resolvers, positional, skipInputValidation };
1617
1701
  }
1618
1702
  function buildSurfaceRegistry(context, packageFilter) {
1619
1703
  const surface = {};
@@ -1666,6 +1750,11 @@ function nestedResolvers(resolver) {
1666
1750
  for (const field of Object.values(resolver.properties ?? {})) {
1667
1751
  if (!isResolverRef(field.resolver)) out.push(field.resolver);
1668
1752
  }
1753
+ const ak = resolver.additionalKeys;
1754
+ if (ak) {
1755
+ if (!isResolverRef(ak.values)) out.push(ak.values);
1756
+ if (ak.keys && !isResolverRef(ak.keys)) out.push(ak.keys);
1757
+ }
1669
1758
  out.push(...Object.values(resolver.definitions ?? {}));
1670
1759
  } else if (resolver.type === "array") {
1671
1760
  if (!isResolverRef(resolver.items)) out.push(resolver.items);
@@ -1790,16 +1879,16 @@ function collectPlugins(root, materialized = /* @__PURE__ */ new Set(), configur
1790
1879
  }
1791
1880
  return byId;
1792
1881
  }
1793
- function bindValue(target, key2, entry, callType = "surface") {
1882
+ function bindValue(target, key, entry, callType = "surface", ctx) {
1794
1883
  if (entry.pluginType === "property" && entry.getValue) {
1795
- Object.defineProperty(target, key2, {
1884
+ Object.defineProperty(target, key, {
1796
1885
  get: entry.getValue,
1797
1886
  enumerable: true,
1798
1887
  configurable: true
1799
1888
  });
1800
1889
  } else {
1801
- const value = callType === "internal" && entry.pluginType === "method" ? entry.internalValue ?? entry.value : entry.value;
1802
- Object.defineProperty(target, key2, {
1890
+ const value = callType === "internal" && entry.pluginType === "method" ? entry.bindInternal?.(ctx) ?? entry.internalValue ?? entry.value : entry.value;
1891
+ Object.defineProperty(target, key, {
1803
1892
  value,
1804
1893
  writable: true,
1805
1894
  enumerable: true,
@@ -1816,7 +1905,7 @@ function buildSurface(context, ...maps) {
1816
1905
  sdk[CONTEXT] = context;
1817
1906
  return sdk;
1818
1907
  }
1819
- function buildImports(plugins, importBindings) {
1908
+ function buildImports(plugins, importBindings, ctx) {
1820
1909
  const imports = {};
1821
1910
  for (const { binding, id, optional } of importBindings) {
1822
1911
  const entry = plugins[id];
@@ -1829,7 +1918,7 @@ function buildImports(plugins, importBindings) {
1829
1918
  });
1830
1919
  continue;
1831
1920
  }
1832
- bindValue(imports, binding, entry, "internal");
1921
+ bindValue(imports, binding, entry, "internal", ctx);
1833
1922
  }
1834
1923
  return imports;
1835
1924
  }
@@ -1908,6 +1997,19 @@ function bindResolver(resolver, plugins) {
1908
1997
  const { getProperties } = resolver;
1909
1998
  if (getProperties)
1910
1999
  bound.getProperties = ({ input }) => getProperties({ imports, input });
2000
+ if (resolver.additionalKeys) {
2001
+ const ak = resolver.additionalKeys;
2002
+ const boundAk = {
2003
+ values: isResolverRef(ak.values) ? ak.values : bindResolver(ak.values, plugins),
2004
+ minEntries: ak.minEntries,
2005
+ maxEntries: ak.maxEntries,
2006
+ keyValueType: ak.keyValueType,
2007
+ valueValueType: ak.valueValueType
2008
+ };
2009
+ if (ak.keys)
2010
+ boundAk.keys = isResolverRef(ak.keys) ? ak.keys : bindResolver(ak.keys, plugins);
2011
+ bound.additionalKeys = boundAk;
2012
+ }
1911
2013
  return bound;
1912
2014
  }
1913
2015
  case "array": {
@@ -1963,8 +2065,8 @@ function bindResolver(resolver, plugins) {
1963
2065
  }
1964
2066
  function bindFields(fields, plugins) {
1965
2067
  const out = {};
1966
- for (const [key2, field] of Object.entries(fields)) {
1967
- out[key2] = {
2068
+ for (const [key, field] of Object.entries(fields)) {
2069
+ out[key] = {
1968
2070
  ...field,
1969
2071
  resolver: isResolverRef(field.resolver) ? field.resolver : bindResolver(field.resolver, plugins)
1970
2072
  };
@@ -1973,8 +2075,8 @@ function bindFields(fields, plugins) {
1973
2075
  }
1974
2076
  function bindDefinitions(definitions, plugins) {
1975
2077
  const out = {};
1976
- for (const [key2, def] of Object.entries(definitions)) {
1977
- out[key2] = bindResolver(def, plugins);
2078
+ for (const [key, def] of Object.entries(definitions)) {
2079
+ out[key] = bindResolver(def, plugins);
1978
2080
  }
1979
2081
  return out;
1980
2082
  }
@@ -2058,6 +2160,7 @@ function buildMethodEntries(descriptors, context, states) {
2058
2160
  name: descriptor.name,
2059
2161
  chain: [],
2060
2162
  inputSchema: descriptor.inputSchema,
2163
+ skipInputValidation: descriptor.skipInputValidation,
2061
2164
  // Derive the presentation type from the output mode when the author did
2062
2165
  // not set one; an explicit meta.type (e.g. "create") still wins.
2063
2166
  meta: out.type === "raw" || descriptor.meta?.type ? descriptor.meta : { ...descriptor.meta, type: out.type },
@@ -2065,17 +2168,17 @@ function buildMethodEntries(descriptors, context, states) {
2065
2168
  // Replaced below; never called.
2066
2169
  value: () => void 0
2067
2170
  };
2068
- const callRun = (input) => descriptor.run({
2069
- imports: buildImports(plugins, descriptor.importBindings),
2171
+ const callRun = (input, ctx) => descriptor.run({
2172
+ imports: buildImports(plugins, descriptor.importBindings, ctx),
2070
2173
  state: states.get(id),
2071
2174
  input
2072
2175
  });
2073
- const fold = (coreFn) => (input) => {
2074
- let next = coreFn;
2176
+ const fold = (coreFn) => (input, ctx) => {
2177
+ let next = (i) => coreFn(i, ctx);
2075
2178
  for (const wrap of entry.chain) {
2076
2179
  const inner = next;
2077
2180
  next = (i) => wrap.run({
2078
- imports: buildImports(plugins, wrap.owner.importBindings),
2181
+ imports: buildImports(plugins, wrap.owner.importBindings, ctx),
2079
2182
  next: inner,
2080
2183
  input: i,
2081
2184
  // Overwritten by the chain item's own closure with the owning
@@ -2099,7 +2202,7 @@ function buildMethodEntries(descriptors, context, states) {
2099
2202
  }
2100
2203
  );
2101
2204
  } else if (out.type === "item") {
2102
- const itemCore = async (input) => callRun(input);
2205
+ const itemCore = async (input, ctx) => callRun(input, ctx);
2103
2206
  entry.value = createFunction(
2104
2207
  fold(itemCore),
2105
2208
  {
@@ -2111,7 +2214,7 @@ function buildMethodEntries(descriptors, context, states) {
2111
2214
  );
2112
2215
  } else {
2113
2216
  entry.value = createRawFunction(
2114
- (input) => fold(callRun)(input),
2217
+ (input, ctx) => fold(callRun)(input, ctx),
2115
2218
  {
2116
2219
  sdk,
2117
2220
  name: descriptor.name,
@@ -2134,11 +2237,15 @@ function buildMethodEntries(descriptors, context, states) {
2134
2237
  });
2135
2238
  return packed;
2136
2239
  };
2240
+ const internalValue = (...args) => canonicalValue(pack(args), INTERNAL_CALL);
2137
2241
  entry.value = (...args) => canonicalValue(pack(args));
2138
- entry.internalValue = (...args) => canonicalValue(pack(args), INTERNAL_CALL);
2242
+ entry.internalValue = internalValue;
2243
+ entry.bindInternal = (ctx) => ctx ? (...args) => canonicalValue(pack(args), childCallContext(ctx)) : internalValue;
2139
2244
  entry.positional = names;
2140
2245
  } else {
2141
- entry.internalValue = (input) => canonicalValue(input, INTERNAL_CALL);
2246
+ const internalValue = (input) => canonicalValue(input, INTERNAL_CALL);
2247
+ entry.internalValue = internalValue;
2248
+ entry.bindInternal = (ctx) => ctx ? (input) => canonicalValue(input, childCallContext(ctx)) : internalValue;
2142
2249
  }
2143
2250
  plugins[id] = entry;
2144
2251
  }
@@ -2378,7 +2485,7 @@ function createSdk(root, options) {
2378
2485
  pluginSurface = {};
2379
2486
  bindValue(pluginSurface, plugin.name, plugins2[plugin.id]);
2380
2487
  }
2381
- for (const key2 of Object.keys(legacyExports)) context.surface[key2] = key2;
2488
+ for (const key of Object.keys(legacyExports)) context.surface[key] = key;
2382
2489
  if (plugin.pluginType === "aggregate") {
2383
2490
  recordExportSurface(context, plugin.exports);
2384
2491
  } else {
@@ -2509,6 +2616,7 @@ function valueTypeOf(inner) {
2509
2616
  if (inner instanceof z.ZodEnum) return "string";
2510
2617
  if (inner instanceof z.ZodArray) return "array";
2511
2618
  if (inner instanceof z.ZodObject) return "object";
2619
+ if (inner instanceof z.ZodRecord) return "object";
2512
2620
  return void 0;
2513
2621
  }
2514
2622
  function staticChoicesOf(inner) {
@@ -2519,7 +2627,8 @@ function staticChoicesOf(inner) {
2519
2627
  return void 0;
2520
2628
  }
2521
2629
  function objectShape(schema) {
2522
- const { inner } = schema ? unwrap(schema) : { inner: void 0 };
2630
+ const canonical = canonicalInputSchema(schema);
2631
+ const { inner } = canonical ? unwrap(canonical) : { inner: void 0 };
2523
2632
  if (inner instanceof z.ZodObject) {
2524
2633
  return inner.shape;
2525
2634
  }
@@ -2541,7 +2650,7 @@ function topoOrder2(specs) {
2541
2650
  }
2542
2651
  function planParameters(entry) {
2543
2652
  const shape = objectShape(entry.inputSchema);
2544
- const resolvers = entry.boundResolvers ?? {};
2653
+ const resolvers = entry.resolvers ?? {};
2545
2654
  const names = shape ? [
2546
2655
  ...Object.keys(shape),
2547
2656
  ...Object.keys(resolvers).filter(
@@ -2577,24 +2686,48 @@ function getAtPath(root, path) {
2577
2686
  }
2578
2687
  return node;
2579
2688
  }
2689
+ function defineOwn(node, key, value) {
2690
+ Object.defineProperty(node, key, {
2691
+ value,
2692
+ writable: true,
2693
+ enumerable: true,
2694
+ configurable: true
2695
+ });
2696
+ }
2580
2697
  function setAtPath(root, path, value) {
2581
2698
  let node = root;
2582
2699
  for (let i = 0; i < path.length - 1; i++) {
2583
2700
  const seg = path[i];
2584
- if (node[seg] == null || typeof node[seg] !== "object") node[seg] = {};
2585
- node = node[seg];
2701
+ const existing = Object.prototype.hasOwnProperty.call(node, seg) ? node[seg] : void 0;
2702
+ if (existing != null && typeof existing === "object") {
2703
+ node = existing;
2704
+ } else {
2705
+ const child = {};
2706
+ defineOwn(node, seg, child);
2707
+ node = child;
2708
+ }
2586
2709
  }
2587
- node[path[path.length - 1]] = value;
2710
+ defineOwn(node, path[path.length - 1], value);
2588
2711
  }
2589
- var key = (path) => path.join(".");
2712
+ var SAFE_SEGMENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
2713
+ var pathToKey = (path) => {
2714
+ let out = "";
2715
+ for (const segment of path) {
2716
+ if (typeof segment === "number") out += `[${segment}]`;
2717
+ else if (SAFE_SEGMENT.test(segment))
2718
+ out += out === "" ? segment : `.${segment}`;
2719
+ else out += `[${JSON.stringify(segment)}]`;
2720
+ }
2721
+ return out;
2722
+ };
2590
2723
  function isSettled(state, path) {
2591
- return state.settled.includes(key(path));
2724
+ return state.settled.includes(pathToKey(path));
2592
2725
  }
2593
2726
  function remember(state, k) {
2594
2727
  if (!state.settled.includes(k)) state.settled.push(k);
2595
2728
  }
2596
2729
  function settle(state, path) {
2597
- remember(state, key(path));
2730
+ remember(state, pathToKey(path));
2598
2731
  }
2599
2732
  function clone(state) {
2600
2733
  return JSON.parse(JSON.stringify(state));
@@ -2609,6 +2742,28 @@ function coerce(leaf, raw) {
2609
2742
  if (raw === "true") return true;
2610
2743
  if (raw === "false") return false;
2611
2744
  }
2745
+ if (leaf.valueType === "object") {
2746
+ const trimmed = raw.trim();
2747
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
2748
+ try {
2749
+ return JSON.parse(trimmed);
2750
+ } catch {
2751
+ return raw;
2752
+ }
2753
+ }
2754
+ return raw;
2755
+ }
2756
+ if (leaf.valueType === "array") {
2757
+ const trimmed = raw.trim();
2758
+ if (trimmed.startsWith("[")) {
2759
+ try {
2760
+ return JSON.parse(trimmed);
2761
+ } catch {
2762
+ return raw;
2763
+ }
2764
+ }
2765
+ return raw;
2766
+ }
2612
2767
  return raw;
2613
2768
  }
2614
2769
  async function validationError(leaf, value, state) {
@@ -2666,27 +2821,6 @@ async function objectChildren(resolver, input) {
2666
2821
  return toLeaf(name, field, resolver.definitions);
2667
2822
  });
2668
2823
  }
2669
- function arrayItem(resolver) {
2670
- const items = resolver.items;
2671
- const valueType = resolver.itemValueType;
2672
- if (isRef(items)) {
2673
- return {
2674
- name: "",
2675
- required: true,
2676
- resolver: resolver.definitions?.[items.ref],
2677
- extraInput: items.input,
2678
- valueType,
2679
- requires: []
2680
- };
2681
- }
2682
- return {
2683
- name: "",
2684
- required: true,
2685
- resolver: items,
2686
- valueType,
2687
- requires: []
2688
- };
2689
- }
2690
2824
  function autoSettles(resolver) {
2691
2825
  return resolver.type === "constant" || resolver.type === "info";
2692
2826
  }
@@ -2706,10 +2840,28 @@ async function leafAt(ctx, path, resolved) {
2706
2840
  const seg = path[i];
2707
2841
  if (typeof seg === "number") {
2708
2842
  if (leaf?.resolver?.type !== "array") return void 0;
2709
- leaf = arrayItem(leaf.resolver);
2843
+ leaf = boundLeaf(
2844
+ "",
2845
+ leaf.resolver.items,
2846
+ leaf.resolver.definitions,
2847
+ leaf.resolver.itemValueType
2848
+ );
2710
2849
  } else {
2711
- leaf = children.find((c) => c.name === seg);
2712
- if (!leaf) return void 0;
2850
+ const parent = leaf;
2851
+ const found = children.find((c) => c.name === seg);
2852
+ if (found) {
2853
+ leaf = found;
2854
+ } else if (parent?.resolver?.type === "object" && parent.resolver.additionalKeys) {
2855
+ const ak = parent.resolver.additionalKeys;
2856
+ leaf = boundLeaf(
2857
+ String(seg),
2858
+ ak.values,
2859
+ parent.resolver.definitions,
2860
+ ak.valueValueType
2861
+ );
2862
+ } else {
2863
+ return void 0;
2864
+ }
2713
2865
  }
2714
2866
  if (i < path.length - 1 && typeof path[i + 1] === "string") {
2715
2867
  if (leaf?.resolver?.type !== "object") return void 0;
@@ -2721,16 +2873,81 @@ async function leafAt(ctx, path, resolved) {
2721
2873
  }
2722
2874
  return leaf;
2723
2875
  }
2876
+ function boundLeaf(name, resolverOrRef, definitions, valueType) {
2877
+ if (isRef(resolverOrRef)) {
2878
+ return {
2879
+ name,
2880
+ required: true,
2881
+ resolver: definitions?.[resolverOrRef.ref],
2882
+ extraInput: resolverOrRef.input,
2883
+ valueType,
2884
+ requires: []
2885
+ };
2886
+ }
2887
+ return {
2888
+ name,
2889
+ required: true,
2890
+ resolver: resolverOrRef,
2891
+ valueType,
2892
+ requires: []
2893
+ };
2894
+ }
2895
+ async function recordInfoAt(ctx, path, resolved) {
2896
+ const leaf = await leafAt(ctx, path, resolved);
2897
+ const resolver = leaf?.resolver;
2898
+ if (resolver?.type !== "object" || !resolver.additionalKeys) {
2899
+ throw new Error(
2900
+ `expected an object resolver with additionalKeys at "${pathToKey(path)}"`
2901
+ );
2902
+ }
2903
+ if (resolver.getProperties) {
2904
+ throw new Error(
2905
+ `object resolver at "${pathToKey(path)}" cannot combine getProperties with additionalKeys`
2906
+ );
2907
+ }
2908
+ const ak = resolver.additionalKeys;
2909
+ const defs = resolver.definitions;
2910
+ const keyLeaf = ak.keys ? boundLeaf("key", ak.keys, defs, ak.keyValueType ?? "string") : {
2911
+ name: "key",
2912
+ required: true,
2913
+ resolver: { type: "static", inputType: "text" },
2914
+ valueType: "string",
2915
+ requires: []
2916
+ };
2917
+ const valueLeaf = boundLeaf("value", ak.values, defs, ak.valueValueType);
2918
+ if (keyLeaf.resolver && keyLeaf.resolver.type !== "static") {
2919
+ throw new Error(
2920
+ `record key resolver at "${pathToKey(path)}" must be a static free-text prompt, not "${keyLeaf.resolver.type}"`
2921
+ );
2922
+ }
2923
+ if (valueLeaf.resolver?.type === "object" || valueLeaf.resolver?.type === "array") {
2924
+ throw new Error(
2925
+ `record value resolver at "${pathToKey(path)}" must be a single value, not "${valueLeaf.resolver.type}"`
2926
+ );
2927
+ }
2928
+ return {
2929
+ min: ak.minEntries ?? 0,
2930
+ max: ak.maxEntries ?? Infinity,
2931
+ keyLeaf,
2932
+ valueLeaf,
2933
+ fixedKeys: Object.keys(resolver.properties ?? {})
2934
+ };
2935
+ }
2724
2936
  async function arrayInfoAt(ctx, path, resolved) {
2725
2937
  const leaf = await leafAt(ctx, path, resolved);
2726
2938
  const resolver = leaf?.resolver;
2727
2939
  if (resolver?.type !== "array") {
2728
- throw new Error(`expected an array resolver at "${key(path)}"`);
2940
+ throw new Error(`expected an array resolver at "${pathToKey(path)}"`);
2729
2941
  }
2730
2942
  return {
2731
2943
  min: resolver.minItems ?? 0,
2732
2944
  max: resolver.maxItems ?? Infinity,
2733
- item: { ...arrayItem(resolver), name: String(path[path.length - 1]) }
2945
+ item: boundLeaf(
2946
+ String(path[path.length - 1]),
2947
+ resolver.items,
2948
+ resolver.definitions,
2949
+ resolver.itemValueType
2950
+ )
2734
2951
  };
2735
2952
  }
2736
2953
  async function firstPage(result) {
@@ -2809,6 +3026,9 @@ var AFFORDANCE = {
2809
3026
  retry: { action: "retry", description: "Retry loading the options" },
2810
3027
  cancel: { action: "cancel", description: "Cancel resolution" }
2811
3028
  };
3029
+ function affordance(base, description) {
3030
+ return { ...base, description };
3031
+ }
2812
3032
  function selectActions(leaf, page, multiple) {
2813
3033
  const searchMode = leaf.resolver?.type === "dynamic" && leaf.resolver.inputType === "search";
2814
3034
  if (searchMode && page.position.search === void 0 && page.items.length === 0) {
@@ -2923,7 +3143,7 @@ async function buildQuestion(leaf, path, input) {
2923
3143
  }
2924
3144
  };
2925
3145
  }
2926
- function collectionQuestion(t) {
3146
+ function arrayItemsQuestion(t) {
2927
3147
  const actions = [AFFORDANCE.add];
2928
3148
  if (t.count >= t.min) actions.push(AFFORDANCE.done);
2929
3149
  return {
@@ -2939,22 +3159,37 @@ function collectionQuestion(t) {
2939
3159
  actions
2940
3160
  };
2941
3161
  }
2942
- function objectGateQuestion(path) {
3162
+ function recordEntriesQuestion(t) {
3163
+ const actions = [
3164
+ affordance(AFFORDANCE.add, "Add another entry")
3165
+ ];
3166
+ if (t.count >= t.min) {
3167
+ actions.push(affordance(AFFORDANCE.done, "Finish the entries"));
3168
+ }
3169
+ return {
3170
+ type: "collection",
3171
+ path: t.path,
3172
+ message: `Add another ${t.path[t.path.length - 1]} entry? (${t.count} so far)`,
3173
+ container: "record",
3174
+ count: t.count,
3175
+ min: t.min,
3176
+ ...Number.isFinite(t.max) ? { max: t.max } : {},
3177
+ actions
3178
+ };
3179
+ }
3180
+ function objectOptionalQuestion(path) {
2943
3181
  return {
2944
3182
  type: "collection",
2945
3183
  path,
2946
3184
  message: `Add ${path[path.length - 1]}?`,
2947
3185
  container: "object",
2948
3186
  actions: [
2949
- {
2950
- action: "add",
2951
- description: "Provide values for these fields"
2952
- },
2953
- { action: "done", description: "Skip these fields" }
3187
+ affordance(AFFORDANCE.add, "Provide values for these fields"),
3188
+ affordance(AFFORDANCE.done, "Skip these fields")
2954
3189
  ]
2955
3190
  };
2956
3191
  }
2957
- function optionalsGateQuestion(path, pending) {
3192
+ function objectOptionalPropertiesQuestion(path, pending) {
2958
3193
  return {
2959
3194
  type: "collection",
2960
3195
  path,
@@ -2971,8 +3206,8 @@ function optionalsGateQuestion(path, pending) {
2971
3206
  ...leaf.valueType ? { valueType: leaf.valueType } : {}
2972
3207
  })),
2973
3208
  actions: [
2974
- { action: "add", description: "Configure the optional fields" },
2975
- { action: "done", description: "Skip the optional fields" }
3209
+ affordance(AFFORDANCE.add, "Configure the optional fields"),
3210
+ affordance(AFFORDANCE.done, "Skip the optional fields")
2976
3211
  ]
2977
3212
  };
2978
3213
  }
@@ -2988,7 +3223,8 @@ function finalize(ctx, resolved) {
2988
3223
  }));
2989
3224
  return { status: "invalid", issues };
2990
3225
  }
2991
- var optionalsMarker = (path) => `${key(path)}?optionals`;
3226
+ var optionalsMarker = (path) => `${pathToKey(path)}?optionals`;
3227
+ var UNSAFE_RECORD_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
2992
3228
  async function findInArray(ctx, state, path) {
2993
3229
  if (isSettled(state, path)) return null;
2994
3230
  if (getAtPath(state.resolved, path) == null)
@@ -3009,7 +3245,28 @@ async function findInArray(ctx, state, path) {
3009
3245
  }
3010
3246
  }
3011
3247
  if (len < min) return descendItem(ctx, state, path, len, item);
3012
- if (len < max) return { kind: "array", path, count: len, min, max };
3248
+ if (len < max) return { type: "array_items", path, count: len, min, max };
3249
+ settle(state, path);
3250
+ return null;
3251
+ }
3252
+ async function findInRecord(ctx, state, path) {
3253
+ if (isSettled(state, path)) return null;
3254
+ if (getAtPath(state.resolved, path) == null)
3255
+ setAtPath(state.resolved, path, {});
3256
+ if (!state.interactive) {
3257
+ settle(state, path);
3258
+ return null;
3259
+ }
3260
+ const { min, max, keyLeaf, fixedKeys } = await recordInfoAt(
3261
+ ctx,
3262
+ path,
3263
+ state.resolved
3264
+ );
3265
+ const container = getAtPath(state.resolved, path);
3266
+ const fixed = new Set(fixedKeys);
3267
+ const count = Object.keys(container).filter((k) => !fixed.has(k)).length;
3268
+ if (count < min) return { type: "record_key", path, leaf: keyLeaf };
3269
+ if (count < max) return { type: "record_entries", path, count, min, max };
3013
3270
  settle(state, path);
3014
3271
  return null;
3015
3272
  }
@@ -3027,10 +3284,10 @@ function seedItemSlot(state, itemPath, item) {
3027
3284
  }
3028
3285
  async function descendItem(ctx, state, arrayPath, index, item) {
3029
3286
  const itemPath = [...arrayPath, index];
3030
- const kind = seedItemSlot(state, itemPath, item);
3031
- if (kind === "object") return findNext(ctx, state, itemPath);
3032
- if (kind === "array") return findInArray(ctx, state, itemPath);
3033
- return { kind: "leaf", path: itemPath, leaf: item };
3287
+ const slotType = seedItemSlot(state, itemPath, item);
3288
+ if (slotType === "object") return findNext(ctx, state, itemPath);
3289
+ if (slotType === "array") return findInArray(ctx, state, itemPath);
3290
+ return { type: "leaf", path: itemPath, leaf: item };
3034
3291
  }
3035
3292
  async function findNext(ctx, state, path = []) {
3036
3293
  const container = getAtPath(state.resolved, path) ?? {};
@@ -3055,7 +3312,7 @@ async function findNext(ctx, state, path = []) {
3055
3312
  const pending = ordered.filter(
3056
3313
  (c) => !c.required && asksUser(c) && isPendingChild(c)
3057
3314
  );
3058
- return { kind: "optionals", path, pending };
3315
+ return { type: "object_optional_properties", path, pending };
3059
3316
  }
3060
3317
  if (leaf.resolver?.type === "object") {
3061
3318
  if (isSettled(state, childPath)) continue;
@@ -3065,7 +3322,7 @@ async function findNext(ctx, state, path = []) {
3065
3322
  settle(state, childPath);
3066
3323
  continue;
3067
3324
  }
3068
- return { kind: "object", path: childPath, leaf };
3325
+ return { type: "object_optional", path: childPath, leaf };
3069
3326
  }
3070
3327
  setAtPath(state.resolved, childPath, {});
3071
3328
  }
@@ -3097,13 +3354,21 @@ async function findNext(ctx, state, path = []) {
3097
3354
  }
3098
3355
  if (container[leaf.name] !== void 0 || isSettled(state, childPath))
3099
3356
  continue;
3100
- return { kind: "leaf", path: childPath, leaf };
3357
+ return { type: "leaf", path: childPath, leaf };
3358
+ }
3359
+ if (inObject && !isSettled(state, path)) {
3360
+ const self = await leafAt(ctx, path, state.resolved);
3361
+ if (self?.resolver?.type === "object" && self.resolver.additionalKeys) {
3362
+ const rec = await findInRecord(ctx, state, path);
3363
+ if (rec) return rec;
3364
+ }
3101
3365
  }
3102
3366
  return null;
3103
3367
  }
3104
3368
  async function askLeaf(state, path, leaf, opts = {}) {
3105
3369
  state.current = path;
3106
- delete state.gate;
3370
+ if (opts.gate) state.gate = opts.gate;
3371
+ else delete state.gate;
3107
3372
  try {
3108
3373
  const { question, pagination } = await buildQuestion(
3109
3374
  leaf,
@@ -3124,6 +3389,28 @@ async function askLeaf(state, path, leaf, opts = {}) {
3124
3389
  return failedResult(state, leaf.name, error);
3125
3390
  }
3126
3391
  }
3392
+ async function askRecordKey(state, path, keyLeaf, opts = {}) {
3393
+ return askLeaf(state, path, keyLeaf, { gate: "record_key", ...opts });
3394
+ }
3395
+ async function autoResolveLeaf(state, path, leaf) {
3396
+ const resolver = leaf.resolver;
3397
+ if (resolver && autoSettles(resolver)) {
3398
+ if (resolver.type === "constant")
3399
+ setAtPath(state.resolved, path, resolver.value);
3400
+ settle(state, path);
3401
+ return true;
3402
+ }
3403
+ const auto = resolver?.type === "dynamic" ? await resolver.tryResolveWithoutPrompt?.({
3404
+ input: mergeInput(state.resolved, leaf.extraInput)
3405
+ }) : void 0;
3406
+ if (auto) {
3407
+ if (auto.resolvedValue !== void 0)
3408
+ setAtPath(state.resolved, path, auto.resolvedValue);
3409
+ settle(state, path);
3410
+ return true;
3411
+ }
3412
+ return false;
3413
+ }
3127
3414
  async function advance(ctx, state) {
3128
3415
  for (; ; ) {
3129
3416
  const target = await findNext(ctx, state);
@@ -3133,54 +3420,56 @@ async function advance(ctx, state) {
3133
3420
  delete state.pagination;
3134
3421
  return { state, result: finalize(ctx, state.resolved) };
3135
3422
  }
3136
- if (target.kind === "array") {
3423
+ if (target.type === "array_items") {
3137
3424
  state.current = target.path;
3138
- state.gate = "array";
3425
+ state.gate = "array_items";
3139
3426
  delete state.pagination;
3140
3427
  return {
3141
3428
  state,
3142
- result: { status: "ask", question: collectionQuestion(target) }
3429
+ result: { status: "ask", question: arrayItemsQuestion(target) }
3143
3430
  };
3144
3431
  }
3145
- if (target.kind === "object") {
3432
+ if (target.type === "object_optional") {
3146
3433
  state.current = target.path;
3147
- state.gate = "entry";
3434
+ state.gate = "object_optional";
3148
3435
  delete state.pagination;
3149
3436
  return {
3150
3437
  state,
3151
- result: { status: "ask", question: objectGateQuestion(target.path) }
3438
+ result: {
3439
+ status: "ask",
3440
+ question: objectOptionalQuestion(target.path)
3441
+ }
3152
3442
  };
3153
3443
  }
3154
- if (target.kind === "optionals") {
3444
+ if (target.type === "object_optional_properties") {
3155
3445
  state.current = target.path;
3156
- state.gate = "optionals";
3446
+ state.gate = "object_optional_properties";
3157
3447
  delete state.pagination;
3158
3448
  return {
3159
3449
  state,
3160
3450
  result: {
3161
3451
  status: "ask",
3162
- question: optionalsGateQuestion(target.path, target.pending)
3452
+ question: objectOptionalPropertiesQuestion(
3453
+ target.path,
3454
+ target.pending
3455
+ )
3163
3456
  }
3164
3457
  };
3165
3458
  }
3166
- const { path, leaf } = target;
3167
- const resolver = leaf.resolver;
3168
- if (resolver && autoSettles(resolver)) {
3169
- if (resolver.type === "constant") {
3170
- setAtPath(state.resolved, path, resolver.value);
3171
- }
3172
- settle(state, path);
3173
- continue;
3459
+ if (target.type === "record_entries") {
3460
+ state.current = target.path;
3461
+ state.gate = "record_entries";
3462
+ delete state.pagination;
3463
+ return {
3464
+ state,
3465
+ result: { status: "ask", question: recordEntriesQuestion(target) }
3466
+ };
3174
3467
  }
3175
- const auto = resolver?.type === "dynamic" ? await resolver.tryResolveWithoutPrompt?.({
3176
- input: mergeInput(state.resolved, leaf.extraInput)
3177
- }) : void 0;
3178
- if (auto) {
3179
- if (auto.resolvedValue !== void 0)
3180
- setAtPath(state.resolved, path, auto.resolvedValue);
3181
- settle(state, path);
3182
- continue;
3468
+ if (target.type === "record_key") {
3469
+ return askRecordKey(state, target.path, target.leaf);
3183
3470
  }
3471
+ const { path, leaf } = target;
3472
+ if (await autoResolveLeaf(state, path, leaf)) continue;
3184
3473
  if (!state.interactive) {
3185
3474
  if (!leaf.required) {
3186
3475
  settle(state, path);
@@ -3213,10 +3502,18 @@ async function step(ctx, prior, action) {
3213
3502
  delete state.pagination;
3214
3503
  return { state, result: { status: "cancelled" } };
3215
3504
  }
3505
+ if (state.gate === "record_key") {
3506
+ return stepRecordKey(ctx, state, action);
3507
+ }
3216
3508
  const path = state.current;
3217
3509
  if (!path) throw new Error("step called with no outstanding question");
3218
3510
  const leaf = await leafAt(ctx, path, state.resolved);
3219
- if (leaf && (action.type === "search" || action.type === "next_page" || action.type === "previous_page" || action.type === "retry")) {
3511
+ if (!leaf) {
3512
+ throw new Error(
3513
+ `no resolver for the outstanding question at "${pathToKey(path)}"`
3514
+ );
3515
+ }
3516
+ if (action.type === "search" || action.type === "next_page" || action.type === "previous_page" || action.type === "retry") {
3220
3517
  return refine(ctx, state, leaf, path, action);
3221
3518
  }
3222
3519
  if (action.type === "add" || action.type === "done") {
@@ -3233,19 +3530,26 @@ async function step(ctx, prior, action) {
3233
3530
  settle(state, path);
3234
3531
  return advance(ctx, state);
3235
3532
  }
3236
- if (gate === "entry") {
3533
+ if (gate === "object_optional") {
3237
3534
  setAtPath(state.resolved, path, {});
3238
3535
  return advance(ctx, state);
3239
3536
  }
3240
- if (gate === "optionals") {
3537
+ if (gate === "object_optional_properties") {
3241
3538
  remember(state, optionalsMarker(path));
3242
3539
  return advance(ctx, state);
3243
3540
  }
3541
+ if (gate === "record_entries") {
3542
+ const { keyLeaf } = await recordInfoAt(ctx, path, state.resolved);
3543
+ return askRecordKey(state, path, keyLeaf);
3544
+ }
3244
3545
  const items = getAtPath(state.resolved, path) ?? [];
3245
3546
  const { item } = await arrayInfoAt(ctx, path, state.resolved);
3246
3547
  const itemPath = [...path, items.length];
3247
- if (seedItemSlot(state, itemPath, item) === "leaf")
3548
+ if (seedItemSlot(state, itemPath, item) === "leaf") {
3549
+ if (await autoResolveLeaf(state, itemPath, item))
3550
+ return advance(ctx, state);
3248
3551
  return askLeaf(state, itemPath, item);
3552
+ }
3249
3553
  return advance(ctx, state);
3250
3554
  }
3251
3555
  if (state.gate) {
@@ -3256,81 +3560,37 @@ async function step(ctx, prior, action) {
3256
3560
  switch (action.type) {
3257
3561
  case "choose":
3258
3562
  case "custom": {
3259
- if (leaf) {
3260
- let error;
3261
- try {
3262
- error = await validationError(leaf, action.value, state);
3263
- } catch (thrown) {
3264
- return failedResult(state, leaf.name, thrown);
3265
- }
3266
- if (error) {
3267
- if (state.pagination && leaf.resolver?.type === "dynamic") {
3268
- try {
3269
- const context = await resolveContext(leaf, state.resolved);
3270
- const page = await fetchListing(
3271
- leaf,
3272
- state.resolved,
3273
- state.pagination.position,
3274
- context
3275
- );
3276
- state.pagination = toPagination(page);
3277
- return {
3278
- state,
3279
- result: {
3280
- status: "ask",
3281
- question: selectQuestion(
3282
- leaf,
3283
- path,
3284
- state.resolved,
3285
- page,
3286
- context
3287
- ),
3288
- error
3289
- }
3290
- };
3291
- } catch (fetchError) {
3292
- state.pagination = failedPagination(
3293
- state.pagination,
3294
- state.pagination.position
3295
- );
3296
- return failedResult(state, leaf.name, fetchError);
3297
- }
3298
- }
3299
- return askLeaf(state, path, leaf, { error });
3563
+ let error;
3564
+ try {
3565
+ error = await validationError(leaf, action.value, state);
3566
+ } catch (thrown) {
3567
+ return failedResult(state, leaf.name, thrown);
3568
+ }
3569
+ if (error) {
3570
+ if (state.pagination && leaf.resolver?.type === "dynamic") {
3571
+ return renderPageAt(state, leaf, path, state.pagination.position, {
3572
+ error
3573
+ });
3300
3574
  }
3575
+ return askLeaf(state, path, leaf, { error });
3301
3576
  }
3302
- setAtPath(
3303
- state.resolved,
3304
- path,
3305
- leaf ? coerce(leaf, action.value) : action.value
3306
- );
3577
+ setAtPath(state.resolved, path, coerce(leaf, action.value));
3307
3578
  break;
3308
3579
  }
3309
3580
  case "skip":
3310
3581
  settle(state, path);
3311
3582
  break;
3312
3583
  default:
3313
- throw new Error(`action "${action.type}" is not supported here`);
3584
+ throw new Error(
3585
+ `action "${action.type}" is not supported here`
3586
+ );
3314
3587
  }
3315
3588
  delete state.current;
3316
3589
  delete state.pagination;
3317
3590
  return advance(ctx, state);
3318
3591
  }
3319
- async function refine(ctx, state, leaf, path, action) {
3320
- const position = positionAfter(state.pagination, action);
3592
+ async function renderPageAt(state, leaf, path, position, opts = {}) {
3321
3593
  try {
3322
- if (action.type === "search") {
3323
- const exact = leaf.resolver?.type === "dynamic" ? await leaf.resolver.tryResolveFromSearch?.({
3324
- input: mergeInput(state.resolved, leaf.extraInput),
3325
- search: action.term
3326
- }) : void 0;
3327
- if (exact) {
3328
- setAtPath(state.resolved, path, coerce(leaf, exact.resolvedValue));
3329
- delete state.current;
3330
- delete state.pagination;
3331
- return advance(ctx, state);
3332
- }
3333
- }
3334
3594
  const context = await resolveContext(leaf, state.resolved);
3335
3595
  const page = await fetchListing(leaf, state.resolved, position, context);
3336
3596
  state.pagination = toPagination(page);
@@ -3338,7 +3598,8 @@ async function refine(ctx, state, leaf, path, action) {
3338
3598
  state,
3339
3599
  result: {
3340
3600
  status: "ask",
3341
- question: selectQuestion(leaf, path, state.resolved, page, context)
3601
+ question: selectQuestion(leaf, path, state.resolved, page, context),
3602
+ ...opts.error ? { error: opts.error } : {}
3342
3603
  }
3343
3604
  };
3344
3605
  } catch (error) {
@@ -3346,6 +3607,65 @@ async function refine(ctx, state, leaf, path, action) {
3346
3607
  return failedResult(state, leaf.name, error);
3347
3608
  }
3348
3609
  }
3610
+ async function refine(ctx, state, leaf, path, action) {
3611
+ const position = positionAfter(state.pagination, action);
3612
+ if (action.type === "search") {
3613
+ try {
3614
+ const exact = leaf.resolver?.type === "dynamic" ? await leaf.resolver.tryResolveFromSearch?.({
3615
+ input: mergeInput(state.resolved, leaf.extraInput),
3616
+ search: action.term
3617
+ }) : void 0;
3618
+ if (exact) {
3619
+ setAtPath(state.resolved, path, coerce(leaf, exact.resolvedValue));
3620
+ delete state.current;
3621
+ delete state.pagination;
3622
+ return advance(ctx, state);
3623
+ }
3624
+ } catch (error) {
3625
+ state.pagination = failedPagination(state.pagination, position);
3626
+ return failedResult(state, leaf.name, error);
3627
+ }
3628
+ }
3629
+ return renderPageAt(state, leaf, path, position);
3630
+ }
3631
+ async function stepRecordKey(ctx, state, action) {
3632
+ const path = state.current;
3633
+ if (!path)
3634
+ throw new Error("record key step called with no outstanding question");
3635
+ const { keyLeaf, valueLeaf } = await recordInfoAt(ctx, path, state.resolved);
3636
+ if (action.type === "skip") {
3637
+ delete state.gate;
3638
+ delete state.current;
3639
+ delete state.pagination;
3640
+ return advance(ctx, state);
3641
+ }
3642
+ if (action.type !== "custom" && action.type !== "choose") {
3643
+ throw new Error(
3644
+ `action "${action.type}" is not supported while entering a record key`
3645
+ );
3646
+ }
3647
+ const raw = Array.isArray(action.value) ? action.value[0] : action.value;
3648
+ const entryKey = String(coerce(keyLeaf, raw));
3649
+ if (entryKey.trim() === "") {
3650
+ return askRecordKey(state, path, keyLeaf, { error: "A key is required." });
3651
+ }
3652
+ if (UNSAFE_RECORD_KEYS.has(entryKey)) {
3653
+ return askRecordKey(state, path, keyLeaf, {
3654
+ error: `"${entryKey}" is not an allowed key.`
3655
+ });
3656
+ }
3657
+ const container = getAtPath(state.resolved, path);
3658
+ if (Object.prototype.hasOwnProperty.call(container, entryKey)) {
3659
+ return askRecordKey(state, path, keyLeaf, {
3660
+ error: `"${entryKey}" is already set.`
3661
+ });
3662
+ }
3663
+ const valuePath = [...path, entryKey];
3664
+ if (await autoResolveLeaf(state, valuePath, valueLeaf)) {
3665
+ return advance(ctx, state);
3666
+ }
3667
+ return askLeaf(state, valuePath, valueLeaf);
3668
+ }
3349
3669
  function failedPagination(pagination, retryPosition) {
3350
3670
  return {
3351
3671
  position: pagination?.position ?? firstPagePosition(),
@@ -3399,7 +3719,7 @@ function projectSummary(entry) {
3399
3719
  };
3400
3720
  }
3401
3721
  function projectMethod(entry) {
3402
- const inputProperties = toJsonSchema(entry.inputSchema)?.properties;
3722
+ const inputProperties = toJsonSchema(canonicalInputSchema(entry.inputSchema))?.properties;
3403
3723
  const parameters = {};
3404
3724
  for (const spec of planParameters(entry).parameters) {
3405
3725
  const dynamic = spec.resolver?.type === "dynamic" ? spec.resolver : void 0;
@@ -3432,7 +3752,12 @@ function createController(sdk) {
3432
3752
  const entry = entryFor(method);
3433
3753
  return {
3434
3754
  method,
3435
- schema: entry.inputSchema,
3755
+ // A method that owns its input validation (`skipInputValidation`, e.g.
3756
+ // fetch) must not be re-validated by the controller's final `safeParse`;
3757
+ // drop the schema so `finalize` returns the resolved input untouched.
3758
+ // Planning still reads `entry.inputSchema` directly, so parameters are
3759
+ // unaffected.
3760
+ schema: entry.skipInputValidation ? void 0 : entry.inputSchema,
3436
3761
  parameters: planParameters(entry).parameters
3437
3762
  };
3438
3763
  }
@@ -3495,27 +3820,6 @@ function createCorePlugin(options) {
3495
3820
  }
3496
3821
  });
3497
3822
  }
3498
- function withPositional(schema) {
3499
- Object.assign(schema._zod.def, {
3500
- positionalMeta: { positional: true }
3501
- });
3502
- return schema;
3503
- }
3504
- function schemaHasPositionalMeta(schema) {
3505
- return "positionalMeta" in schema._zod.def;
3506
- }
3507
- function isPositional(schema) {
3508
- if (schemaHasPositionalMeta(schema) && schema._zod.def.positionalMeta?.positional) {
3509
- return true;
3510
- }
3511
- if (schema instanceof z.ZodOptional) {
3512
- return isPositional(schema._zod.def.innerType);
3513
- }
3514
- if (schema instanceof z.ZodDefault) {
3515
- return isPositional(schema._zod.def.innerType);
3516
- }
3517
- return false;
3518
- }
3519
3823
 
3520
3824
  // src/constants.ts
3521
3825
  var ZAPIER_BASE_URL = globalThis.process?.env?.ZAPIER_BASE_URL || "https://zapier.com";
@@ -4070,8 +4374,8 @@ function censorHeaders(headers) {
4070
4374
  if (!headers) return headers;
4071
4375
  const headersObj = new Headers(headers);
4072
4376
  const authKeys = ["authorization", "x-api-key"];
4073
- for (const [key2, value] of headersObj.entries()) {
4074
- if (authKeys.some((authKey) => key2.toLowerCase() === authKey)) {
4377
+ for (const [key, value] of headersObj.entries()) {
4378
+ if (authKeys.some((authKey) => key.toLowerCase() === authKey)) {
4075
4379
  const spaceIndex = value.indexOf(" ");
4076
4380
  if (spaceIndex > 0 && spaceIndex < value.length - 1) {
4077
4381
  const prefix = value.substring(0, spaceIndex + 1);
@@ -4079,19 +4383,19 @@ function censorHeaders(headers) {
4079
4383
  if (token.length > 12) {
4080
4384
  const start2 = token.substring(0, 4);
4081
4385
  const end = token.substring(token.length - 4);
4082
- headersObj.set(key2, `${prefix}${start2}...${end}`);
4386
+ headersObj.set(key, `${prefix}${start2}...${end}`);
4083
4387
  } else {
4084
4388
  const firstChar = token.charAt(0);
4085
- headersObj.set(key2, `${prefix}${firstChar}...`);
4389
+ headersObj.set(key, `${prefix}${firstChar}...`);
4086
4390
  }
4087
4391
  } else {
4088
4392
  if (value.length > 12) {
4089
4393
  const start2 = value.substring(0, 4);
4090
4394
  const end = value.substring(value.length - 4);
4091
- headersObj.set(key2, `${start2}...${end}`);
4395
+ headersObj.set(key, `${start2}...${end}`);
4092
4396
  } else {
4093
4397
  const firstChar = value.charAt(0);
4094
- headersObj.set(key2, `${firstChar}...`);
4398
+ headersObj.set(key, `${firstChar}...`);
4095
4399
  }
4096
4400
  }
4097
4401
  }
@@ -4742,21 +5046,21 @@ function getClientIdFromCredentials(credentials) {
4742
5046
  function createMemoryCache() {
4743
5047
  const store = /* @__PURE__ */ new Map();
4744
5048
  return {
4745
- async get(key2) {
4746
- const entry = store.get(key2);
5049
+ async get(key) {
5050
+ const entry = store.get(key);
4747
5051
  if (!entry) return void 0;
4748
5052
  if (entry.expiresAt !== void 0 && entry.expiresAt <= Date.now()) {
4749
- store.delete(key2);
5053
+ store.delete(key);
4750
5054
  return void 0;
4751
5055
  }
4752
5056
  return { value: entry.value, expiresAt: entry.expiresAt };
4753
5057
  },
4754
- async set(key2, value, options) {
5058
+ async set(key, value, options) {
4755
5059
  const expiresAt = options?.ttl ? Date.now() + options.ttl * 1e3 : void 0;
4756
- store.set(key2, { value, expiresAt });
5060
+ store.set(key, { value, expiresAt });
4757
5061
  },
4758
- async delete(key2) {
4759
- store.delete(key2);
5062
+ async delete(key) {
5063
+ store.delete(key);
4760
5064
  }
4761
5065
  };
4762
5066
  }
@@ -5419,7 +5723,7 @@ function parseDeprecationDate(value) {
5419
5723
  }
5420
5724
 
5421
5725
  // src/sdk-version.ts
5422
- var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.85.0" : void 0) || "unknown";
5726
+ var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.86.0" : void 0) || "unknown";
5423
5727
 
5424
5728
  // src/utils/open-url.ts
5425
5729
  var nodePrefix = "node:";
@@ -5677,11 +5981,11 @@ var ZapierApiClient = class {
5677
5981
  );
5678
5982
  const inputHeaders = new Headers(init?.headers ?? {});
5679
5983
  const mergedHeaders = new Headers();
5680
- builtHeaders.forEach((value, key2) => {
5681
- mergedHeaders.set(key2, value);
5984
+ builtHeaders.forEach((value, key) => {
5985
+ mergedHeaders.set(key, value);
5682
5986
  });
5683
- inputHeaders.forEach((value, key2) => {
5684
- mergedHeaders.set(key2, value);
5987
+ inputHeaders.forEach((value, key) => {
5988
+ mergedHeaders.set(key, value);
5685
5989
  });
5686
5990
  this.applyTelemetryHeaders(mergedHeaders);
5687
5991
  let retries = 0;
@@ -6206,8 +6510,8 @@ var ZapierApiClient = class {
6206
6510
  canSendDeprecationMessaging
6207
6511
  } = this.applyPathConfiguration(path);
6208
6512
  if (searchParams) {
6209
- Object.entries(searchParams).forEach(([key2, value]) => {
6210
- url.searchParams.set(key2, value);
6513
+ Object.entries(searchParams).forEach(([key, value]) => {
6514
+ url.searchParams.set(key, value);
6211
6515
  });
6212
6516
  }
6213
6517
  return {
@@ -7106,13 +7410,13 @@ function parseManifestSection({
7106
7410
  return void 0;
7107
7411
  }
7108
7412
  const kept = {};
7109
- for (const [key2, value] of Object.entries(raw)) {
7413
+ for (const [key, value] of Object.entries(raw)) {
7110
7414
  const result = schema.safeParse(value);
7111
7415
  if (result.success) {
7112
- kept[key2] = result.data;
7416
+ kept[key] = result.data;
7113
7417
  } else {
7114
7418
  console.warn(
7115
- `\u26A0\uFE0F Dropping invalid "${section}" entry "${key2}" in ${source}: ${result.error}`
7419
+ `\u26A0\uFE0F Dropping invalid "${section}" entry "${key}" in ${source}: ${result.error}`
7116
7420
  );
7117
7421
  }
7118
7422
  }
@@ -7261,9 +7565,9 @@ function findManifestEntry({
7261
7565
  return [slug, manifest.apps[slug]];
7262
7566
  }
7263
7567
  }
7264
- for (const [key2, entry] of Object.entries(manifest.apps)) {
7568
+ for (const [key, entry] of Object.entries(manifest.apps)) {
7265
7569
  if (entry.implementationName === appKeyWithoutVersion) {
7266
- return [key2, entry];
7570
+ return [key, entry];
7267
7571
  }
7268
7572
  }
7269
7573
  return null;
@@ -7517,8 +7821,8 @@ function normalizeHeaders(optionsHeaders) {
7517
7821
  return headers;
7518
7822
  }
7519
7823
  const headerEntries = optionsHeaders instanceof Headers ? Array.from(optionsHeaders.entries()) : Array.isArray(optionsHeaders) ? optionsHeaders : Object.entries(optionsHeaders);
7520
- for (const [key2, value] of headerEntries) {
7521
- headers[key2] = value;
7824
+ for (const [key, value] of headerEntries) {
7825
+ headers[key] = value;
7522
7826
  }
7523
7827
  return headers;
7524
7828
  }
@@ -7589,14 +7893,9 @@ var fetchPlugin = defineMethod({
7589
7893
  // of order.
7590
7894
  categories: [{ key: "http", title: "HTTP Request" }],
7591
7895
  returnType: "Response",
7592
- // The controller / MCP project fetch's parameters from `inputSchema` +
7593
- // `positional`. The CLI command layer instead flattens `init`'s fields into
7594
- // individual flags (--method, --connection, ...) from `inputParameters`; it is
7595
- // the only surface that reads this. Both describe the same (url, init) shape.
7596
- inputParameters: [
7597
- { name: "url", schema: FetchUrlSchema },
7598
- { name: "init", schema: FetchInitSchema }
7599
- ],
7896
+ // The CLI, controller, and MCP all derive fetch's `(url, init)` shape from
7897
+ // `inputSchema` + `positional`; the CLI flattens `init`'s fields into
7898
+ // individual flags (--method, --connection, ...) off that same schema.
7600
7899
  // Build the validator once, binding it to the head's `adaptError` so failures
7601
7900
  // surface as `ZapierValidationError` rather than the neutral kitcore fallback.
7602
7901
  setup: ({ imports }) => {
@@ -7735,9 +8034,9 @@ var RunActionInputSchema = z.union([RunActionSchema, RunActionSchemaDeprecated])
7735
8034
  var ActionResultItemSchema = z.unknown().describe("Action execution result");
7736
8035
 
7737
8036
  // src/formatters/actionResult.ts
7738
- function getStringProperty(obj, key2) {
7739
- if (typeof obj === "object" && obj !== null && key2 in obj) {
7740
- const value = obj[key2];
8037
+ function getStringProperty(obj, key) {
8038
+ if (typeof obj === "object" && obj !== null && key in obj) {
8039
+ const value = obj[key];
7741
8040
  return typeof value === "string" ? value : void 0;
7742
8041
  }
7743
8042
  return void 0;
@@ -8223,21 +8522,21 @@ var actionKeyResolver = defineResolver({
8223
8522
  });
8224
8523
 
8225
8524
  // src/plugins/capabilities/index.ts
8226
- function toDescription(key2) {
8227
- const words = key2.replace(/^can/, "").replace(/([A-Z])/g, " $1").trim().toLowerCase();
8525
+ function toDescription(key) {
8526
+ const words = key.replace(/^can/, "").replace(/([A-Z])/g, " $1").trim().toLowerCase();
8228
8527
  return `To ${words}`;
8229
8528
  }
8230
- function toEnvVar(key2) {
8231
- return "ZAPIER_" + key2.replace(/([A-Z])/g, "_$1").toUpperCase();
8529
+ function toEnvVar(key) {
8530
+ return "ZAPIER_" + key.replace(/([A-Z])/g, "_$1").toUpperCase();
8232
8531
  }
8233
- function toCliFlag(key2) {
8234
- return "--" + key2.replace(/([A-Z])/g, "-$1").toLowerCase();
8532
+ function toCliFlag(key) {
8533
+ return "--" + key.replace(/([A-Z])/g, "-$1").toLowerCase();
8235
8534
  }
8236
- function buildCapabilityMessage(key2) {
8535
+ function buildCapabilityMessage(key) {
8237
8536
  return [
8238
- `${toDescription(key2)}, use ${toCliFlag(key2)} in the CLI,`,
8239
- `set ${key2}: true in SDK options or .zapierrc,`,
8240
- `or set ${toEnvVar(key2)}=true.`
8537
+ `${toDescription(key)}, use ${toCliFlag(key)} in the CLI,`,
8538
+ `set ${key}: true in SDK options or .zapierrc,`,
8539
+ `or set ${toEnvVar(key)}=true.`
8241
8540
  ].join(" ");
8242
8541
  }
8243
8542
  var GATED_FLAGS = [
@@ -8245,8 +8544,8 @@ var GATED_FLAGS = [
8245
8544
  "canIncludeSharedTables",
8246
8545
  "canDeleteTables"
8247
8546
  ];
8248
- function isEnabledByEnv(key2) {
8249
- const value = globalThis.process?.env?.[toEnvVar(key2)];
8547
+ function isEnabledByEnv(key) {
8548
+ const value = globalThis.process?.env?.[toEnvVar(key)];
8250
8549
  if (value === void 0) return void 0;
8251
8550
  if (value === "true" || value === "1") return true;
8252
8551
  if (value === "false" || value === "0") return false;
@@ -8273,17 +8572,17 @@ var capabilitiesPlugin = defineProperty({
8273
8572
  return cached;
8274
8573
  }
8275
8574
  return {
8276
- checkCapability: async (key2) => {
8575
+ checkCapability: async (key) => {
8277
8576
  const flags = await resolveFlags();
8278
- if (flags[key2]) return;
8577
+ if (flags[key]) return;
8279
8578
  throw new ZapierConfigurationError(
8280
- buildCapabilityMessage(key2) + " (If you are an AI agent, you MUST NOT retry. Ask the user if they want to enable this.)",
8281
- { configType: key2 }
8579
+ buildCapabilityMessage(key) + " (If you are an AI agent, you MUST NOT retry. Ask the user if they want to enable this.)",
8580
+ { configType: key }
8282
8581
  );
8283
8582
  },
8284
- hasCapability: async (key2) => {
8583
+ hasCapability: async (key) => {
8285
8584
  const flags = await resolveFlags();
8286
- return flags[key2];
8585
+ return flags[key];
8287
8586
  }
8288
8587
  };
8289
8588
  },
@@ -8780,7 +9079,7 @@ function formatRecordError(fieldId, err) {
8780
9079
  function formatResponseError(err) {
8781
9080
  const message = err.human_title || err.title || "Unknown error";
8782
9081
  if (err.meta && Object.keys(err.meta).length > 0) {
8783
- const metaParts = Object.entries(err.meta).map(([key2, val]) => `${key2}: ${JSON.stringify(val)}`).join(", ");
9082
+ const metaParts = Object.entries(err.meta).map(([key, val]) => `${key}: ${JSON.stringify(val)}`).join(", ");
8784
9083
  return `${message} (${metaParts})`;
8785
9084
  }
8786
9085
  return message;
@@ -8815,8 +9114,8 @@ var TrashSchema = z.enum(["exclude", "include", "only"]).optional().describe(
8815
9114
  'Control soft-deleted item visibility. "exclude" (default) returns active items only, "include" returns both active and soft-deleted, "only" returns soft-deleted items only.'
8816
9115
  );
8817
9116
  var FIELD_ID_PATTERN = /^f\d+$/;
8818
- function isFieldId(key2) {
8819
- return FIELD_ID_PATTERN.test(key2);
9117
+ function isFieldId(key) {
9118
+ return FIELD_ID_PATTERN.test(key);
8820
9119
  }
8821
9120
  var NESTED_COMPONENTS = {
8822
9121
  labeled_string: /* @__PURE__ */ new Set(["value"]),
@@ -8854,7 +9153,7 @@ async function resolveFieldKeys({
8854
9153
  fieldKeys
8855
9154
  }) {
8856
9155
  const allAreIds = fieldKeys.every(
8857
- (key2) => typeof key2 === "number" || /^(f?\d+)$/.test(key2)
9156
+ (key) => typeof key === "number" || /^(f?\d+)$/.test(key)
8858
9157
  );
8859
9158
  if (allAreIds) {
8860
9159
  return fieldKeys.map(toNumericFieldId);
@@ -8863,13 +9162,13 @@ async function resolveFieldKeys({
8863
9162
  if (!mapping) {
8864
9163
  return fieldKeys.map(toNumericFieldId);
8865
9164
  }
8866
- return fieldKeys.map((key2) => {
8867
- if (typeof key2 === "number") return key2;
8868
- if (FIELD_ID_PATTERN.test(key2)) return toNumericFieldId(key2);
8869
- const id = mapping.nameToId.get(key2);
9165
+ return fieldKeys.map((key) => {
9166
+ if (typeof key === "number") return key;
9167
+ if (FIELD_ID_PATTERN.test(key)) return toNumericFieldId(key);
9168
+ const id = mapping.nameToId.get(key);
8870
9169
  if (!id) {
8871
9170
  throw new ZapierValidationError(
8872
- `Unknown field name: "${key2}". Use a valid field name or ID.`
9171
+ `Unknown field name: "${key}". Use a valid field name or ID.`
8873
9172
  );
8874
9173
  }
8875
9174
  return toNumericFieldId(id);
@@ -8885,13 +9184,13 @@ async function createFieldKeyTranslator({
8885
9184
  translateInput(data) {
8886
9185
  if (!mapping) return data;
8887
9186
  const result = {};
8888
- for (const [key2, value] of Object.entries(data)) {
8889
- if (FIELD_ID_PATTERN.test(key2) && mapping.idToName.has(key2)) {
8890
- result[key2] = value;
8891
- } else if (mapping.nameToId.has(key2)) {
8892
- result[mapping.nameToId.get(key2)] = value;
9187
+ for (const [key, value] of Object.entries(data)) {
9188
+ if (FIELD_ID_PATTERN.test(key) && mapping.idToName.has(key)) {
9189
+ result[key] = value;
9190
+ } else if (mapping.nameToId.has(key)) {
9191
+ result[mapping.nameToId.get(key)] = value;
8893
9192
  } else {
8894
- result[key2] = value;
9193
+ result[key] = value;
8895
9194
  }
8896
9195
  }
8897
9196
  return result;
@@ -8899,29 +9198,29 @@ async function createFieldKeyTranslator({
8899
9198
  translateOutput(data) {
8900
9199
  if (!mapping) return data;
8901
9200
  const result = {};
8902
- for (const [key2, value] of Object.entries(data)) {
8903
- if (mapping.idToName.has(key2)) {
8904
- result[mapping.idToName.get(key2)] = value;
9201
+ for (const [key, value] of Object.entries(data)) {
9202
+ if (mapping.idToName.has(key)) {
9203
+ result[mapping.idToName.get(key)] = value;
8905
9204
  } else {
8906
- result[key2] = value;
9205
+ result[key] = value;
8907
9206
  }
8908
9207
  }
8909
9208
  return result;
8910
9209
  },
8911
- translateFieldKey(key2) {
8912
- if (!mapping) return key2;
8913
- if (FIELD_ID_PATTERN.test(key2) && mapping.idToName.has(key2)) {
8914
- const fieldType = mapping.idToType.get(key2);
9210
+ translateFieldKey(key) {
9211
+ if (!mapping) return key;
9212
+ if (FIELD_ID_PATTERN.test(key) && mapping.idToName.has(key)) {
9213
+ const fieldType = mapping.idToType.get(key);
8915
9214
  if (fieldType) {
8916
9215
  const components = NESTED_COMPONENTS[fieldType];
8917
9216
  if (components?.size === 1) {
8918
- return `${key2}__${[...components][0]}`;
9217
+ return `${key}__${[...components][0]}`;
8919
9218
  }
8920
9219
  }
8921
- return key2;
9220
+ return key;
8922
9221
  }
8923
- if (mapping.nameToId.has(key2)) {
8924
- const fieldId = mapping.nameToId.get(key2);
9222
+ if (mapping.nameToId.has(key)) {
9223
+ const fieldId = mapping.nameToId.get(key);
8925
9224
  const fieldType = mapping.idToType.get(fieldId);
8926
9225
  if (fieldType) {
8927
9226
  const components = NESTED_COMPONENTS[fieldType];
@@ -8931,10 +9230,10 @@ async function createFieldKeyTranslator({
8931
9230
  }
8932
9231
  return fieldId;
8933
9232
  }
8934
- const sepIndex = key2.lastIndexOf("__");
9233
+ const sepIndex = key.lastIndexOf("__");
8935
9234
  if (sepIndex > 0) {
8936
- const prefix = key2.slice(0, sepIndex);
8937
- const component = key2.slice(sepIndex + 2);
9235
+ const prefix = key.slice(0, sepIndex);
9236
+ const component = key.slice(sepIndex + 2);
8938
9237
  let fieldId;
8939
9238
  if (FIELD_ID_PATTERN.test(prefix) && mapping.idToName.has(prefix)) {
8940
9239
  fieldId = prefix;
@@ -8948,7 +9247,7 @@ async function createFieldKeyTranslator({
8948
9247
  }
8949
9248
  }
8950
9249
  }
8951
- return key2;
9250
+ return key;
8952
9251
  }
8953
9252
  };
8954
9253
  }
@@ -9544,13 +9843,13 @@ var runActionPlugin = defineMethod({
9544
9843
  let oldestKey;
9545
9844
  let oldestExpiry = Infinity;
9546
9845
  let evictedAny = false;
9547
- for (const [key2, entry] of cache) {
9846
+ for (const [key, entry] of cache) {
9548
9847
  if (now >= entry.expiresAt) {
9549
- cache.delete(key2);
9848
+ cache.delete(key);
9550
9849
  evictedAny = true;
9551
9850
  } else if (entry.expiresAt < oldestExpiry) {
9552
9851
  oldestExpiry = entry.expiresAt;
9553
- oldestKey = key2;
9852
+ oldestKey = key;
9554
9853
  }
9555
9854
  }
9556
9855
  if (!evictedAny && oldestKey) cache.delete(oldestKey);
@@ -9908,7 +10207,7 @@ var listAppsPlugin = defineMethod({
9908
10207
  locator
9909
10208
  ];
9910
10209
  }
9911
- const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key2) => implementationNameToLocator[key2].length > 1).map((key2) => implementationNameToLocator[key2]).flat().map((locator) => locator.lookupAppKey);
10210
+ const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key) => implementationNameToLocator[key].length > 1).map((key) => implementationNameToLocator[key]).flat().map((locator) => locator.lookupAppKey);
9912
10211
  if (duplicatedLookupAppKeys.length > 0) {
9913
10212
  throw new Error(
9914
10213
  `Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`
@@ -10073,8 +10372,8 @@ function formatRootField(item) {
10073
10372
  }
10074
10373
  var rootFieldItemFormatter = defineFormatter({
10075
10374
  format: ({ item }) => {
10076
- const { key: key2, ...rest } = formatRootField(item);
10077
- return { ...rest, hint: key2 };
10375
+ const { key, ...rest } = formatRootField(item);
10376
+ return { ...rest, hint: key };
10078
10377
  }
10079
10378
  });
10080
10379
 
@@ -11734,7 +12033,7 @@ var createTriggerInboxPlugin = defineMethod({
11734
12033
  inputs = {},
11735
12034
  notificationUrl
11736
12035
  } = input;
11737
- const key2 = input.key ?? input.name;
12036
+ const key = input.key ?? input.name;
11738
12037
  const resolvedConnectionId = await resolveConnectionId({
11739
12038
  connection,
11740
12039
  resolveConnection
@@ -11754,8 +12053,8 @@ var createTriggerInboxPlugin = defineMethod({
11754
12053
  connection_id: resolvedConnectionId ?? null
11755
12054
  }
11756
12055
  };
11757
- if (key2 !== void 0) {
11758
- requestBody.key = key2;
12056
+ if (key !== void 0) {
12057
+ requestBody.key = key;
11759
12058
  }
11760
12059
  if (notificationUrl !== void 0) {
11761
12060
  requestBody.notification_url = notificationUrl;
@@ -11769,7 +12068,7 @@ var createTriggerInboxPlugin = defineMethod({
11769
12068
  if (status === 409) {
11770
12069
  const detail = extractErrorDetail(data);
11771
12070
  return new ZapierConflictError(
11772
- detail ?? `An inbox with key "${key2}" already exists with a different subscription.`,
12071
+ detail ?? `An inbox with key "${key}" already exists with a different subscription.`,
11773
12072
  { statusCode: status, resourceType: "trigger_inbox" }
11774
12073
  );
11775
12074
  }
@@ -11837,7 +12136,7 @@ var ensureTriggerInboxPlugin = defineMethod({
11837
12136
  inputs = {},
11838
12137
  notificationUrl
11839
12138
  } = input;
11840
- const key2 = "key" in input ? input.key : input.name;
12139
+ const key = "key" in input ? input.key : input.name;
11841
12140
  const resolvedConnectionId = await resolveConnectionId({
11842
12141
  connection,
11843
12142
  resolveConnection
@@ -11850,7 +12149,7 @@ var ensureTriggerInboxPlugin = defineMethod({
11850
12149
  );
11851
12150
  }
11852
12151
  const requestBody = {
11853
- key: key2,
12152
+ key,
11854
12153
  subscription: {
11855
12154
  app_key: selectedApi,
11856
12155
  action_key: actionKey,
@@ -11870,7 +12169,7 @@ var ensureTriggerInboxPlugin = defineMethod({
11870
12169
  if (status === 409) {
11871
12170
  const detail = extractErrorDetail(data);
11872
12171
  return new ZapierConflictError(
11873
- detail ?? `An inbox with key "${key2}" already exists with a different subscription.`,
12172
+ detail ?? `An inbox with key "${key}" already exists with a different subscription.`,
11874
12173
  { statusCode: status, resourceType: "trigger_inbox" }
11875
12174
  );
11876
12175
  }
@@ -12454,9 +12753,9 @@ function createWaiter() {
12454
12753
  }
12455
12754
  };
12456
12755
  }
12457
- function addToMap(m, key2, value) {
12458
- const existing = m.get(key2) ?? [];
12459
- m.set(key2, [...existing, value]);
12756
+ function addToMap(m, key, value) {
12757
+ const existing = m.get(key) ?? [];
12758
+ m.set(key, [...existing, value]);
12460
12759
  }
12461
12760
  async function runBatchedDrainPipeline(options) {
12462
12761
  const {
@@ -14153,8 +14452,8 @@ function getOsInfo() {
14153
14452
  function getPlatformVersions() {
14154
14453
  const versions = {};
14155
14454
  if (typeof globalThis.process?.versions === "object") {
14156
- for (const [key2, value] of Object.entries(globalThis.process.versions)) {
14157
- versions[key2] = value || null;
14455
+ for (const [key, value] of Object.entries(globalThis.process.versions)) {
14456
+ versions[key] = value || null;
14158
14457
  }
14159
14458
  }
14160
14459
  return versions;
@@ -14408,9 +14707,9 @@ async function emitWithTimeout(transport, subject, event) {
14408
14707
  }
14409
14708
  function mergeUserContext(event, userContext) {
14410
14709
  const merged = { ...event };
14411
- for (const [key2, value] of Object.entries(userContext)) {
14412
- if (merged[key2] == null) {
14413
- merged[key2] = value;
14710
+ for (const [key, value] of Object.entries(userContext)) {
14711
+ if (merged[key] == null) {
14712
+ merged[key] = value;
14414
14713
  }
14415
14714
  }
14416
14715
  return merged;