@zapier/zapier-sdk 0.78.0 → 0.80.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.
@@ -53,18 +53,20 @@ function buildRegistry({
53
53
  sdk,
54
54
  meta,
55
55
  formatters,
56
+ boundResolvers,
57
+ positional,
56
58
  packageFilter
57
59
  }) {
58
60
  const definitionsByKey = /* @__PURE__ */ new Map();
59
61
  const objectDeclaredKeys = /* @__PURE__ */ new Set();
60
62
  for (const m of Object.values(meta)) {
61
63
  for (const ref of m.categories ?? []) {
62
- const key = typeof ref === "string" ? ref : ref.key;
64
+ const key2 = typeof ref === "string" ? ref : ref.key;
63
65
  if (typeof ref === "object") {
64
- objectDeclaredKeys.add(key);
65
- definitionsByKey.set(key, resolveCategoryDefinition(ref));
66
- } else if (!objectDeclaredKeys.has(key)) {
67
- definitionsByKey.set(key, resolveCategoryDefinition(ref));
66
+ objectDeclaredKeys.add(key2);
67
+ definitionsByKey.set(key2, resolveCategoryDefinition(ref));
68
+ } else if (!objectDeclaredKeys.has(key2)) {
69
+ definitionsByKey.set(key2, resolveCategoryDefinition(ref));
68
70
  }
69
71
  }
70
72
  }
@@ -72,16 +74,16 @@ function buildRegistry({
72
74
  definitionsByKey.set("other", resolveCategoryDefinition("other"));
73
75
  }
74
76
  const knownCategories = Array.from(definitionsByKey.keys());
75
- const functions = Object.keys(meta).filter((key) => {
76
- const property = sdk[key];
77
+ const functions = Object.keys(meta).filter((key2) => {
78
+ const property = sdk[key2];
77
79
  if (typeof property === "function") return true;
78
- const [rootKey] = key.split(".");
80
+ const [rootKey] = key2.split(".");
79
81
  const rootProperty = sdk[rootKey];
80
82
  return typeof rootProperty === "object" && rootProperty !== null;
81
- }).map((key) => {
82
- const m = meta[key];
83
+ }).map((key2) => {
84
+ const m = meta[key2];
83
85
  return {
84
- name: key,
86
+ name: key2,
85
87
  description: m.description,
86
88
  type: m.type,
87
89
  itemType: m.itemType,
@@ -89,11 +91,13 @@ function buildRegistry({
89
91
  inputSchema: canonicalInputSchema(m.inputSchema),
90
92
  inputParameters: m.inputParameters,
91
93
  outputSchema: m.outputSchema,
94
+ positional: positional?.[key2],
92
95
  categories: (m.categories ?? []).map(
93
96
  (c) => typeof c === "string" ? c : c.key
94
97
  ),
95
98
  resolvers: m.resolvers,
96
- formatter: formatters?.[key],
99
+ boundResolvers: boundResolvers?.[key2],
100
+ formatter: formatters?.[key2],
97
101
  experimental: m.experimental,
98
102
  packages: m.packages,
99
103
  confirm: m.confirm ?? (m.type === "delete" ? "delete" : void 0),
@@ -131,8 +135,8 @@ function composeVoid(existing, added) {
131
135
  }
132
136
  function buildHooks(existing, added) {
133
137
  const result = {};
134
- const start = composeVoid(existing.onMethodStart, added.onMethodStart);
135
- if (start) result.onMethodStart = start;
138
+ const start2 = composeVoid(existing.onMethodStart, added.onMethodStart);
139
+ if (start2) result.onMethodStart = start2;
136
140
  const end = composeVoid(existing.onMethodEnd, added.onMethodEnd);
137
141
  if (end) result.onMethodEnd = end;
138
142
  return result;
@@ -765,11 +769,11 @@ var RESERVED_ROOT_KEYS = /* @__PURE__ */ new Set([
765
769
  "context",
766
770
  "getRegistry"
767
771
  ]);
768
- function hasOwn(obj, key) {
769
- return Object.prototype.hasOwnProperty.call(obj, key);
772
+ function hasOwn(obj, key2) {
773
+ return Object.prototype.hasOwnProperty.call(obj, key2);
770
774
  }
771
- function setOwn(target, key, value) {
772
- Object.defineProperty(target, key, {
775
+ function setOwn(target, key2, value) {
776
+ Object.defineProperty(target, key2, {
773
777
  value,
774
778
  enumerable: true,
775
779
  configurable: true,
@@ -781,31 +785,31 @@ function checkCollisions(target, source, kind, callerLabel, override) {
781
785
  checkRootKeyCollisions(target, Object.keys(source), override, callerLabel);
782
786
  return;
783
787
  }
784
- for (const key of Object.keys(source)) {
785
- if (!override && hasOwn(target, key)) {
788
+ for (const key2 of Object.keys(source)) {
789
+ if (!override && hasOwn(target, key2)) {
786
790
  throw new Error(
787
- `${callerLabel}: duplicate ${kind} "${key}". If the override is intentional, pass { override: true } in the options.`
791
+ `${callerLabel}: duplicate ${kind} "${key2}". If the override is intentional, pass { override: true } in the options.`
788
792
  );
789
793
  }
790
794
  }
791
795
  }
792
796
  function checkRootKeyCollisions(target, keys, override, callerLabel) {
793
- for (const key of keys) {
794
- if (RESERVED_ROOT_KEYS.has(key)) {
797
+ for (const key2 of keys) {
798
+ if (RESERVED_ROOT_KEYS.has(key2)) {
795
799
  throw new Error(
796
- `${callerLabel}: plugin attempted to register reserved root key "${key}". The SDK uses this key for its own accessor; rename the plugin's method.`
800
+ `${callerLabel}: plugin attempted to register reserved root key "${key2}". The SDK uses this key for its own accessor; rename the plugin's method.`
797
801
  );
798
802
  }
799
- if (!override && hasOwn(target, key)) {
803
+ if (!override && hasOwn(target, key2)) {
800
804
  throw new Error(
801
- `${callerLabel}: duplicate root key "${key}". If the override is intentional, pass { override: true } in the options.`
805
+ `${callerLabel}: duplicate root key "${key2}". If the override is intentional, pass { override: true } in the options.`
802
806
  );
803
807
  }
804
808
  }
805
809
  }
806
810
  function applyOwnProperties(target, source) {
807
- for (const key of Object.keys(source)) {
808
- setOwn(target, key, source[key]);
811
+ for (const key2 of Object.keys(source)) {
812
+ setOwn(target, key2, source[key2]);
809
813
  }
810
814
  }
811
815
  function createPluginAccumulator(initialProperties = {}, initialContext = {}) {
@@ -1053,8 +1057,8 @@ function normalizeImports(deps) {
1053
1057
  }
1054
1058
  function collectLeafMeta(config) {
1055
1059
  let meta;
1056
- for (const key of LEAF_META_KEYS) {
1057
- if (config[key] !== void 0) (meta ?? (meta = {}))[key] = config[key];
1060
+ for (const key2 of LEAF_META_KEYS) {
1061
+ if (config[key2] !== void 0) (meta ?? (meta = {}))[key2] = config[key2];
1058
1062
  }
1059
1063
  return meta;
1060
1064
  }
@@ -1077,12 +1081,66 @@ function defineMethod(config) {
1077
1081
  run: config.run
1078
1082
  };
1079
1083
  }
1084
+ function defineResolver(config) {
1085
+ const deps = normalizeImports(config.imports);
1086
+ const base = { imports: deps.plugins, importBindings: deps.bindings };
1087
+ const gates = {
1088
+ requireParameters: config.requireParameters
1089
+ };
1090
+ switch (config.type) {
1091
+ case "static":
1092
+ return {
1093
+ ...base,
1094
+ ...gates,
1095
+ type: "static",
1096
+ inputType: config.inputType,
1097
+ placeholder: config.placeholder
1098
+ };
1099
+ case "constant":
1100
+ return { ...base, ...gates, type: "constant", value: config.value };
1101
+ case "info":
1102
+ return { ...base, type: "info", text: config.text ?? "" };
1103
+ case "object":
1104
+ return {
1105
+ ...base,
1106
+ ...gates,
1107
+ type: "object",
1108
+ properties: config.properties,
1109
+ definitions: config.definitions,
1110
+ getProperties: config.getProperties
1111
+ };
1112
+ case "array":
1113
+ return {
1114
+ ...base,
1115
+ ...gates,
1116
+ type: "array",
1117
+ items: config.items,
1118
+ minItems: config.minItems,
1119
+ maxItems: config.maxItems,
1120
+ itemValueType: config.itemValueType,
1121
+ definitions: config.definitions
1122
+ };
1123
+ default:
1124
+ return {
1125
+ ...base,
1126
+ ...gates,
1127
+ type: "dynamic",
1128
+ inputType: config.inputType,
1129
+ placeholder: config.placeholder,
1130
+ getContext: config.getContext,
1131
+ listItems: config.listItems,
1132
+ prompt: config.prompt,
1133
+ tryResolveWithoutPrompt: config.tryResolveWithoutPrompt,
1134
+ tryResolveFromSearch: config.tryResolveFromSearch
1135
+ };
1136
+ }
1137
+ }
1080
1138
  function defineFormatter(config) {
1081
1139
  const deps = normalizeImports(config.imports);
1082
1140
  return {
1083
1141
  imports: deps.plugins,
1084
1142
  importBindings: deps.bindings,
1085
- fetchContext: config.fetchContext,
1143
+ getContext: config.getContext,
1086
1144
  format: config.format
1087
1145
  };
1088
1146
  }
@@ -1211,7 +1269,7 @@ function legacyGraphEntry(name, value, pluginMeta) {
1211
1269
  function adaptLegacyFormatter(legacy, sdk) {
1212
1270
  const legacyFetch = legacy.fetch;
1213
1271
  return {
1214
- fetchContext: legacyFetch ? async ({ items, input, context }) => {
1272
+ getContext: legacyFetch ? async ({ items, input, context }) => {
1215
1273
  let ctx = context;
1216
1274
  for (const item of items) {
1217
1275
  ctx = await legacyFetch(sdk, input, item, ctx);
@@ -1227,6 +1285,14 @@ function normalizeFormatter(entry, sdk) {
1227
1285
  const legacy = entry.meta?.formatter;
1228
1286
  return legacy ? adaptLegacyFormatter(legacy, sdk) : void 0;
1229
1287
  }
1288
+ function normalizeBoundResolvers(entry) {
1289
+ if (entry.pluginType !== "method") return void 0;
1290
+ return entry.resolvers;
1291
+ }
1292
+ function methodPositional(entry) {
1293
+ if (entry.pluginType !== "method") return void 0;
1294
+ return entry.positional;
1295
+ }
1230
1296
  function pluginEntryMeta(entry) {
1231
1297
  if (entry.pluginType === "method" && entry.meta) {
1232
1298
  return entry.inputSchema ? { ...entry.meta, inputSchema: entry.inputSchema } : entry.meta;
@@ -1247,11 +1313,24 @@ function buildSurfaceRegistry(context, packageFilter) {
1247
1313
  if (m) meta[binding] = m;
1248
1314
  }
1249
1315
  const formatters = {};
1316
+ const boundResolvers = {};
1317
+ const positional = {};
1250
1318
  for (const [binding, entry] of Object.entries(entries)) {
1251
1319
  const f = normalizeFormatter(entry, surface);
1252
1320
  if (f) formatters[binding] = f;
1253
- }
1254
- return buildRegistry({ sdk: surface, meta, formatters, packageFilter });
1321
+ const r = normalizeBoundResolvers(entry);
1322
+ if (r) boundResolvers[binding] = r;
1323
+ const p = methodPositional(entry);
1324
+ if (p) positional[binding] = p;
1325
+ }
1326
+ return buildRegistry({
1327
+ sdk: surface,
1328
+ meta,
1329
+ formatters,
1330
+ boundResolvers,
1331
+ positional,
1332
+ packageFilter
1333
+ });
1255
1334
  }
1256
1335
  var dangerousContextPlugin = {
1257
1336
  pluginType: "property",
@@ -1368,15 +1447,15 @@ function collectPlugins(root, materialized = /* @__PURE__ */ new Set()) {
1368
1447
  }
1369
1448
  return byId;
1370
1449
  }
1371
- function bindValue(target, key, entry) {
1450
+ function bindValue(target, key2, entry) {
1372
1451
  if (entry.pluginType === "property" && entry.getValue) {
1373
- Object.defineProperty(target, key, {
1452
+ Object.defineProperty(target, key2, {
1374
1453
  get: entry.getValue,
1375
1454
  enumerable: true,
1376
1455
  configurable: true
1377
1456
  });
1378
1457
  } else {
1379
- Object.defineProperty(target, key, {
1458
+ Object.defineProperty(target, key2, {
1380
1459
  value: entry.value,
1381
1460
  writable: true,
1382
1461
  enumerable: true,
@@ -1428,8 +1507,7 @@ function bindResolver(resolver, plugins) {
1428
1507
  case "static":
1429
1508
  return {
1430
1509
  type: "static",
1431
- requireParams: resolver.requireParams,
1432
- requireCapabilities: resolver.requireCapabilities,
1510
+ requireParameters: resolver.requireParameters,
1433
1511
  inputType: resolver.inputType,
1434
1512
  placeholder: resolver.placeholder
1435
1513
  };
@@ -1437,8 +1515,7 @@ function bindResolver(resolver, plugins) {
1437
1515
  return {
1438
1516
  type: "constant",
1439
1517
  value: resolver.value,
1440
- requireParams: resolver.requireParams,
1441
- requireCapabilities: resolver.requireCapabilities
1518
+ requireParameters: resolver.requireParameters
1442
1519
  };
1443
1520
  case "info":
1444
1521
  return { type: "info", text: resolver.text };
@@ -1446,24 +1523,24 @@ function bindResolver(resolver, plugins) {
1446
1523
  const imports = buildImports(plugins, resolver.importBindings);
1447
1524
  const bound = {
1448
1525
  type: "object",
1449
- requireParams: resolver.requireParams,
1450
- requireCapabilities: resolver.requireCapabilities
1526
+ requireParameters: resolver.requireParameters
1451
1527
  };
1452
1528
  if (resolver.properties)
1453
1529
  bound.properties = bindFields(resolver.properties, plugins);
1454
1530
  if (resolver.definitions)
1455
1531
  bound.definitions = bindDefinitions(resolver.definitions, plugins);
1456
- const { fetch: fetch2 } = resolver;
1457
- if (fetch2) bound.fetch = ({ params }) => fetch2({ imports, params });
1532
+ const { getProperties } = resolver;
1533
+ if (getProperties)
1534
+ bound.getProperties = ({ input }) => getProperties({ imports, input });
1458
1535
  return bound;
1459
1536
  }
1460
1537
  case "array": {
1461
1538
  const bound = {
1462
1539
  type: "array",
1463
- requireParams: resolver.requireParams,
1464
- requireCapabilities: resolver.requireCapabilities,
1540
+ requireParameters: resolver.requireParameters,
1465
1541
  minItems: resolver.minItems,
1466
1542
  maxItems: resolver.maxItems,
1543
+ itemValueType: resolver.itemValueType,
1467
1544
  items: isResolverRef(resolver.items) ? resolver.items : bindResolver(resolver.items, plugins)
1468
1545
  };
1469
1546
  if (resolver.definitions)
@@ -1474,17 +1551,26 @@ function bindResolver(resolver, plugins) {
1474
1551
  const imports = buildImports(plugins, resolver.importBindings);
1475
1552
  const bound = {
1476
1553
  type: "dynamic",
1477
- requireParams: resolver.requireParams,
1478
- requireCapabilities: resolver.requireCapabilities,
1554
+ requireParameters: resolver.requireParameters,
1479
1555
  inputType: resolver.inputType,
1480
1556
  placeholder: resolver.placeholder,
1481
1557
  prompt: resolver.prompt
1482
1558
  };
1483
- const { fetch: fetch2, tryResolveWithoutPrompt } = resolver;
1484
- if (fetch2)
1485
- bound.fetch = ({ params, search }) => fetch2({ imports, params, search });
1559
+ const {
1560
+ getContext: getContext2,
1561
+ listItems,
1562
+ tryResolveWithoutPrompt,
1563
+ tryResolveFromSearch
1564
+ } = resolver;
1565
+ if (getContext2)
1566
+ bound.getContext = ({ input }) => getContext2({ imports, input });
1567
+ if (listItems)
1568
+ bound.listItems = ({ input, context, search, cursor }) => listItems({ imports, input, context, search, cursor });
1486
1569
  if (tryResolveWithoutPrompt) {
1487
- bound.tryResolveWithoutPrompt = ({ params }) => tryResolveWithoutPrompt({ imports, params });
1570
+ bound.tryResolveWithoutPrompt = ({ input }) => tryResolveWithoutPrompt({ imports, input });
1571
+ }
1572
+ if (tryResolveFromSearch) {
1573
+ bound.tryResolveFromSearch = ({ input, search }) => tryResolveFromSearch({ imports, input, search });
1488
1574
  }
1489
1575
  return bound;
1490
1576
  }
@@ -1492,8 +1578,8 @@ function bindResolver(resolver, plugins) {
1492
1578
  }
1493
1579
  function bindFields(fields, plugins) {
1494
1580
  const out = {};
1495
- for (const [key, field] of Object.entries(fields)) {
1496
- out[key] = {
1581
+ for (const [key2, field] of Object.entries(fields)) {
1582
+ out[key2] = {
1497
1583
  ...field,
1498
1584
  resolver: isResolverRef(field.resolver) ? field.resolver : bindResolver(field.resolver, plugins)
1499
1585
  };
@@ -1502,17 +1588,17 @@ function bindFields(fields, plugins) {
1502
1588
  }
1503
1589
  function bindDefinitions(definitions, plugins) {
1504
1590
  const out = {};
1505
- for (const [key, def] of Object.entries(definitions)) {
1506
- out[key] = bindResolver(def, plugins);
1591
+ for (const [key2, def] of Object.entries(definitions)) {
1592
+ out[key2] = bindResolver(def, plugins);
1507
1593
  }
1508
1594
  return out;
1509
1595
  }
1510
1596
  function bindFormatter(formatter, plugins) {
1511
1597
  const imports = buildImports(plugins, formatter.importBindings);
1512
1598
  const bound = { format: formatter.format };
1513
- const { fetchContext } = formatter;
1514
- if (fetchContext)
1515
- bound.fetchContext = ({ items, input, context }) => fetchContext({ imports, items, input, context });
1599
+ const { getContext: getContext2 } = formatter;
1600
+ if (getContext2)
1601
+ bound.getContext = ({ items, input, context }) => getContext2({ imports, items, input, context });
1516
1602
  return bound;
1517
1603
  }
1518
1604
  function bindAttachments(descriptors, context) {
@@ -1560,6 +1646,7 @@ function runLegacyPass(descriptors, context) {
1560
1646
  const sdk = this ?? exports;
1561
1647
  const meta2 = {};
1562
1648
  const formatters = {};
1649
+ const boundResolvers = {};
1563
1650
  for (const [binding, id2] of Object.entries(context.surface)) {
1564
1651
  const entry = context.plugins[id2];
1565
1652
  if (!entry || entry.pluginType === "aggregate") continue;
@@ -1567,12 +1654,15 @@ function runLegacyPass(descriptors, context) {
1567
1654
  if (m) meta2[binding] = m;
1568
1655
  const f = normalizeFormatter(entry, sdk);
1569
1656
  if (f) formatters[binding] = f;
1657
+ const r = normalizeBoundResolvers(entry);
1658
+ if (r) boundResolvers[binding] = r;
1570
1659
  }
1571
1660
  Object.assign(meta2, context.meta);
1572
1661
  return buildRegistry({
1573
1662
  sdk,
1574
1663
  meta: meta2,
1575
1664
  formatters,
1665
+ boundResolvers,
1576
1666
  packageFilter: options?.package
1577
1667
  });
1578
1668
  };
@@ -1788,7 +1878,7 @@ function createSdk(root) {
1788
1878
  pluginSurface = {};
1789
1879
  bindValue(pluginSurface, plugin.name, plugins2[plugin.id]);
1790
1880
  }
1791
- for (const key of Object.keys(legacyExports)) context.surface[key] = key;
1881
+ for (const key2 of Object.keys(legacyExports)) context.surface[key2] = key2;
1792
1882
  if (plugin.pluginType === "aggregate") {
1793
1883
  recordExportSurface(context, plugin.exports);
1794
1884
  } else {
@@ -1858,6 +1948,756 @@ function addPlugin(sdk, plugin, options) {
1858
1948
  options ?? {}
1859
1949
  );
1860
1950
  }
1951
+ var CORE_SIGNAL_SYMBOL = Symbol.for("kitcore.signal");
1952
+ var CoreSignal = class extends Error {
1953
+ constructor(message) {
1954
+ super(message);
1955
+ Object.setPrototypeOf(this, new.target.prototype);
1956
+ Object.defineProperty(this, CORE_SIGNAL_SYMBOL, {
1957
+ value: true,
1958
+ enumerable: false,
1959
+ configurable: true,
1960
+ writable: false
1961
+ });
1962
+ }
1963
+ };
1964
+ function isCoreSignal(value) {
1965
+ return Boolean(
1966
+ value && typeof value === "object" && value[CORE_SIGNAL_SYMBOL] === true
1967
+ );
1968
+ }
1969
+ var CoreCancelledSignal = class extends CoreSignal {
1970
+ constructor(message = "resolution cancelled") {
1971
+ super(message);
1972
+ this.name = "CoreCancelledSignal";
1973
+ this.code = "CANCELLED";
1974
+ }
1975
+ };
1976
+ function unwrap(schema) {
1977
+ let inner = schema;
1978
+ let required = true;
1979
+ for (; ; ) {
1980
+ if (inner instanceof zod.z.ZodOptional) {
1981
+ required = false;
1982
+ inner = inner._zod.def.innerType;
1983
+ } else if (inner instanceof zod.z.ZodDefault) {
1984
+ required = false;
1985
+ inner = inner._zod.def.innerType;
1986
+ } else if (inner instanceof zod.z.ZodNullable) {
1987
+ inner = inner._zod.def.innerType;
1988
+ } else {
1989
+ break;
1990
+ }
1991
+ }
1992
+ return { inner, required };
1993
+ }
1994
+ function valueTypeOf(inner) {
1995
+ if (inner instanceof zod.z.ZodString) return "string";
1996
+ if (inner instanceof zod.z.ZodNumber) return "number";
1997
+ if (inner instanceof zod.z.ZodBoolean) return "boolean";
1998
+ if (inner instanceof zod.z.ZodEnum) return "string";
1999
+ if (inner instanceof zod.z.ZodArray) return "array";
2000
+ if (inner instanceof zod.z.ZodObject) return "object";
2001
+ return void 0;
2002
+ }
2003
+ function staticChoicesOf(inner) {
2004
+ if (inner instanceof zod.z.ZodEnum) {
2005
+ const values = inner.options;
2006
+ return values.map((value) => ({ label: value, value }));
2007
+ }
2008
+ return void 0;
2009
+ }
2010
+ function objectShape(schema) {
2011
+ const { inner } = schema ? unwrap(schema) : { inner: void 0 };
2012
+ if (inner instanceof zod.z.ZodObject) {
2013
+ return inner.shape;
2014
+ }
2015
+ return void 0;
2016
+ }
2017
+ function topoOrder2(specs) {
2018
+ const byName = new Map(specs.map((s) => [s.name, s]));
2019
+ const ordered = [];
2020
+ const placed = /* @__PURE__ */ new Set();
2021
+ let progressed = true;
2022
+ while (ordered.length < specs.length && progressed) {
2023
+ progressed = false;
2024
+ for (const spec of specs) {
2025
+ if (placed.has(spec.name)) continue;
2026
+ const ready = spec.requires.every((r) => !byName.has(r) || placed.has(r));
2027
+ if (ready) {
2028
+ ordered.push(spec);
2029
+ placed.add(spec.name);
2030
+ progressed = true;
2031
+ }
2032
+ }
2033
+ }
2034
+ for (const spec of specs) if (!placed.has(spec.name)) ordered.push(spec);
2035
+ return ordered;
2036
+ }
2037
+ function planParameters(entry) {
2038
+ const shape = objectShape(entry.inputSchema);
2039
+ const resolvers = entry.boundResolvers ?? {};
2040
+ const names = shape ? Object.keys(shape) : Object.keys(resolvers);
2041
+ const specs = names.map((name) => {
2042
+ const field = shape?.[name];
2043
+ const { inner, required } = field ? unwrap(field) : { inner: void 0, required: false };
2044
+ const resolver = resolvers[name];
2045
+ return {
2046
+ name,
2047
+ required,
2048
+ valueType: inner ? valueTypeOf(inner) : void 0,
2049
+ staticChoices: inner ? staticChoicesOf(inner) : void 0,
2050
+ resolver,
2051
+ requires: resolver?.requireParameters ?? []
2052
+ };
2053
+ });
2054
+ return { parameters: topoOrder2(specs) };
2055
+ }
2056
+ function getAtPath(root, path) {
2057
+ let node = root;
2058
+ for (const seg of path) {
2059
+ if (node == null || typeof node !== "object") return void 0;
2060
+ node = node[seg];
2061
+ }
2062
+ return node;
2063
+ }
2064
+ function setAtPath(root, path, value) {
2065
+ let node = root;
2066
+ for (let i = 0; i < path.length - 1; i++) {
2067
+ const seg = path[i];
2068
+ if (node[seg] == null || typeof node[seg] !== "object") node[seg] = {};
2069
+ node = node[seg];
2070
+ }
2071
+ node[path[path.length - 1]] = value;
2072
+ }
2073
+ var key = (path) => path.join(".");
2074
+ function isSettled(state, path) {
2075
+ return state.settled.includes(key(path));
2076
+ }
2077
+ function settle(state, path) {
2078
+ const k = key(path);
2079
+ if (!state.settled.includes(k)) state.settled.push(k);
2080
+ }
2081
+ function clone(state) {
2082
+ return JSON.parse(JSON.stringify(state));
2083
+ }
2084
+ function coerce(leaf, raw) {
2085
+ if (typeof raw !== "string") return raw;
2086
+ if (leaf.valueType === "number") {
2087
+ const n = Number(raw);
2088
+ return raw.trim() !== "" && !Number.isNaN(n) ? n : raw;
2089
+ }
2090
+ if (leaf.valueType === "boolean") {
2091
+ if (raw === "true") return true;
2092
+ if (raw === "false") return false;
2093
+ }
2094
+ return raw;
2095
+ }
2096
+ async function validationError(leaf, value, state) {
2097
+ const context = await resolveContext(leaf, state.resolved);
2098
+ const config = leaf.resolver?.prompt?.({
2099
+ items: state.listing?.items ?? [],
2100
+ input: mergeInput(state.resolved, leaf.extraInput),
2101
+ context
2102
+ });
2103
+ if (!config?.validate) return null;
2104
+ const verdict = config.validate(value);
2105
+ if (verdict === true) return null;
2106
+ return typeof verdict === "string" ? verdict : `${leaf.name}: invalid value`;
2107
+ }
2108
+ function toChoice(c) {
2109
+ const label = "label" in c ? c.label : c.name;
2110
+ const hint = Array.isArray(c.hint) ? c.hint.join(", ") : c.hint;
2111
+ return { label, value: String(c.value), hint };
2112
+ }
2113
+ function isRef(r) {
2114
+ return typeof r === "object" && r !== null && "ref" in r;
2115
+ }
2116
+ function toLeaf(name, field, definitions) {
2117
+ let resolver;
2118
+ let extraInput;
2119
+ if (isRef(field.resolver)) {
2120
+ resolver = definitions?.[field.resolver.ref];
2121
+ extraInput = field.resolver.input;
2122
+ } else {
2123
+ resolver = field.resolver;
2124
+ }
2125
+ return {
2126
+ name,
2127
+ required: field.required ?? false,
2128
+ resolver,
2129
+ extraInput,
2130
+ // Carry the field's value type so nested answers coerce (number/boolean)
2131
+ // the same way top-level params do. Without this a nested `z.number()`
2132
+ // field's typed answer stays a string and fails final validation.
2133
+ valueType: field.valueType,
2134
+ requires: resolver?.requireParameters ?? []
2135
+ };
2136
+ }
2137
+ async function objectChildren(resolver, input) {
2138
+ if (resolver.properties) {
2139
+ return Object.entries(resolver.properties).map(
2140
+ ([name, field]) => toLeaf(name, field, resolver.definitions)
2141
+ );
2142
+ }
2143
+ if (!resolver.getProperties) return [];
2144
+ const fields = await resolver.getProperties({ input });
2145
+ return Object.entries(fields).map(([name, field]) => {
2146
+ if (!isRef(field.resolver) && (field.resolver.imports?.length ?? 0) > 0) {
2147
+ throw new Error(
2148
+ `dynamic object field "${name}" inlines an import-bearing resolver; use { ref } into the object's definitions so its imports bind`
2149
+ );
2150
+ }
2151
+ return toLeaf(name, field, resolver.definitions);
2152
+ });
2153
+ }
2154
+ function arrayItem(resolver) {
2155
+ const items = resolver.items;
2156
+ const valueType = resolver.itemValueType;
2157
+ if (isRef(items)) {
2158
+ return {
2159
+ name: "",
2160
+ required: true,
2161
+ resolver: resolver.definitions?.[items.ref],
2162
+ extraInput: items.input,
2163
+ valueType,
2164
+ requires: []
2165
+ };
2166
+ }
2167
+ return {
2168
+ name: "",
2169
+ required: true,
2170
+ resolver: items,
2171
+ valueType,
2172
+ requires: []
2173
+ };
2174
+ }
2175
+ function mergeInput(input, extra) {
2176
+ return extra ? { ...input, ...extra } : input;
2177
+ }
2178
+ async function childrenAt(ctx, path, resolved) {
2179
+ if (path.length === 0) return ctx.parameters;
2180
+ const leaf = await leafAt(ctx, path, resolved);
2181
+ if (!leaf?.resolver || leaf.resolver.type !== "object") return [];
2182
+ return objectChildren(leaf.resolver, mergeInput(resolved, leaf.extraInput));
2183
+ }
2184
+ async function leafAt(ctx, path, resolved) {
2185
+ let children = ctx.parameters;
2186
+ let leaf;
2187
+ for (let i = 0; i < path.length; i++) {
2188
+ const seg = path[i];
2189
+ if (typeof seg === "number") {
2190
+ if (leaf?.resolver?.type !== "array") return void 0;
2191
+ leaf = arrayItem(leaf.resolver);
2192
+ } else {
2193
+ leaf = children.find((c) => c.name === seg);
2194
+ if (!leaf) return void 0;
2195
+ }
2196
+ if (i < path.length - 1 && typeof path[i + 1] === "string") {
2197
+ if (leaf?.resolver?.type !== "object") return void 0;
2198
+ children = await objectChildren(
2199
+ leaf.resolver,
2200
+ mergeInput(resolved, leaf.extraInput)
2201
+ );
2202
+ }
2203
+ }
2204
+ return leaf;
2205
+ }
2206
+ async function arrayInfoAt(ctx, path, resolved) {
2207
+ const leaf = await leafAt(ctx, path, resolved);
2208
+ const resolver = leaf?.resolver;
2209
+ if (resolver?.type !== "array") {
2210
+ throw new Error(`expected an array resolver at "${key(path)}"`);
2211
+ }
2212
+ return {
2213
+ min: resolver.minItems ?? 0,
2214
+ max: resolver.maxItems ?? Infinity,
2215
+ item: { ...arrayItem(resolver), name: String(path[path.length - 1]) }
2216
+ };
2217
+ }
2218
+ var AFFORDANCE = {
2219
+ choose: { action: "choose", description: "Pick one of the listed options" },
2220
+ custom: {
2221
+ action: "custom",
2222
+ description: "Provide a value directly",
2223
+ supply: "value"
2224
+ },
2225
+ search: {
2226
+ action: "search",
2227
+ description: "Filter the options by a search term",
2228
+ supply: "term"
2229
+ },
2230
+ more: { action: "more", description: "Load more options" },
2231
+ skip: { action: "skip", description: "Omit this optional parameter" },
2232
+ add: { action: "add", description: "Add another item" },
2233
+ done: { action: "done", description: "Finish the list" },
2234
+ retry: { action: "retry", description: "Retry loading the options" },
2235
+ cancel: { action: "cancel", description: "Cancel resolution" }
2236
+ };
2237
+ async function firstPage(result) {
2238
+ const page = await result;
2239
+ return {
2240
+ data: Array.isArray(page?.data) ? page.data : [],
2241
+ nextCursor: page?.nextCursor
2242
+ };
2243
+ }
2244
+ async function resolveContext(leaf, input) {
2245
+ return leaf.resolver?.getContext?.({
2246
+ input: mergeInput(input, leaf.extraInput)
2247
+ });
2248
+ }
2249
+ async function fetchListing(leaf, input, opts = {}) {
2250
+ const page = await firstPage(
2251
+ leaf.resolver?.listItems?.({
2252
+ input: mergeInput(input, leaf.extraInput),
2253
+ context: opts.context,
2254
+ search: opts.search,
2255
+ cursor: opts.cursor
2256
+ })
2257
+ );
2258
+ return {
2259
+ items: [...opts.priorItems ?? [], ...page.data],
2260
+ cursor: page.nextCursor,
2261
+ search: opts.search,
2262
+ exhausted: page.nextCursor == null
2263
+ };
2264
+ }
2265
+ function selectActions(leaf, listing, multiple) {
2266
+ const actions = multiple ? [AFFORDANCE.choose] : [AFFORDANCE.choose, AFFORDANCE.custom];
2267
+ if (leaf.resolver?.inputType === "search") actions.push(AFFORDANCE.search);
2268
+ if (listing.cursor) actions.push(AFFORDANCE.more);
2269
+ if (!leaf.required) actions.push(AFFORDANCE.skip);
2270
+ return actions;
2271
+ }
2272
+ function selectQuestion(leaf, input, listing, context) {
2273
+ const config = leaf.resolver?.prompt?.({
2274
+ items: listing.items,
2275
+ input: mergeInput(input, leaf.extraInput),
2276
+ context
2277
+ });
2278
+ const multiple = config?.type === "checkbox";
2279
+ return {
2280
+ type: "select",
2281
+ message: config?.message ?? `Select ${leaf.name}:`,
2282
+ choices: (config?.choices ?? []).map(toChoice),
2283
+ ...multiple ? { multiple: true } : {},
2284
+ ...config?.notes?.length ? { notes: config.notes } : {},
2285
+ actions: selectActions(leaf, listing, multiple)
2286
+ };
2287
+ }
2288
+ function toControllerError(error) {
2289
+ if (error instanceof Error) {
2290
+ const code = error.code;
2291
+ return {
2292
+ name: error.name,
2293
+ message: error.message,
2294
+ ...typeof code === "string" ? { code } : {}
2295
+ };
2296
+ }
2297
+ return { name: "Error", message: String(error) };
2298
+ }
2299
+ function failedResult(state, name, error) {
2300
+ return {
2301
+ state,
2302
+ result: {
2303
+ status: "failed",
2304
+ error: toControllerError(error),
2305
+ question: {
2306
+ type: "select",
2307
+ message: `Could not load options for ${name}.`,
2308
+ choices: [],
2309
+ actions: [AFFORDANCE.retry, AFFORDANCE.cancel]
2310
+ }
2311
+ }
2312
+ };
2313
+ }
2314
+ async function buildQuestion(leaf, input) {
2315
+ const optional = !leaf.required;
2316
+ const resolver = leaf.resolver;
2317
+ if (resolver?.listItems) {
2318
+ const context = await resolveContext(leaf, input);
2319
+ const listing = await fetchListing(leaf, input, { context });
2320
+ return {
2321
+ question: selectQuestion(leaf, input, listing, context),
2322
+ listing
2323
+ };
2324
+ }
2325
+ if (leaf.staticChoices) {
2326
+ const actions2 = [AFFORDANCE.choose];
2327
+ if (optional) actions2.push(AFFORDANCE.skip);
2328
+ return {
2329
+ question: {
2330
+ type: "select",
2331
+ message: `Select ${leaf.name}:`,
2332
+ choices: leaf.staticChoices,
2333
+ actions: actions2
2334
+ }
2335
+ };
2336
+ }
2337
+ const inputType = resolver?.inputType && resolver.inputType !== "search" ? resolver.inputType : "text";
2338
+ const actions = [AFFORDANCE.custom];
2339
+ if (optional) actions.push(AFFORDANCE.skip);
2340
+ return {
2341
+ question: {
2342
+ type: "input",
2343
+ message: `Enter ${leaf.name}:`,
2344
+ inputType,
2345
+ placeholder: resolver?.placeholder,
2346
+ actions
2347
+ }
2348
+ };
2349
+ }
2350
+ function finalize(ctx, resolved) {
2351
+ if (!ctx.schema) return { status: "done", value: resolved };
2352
+ const parsed = ctx.schema.safeParse(resolved);
2353
+ if (parsed.success) {
2354
+ return { status: "done", value: parsed.data };
2355
+ }
2356
+ const issues = parsed.error.issues.map((i) => ({
2357
+ parameter: i.path.map(String).join(".") || void 0,
2358
+ message: i.message
2359
+ }));
2360
+ return { status: "invalid", issues };
2361
+ }
2362
+ function collectionQuestion(t) {
2363
+ const actions = [AFFORDANCE.add];
2364
+ if (t.count >= t.min) actions.push(AFFORDANCE.done);
2365
+ return {
2366
+ type: "collection",
2367
+ message: `Add another ${t.path[t.path.length - 1]}? (${t.count} so far)`,
2368
+ count: t.count,
2369
+ min: t.min,
2370
+ // An unbounded array's max is Infinity, which JSON.stringify turns to null;
2371
+ // omit it so the question round-trips across the wall as plain data.
2372
+ ...Number.isFinite(t.max) ? { max: t.max } : {},
2373
+ actions
2374
+ };
2375
+ }
2376
+ async function findInArray(ctx, state, path) {
2377
+ if (isSettled(state, path)) return null;
2378
+ if (getAtPath(state.resolved, path) == null)
2379
+ setAtPath(state.resolved, path, []);
2380
+ if (!state.interactive) {
2381
+ settle(state, path);
2382
+ return null;
2383
+ }
2384
+ const { min, max, item } = await arrayInfoAt(ctx, path, state.resolved);
2385
+ const items = getAtPath(state.resolved, path);
2386
+ const len = items.length;
2387
+ const itemType = item.resolver?.type;
2388
+ if (len > 0 && (itemType === "object" || itemType === "array")) {
2389
+ const inner = await findNext(ctx, state, [...path, len - 1]);
2390
+ if (inner) return inner;
2391
+ }
2392
+ if (len < min) return descendItem(ctx, state, path, len, item);
2393
+ if (len < max) return { kind: "array", path, count: len, min, max };
2394
+ settle(state, path);
2395
+ return null;
2396
+ }
2397
+ function seedItemSlot(state, itemPath, item) {
2398
+ const type = item.resolver?.type;
2399
+ if (type === "object") {
2400
+ setAtPath(state.resolved, itemPath, {});
2401
+ return "object";
2402
+ }
2403
+ if (type === "array") {
2404
+ setAtPath(state.resolved, itemPath, []);
2405
+ return "array";
2406
+ }
2407
+ return "leaf";
2408
+ }
2409
+ async function descendItem(ctx, state, arrayPath, index, item) {
2410
+ const itemPath = [...arrayPath, index];
2411
+ const kind = seedItemSlot(state, itemPath, item);
2412
+ if (kind === "object") return findNext(ctx, state, itemPath);
2413
+ if (kind === "array") return findInArray(ctx, state, itemPath);
2414
+ return { kind: "leaf", path: itemPath, leaf: item };
2415
+ }
2416
+ async function findNext(ctx, state, path = []) {
2417
+ const container = getAtPath(state.resolved, path) ?? {};
2418
+ for (const leaf of await childrenAt(ctx, path, state.resolved)) {
2419
+ const childPath = [...path, leaf.name];
2420
+ if (!leaf.requires.every((r) => container[r] !== void 0)) continue;
2421
+ if (leaf.resolver?.type === "object") {
2422
+ if (getAtPath(state.resolved, childPath) == null)
2423
+ setAtPath(state.resolved, childPath, {});
2424
+ const inner = await findNext(ctx, state, childPath);
2425
+ if (inner) return inner;
2426
+ continue;
2427
+ }
2428
+ if (leaf.resolver?.type === "array") {
2429
+ const inner = await findInArray(ctx, state, childPath);
2430
+ if (inner) return inner;
2431
+ continue;
2432
+ }
2433
+ if (container[leaf.name] !== void 0 || isSettled(state, childPath))
2434
+ continue;
2435
+ return { kind: "leaf", path: childPath, leaf };
2436
+ }
2437
+ return null;
2438
+ }
2439
+ async function askLeaf(state, path, leaf, opts = {}) {
2440
+ state.current = path;
2441
+ try {
2442
+ const { question, listing } = await buildQuestion(leaf, state.resolved);
2443
+ state.listing = listing;
2444
+ return {
2445
+ state,
2446
+ result: {
2447
+ status: "ask",
2448
+ question,
2449
+ ...opts.error ? { error: opts.error } : {}
2450
+ }
2451
+ };
2452
+ } catch (error) {
2453
+ state.listing = { items: [], exhausted: false };
2454
+ return failedResult(state, leaf.name, error);
2455
+ }
2456
+ }
2457
+ async function advance(ctx, state) {
2458
+ for (; ; ) {
2459
+ const target = await findNext(ctx, state);
2460
+ if (!target) {
2461
+ delete state.current;
2462
+ delete state.listing;
2463
+ return { state, result: finalize(ctx, state.resolved) };
2464
+ }
2465
+ if (target.kind === "array") {
2466
+ state.current = target.path;
2467
+ delete state.listing;
2468
+ return {
2469
+ state,
2470
+ result: { status: "ask", question: collectionQuestion(target) }
2471
+ };
2472
+ }
2473
+ const { path, leaf } = target;
2474
+ const auto = await leaf.resolver?.tryResolveWithoutPrompt?.({
2475
+ input: mergeInput(state.resolved, leaf.extraInput)
2476
+ });
2477
+ if (auto) {
2478
+ if (auto.resolvedValue !== void 0)
2479
+ setAtPath(state.resolved, path, auto.resolvedValue);
2480
+ settle(state, path);
2481
+ continue;
2482
+ }
2483
+ if (!state.interactive) {
2484
+ if (!leaf.required) {
2485
+ settle(state, path);
2486
+ continue;
2487
+ }
2488
+ } else if (!leaf.required && !leaf.resolver) {
2489
+ settle(state, path);
2490
+ continue;
2491
+ }
2492
+ return askLeaf(state, path, leaf);
2493
+ }
2494
+ }
2495
+ async function start(ctx, input = {}, interactive = true) {
2496
+ const resolved = {};
2497
+ for (const spec of ctx.parameters) {
2498
+ if (spec.resolver?.type === "constant")
2499
+ resolved[spec.name] = spec.resolver.value;
2500
+ }
2501
+ Object.assign(resolved, input);
2502
+ return advance(ctx, {
2503
+ method: ctx.method,
2504
+ resolved,
2505
+ settled: [],
2506
+ interactive
2507
+ });
2508
+ }
2509
+ async function step(ctx, prior, action) {
2510
+ const state = clone(prior);
2511
+ if (action.type === "cancel") {
2512
+ delete state.current;
2513
+ delete state.listing;
2514
+ return { state, result: { status: "cancelled" } };
2515
+ }
2516
+ const path = state.current;
2517
+ if (!path) throw new Error("step called with no outstanding question");
2518
+ const leaf = await leafAt(ctx, path, state.resolved);
2519
+ if (leaf && (action.type === "search" || action.type === "more" || action.type === "retry")) {
2520
+ return refine(ctx, state, leaf, path, action);
2521
+ }
2522
+ if (action.type === "add" || action.type === "done") {
2523
+ delete state.current;
2524
+ delete state.listing;
2525
+ if (action.type === "done") {
2526
+ settle(state, path);
2527
+ return advance(ctx, state);
2528
+ }
2529
+ const items = getAtPath(state.resolved, path) ?? [];
2530
+ const { item } = await arrayInfoAt(ctx, path, state.resolved);
2531
+ const itemPath = [...path, items.length];
2532
+ if (seedItemSlot(state, itemPath, item) === "leaf")
2533
+ return askLeaf(state, itemPath, item);
2534
+ return advance(ctx, state);
2535
+ }
2536
+ switch (action.type) {
2537
+ case "choose":
2538
+ case "custom": {
2539
+ if (leaf) {
2540
+ const error = await validationError(leaf, action.value, state);
2541
+ if (error) return askLeaf(state, path, leaf, { error });
2542
+ }
2543
+ setAtPath(
2544
+ state.resolved,
2545
+ path,
2546
+ leaf ? coerce(leaf, action.value) : action.value
2547
+ );
2548
+ break;
2549
+ }
2550
+ case "skip":
2551
+ settle(state, path);
2552
+ break;
2553
+ default:
2554
+ throw new Error(`action "${action.type}" is not supported here`);
2555
+ }
2556
+ delete state.current;
2557
+ delete state.listing;
2558
+ return advance(ctx, state);
2559
+ }
2560
+ async function refine(ctx, state, leaf, path, action) {
2561
+ const attempt = action.type === "search" ? { search: action.term, cursor: void 0, priorItems: [] } : {
2562
+ search: state.listing?.search,
2563
+ cursor: state.listing?.cursor,
2564
+ priorItems: state.listing?.items ?? []
2565
+ };
2566
+ try {
2567
+ if (action.type === "search") {
2568
+ const exact = await leaf.resolver?.tryResolveFromSearch?.({
2569
+ input: mergeInput(state.resolved, leaf.extraInput),
2570
+ search: action.term
2571
+ });
2572
+ if (exact) {
2573
+ setAtPath(state.resolved, path, coerce(leaf, exact.resolvedValue));
2574
+ delete state.current;
2575
+ delete state.listing;
2576
+ return advance(ctx, state);
2577
+ }
2578
+ }
2579
+ const context = await resolveContext(leaf, state.resolved);
2580
+ state.listing = await fetchListing(leaf, state.resolved, {
2581
+ ...attempt,
2582
+ context
2583
+ });
2584
+ return {
2585
+ state,
2586
+ result: {
2587
+ status: "ask",
2588
+ question: selectQuestion(leaf, state.resolved, state.listing, context)
2589
+ }
2590
+ };
2591
+ } catch (error) {
2592
+ state.listing = {
2593
+ items: attempt.priorItems,
2594
+ search: attempt.search,
2595
+ cursor: attempt.cursor,
2596
+ exhausted: false
2597
+ };
2598
+ return failedResult(state, leaf.name, error);
2599
+ }
2600
+ }
2601
+ function toJsonSchema(schema) {
2602
+ if (!schema) return void 0;
2603
+ try {
2604
+ return zod.z.toJSONSchema(schema);
2605
+ } catch {
2606
+ return void 0;
2607
+ }
2608
+ }
2609
+ function projectSummary(entry) {
2610
+ return {
2611
+ name: entry.name,
2612
+ ...entry.description ? { description: entry.description } : {},
2613
+ ...entry.categories?.length ? { categories: entry.categories } : {}
2614
+ };
2615
+ }
2616
+ function projectMethod(entry) {
2617
+ const inputProperties = toJsonSchema(entry.inputSchema)?.properties;
2618
+ const parameters = {};
2619
+ for (const spec of planParameters(entry).parameters) {
2620
+ parameters[spec.name] = {
2621
+ required: spec.required,
2622
+ dynamic: Boolean(spec.resolver?.listItems),
2623
+ ...spec.resolver?.inputType === "search" ? { searchable: true } : {},
2624
+ ...inputProperties?.[spec.name] ? { schema: inputProperties[spec.name] } : {},
2625
+ ...spec.staticChoices ? { choices: spec.staticChoices } : {},
2626
+ ...spec.requires.length ? { requireParameters: spec.requires } : {}
2627
+ };
2628
+ }
2629
+ const output = toJsonSchema(entry.outputSchema);
2630
+ return {
2631
+ name: entry.name,
2632
+ ...entry.description ? { description: entry.description } : {},
2633
+ ...entry.categories?.length ? { categories: entry.categories } : {},
2634
+ parameters,
2635
+ ...entry.positional?.length ? { positional: entry.positional } : {},
2636
+ ...output ? { output } : {}
2637
+ };
2638
+ }
2639
+ function createController(sdk) {
2640
+ function entryFor(method) {
2641
+ const entry = sdk.getRegistry().functions.find((f) => f.name === method);
2642
+ if (!entry) throw new Error(`unknown method "${method}"`);
2643
+ return entry;
2644
+ }
2645
+ function contextFor(method) {
2646
+ const entry = entryFor(method);
2647
+ return {
2648
+ method,
2649
+ schema: entry.inputSchema,
2650
+ parameters: planParameters(entry).parameters
2651
+ };
2652
+ }
2653
+ const start2 = ({ method, input, interactive }) => start(contextFor(method), input, interactive);
2654
+ const step2 = ({ state, action }) => step(contextFor(state.method), state, action);
2655
+ const resolve2 = async ({
2656
+ method,
2657
+ input,
2658
+ answer,
2659
+ interactive
2660
+ }) => {
2661
+ const ctx = contextFor(method);
2662
+ let { state, result } = await start(ctx, input, interactive);
2663
+ while (result.status === "ask" || result.status === "failed") {
2664
+ const action = await answer({ state, result });
2665
+ ({ state, result } = await step(ctx, state, action));
2666
+ }
2667
+ if (result.status === "done") return result.value;
2668
+ if (result.status === "cancelled") {
2669
+ throw new CoreCancelledSignal(`resolution cancelled for "${method}"`);
2670
+ }
2671
+ const detail = result.issues.map((i) => i.parameter ? `${i.parameter}: ${i.message}` : i.message).join("; ");
2672
+ throw new Error(`invalid input for "${method}": ${detail}`);
2673
+ };
2674
+ const listMethods = () => ({
2675
+ data: sdk.getRegistry().functions.map(projectSummary)
2676
+ });
2677
+ const getMethod = ({ method }) => ({
2678
+ data: projectMethod(entryFor(method))
2679
+ });
2680
+ const listChoices = async ({
2681
+ method,
2682
+ parameter,
2683
+ input = {},
2684
+ search,
2685
+ cursor
2686
+ }) => {
2687
+ const spec = contextFor(method).parameters.find(
2688
+ (p) => p.name === parameter
2689
+ );
2690
+ if (!spec?.resolver?.listItems) return { data: [] };
2691
+ const context = await spec.resolver.getContext?.({ input });
2692
+ const page = await firstPage(
2693
+ spec.resolver.listItems({ input, context, search, cursor })
2694
+ );
2695
+ const config = spec.resolver.prompt?.({ items: page.data, input, context });
2696
+ const data = (config?.choices ?? []).map(toChoice);
2697
+ return { data, nextCursor: page.nextCursor };
2698
+ };
2699
+ return { resolve: resolve2, start: start2, step: step2, listMethods, getMethod, listChoices };
2700
+ }
1861
2701
  function createCorePlugin(options) {
1862
2702
  return () => ({
1863
2703
  context: {
@@ -2825,8 +3665,8 @@ function normalizeHeaders(optionsHeaders) {
2825
3665
  return headers;
2826
3666
  }
2827
3667
  const headerEntries = optionsHeaders instanceof Headers ? Array.from(optionsHeaders.entries()) : Array.isArray(optionsHeaders) ? optionsHeaders : Object.entries(optionsHeaders);
2828
- for (const [key, value] of headerEntries) {
2829
- headers[key] = value;
3668
+ for (const [key2, value] of headerEntries) {
3669
+ headers[key2] = value;
2830
3670
  }
2831
3671
  return headers;
2832
3672
  }
@@ -3116,28 +3956,28 @@ function censorHeaders(headers) {
3116
3956
  if (!headers) return headers;
3117
3957
  const headersObj = new Headers(headers);
3118
3958
  const authKeys = ["authorization", "x-api-key"];
3119
- for (const [key, value] of headersObj.entries()) {
3120
- if (authKeys.some((authKey) => key.toLowerCase() === authKey)) {
3959
+ for (const [key2, value] of headersObj.entries()) {
3960
+ if (authKeys.some((authKey) => key2.toLowerCase() === authKey)) {
3121
3961
  const spaceIndex = value.indexOf(" ");
3122
3962
  if (spaceIndex > 0 && spaceIndex < value.length - 1) {
3123
3963
  const prefix = value.substring(0, spaceIndex + 1);
3124
3964
  const token = value.substring(spaceIndex + 1);
3125
3965
  if (token.length > 12) {
3126
- const start = token.substring(0, 4);
3966
+ const start2 = token.substring(0, 4);
3127
3967
  const end = token.substring(token.length - 4);
3128
- headersObj.set(key, `${prefix}${start}...${end}`);
3968
+ headersObj.set(key2, `${prefix}${start2}...${end}`);
3129
3969
  } else {
3130
3970
  const firstChar = token.charAt(0);
3131
- headersObj.set(key, `${prefix}${firstChar}...`);
3971
+ headersObj.set(key2, `${prefix}${firstChar}...`);
3132
3972
  }
3133
3973
  } else {
3134
3974
  if (value.length > 12) {
3135
- const start = value.substring(0, 4);
3975
+ const start2 = value.substring(0, 4);
3136
3976
  const end = value.substring(value.length - 4);
3137
- headersObj.set(key, `${start}...${end}`);
3977
+ headersObj.set(key2, `${start2}...${end}`);
3138
3978
  } else {
3139
3979
  const firstChar = value.charAt(0);
3140
- headersObj.set(key, `${firstChar}...`);
3980
+ headersObj.set(key2, `${firstChar}...`);
3141
3981
  }
3142
3982
  }
3143
3983
  }
@@ -3706,21 +4546,21 @@ function getClientIdFromCredentials(credentials) {
3706
4546
  function createMemoryCache() {
3707
4547
  const store = /* @__PURE__ */ new Map();
3708
4548
  return {
3709
- async get(key) {
3710
- const entry = store.get(key);
4549
+ async get(key2) {
4550
+ const entry = store.get(key2);
3711
4551
  if (!entry) return void 0;
3712
4552
  if (entry.expiresAt !== void 0 && entry.expiresAt <= Date.now()) {
3713
- store.delete(key);
4553
+ store.delete(key2);
3714
4554
  return void 0;
3715
4555
  }
3716
4556
  return { value: entry.value, expiresAt: entry.expiresAt };
3717
4557
  },
3718
- async set(key, value, options) {
4558
+ async set(key2, value, options) {
3719
4559
  const expiresAt = options?.ttl ? Date.now() + options.ttl * 1e3 : void 0;
3720
- store.set(key, { value, expiresAt });
4560
+ store.set(key2, { value, expiresAt });
3721
4561
  },
3722
- async delete(key) {
3723
- store.delete(key);
4562
+ async delete(key2) {
4563
+ store.delete(key2);
3724
4564
  }
3725
4565
  };
3726
4566
  }
@@ -4211,14 +5051,14 @@ function createSseParserStream() {
4211
5051
  transform(chunk, controller) {
4212
5052
  buffer += chunk;
4213
5053
  const newline = /\r\n|\r|\n/g;
4214
- let start = 0;
5054
+ let start2 = 0;
4215
5055
  let match;
4216
5056
  while ((match = newline.exec(buffer)) !== null) {
4217
5057
  if (match[0] === "\r" && match.index === buffer.length - 1) break;
4218
- processLine(buffer.slice(start, match.index), controller);
4219
- start = match.index + match[0].length;
5058
+ processLine(buffer.slice(start2, match.index), controller);
5059
+ start2 = match.index + match[0].length;
4220
5060
  }
4221
- buffer = buffer.slice(start);
5061
+ buffer = buffer.slice(start2);
4222
5062
  },
4223
5063
  flush(controller) {
4224
5064
  if (buffer.endsWith("\r")) {
@@ -4320,8 +5160,63 @@ function parseApprovalReviewStreamPayload(parsed, toolNames) {
4320
5160
  }
4321
5161
  }
4322
5162
 
5163
+ // src/api/deprecation.ts
5164
+ var DEPRECATION_MESSAGE_HEADER = "zapier-sdk-deprecation-message";
5165
+ var DEPRECATION_ID_HEADER = "zapier-sdk-deprecation-id";
5166
+ var DEPRECATION_NOTICE_EVENT = "api:deprecation_notice";
5167
+ var displayedNoticeIds = /* @__PURE__ */ new Set();
5168
+ function handleDeprecationNotice({
5169
+ response,
5170
+ canSendDeprecationMessaging,
5171
+ onEvent
5172
+ }) {
5173
+ try {
5174
+ sniffDeprecationNotice({ response, canSendDeprecationMessaging, onEvent });
5175
+ } catch {
5176
+ }
5177
+ }
5178
+ function sniffDeprecationNotice({
5179
+ response,
5180
+ canSendDeprecationMessaging,
5181
+ onEvent
5182
+ }) {
5183
+ if (!canSendDeprecationMessaging) return;
5184
+ const message = response.headers?.get(DEPRECATION_MESSAGE_HEADER);
5185
+ if (!message) return;
5186
+ const id = response.headers.get(DEPRECATION_ID_HEADER) ?? message;
5187
+ if (!displayedNoticeIds.has(id)) {
5188
+ displayedNoticeIds.add(id);
5189
+ console.warn(`[zapier-sdk] Deprecation: ${message}`);
5190
+ }
5191
+ if (onEvent) {
5192
+ const payload = { id, message };
5193
+ const deprecation = parseDeprecationDate(
5194
+ response.headers.get("deprecation")
5195
+ );
5196
+ if (deprecation !== void 0) payload.deprecation = deprecation;
5197
+ const maybePromise = onEvent({
5198
+ type: DEPRECATION_NOTICE_EVENT,
5199
+ payload: { ...payload },
5200
+ timestamp: Date.now()
5201
+ });
5202
+ if (isPromiseLike(maybePromise)) {
5203
+ void Promise.resolve(maybePromise).catch(() => {
5204
+ });
5205
+ }
5206
+ }
5207
+ }
5208
+ function isPromiseLike(value) {
5209
+ return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
5210
+ }
5211
+ function parseDeprecationDate(value) {
5212
+ if (!value) return void 0;
5213
+ const match = /^@(-?\d+)$/.exec(value.trim());
5214
+ if (!match) return void 0;
5215
+ return Number(match[1]) * 1e3;
5216
+ }
5217
+
4323
5218
  // src/sdk-version.ts
4324
- var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.78.0" : void 0) || "unknown";
5219
+ var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.80.0" : void 0) || "unknown";
4325
5220
 
4326
5221
  // src/utils/open-url.ts
4327
5222
  var nodePrefix = "node:";
@@ -4433,6 +5328,30 @@ var PollApprovalResponseSchema = zod.z.object({
4433
5328
  reason: zod.z.string().optional()
4434
5329
  });
4435
5330
  var APPROVAL_MAX_POLLING_INTERVAL_MS = 5e3;
5331
+ function validateSdkPath(path) {
5332
+ if (!path.startsWith("/") || path.startsWith("//")) {
5333
+ throw new ZapierValidationError(
5334
+ `fetch expects a path starting with a single '/', got: ${path}`
5335
+ );
5336
+ }
5337
+ }
5338
+ function findPathConfigEntries({
5339
+ path,
5340
+ matchResolvedGatewayPath = false
5341
+ }) {
5342
+ const pathSegments = path.split("/").filter(Boolean);
5343
+ return Object.entries(pathConfig).filter(([configPath, config]) => {
5344
+ if (!matchResolvedGatewayPath) {
5345
+ return path === configPath || path.startsWith(`${configPath}/`);
5346
+ }
5347
+ const prefixSegments = (config.pathPrefix ?? configPath).split("/").filter(Boolean);
5348
+ return pathSegments.some(
5349
+ (_, startIndex) => prefixSegments.every(
5350
+ (segment, offset) => pathSegments[startIndex + offset] === segment
5351
+ )
5352
+ );
5353
+ }).map(([configPath, config]) => ({ configPath, config }));
5354
+ }
4436
5355
  function parseRateLimitHeaders(response) {
4437
5356
  const info = {};
4438
5357
  const retryAfter = response.headers.get("retry-after");
@@ -4477,8 +5396,18 @@ var pathConfig = {
4477
5396
  // e.g. /relay -> https://sdkapi.zapier.com/api/v0/sdk/relay/...
4478
5397
  "/relay": {
4479
5398
  authHeader: "X-Relay-Authorization",
4480
- pathPrefix: "/api/v0/sdk/relay"
5399
+ pathPrefix: "/api/v0/sdk/relay",
5400
+ omitDeprecationMessaging: true
5401
+ },
5402
+ // The concrete gateway form of the relay route. Callers that pass the
5403
+ // already-prefixed path reach the same third-party upstreams, so it must
5404
+ // classify as relay too; without this entry it would match nothing and
5405
+ // sniff deprecation headers off a relay response.
5406
+ "/api/v0/sdk/relay": {
5407
+ omitDeprecationMessaging: true
4481
5408
  },
5409
+ // Concrete sdkapi routes that do not live behind /api/v0/sdk/<service>.
5410
+ "/api/v0": {},
4482
5411
  // e.g. /zapier -> https://sdkapi.zapier.com/api/v0/sdk/zapier/...
4483
5412
  "/zapier": {
4484
5413
  authHeader: "Authorization",
@@ -4533,11 +5462,11 @@ var ZapierApiClient = class {
4533
5462
  );
4534
5463
  const inputHeaders = new Headers(init?.headers ?? {});
4535
5464
  const mergedHeaders = new Headers();
4536
- builtHeaders.forEach((value, key) => {
4537
- mergedHeaders.set(key, value);
5465
+ builtHeaders.forEach((value, key2) => {
5466
+ mergedHeaders.set(key2, value);
4538
5467
  });
4539
- inputHeaders.forEach((value, key) => {
4540
- mergedHeaders.set(key, value);
5468
+ inputHeaders.forEach((value, key2) => {
5469
+ mergedHeaders.set(key2, value);
4541
5470
  });
4542
5471
  this.applyTelemetryHeaders(mergedHeaders);
4543
5472
  let retries = 0;
@@ -4627,17 +5556,50 @@ var ZapierApiClient = class {
4627
5556
  * parallelism into the queue.
4628
5557
  */
4629
5558
  this.rawFetch = async (path, init) => {
4630
- if (!path.startsWith("/")) {
4631
- throw new ZapierValidationError(
4632
- `fetch expects a path starting with '/', got: ${path}`
4633
- );
4634
- }
5559
+ validateSdkPath(path);
4635
5560
  const { url, pathConfig: pathConfig2 } = this.buildUrl(path, init?.searchParams);
4636
5561
  return this.withSemaphore(
4637
5562
  { url, method: init?.method ?? "GET", signal: init?.signal },
4638
5563
  () => this.rawFetchUrl(url, init, pathConfig2)
4639
5564
  );
4640
5565
  };
5566
+ this.runApprovalFetchLoop = async ({
5567
+ path,
5568
+ init,
5569
+ maxRetries,
5570
+ approvalMode,
5571
+ approvalContext
5572
+ }) => {
5573
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
5574
+ const response = await this.rawFetch(path, init);
5575
+ if (response.status !== 403) {
5576
+ return { response };
5577
+ }
5578
+ const errorType = response.headers.get("x-zapier-error-type");
5579
+ if (errorType !== "approval_required") {
5580
+ return { response };
5581
+ }
5582
+ if (attempt === maxRetries) {
5583
+ return { response };
5584
+ }
5585
+ if (approvalMode === "disabled") {
5586
+ return { response };
5587
+ }
5588
+ if (!approvalContext) {
5589
+ return { response };
5590
+ }
5591
+ try {
5592
+ await this.runOneApprovalRound(
5593
+ approvalContext,
5594
+ approvalMode,
5595
+ init?.signal ?? void 0
5596
+ );
5597
+ } catch (error) {
5598
+ return { response, approvalRoundError: error };
5599
+ }
5600
+ }
5601
+ throw new ZapierApiError("Approval retry loop ended unexpectedly");
5602
+ };
4641
5603
  /**
4642
5604
  * Approval-aware HTTP fetch.
4643
5605
  *
@@ -4667,46 +5629,62 @@ var ZapierApiClient = class {
4667
5629
  * `max_retries_exceeded` instead.
4668
5630
  */
4669
5631
  this.fetch = async (path, init) => {
5632
+ validateSdkPath(path);
4670
5633
  const maxRetries = this.options.maxApprovalRetries ?? DEFAULT_MAX_APPROVAL_RETRIES;
4671
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
4672
- const response = await this.rawFetch(path, init);
4673
- if (response.status !== 403) return response;
4674
- const errorType = response.headers.get("x-zapier-error-type");
4675
- if (errorType === "request_denied_by_policy") {
4676
- const { data } = await this.parseResult(response);
4677
- const { message, errors } = this.parseErrorResponse({
4678
- status: response.status,
4679
- statusText: response.statusText,
4680
- data
4681
- });
4682
- throw new ZapierApprovalError(
4683
- message || "Request explicitly denied by policy",
4684
- {
4685
- status: "policy_denied",
4686
- statusCode: response.status,
4687
- errors
4688
- }
4689
- );
4690
- }
4691
- if (errorType !== "approval_required") return response;
4692
- if (attempt === maxRetries) break;
4693
- const mode = this.options.approvalMode ?? getZapierApprovalMode() ?? getZapierDefaultApprovalMode();
4694
- if (mode === "disabled") {
4695
- throw new ZapierApprovalError(
4696
- "Approvals are disabled. Set approvalMode to 'poll' or 'throw' (or ZAPIER_APPROVAL_MODE) to enable.",
4697
- { status: "approval_required" }
4698
- );
4699
- }
4700
- if (!init?.approvalContext) {
4701
- throw new ZapierApiError(
4702
- `Received 403 approval_required for ${path}, but the caller did not provide an approvalContext builder. Every approval-capable request must pass approvalContext so the SDK can create the approval with the correct policy context.`,
4703
- { statusCode: 403 }
4704
- );
4705
- }
4706
- await this.runOneApprovalRound(
4707
- init.approvalContext,
4708
- mode,
4709
- init.signal ?? void 0
5634
+ const { canSendDeprecationMessaging } = this.buildUrl(
5635
+ path,
5636
+ init?.searchParams
5637
+ );
5638
+ const approvalMode = this.options.approvalMode ?? getZapierApprovalMode() ?? getZapierDefaultApprovalMode();
5639
+ const approvalContext = init?.approvalContext;
5640
+ const { response, approvalRoundError } = await this.runApprovalFetchLoop({
5641
+ path,
5642
+ init,
5643
+ maxRetries,
5644
+ approvalMode,
5645
+ approvalContext
5646
+ });
5647
+ handleDeprecationNotice({
5648
+ response,
5649
+ canSendDeprecationMessaging,
5650
+ onEvent: this.options.onEvent
5651
+ });
5652
+ if (response.status !== 403) {
5653
+ return response;
5654
+ }
5655
+ const errorType = response.headers.get("x-zapier-error-type");
5656
+ if (errorType === "request_denied_by_policy") {
5657
+ const { data } = await this.parseResult(response);
5658
+ const { message, errors } = this.parseErrorResponse({
5659
+ status: response.status,
5660
+ statusText: response.statusText,
5661
+ data
5662
+ });
5663
+ throw new ZapierApprovalError(
5664
+ message || "Request explicitly denied by policy",
5665
+ {
5666
+ status: "policy_denied",
5667
+ statusCode: response.status,
5668
+ errors
5669
+ }
5670
+ );
5671
+ }
5672
+ if (errorType !== "approval_required") {
5673
+ return response;
5674
+ }
5675
+ if (approvalRoundError) {
5676
+ throw approvalRoundError;
5677
+ }
5678
+ if (approvalMode === "disabled") {
5679
+ throw new ZapierApprovalError(
5680
+ "Approvals are disabled. Set approvalMode to 'poll' or 'throw' (or ZAPIER_APPROVAL_MODE) to enable.",
5681
+ { status: "approval_required" }
5682
+ );
5683
+ }
5684
+ if (!approvalContext) {
5685
+ throw new ZapierApiError(
5686
+ `Received 403 approval_required for ${path}, but the caller did not provide an approvalContext builder. Every approval-capable request must pass approvalContext so the SDK can create the approval with the correct policy context.`,
5687
+ { statusCode: 403 }
4710
5688
  );
4711
5689
  }
4712
5690
  throw new ZapierApprovalError(
@@ -4968,40 +5946,60 @@ var ZapierApiClient = class {
4968
5946
  }
4969
5947
  // Apply any special routing logic for configured paths.
4970
5948
  applyPathConfiguration(path) {
4971
- const matchingPathKey = Object.keys(pathConfig).find(
4972
- (configPath) => path === configPath || path.startsWith(configPath + "/")
4973
- );
4974
- const config = matchingPathKey ? pathConfig[matchingPathKey] : void 0;
5949
+ const matchingPathEntries = findPathConfigEntries({ path });
5950
+ const routingMatch = matchingPathEntries[0];
5951
+ const buildResult = (url2) => {
5952
+ const resolvedPathEntries = findPathConfigEntries({
5953
+ path: url2.pathname,
5954
+ matchResolvedGatewayPath: true
5955
+ });
5956
+ const deprecationPathMatches = [
5957
+ ...matchingPathEntries,
5958
+ ...resolvedPathEntries
5959
+ ];
5960
+ const canSendDeprecationMessaging = deprecationPathMatches.length > 0 && deprecationPathMatches.every(
5961
+ ({ config }) => config.omitDeprecationMessaging !== true
5962
+ );
5963
+ return {
5964
+ url: url2,
5965
+ pathConfig: routingMatch?.config,
5966
+ canSendDeprecationMessaging
5967
+ };
5968
+ };
4975
5969
  let finalPath = path;
4976
- if (config && "pathPrefix" in config && config.pathPrefix && matchingPathKey) {
4977
- const pathWithoutPrefix = path.slice(matchingPathKey.length) || "/";
4978
- finalPath = `${config.pathPrefix}${pathWithoutPrefix}`;
5970
+ if (routingMatch?.config.pathPrefix) {
5971
+ const pathWithoutPrefix = path.slice(routingMatch.configPath.length) || "/";
5972
+ finalPath = `${routingMatch.config.pathPrefix}${pathWithoutPrefix}`;
4979
5973
  }
4980
5974
  const zapierBaseUrl = getZapierBaseUrl(this.options.baseUrl);
4981
5975
  if (zapierBaseUrl === this.options.baseUrl.replace(/\/$/, "")) {
4982
5976
  const originalBaseUrl = new URL(this.options.baseUrl);
4983
5977
  const finalBaseUrl = `https://sdkapi.${originalBaseUrl.hostname}`;
4984
- return {
4985
- url: new URL(finalPath, finalBaseUrl),
4986
- pathConfig: config
4987
- };
5978
+ const url2 = new URL(finalPath, finalBaseUrl);
5979
+ return buildResult(url2);
4988
5980
  }
4989
5981
  const baseUrl = new URL(this.options.baseUrl);
4990
5982
  const basePath = baseUrl.pathname.replace(/\/$/, "");
4991
- return {
4992
- url: new URL(basePath + finalPath, baseUrl.origin),
4993
- pathConfig: config
4994
- };
5983
+ const url = new URL(basePath + finalPath, baseUrl.origin);
5984
+ return buildResult(url);
4995
5985
  }
4996
5986
  // Helper to build full URLs and return routing info
4997
5987
  buildUrl(path, searchParams) {
4998
- const { url, pathConfig: config } = this.applyPathConfiguration(path);
5988
+ const {
5989
+ url,
5990
+ pathConfig: config,
5991
+ canSendDeprecationMessaging
5992
+ } = this.applyPathConfiguration(path);
4999
5993
  if (searchParams) {
5000
- Object.entries(searchParams).forEach(([key, value]) => {
5001
- url.searchParams.set(key, value);
5994
+ Object.entries(searchParams).forEach(([key2, value]) => {
5995
+ url.searchParams.set(key2, value);
5002
5996
  });
5003
5997
  }
5004
- return { url: url.toString(), pathConfig: config };
5998
+ return {
5999
+ url: url.toString(),
6000
+ pathConfig: config,
6001
+ canSendDeprecationMessaging
6002
+ };
5005
6003
  }
5006
6004
  // Helper to build headers
5007
6005
  async buildHeaders(options = {}, pathConfig2) {
@@ -5645,7 +6643,7 @@ var listAppsPlugin = definePlugin(
5645
6643
  locator
5646
6644
  ];
5647
6645
  }
5648
- const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key) => implementationNameToLocator[key].length > 1).map((key) => implementationNameToLocator[key]).flat().map((locator) => locator.lookupAppKey);
6646
+ const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator).filter((key2) => implementationNameToLocator[key2].length > 1).map((key2) => implementationNameToLocator[key2]).flat().map((locator) => locator.lookupAppKey);
5649
6647
  if (duplicatedLookupAppKeys.length > 0) {
5650
6648
  throw new Error(
5651
6649
  `Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`
@@ -6138,7 +7136,7 @@ function formatRecordError(fieldId, err) {
6138
7136
  function formatResponseError(err) {
6139
7137
  const message = err.human_title || err.title || "Unknown error";
6140
7138
  if (err.meta && Object.keys(err.meta).length > 0) {
6141
- const metaParts = Object.entries(err.meta).map(([key, val]) => `${key}: ${JSON.stringify(val)}`).join(", ");
7139
+ const metaParts = Object.entries(err.meta).map(([key2, val]) => `${key2}: ${JSON.stringify(val)}`).join(", ");
6142
7140
  return `${message} (${metaParts})`;
6143
7141
  }
6144
7142
  return message;
@@ -6173,8 +7171,8 @@ var TrashSchema = zod.z.enum(["exclude", "include", "only"]).optional().describe
6173
7171
  'Control soft-deleted item visibility. "exclude" (default) returns active items only, "include" returns both active and soft-deleted, "only" returns soft-deleted items only.'
6174
7172
  );
6175
7173
  var FIELD_ID_PATTERN = /^f\d+$/;
6176
- function isFieldId(key) {
6177
- return FIELD_ID_PATTERN.test(key);
7174
+ function isFieldId(key2) {
7175
+ return FIELD_ID_PATTERN.test(key2);
6178
7176
  }
6179
7177
  var NESTED_COMPONENTS = {
6180
7178
  labeled_string: /* @__PURE__ */ new Set(["value"]),
@@ -6212,7 +7210,7 @@ async function resolveFieldKeys({
6212
7210
  fieldKeys
6213
7211
  }) {
6214
7212
  const allAreIds = fieldKeys.every(
6215
- (key) => typeof key === "number" || /^(f?\d+)$/.test(key)
7213
+ (key2) => typeof key2 === "number" || /^(f?\d+)$/.test(key2)
6216
7214
  );
6217
7215
  if (allAreIds) {
6218
7216
  return fieldKeys.map(toNumericFieldId);
@@ -6221,13 +7219,13 @@ async function resolveFieldKeys({
6221
7219
  if (!mapping) {
6222
7220
  return fieldKeys.map(toNumericFieldId);
6223
7221
  }
6224
- return fieldKeys.map((key) => {
6225
- if (typeof key === "number") return key;
6226
- if (FIELD_ID_PATTERN.test(key)) return toNumericFieldId(key);
6227
- const id = mapping.nameToId.get(key);
7222
+ return fieldKeys.map((key2) => {
7223
+ if (typeof key2 === "number") return key2;
7224
+ if (FIELD_ID_PATTERN.test(key2)) return toNumericFieldId(key2);
7225
+ const id = mapping.nameToId.get(key2);
6228
7226
  if (!id) {
6229
7227
  throw new ZapierValidationError(
6230
- `Unknown field name: "${key}". Use a valid field name or ID.`
7228
+ `Unknown field name: "${key2}". Use a valid field name or ID.`
6231
7229
  );
6232
7230
  }
6233
7231
  return toNumericFieldId(id);
@@ -6243,13 +7241,13 @@ async function createFieldKeyTranslator({
6243
7241
  translateInput(data) {
6244
7242
  if (!mapping) return data;
6245
7243
  const result = {};
6246
- for (const [key, value] of Object.entries(data)) {
6247
- if (FIELD_ID_PATTERN.test(key) && mapping.idToName.has(key)) {
6248
- result[key] = value;
6249
- } else if (mapping.nameToId.has(key)) {
6250
- result[mapping.nameToId.get(key)] = value;
7244
+ for (const [key2, value] of Object.entries(data)) {
7245
+ if (FIELD_ID_PATTERN.test(key2) && mapping.idToName.has(key2)) {
7246
+ result[key2] = value;
7247
+ } else if (mapping.nameToId.has(key2)) {
7248
+ result[mapping.nameToId.get(key2)] = value;
6251
7249
  } else {
6252
- result[key] = value;
7250
+ result[key2] = value;
6253
7251
  }
6254
7252
  }
6255
7253
  return result;
@@ -6257,29 +7255,29 @@ async function createFieldKeyTranslator({
6257
7255
  translateOutput(data) {
6258
7256
  if (!mapping) return data;
6259
7257
  const result = {};
6260
- for (const [key, value] of Object.entries(data)) {
6261
- if (mapping.idToName.has(key)) {
6262
- result[mapping.idToName.get(key)] = value;
7258
+ for (const [key2, value] of Object.entries(data)) {
7259
+ if (mapping.idToName.has(key2)) {
7260
+ result[mapping.idToName.get(key2)] = value;
6263
7261
  } else {
6264
- result[key] = value;
7262
+ result[key2] = value;
6265
7263
  }
6266
7264
  }
6267
7265
  return result;
6268
7266
  },
6269
- translateFieldKey(key) {
6270
- if (!mapping) return key;
6271
- if (FIELD_ID_PATTERN.test(key) && mapping.idToName.has(key)) {
6272
- const fieldType = mapping.idToType.get(key);
7267
+ translateFieldKey(key2) {
7268
+ if (!mapping) return key2;
7269
+ if (FIELD_ID_PATTERN.test(key2) && mapping.idToName.has(key2)) {
7270
+ const fieldType = mapping.idToType.get(key2);
6273
7271
  if (fieldType) {
6274
7272
  const components = NESTED_COMPONENTS[fieldType];
6275
7273
  if (components?.size === 1) {
6276
- return `${key}__${[...components][0]}`;
7274
+ return `${key2}__${[...components][0]}`;
6277
7275
  }
6278
7276
  }
6279
- return key;
7277
+ return key2;
6280
7278
  }
6281
- if (mapping.nameToId.has(key)) {
6282
- const fieldId = mapping.nameToId.get(key);
7279
+ if (mapping.nameToId.has(key2)) {
7280
+ const fieldId = mapping.nameToId.get(key2);
6283
7281
  const fieldType = mapping.idToType.get(fieldId);
6284
7282
  if (fieldType) {
6285
7283
  const components = NESTED_COMPONENTS[fieldType];
@@ -6289,10 +7287,10 @@ async function createFieldKeyTranslator({
6289
7287
  }
6290
7288
  return fieldId;
6291
7289
  }
6292
- const sepIndex = key.lastIndexOf("__");
7290
+ const sepIndex = key2.lastIndexOf("__");
6293
7291
  if (sepIndex > 0) {
6294
- const prefix = key.slice(0, sepIndex);
6295
- const component = key.slice(sepIndex + 2);
7292
+ const prefix = key2.slice(0, sepIndex);
7293
+ const component = key2.slice(sepIndex + 2);
6296
7294
  let fieldId;
6297
7295
  if (FIELD_ID_PATTERN.test(prefix) && mapping.idToName.has(prefix)) {
6298
7296
  fieldId = prefix;
@@ -6306,7 +7304,7 @@ async function createFieldKeyTranslator({
6306
7304
  }
6307
7305
  }
6308
7306
  }
6309
- return key;
7307
+ return key2;
6310
7308
  }
6311
7309
  };
6312
7310
  }
@@ -7223,9 +8221,9 @@ var RunActionSchemaDeprecated = zod.z.object({
7223
8221
  var RunActionInputSchema = zod.z.union([RunActionSchema, RunActionSchemaDeprecated]).describe(RunActionDescription);
7224
8222
 
7225
8223
  // src/formatters/actionResult.ts
7226
- function getStringProperty(obj, key) {
7227
- if (typeof obj === "object" && obj !== null && key in obj) {
7228
- const value = obj[key];
8224
+ function getStringProperty(obj, key2) {
8225
+ if (typeof obj === "object" && obj !== null && key2 in obj) {
8226
+ const value = obj[key2];
7229
8227
  return typeof value === "string" ? value : void 0;
7230
8228
  }
7231
8229
  return void 0;
@@ -7312,13 +8310,13 @@ var runActionPlugin = definePlugin(
7312
8310
  let oldestKey;
7313
8311
  let oldestExpiry = Infinity;
7314
8312
  let evictedAny = false;
7315
- for (const [key, entry] of runActionContextCache) {
8313
+ for (const [key2, entry] of runActionContextCache) {
7316
8314
  if (now >= entry.expiresAt) {
7317
- runActionContextCache.delete(key);
8315
+ runActionContextCache.delete(key2);
7318
8316
  evictedAny = true;
7319
8317
  } else if (entry.expiresAt < oldestExpiry) {
7320
8318
  oldestExpiry = entry.expiresAt;
7321
- oldestKey = key;
8319
+ oldestKey = key2;
7322
8320
  }
7323
8321
  }
7324
8322
  if (!evictedAny && oldestKey) {
@@ -7946,36 +8944,36 @@ var createConnectionPlugin = definePlugin(
7946
8944
  sdk: inner,
7947
8945
  options
7948
8946
  }) => {
7949
- const { data: start } = await inner.getConnectionStartUrl({
8947
+ const { data: start2 } = await inner.getConnectionStartUrl({
7950
8948
  app: options.app
7951
8949
  });
7952
- setMethodMetadata({ selectedApi: start.app });
8950
+ setMethodMetadata({ selectedApi: start2.app });
7953
8951
  console.error(
7954
8952
  `
7955
8953
  Open this URL to complete the connection:
7956
- ${start.url}
8954
+ ${start2.url}
7957
8955
  `
7958
8956
  );
7959
8957
  const shouldOpen = options.browser === "always" || options.browser === "auto" && shouldOpenBrowser();
7960
8958
  if (shouldOpen) {
7961
8959
  try {
7962
- await open_url_default(start.url);
8960
+ await open_url_default(start2.url);
7963
8961
  } catch {
7964
8962
  }
7965
8963
  }
7966
8964
  const { data: fresh } = await inner.waitForNewConnection({
7967
- app: start.app,
8965
+ app: start2.app,
7968
8966
  // Server-stamped mint time: measured on the same clock as a
7969
8967
  // connection's `date`, so the freshness check is immune to
7970
8968
  // client/server clock skew.
7971
- startedAt: start.startedAt,
8969
+ startedAt: start2.startedAt,
7972
8970
  timeoutMs: options.timeoutMs,
7973
8971
  pollIntervalMs: options.pollIntervalMs
7974
8972
  });
7975
8973
  return {
7976
8974
  data: CreateConnectionItemSchema.parse({
7977
8975
  id: fresh.id,
7978
- app: start.app,
8976
+ app: start2.app,
7979
8977
  title: fresh.title ?? null
7980
8978
  })
7981
8979
  };
@@ -9974,9 +10972,9 @@ function findManifestEntry({
9974
10972
  return [slug, manifest.apps[slug]];
9975
10973
  }
9976
10974
  }
9977
- for (const [key, entry] of Object.entries(manifest.apps)) {
10975
+ for (const [key2, entry] of Object.entries(manifest.apps)) {
9978
10976
  if (entry.implementationName === appKeyWithoutVersion) {
9979
- return [key, entry];
10977
+ return [key2, entry];
9980
10978
  }
9981
10979
  }
9982
10980
  return null;
@@ -10233,21 +11231,21 @@ var manifestPlugin = definePlugin(
10233
11231
  );
10234
11232
 
10235
11233
  // src/plugins/capabilities/index.ts
10236
- function toDescription(key) {
10237
- const words = key.replace(/^can/, "").replace(/([A-Z])/g, " $1").trim().toLowerCase();
11234
+ function toDescription(key2) {
11235
+ const words = key2.replace(/^can/, "").replace(/([A-Z])/g, " $1").trim().toLowerCase();
10238
11236
  return `To ${words}`;
10239
11237
  }
10240
- function toEnvVar(key) {
10241
- return "ZAPIER_" + key.replace(/([A-Z])/g, "_$1").toUpperCase();
11238
+ function toEnvVar(key2) {
11239
+ return "ZAPIER_" + key2.replace(/([A-Z])/g, "_$1").toUpperCase();
10242
11240
  }
10243
- function toCliFlag(key) {
10244
- return "--" + key.replace(/([A-Z])/g, "-$1").toLowerCase();
11241
+ function toCliFlag(key2) {
11242
+ return "--" + key2.replace(/([A-Z])/g, "-$1").toLowerCase();
10245
11243
  }
10246
- function buildCapabilityMessage(key) {
11244
+ function buildCapabilityMessage(key2) {
10247
11245
  return [
10248
- `${toDescription(key)}, use ${toCliFlag(key)} in the CLI,`,
10249
- `set ${key}: true in SDK options or .zapierrc,`,
10250
- `or set ${toEnvVar(key)}=true.`
11246
+ `${toDescription(key2)}, use ${toCliFlag(key2)} in the CLI,`,
11247
+ `set ${key2}: true in SDK options or .zapierrc,`,
11248
+ `or set ${toEnvVar(key2)}=true.`
10251
11249
  ].join(" ");
10252
11250
  }
10253
11251
  var GATED_FLAGS = [
@@ -10255,8 +11253,8 @@ var GATED_FLAGS = [
10255
11253
  "canIncludeSharedTables",
10256
11254
  "canDeleteTables"
10257
11255
  ];
10258
- function isEnabledByEnv(key) {
10259
- const value = globalThis.process?.env?.[toEnvVar(key)];
11256
+ function isEnabledByEnv(key2) {
11257
+ const value = globalThis.process?.env?.[toEnvVar(key2)];
10260
11258
  if (value === void 0) return void 0;
10261
11259
  if (value === "true" || value === "1") return true;
10262
11260
  if (value === "false" || value === "0") return false;
@@ -10279,17 +11277,17 @@ var capabilitiesPlugin = definePlugin(
10279
11277
  }
10280
11278
  return {
10281
11279
  context: {
10282
- checkCapability: async (key) => {
11280
+ checkCapability: async (key2) => {
10283
11281
  const flags = await resolveFlags();
10284
- if (flags[key]) return;
11282
+ if (flags[key2]) return;
10285
11283
  throw new ZapierConfigurationError(
10286
- buildCapabilityMessage(key) + " (If you are an AI agent, you MUST NOT retry. Ask the user if they want to enable this.)",
10287
- { configType: key }
11284
+ buildCapabilityMessage(key2) + " (If you are an AI agent, you MUST NOT retry. Ask the user if they want to enable this.)",
11285
+ { configType: key2 }
10288
11286
  );
10289
11287
  },
10290
- hasCapability: async (key) => {
11288
+ hasCapability: async (key2) => {
10291
11289
  const flags = await resolveFlags();
10292
- return flags[key];
11290
+ return flags[key2];
10293
11291
  }
10294
11292
  }
10295
11293
  };
@@ -10447,8 +11445,8 @@ function getOsInfo() {
10447
11445
  function getPlatformVersions() {
10448
11446
  const versions = {};
10449
11447
  if (typeof globalThis.process?.versions === "object") {
10450
- for (const [key, value] of Object.entries(globalThis.process.versions)) {
10451
- versions[key] = value || null;
11448
+ for (const [key2, value] of Object.entries(globalThis.process.versions)) {
11449
+ versions[key2] = value || null;
10452
11450
  }
10453
11451
  }
10454
11452
  return versions;
@@ -10690,9 +11688,9 @@ async function emitWithTimeout(transport, subject, event) {
10690
11688
  }
10691
11689
  function mergeUserContext(event, userContext) {
10692
11690
  const merged = { ...event };
10693
- for (const [key, value] of Object.entries(userContext)) {
10694
- if (merged[key] == null) {
10695
- merged[key] = value;
11691
+ for (const [key2, value] of Object.entries(userContext)) {
11692
+ if (merged[key2] == null) {
11693
+ merged[key2] = value;
10696
11694
  }
10697
11695
  }
10698
11696
  return merged;
@@ -11965,9 +12963,9 @@ function createWaiter() {
11965
12963
  }
11966
12964
  };
11967
12965
  }
11968
- function addToMap(m, key, value) {
11969
- const existing = m.get(key) ?? [];
11970
- m.set(key, [...existing, value]);
12966
+ function addToMap(m, key2, value) {
12967
+ const existing = m.get(key2) ?? [];
12968
+ m.set(key2, [...existing, value]);
11971
12969
  }
11972
12970
  async function runBatchedDrainPipeline(options) {
11973
12971
  const {
@@ -12770,14 +13768,14 @@ function toWireConnections(connections) {
12770
13768
  }
12771
13769
  function toWireAppVersions(appVersions) {
12772
13770
  const wire = {};
12773
- for (const [key, entry] of Object.entries(appVersions)) {
13771
+ for (const [key2, entry] of Object.entries(appVersions)) {
12774
13772
  const implementationName = entry.implementationName ?? entry.implementation_name;
12775
13773
  if (implementationName === void 0) {
12776
13774
  throw new ZapierValidationError(
12777
- `appVersions["${key}"] is missing implementationName`
13775
+ `appVersions["${key2}"] is missing implementationName`
12778
13776
  );
12779
13777
  }
12780
- wire[key] = {
13778
+ wire[key2] = {
12781
13779
  implementation_name: implementationName,
12782
13780
  ...entry.version !== void 0 ? { version: entry.version } : {}
12783
13781
  };
@@ -14199,13 +15197,16 @@ exports.BaseSdkOptionsSchema = BaseSdkOptionsSchema;
14199
15197
  exports.CONTEXT_CACHE_MAX_SIZE = CONTEXT_CACHE_MAX_SIZE;
14200
15198
  exports.CONTEXT_CACHE_TTL_MS = CONTEXT_CACHE_TTL_MS;
14201
15199
  exports.CORE_ERROR_SYMBOL = CORE_ERROR_SYMBOL;
15200
+ exports.CORE_SIGNAL_SYMBOL = CORE_SIGNAL_SYMBOL;
14202
15201
  exports.ClientCredentialsObjectSchema = ClientCredentialsObjectSchema;
14203
15202
  exports.ConnectionEntrySchema = ConnectionEntrySchema;
14204
15203
  exports.ConnectionIdPropertySchema = ConnectionIdPropertySchema;
14205
15204
  exports.ConnectionPropertySchema = ConnectionPropertySchema;
14206
15205
  exports.ConnectionsMapSchema = ConnectionsMapSchema;
14207
15206
  exports.ConnectionsPropertySchema = ConnectionsPropertySchema;
15207
+ exports.CoreCancelledSignal = CoreCancelledSignal;
14208
15208
  exports.CoreErrorCode = CoreErrorCode;
15209
+ exports.CoreSignal = CoreSignal;
14209
15210
  exports.CredentialsFunctionSchema = CredentialsFunctionSchema;
14210
15211
  exports.CredentialsObjectSchema = CredentialsObjectSchema;
14211
15212
  exports.CredentialsSchema = CredentialsSchema;
@@ -14214,6 +15215,7 @@ exports.DEFAULT_APPROVAL_TIMEOUT_MS = DEFAULT_APPROVAL_TIMEOUT_MS;
14214
15215
  exports.DEFAULT_CONFIG_PATH = DEFAULT_CONFIG_PATH;
14215
15216
  exports.DEFAULT_MAX_APPROVAL_RETRIES = DEFAULT_MAX_APPROVAL_RETRIES;
14216
15217
  exports.DEFAULT_PAGE_SIZE = DEFAULT_PAGE_SIZE;
15218
+ exports.DEPRECATION_NOTICE_EVENT = DEPRECATION_NOTICE_EVENT;
14217
15219
  exports.DebugPropertySchema = DebugPropertySchema;
14218
15220
  exports.FieldsPropertySchema = FieldsPropertySchema;
14219
15221
  exports.InputFieldPropertySchema = InputFieldPropertySchema;
@@ -14284,6 +15286,7 @@ exports.connectionIdResolver = connectionIdResolver;
14284
15286
  exports.connectionsPlugin = connectionsPlugin;
14285
15287
  exports.createBaseEvent = createBaseEvent;
14286
15288
  exports.createClientCredentialsPlugin = createClientCredentialsPlugin;
15289
+ exports.createController = createController;
14287
15290
  exports.createCorePlugin = createCorePlugin;
14288
15291
  exports.createFunction = createFunction;
14289
15292
  exports.createMemoryCache = createMemoryCache;
@@ -14307,6 +15310,7 @@ exports.defineLegacyMerge = defineLegacyMerge;
14307
15310
  exports.defineMethod = defineMethod;
14308
15311
  exports.definePlugin = definePlugin;
14309
15312
  exports.defineProperty = defineProperty;
15313
+ exports.defineResolver = defineResolver;
14310
15314
  exports.deleteClientCredentialsPlugin = deleteClientCredentialsPlugin;
14311
15315
  exports.deleteTableFieldsPlugin = deleteTableFieldsPlugin;
14312
15316
  exports.deleteTablePlugin = deleteTablePlugin;
@@ -14359,6 +15363,7 @@ exports.isCi = isCi;
14359
15363
  exports.isCliLoginAvailable = isCliLoginAvailable;
14360
15364
  exports.isClientCredentials = isClientCredentials;
14361
15365
  exports.isCoreError = isCoreError;
15366
+ exports.isCoreSignal = isCoreSignal;
14362
15367
  exports.isCredentialsFunction = isCredentialsFunction;
14363
15368
  exports.isCredentialsObject = isCredentialsObject;
14364
15369
  exports.isPermanentHttpError = isPermanentHttpError;