@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.
@@ -270,6 +270,69 @@ interface PaginatedSdkResult<TItem> extends Promise<SdkPage<TItem>> {
270
270
  }
271
271
  type PaginatedSdkFunction<TOptions, TItem> = (options: TOptions) => PaginatedSdkResult<TItem>;
272
272
 
273
+ /**
274
+ * Per-call context threaded explicitly through the method boundary in place of
275
+ * ambient AsyncLocalStorage. It carries call identity, nesting depth, and a
276
+ * per-invocation annotation bag. Because it travels as data, correlation and
277
+ * nested-call dedup work without `async_hooks` — including in browsers, where
278
+ * the old ALS store was inert and nested calls all looked top-level.
279
+ *
280
+ * Framework-neutral: heads surface `callId` under their own name (e.g. a
281
+ * correlation id) and own their annotation field names.
282
+ */
283
+ /**
284
+ * A private brand (a fresh `Symbol()`, never `Symbol.for`) makes a CallContext
285
+ * unforgeable: no outside code can name the symbol to synthesize an id-bearing
286
+ * context, and the brand never collides across bundled copies. This is the same
287
+ * unforgeability the `INTERNAL_CALL` sentinel relies on.
288
+ */
289
+ declare const CALL_CONTEXT_BRAND: unique symbol;
290
+ interface CallContext {
291
+ /** Minted once at the root call; copied verbatim to every nested (child) call. */
292
+ callId: string | null;
293
+ /** 0 at the outermost call; `parent.depth + 1` for a delegated call. */
294
+ depth: number;
295
+ /**
296
+ * Per-invocation scratch space. Never forwarded to callees — a child call
297
+ * gets a fresh bag — so annotations describe one method's own invocation.
298
+ */
299
+ annotations: Record<string, unknown>;
300
+ readonly [CALL_CONTEXT_BRAND]: true;
301
+ }
302
+
303
+ /**
304
+ * Method-call lifecycle hooks. Plugins contribute `onMethodStart` and/or
305
+ * `onMethodEnd` on their context; `buildHooks` composes contributions across
306
+ * plugins so multiple observers can coexist. Composition is right-additive
307
+ * (newer plugins fire after earlier ones); only opt-in methods built through
308
+ * `createPluginMethod` / `createPaginatedPluginMethod` trigger the hooks.
309
+ */
310
+ interface OnMethodStartContext {
311
+ methodName: string;
312
+ args: unknown[];
313
+ isPaginated: boolean;
314
+ /**
315
+ * Depth of this method invocation in the SDK call tree. 0 = outermost
316
+ * (user-initiated) call; 1+ = called from inside another SDK method.
317
+ * Observers can use this to ignore nested calls if they only want
318
+ * top-level events.
319
+ */
320
+ depth: number;
321
+ }
322
+ type OnMethodStart = (ctx: OnMethodStartContext) => void;
323
+ interface OnMethodEndContext {
324
+ methodName: string;
325
+ args: unknown[];
326
+ isPaginated: boolean;
327
+ depth: number;
328
+ durationMs: number;
329
+ error?: Error;
330
+ }
331
+ type OnMethodEnd = (ctx: OnMethodEndContext) => void;
332
+ interface MethodHooks {
333
+ onMethodStart?: OnMethodStart;
334
+ onMethodEnd?: OnMethodEnd;
335
+ }
273
336
  interface FormattedItem {
274
337
  title: string;
275
338
  /**
@@ -360,8 +423,6 @@ type ListPromptConfig = PromptConfig & {
360
423
  * - `filter` — no resolver uses it; transform values in `listItems` instead.
361
424
  * - `validate`— validation is the resolver's top-level `validate`, which
362
425
  * never routes through rendering (and gets `imports`).
363
- * (The legacy `SchemaParameterResolver` still honors `default`/`filter`/
364
- * `validate`, so the full `PromptConfig` stays for that path.)
365
426
  */
366
427
  type ResolverPromptConfig = Omit<PromptConfig, "name" | "default" | "filter" | "validate">;
367
428
  interface Resolver$1 {
@@ -531,40 +592,6 @@ interface PositionalMetadata {
531
592
  }
532
593
  declare function isPositional(schema: z.ZodType): boolean;
533
594
 
534
- /**
535
- * Method-call lifecycle hooks. Plugins contribute `onMethodStart` and/or
536
- * `onMethodEnd` on their context; `buildHooks` composes contributions across
537
- * plugins so multiple observers can coexist. Composition is right-additive
538
- * (newer plugins fire after earlier ones); only opt-in methods built through
539
- * `createPluginMethod` / `createPaginatedPluginMethod` trigger the hooks.
540
- */
541
- interface OnMethodStartContext {
542
- methodName: string;
543
- args: unknown[];
544
- isPaginated: boolean;
545
- /**
546
- * Depth of this method invocation in the SDK call tree. 0 = outermost
547
- * (user-initiated) call; 1+ = called from inside another SDK method.
548
- * Observers can use this to ignore nested calls if they only want
549
- * top-level events.
550
- */
551
- depth: number;
552
- }
553
- type OnMethodStart = (ctx: OnMethodStartContext) => void;
554
- interface OnMethodEndContext {
555
- methodName: string;
556
- args: unknown[];
557
- isPaginated: boolean;
558
- depth: number;
559
- durationMs: number;
560
- error?: Error;
561
- }
562
- type OnMethodEnd = (ctx: OnMethodEndContext) => void;
563
- interface MethodHooks {
564
- onMethodStart?: OnMethodStart;
565
- onMethodEnd?: OnMethodEnd;
566
- }
567
-
568
595
  /**
569
596
  * Descriptive metadata a leaf carries for the registry / CLI / MCP / docs:
570
597
  * description, categories, type, formatter, resolvers, etc.
@@ -587,10 +614,6 @@ interface LeafMetaFields {
587
614
  itemType?: string;
588
615
  returnType?: string;
589
616
  outputSchema?: z.ZodSchema;
590
- inputParameters?: Array<{
591
- name: string;
592
- schema: z.ZodSchema;
593
- }>;
594
617
  packages?: string[];
595
618
  experimental?: boolean;
596
619
  confirm?: "create-secret" | "delete";
@@ -756,12 +779,11 @@ interface DynamicResolver extends ResolverBase {
756
779
  input: Record<string, unknown>;
757
780
  }) => PromiseLike<unknown>;
758
781
  /** Produce the candidate list. Behaves like an SDK list method: returns a
759
- * paginated result (await for the first page + `nextCursor`, or iterate pages),
760
- * never a bare array. `cursor` is the stateless re-entry hook for "load more":
761
- * an in-process host iterates the result; a distributed host awaits one page,
762
- * carries `nextCursor`, and calls again with `cursor`. Required: a dynamic
763
- * resolver IS a candidate-lister; a free-text field (with or without
764
- * auto-resolution someday) is the `static` kind's job. */
782
+ * paginated result (the engine awaits the first page + `nextCursor`), never a
783
+ * bare array. `cursor` is the stateless re-entry hook for "load more": the
784
+ * engine awaits one page, carries `nextCursor`, and calls again with `cursor`.
785
+ * Required: a dynamic resolver IS a candidate-lister; a free-text field (with
786
+ * or without auto-resolution someday) is the `static` kind's job. */
765
787
  listItems: (bag: {
766
788
  imports: Record<string, unknown>;
767
789
  input: Record<string, unknown>;
@@ -845,6 +867,27 @@ interface ObjectResolver extends ResolverBase {
845
867
  input: Record<string, unknown>;
846
868
  }) => PromiseLike<Record<string, Field$1>>;
847
869
  definitions?: Record<string, Resolver>;
870
+ /** Open-ended entries whose keys aren't known up front (a `z.record`): the
871
+ * walk collects entries in an add/done loop, asking each entry's key (via
872
+ * `keys`, default a free-text string) then its value (via `values`), and
873
+ * assembling them onto the object alongside any fixed `properties`. The
874
+ * JSON-Schema `additionalProperties` analog. */
875
+ additionalKeys?: AdditionalKeys;
876
+ }
877
+ /** The open-keyed-entry spec for an {@link ObjectResolver.additionalKeys}. */
878
+ interface AdditionalKeys {
879
+ /** Resolver for each entry's key; defaults to a free-text string prompt. A
880
+ * `{ ref }` resolves against the object's `definitions`. */
881
+ keys?: Resolver | ResolverRef;
882
+ /** Resolver for each entry's value. A `{ ref }` resolves against the
883
+ * object's `definitions`. */
884
+ values: Resolver | ResolverRef;
885
+ minEntries?: number;
886
+ maxEntries?: number;
887
+ /** Coarse value types so a free-text key/value answer coerces (usually
888
+ * `"string"` for the key), the way `Field.valueType` does. */
889
+ keyValueType?: string;
890
+ valueValueType?: string;
848
891
  }
849
892
  /** A homogeneous list: each element resolves through `items`. */
850
893
  interface ArrayResolver extends ResolverBase {
@@ -890,9 +933,9 @@ interface Formatter extends MethodAttachment {
890
933
  }) => FormattedItem;
891
934
  }
892
935
  /** What a dynamic resolver's `listItems` yields: an SDK list-method result
893
- * (`await` for the first page + `nextCursor`, or iterate pages in-process), or a
894
- * plain page / promise of one. No bare array and no scalar: it behaves like any
895
- * other list method, and exact-match short-circuits live on `tryResolveFromSearch`. */
936
+ * (the engine awaits the first page + `nextCursor`), or a plain page / promise
937
+ * of one. No bare array and no scalar: it behaves like any other list method,
938
+ * and exact-match short-circuits live on `tryResolveFromSearch`. */
896
939
  type ListItemsResult<TItem> = PaginatedSdkResult<TItem> | SdkPage<TItem> | Promise<SdkPage<TItem>>;
897
940
  /** A bound object resolver's literal property: its resolver is already bound
898
941
  * (or a `{ ref }` the CLI resolves against `definitions` at runtime). */
@@ -963,7 +1006,8 @@ interface BoundDynamicResolver extends BoundResolverBase {
963
1006
  } | null>;
964
1007
  }
