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