965
1008
  /** Keyed members: static `properties` (bound) or a `getProperties`-built
966
- * (unbound) field map; `definitions` holds ref targets. */
1009
+ * (unbound) field map; `definitions` holds ref targets. `additionalKeys`
1010
+ * carries open-ended entries (a `z.record`). */
967
1011
  interface BoundObjectResolver extends BoundResolverBase {
968
1012
  type: "object";
969
1013
  properties?: Record<string, BoundField>;
@@ -971,6 +1015,17 @@ interface BoundObjectResolver extends BoundResolverBase {
971
1015
  getProperties?: (bag: {
972
1016
  input: Record<string, unknown>;
973
1017
  }) => PromiseLike<Record<string, Field$1>>;
1018
+ additionalKeys?: BoundAdditionalKeys;
1019
+ }
1020
+ /** The bound form of {@link AdditionalKeys}: `keys`/`values` are bound (or a
1021
+ * `{ ref }` into the object's `definitions`). */
1022
+ interface BoundAdditionalKeys {
1023
+ keys?: BoundResolver | ResolverRef;
1024
+ values: BoundResolver | ResolverRef;
1025
+ minEntries?: number;
1026
+ maxEntries?: number;
1027
+ keyValueType?: string;
1028
+ valueValueType?: string;
974
1029
  }
975
1030
  /** A homogeneous list resolved through `items` (bound, or a ref into
976
1031
  * `definitions`). */
@@ -1361,9 +1416,18 @@ interface MethodEntry {
1361
1416
  * `resolvePlugin` bind this; the surface and registry bind `value`. Absent
1362
1417
  * on legacy graph entries (they bind `value`). */
1363
1418
  internalValue?: (input: any) => any;
1419
+ /** Produce the import-facing twin for a given call context: with a context,
1420
+ * the twin mints a fresh child per invocation (callee inherits `callId`, sits
1421
+ * one level deeper); without one it is the parent-less `internalValue`.
1422
+ * `buildImports` binds this. Absent on legacy graph entries. */
1423
+ bindInternal?: (ctx?: CallContext) => (...args: any[]) => any;
1364
1424
  chain: MiddlewareWrap[];
1365
1425
  /** Carried from the descriptor for the registry / CLI / MCP / docs. */
1366
1426
  inputSchema?: z.ZodType;
1427
+ /** When true, the method owns its input validation and the boundary passes it
1428
+ * through unparsed; carried so the controller skips its final `safeParse` too
1429
+ * (it still uses `inputSchema` to plan/prompt parameters). */
1430
+ skipInputValidation?: boolean;
1367
1431
  meta?: LeafMeta;
1368
1432
  /** Resolved output mode; the registry derives presentation from it. */
1369
1433
  output?: NormalizedOutput;
@@ -1608,7 +1672,7 @@ interface CategoryDefinition {
1608
1672
  /** Plural form of `title`. Auto-derived from the resolved title if omitted. */
1609
1673
  titlePlural?: string;
1610
1674
  }
1611
- interface FunctionRegistryEntry<TSdk = any> {
1675
+ interface FunctionRegistryEntry {
1612
1676
  name: string;
1613
1677
  /**
1614
1678
  * Human-readable description of the function. Surfaced wherever the
@@ -1621,29 +1685,30 @@ interface FunctionRegistryEntry<TSdk = any> {
1621
1685
  itemType?: string;
1622
1686
  returnType?: string;
1623
1687
  inputSchema?: z.ZodSchema;
1624
- inputParameters?: Array<{
1625
- name: string;
1626
- schema: z.ZodSchema;
1627
- }>;
1688
+ /**
1689
+ * When true, the method owns its input validation and its boundary passes the
1690
+ * input through unparsed. The resolution controller reads this to skip its
1691
+ * final `safeParse` (it still uses `inputSchema` to plan/prompt parameters),
1692
+ * so a method routed through the controller isn't re-validated against a
1693
+ * schema it deliberately opts out of. Lifted off the materialized entry.
1694
+ */
1695
+ skipInputValidation?: boolean;
1628
1696
  outputSchema?: z.ZodSchema;
1629
1697
  /**
1630
1698
  * Ordered input keys the public surface projects onto positional arguments
1631
1699
  * (the method's `positional` declaration). Absent when the method takes only
1632
1700
  * the canonical single bag. Lifted off the materialized method entry by the
1633
- * surface builder, like `boundResolvers` — a runtime projection, not
1701
+ * surface builder, like `resolvers` — a runtime projection, not
1634
1702
  * descriptive meta.
1635
1703
  */
1636
1704
  positional?: readonly string[];
1637
1705
  categories: string[];
1638
- resolvers?: Record<string, ResolverMetadata<TSdk, any, any>>;
1639
1706
  /**
1640
- * Per-parameter bound resolvers from the new model (imports already captured,
1641
- * called with `input` only, no sdk). Parallel to the legacy `resolvers` field
1642
- * and `formatter`: the surface builder lifts these off the materialized method
1643
- * entry. Additive bridge — populated for migrated `defineMethod` plugins; the
1644
- * legacy `resolvers` field above stays the source for unmigrated ones.
1707
+ * Per-parameter bound resolvers (imports already captured, called with
1708
+ * `input` only, no sdk). Lifted off the materialized method entry by the
1709
+ * surface builder.
1645
1710
  */
1646
- boundResolvers?: Record<string, BoundResolver>;
1711
+ resolvers?: Record<string, BoundResolver>;
1647
1712
  packages?: string[];
1648
1713
  /**
1649
1714
  * True if the plugin is registered only in the experimental SDK
@@ -1677,8 +1742,8 @@ interface FunctionDeprecation {
1677
1742
  /** User-facing deprecation message for why/how to migrate */
1678
1743
  message: string;
1679
1744
  }
1680
- interface RegistryResult<TSdk = any> {
1681
- functions: FunctionRegistryEntry<TSdk>[];
1745
+ interface RegistryResult {
1746
+ functions: FunctionRegistryEntry[];
1682
1747
  categories: {
1683
1748
  key: string;
1684
1749
  title: string;
@@ -1783,7 +1848,7 @@ type Sdk<T = {
1783
1848
  }> = T & {
1784
1849
  getRegistry(options?: {
1785
1850
  package?: string;
1786
- }): RegistryResult<T>;
1851
+ }): RegistryResult;
1787
1852
  };
1788
1853
 
1789
1854
  /**
@@ -2371,6 +2436,8 @@ declare function defineResolver<const TImports extends ImportsInput = readonly [
2371
2436
  input: TInput;
2372
2437
  }) => PromiseLike<Record<string, Field$1>>;
2373
2438
  definitions?: Record<string, Resolver>;
2439
+ /** Open-ended entries whose keys aren't known up front (a `z.record`). */
2440
+ additionalKeys?: AdditionalKeys;
2374
2441
  }): ObjectResolver;
2375
2442
  declare function defineResolver(config: {
2376
2443
  type: "array";
@@ -2745,7 +2812,7 @@ interface CoreOptions {
2745
2812
  */
2746
2813
  declare const getRegistryPlugin: MethodPlugin<"getRegistry", {
2747
2814
  package?: string | undefined;
2748
- } | undefined, RegistryResult<any>, readonly []> & LeafSummary<"kitcore", "getRegistry", readonly [PropertyPlugin<"context", SdkContext>]>;
2815
+ } | undefined, RegistryResult, readonly []> & LeafSummary<"kitcore", "getRegistry", readonly [PropertyPlugin<"context", SdkContext>]>;
2749
2816
 
2750
2817
  /**
2751
2818
  * The external escape-hatch key for an SDK's context. A Symbol,
@@ -2906,13 +2973,13 @@ type ControllerQuestion = {
2906
2973
  path: ControllerPath;
2907
2974
  message: string;
2908
2975
  description?: string;
2909
- /** Which container kind this decision gates. `array` is the add-another
2910
- * loop; `object` is the entry gate on an optional object, fired BEFORE
2911
- * its fields are fetched (`add` descends into the fields, `done` skips
2912
- * the container). A host that renders `message` + `actions` generically
2913
- * needs nothing else; this is additive metadata for hosts that render
2914
- * containers specially. */
2915
- container: "array" | "object";
2976
+ /** Which container type this decision is about. `array`/`record` are the
2977
+ * add-another loops; `object` covers both the optional-object gate (fired
2978
+ * BEFORE its fields are fetched: `add` descends, `done` skips it) and the
2979
+ * optional-fields gate. A host that renders `message` + `actions`
2980
+ * generically needs nothing else; this is additive metadata for hosts
2981
+ * that render containers specially. */
2982
+ container: "array" | "object" | "record";
2916
2983
  /** Object optionals gate only: the fields the `add` action would walk
2917
2984
  * (key + display label + coarse value type), so a smart host can render
2918
2985
  * them (or a form section) instead of a blind yes/no. Dumb hosts keep
@@ -3021,11 +3088,16 @@ interface ControllerState {
3021
3088
  /** The path of the parameter (or nested field) currently being asked. */
3022
3089
  current?: ControllerPath;
3023
3090
  /** Which container decision the outstanding `collection` question is, when
3024
- * `current` points at one: the array add/done loop, an optional object's
3025
- * entry gate, or an object's optionals gate. Recorded explicitly so `step`'s
3026
- * add/done handling never infers the decision from value presence or
3027
- * resolver shape. Absent when `current` is a plain leaf question. */
3028
- gate?: "array" | "entry" | "optionals";
3091
+ * `current` points at one, named `<container>_<subject>`: `array_items` and
3092
+ * `record_entries` are the add/done loops; `object_optional` is whether to
3093
+ * provide an optional object at all (fired before its fields are fetched);
3094
+ * `object_optional_properties` is whether to fill that object's optional
3095
+ * fields. `record_key` marks the one bespoke record step (collecting an
3096
+ * entry's key); the value that follows is an ordinary leaf question with no
3097
+ * gate. Recorded explicitly so `step`'s handling never infers the decision
3098
+ * from value presence or resolver shape. Absent when `current` is a plain
3099
+ * leaf question. */
3100
+ gate?: "array_items" | "record_entries" | "record_key" | "object_optional" | "object_optional_properties";
3029
3101
  /** Where pagination stands for the current dynamic leaf: coordinates only
3030
3102
  * (cursor trail, generation), never items or live iterators — the page's
3031
3103
  * items ride the ask's question. */
@@ -3244,7 +3316,7 @@ type FunctionSdk = {
3244
3316
  * and `context.core`
3245
3317
  * @param options.schema - optional Zod schema for input validation
3246
3318
  */
3247
- declare function createFunction<TOptions, TResult, TSchemaOptions extends TOptions = TOptions>(coreFn: (options: TOptions) => Promise<TResult>, options: {
3319
+ declare function createFunction<TOptions, TResult, TSchemaOptions extends TOptions = TOptions>(coreFn: (options: TOptions, context?: CallContext) => Promise<TResult>, options: {
3248
3320
  sdk: FunctionSdk;
3249
3321
  schema?: z.ZodSchema<TSchemaOptions>;
3250
3322
  name?: string;
@@ -3270,7 +3342,7 @@ type ItemType<TResult> = TResult extends {
3270
3342
  declare function createPaginatedFunction<TUserOptions, TResponse, TItem = ItemType<TResponse>>(coreFn: (options: TUserOptions & {
3271
3343
  cursor?: string;
3272
3344
  pageSize?: number;
3273
- }) => Promise<TResponse>, options: {
3345
+ }, context?: CallContext) => Promise<TResponse>, options: {
3274
3346
  sdk: FunctionSdk;
3275
3347
  schema?: z.ZodSchema<TUserOptions>;
3276
3348
  name?: string;
@@ -7363,7 +7435,7 @@ interface ZapierSdkOptions extends BaseSdkOptions {
7363
7435
  declare function createZapierSdkWithoutRegistry(options?: ZapierSdkOptions): {
7364
7436
  getRegistry: (input?: {
7365
7437
  package?: string | undefined;
7366
- } | undefined) => RegistryResult<any>;
7438
+ } | undefined) => RegistryResult;
7367
7439
  getProfile: (input?: Record<string, never> | undefined) => Promise<{
7368
7440
  data: {
7369
7441
  id: string;
@@ -8808,7 +8880,7 @@ declare function createZapierSdkWithoutRegistry(options?: ZapierSdkOptions): {
8808
8880
  declare const zapierSdkPlugin: AggregatePlugin<"sdk", {
8809
8881
  getRegistry: MethodPlugin<"getRegistry", {
8810
8882
  package?: string | undefined;
8811
- } | undefined, RegistryResult<any>, readonly []> & LeafSummary<"kitcore", "getRegistry", readonly [PropertyPlugin<"context", SdkContext>]>;
8883
+ } | undefined, RegistryResult, readonly []> & LeafSummary<"kitcore", "getRegistry", readonly [PropertyPlugin<"context", SdkContext>]>;
8812
8884
  } & {
8813
8885
  getProfile: MethodPlugin<"getProfile", Record<string, never> | undefined, Promise<{
8814
8886
  data: {
@@ -11571,7 +11643,7 @@ declare const zapierSdkPlugin: AggregatePlugin<"sdk", {
11571
11643
  declare function createZapierSdk(options?: ZapierSdkOptions): {
11572
11644
  getRegistry: (input?: {
11573
11645
  package?: string | undefined;
11574
- } | undefined) => RegistryResult<any>;
11646
+ } | undefined) => RegistryResult;
11575
11647
  getProfile: (input?: Record<string, never> | undefined) => Promise<{
11576
11648
  data: {
11577
11649
  id: string;