/**
 * This file was automatically generated by Zapier's schema-to-ts tool.
 * DO NOT MODIFY IT BY HAND. Instead, modify the source JSON Schema
 * files, and/or the schema-to-ts tool and run its CLI to regenerate
 * these typings.
 *
 * zapier-platform-schema version: 19.1.0
 *  schema-to-ts compiler version: 0.1.0
 */
import type {
  AfterResponseMiddleware,
  BeforeRequestMiddleware,
  PerformFunction,
} from './custom';
import type { InputFields, InferInputData } from './inputs';
import type {
  PollingTriggerPerform,
  WebhookTriggerPerform,
  WebhookTriggerPerformList,
  WebhookTriggerPerformSubscribe,
  WebhookTriggerPerformUnsubscribe,
  HookToPollTriggerPerformList,
  HookToPollTriggerPerformSubscribe,
  HookToPollTriggerPerformUnsubscribe,
  CreatePerform,
  CreatePerformResume,
  CreatePerformGet,
  SearchPerform,
  SearchPerformGet,
  SearchPerformResume,
  OAuth2AuthorizeUrl,
  OAuth2GetAccessToken,
  OAuth2RefreshAccessToken,
} from './functions';

/** Represents a full app. */
export interface BaseApp {
  /** A version identifier for your code. */
  version: Version;

  /** A version identifier for the Zapier execution environment. */
  platformVersion: Version;

  /**
   * EXPERIMENTAL: Before the perform method is called on your app,
   * you can modify the execution context.
   */
  beforeApp?: Middlewares;

  /**
   * EXPERIMENTAL: After the perform method is called on your app, you
   * can modify the response.
   */
  afterApp?: Middlewares;

  /** Choose what scheme your API uses for authentication. */
  authentication?: Authentication;

  /**
   * Define a request mixin, great for setting custom headers,
   * content-types, etc.
   */
  requestTemplate?: Request;

  /**
   * Before an HTTP request is sent via our `z.request()` client, you
   * can modify it.
   */
  beforeRequest?: BeforeRequestMiddleware | BeforeRequestMiddleware[];

  /**
   * After an HTTP response is recieved via our `z.request()` client,
   * you can modify it.
   */
  afterResponse?: AfterResponseMiddleware | AfterResponseMiddleware[];

  /**
   * An optional bank of named functions that you can use in
   * `z.hydrate('someName')` to lazily load data.
   */
  hydrators?: Hydrators;

  /**
   * All the resources for your app. Zapier will take these and
   * generate the relevent triggers/searches/creates automatically.
   */
  resources?: Resources;

  /**
   * All of the read bulks (GETs) your app exposes to retrieve
   * resources in batches.
   */
  bulkReads?: BulkReads;

  /**
   * All the search-or-create combos for your app. You can create your
   * own here, or Zapier will automatically register any from
   * resources that define a search, a create, and a get (or define a
   * searchOrCreate directly). Register non-resource search-or-creates
   * here as well.
   */
  searchOrCreates?: SearchOrCreates;

  /** An alias for "searchOrCreates". */
  searchAndCreates?: SearchAndCreates;

  /** Top-level app options */
  flags?: AppFlags;

  /**
   * Zapier uses this configuration to apply throttling when the limit
   * for the window is exceeded. When set here, it is the default
   * throttle configuration used on each action of the integration.
   * And when set in an action's operation object, it gets overwritten
   * for that action only.
   */
  throttle?: ThrottleObject;

  /**
   * **INTERNAL USE ONLY**. Zapier uses this to hold properties from a
   * legacy Web Builder app.
   */
  legacy?: Record<string, unknown>;

  /**
   * **INTERNAL USE ONLY**. Zapier uses this for internal webhook app
   * configurations.
   */
  firehoseWebhooks?: Record<string, unknown>;
}

/**
 * Represents a simplified semver string, from `0.0.0` to
 * `999.999.999` with optional simplified label. They need to be
 * case-insensitive unique.
 */
export type Version = string;

/**
 * List of before or after middlewares. Can be an array of functions
 * or a single function
 */
export type Middlewares = Function[] | Function;

/** Represents authentication schemes. */
export interface Authentication {
  /** Choose which scheme you want to use. */
  type: 'basic' | 'custom' | 'digest' | 'oauth1' | 'oauth2' | 'session';

  /**
   * A function or request that confirms the authentication is
   * working.
   */
  test: Request | Function;

  /**
   * Fields you can request from the user before they connect your app
   * to Zapier.
   */
  fields?: AuthFields;

  /**
   * A string with variables, function, or request that returns the
   * connection label for the authenticated user.
   */
  connectionLabel?: Request | Function | string;

  basicConfig?: AuthenticationBasicConfig;

  customConfig?: AuthenticationCustomConfig;

  digestConfig?: AuthenticationDigestConfig;

  oauth1Config?: AuthenticationOAuth1Config;

  oauth2Config?: AuthenticationOAuth2Config;

  sessionConfig?: AuthenticationSessionConfig;
}

/**
 * A representation of a HTTP request - you can use the `{{syntax}}`
 * to inject authentication, field or global variables.
 */
export interface Request {
  /** The HTTP method for the request. */
  method?: 'GET' | 'PUT' | 'POST' | 'PATCH' | 'DELETE' | 'HEAD';

  /**
   * A URL for the request (we will parse the querystring and merge
   * with params). Keys and values will not be re-encoded.
   */
  url?: string;

  /** Can be nothing, a raw string or JSON (object or array). */
  body?: null | string | Record<string, unknown> | unknown[];

  /**
   * A mapping of the querystring - will get merged with any query
   * params in the URL. Keys and values will be encoded.
   */
  params?: FlatObject;

  /** The HTTP headers for the request. */
  headers?: FlatObject;

  /**
   * An object holding the auth parameters for OAuth1 request signing,
   * like `{oauth_token: 'abcd', oauth_token_secret: '1234'}`. Or an
   * array reserved (i.e. not implemented yet) to hold the username
   * and password for Basic Auth. Like `['AzureDiamond', 'hunter2']`.
   */
  auth?: string[] | FlatObject;

  /**
   * Should missing values be sent? (empty strings, `null`, and
   * `undefined` only — `[]`, `{}`, and `false` will still be sent).
   * Allowed fields are `params` and `body`. The default is `false`,
   * ex: ```removeMissingValuesFrom: { params: false, body: false }```
   */
  removeMissingValuesFrom?: { params: boolean; body: boolean };

  /**
   * A function to customize how to serialize a value for curlies
   * `{{var}}` in the request object. By default, when this is
   * unspecified, the request client only replaces curlies where
   * variables are strings, and would throw an error for non-strings.
   * The function should accepts a single argument as the value to be
   * serialized and return the string representation of the argument.
   */
  serializeValueForCurlies?: Function;

  /**
   * If `true`, don't throw an exception for response 400 <= status <
   * 600 automatically before resolving with the response. Defaults to
   * `false`.
   */
  skipThrowForStatus?: boolean;

  /**
   * Contains the characters that you want left unencoded in the query
   * params (`req.params`). If unspecified, `z.request()` will
   * percent-encode non-ascii characters and these reserved
   * characters: ``:$/?#[]@$&+,;=^@`\``.
   */
  skipEncodingChars?: string;
}

/**
 * A bank of named functions that you can use in
 * `z.hydrate('someName')` to lazily load data.
 */
export type Hydrators = Record<string, Function>;

/**
 * All the resources that underlie common CRUD methods powering
 * automatically handled triggers, creates, and searches for your
 * app. Zapier will break these apart for you.
 */
export type Resources = Record<string, Resource>;

/** Enumerates the bulk reads your app exposes. */
export type BulkReads = Record<string, BulkRead>;

/**
 * Enumerates the search-or-creates your app has available for
 * users.
 */
export type SearchOrCreates = Record<string, SearchOrCreate>;

/** Alias for /SearchOrCreatesSchema */
export type SearchAndCreates = Record<string, SearchOrCreate>;

/** Codifies high-level options for your integration. */
export interface AppFlags {
  /**
   * By default, Zapier patches the core `http` module so that all
   * requests (including those from 3rd-party SDKs) can be logged. Set
   * this to true if you're seeing issues using an SDK (such as AWS).
   */
  skipHttpPatch?: boolean;

  /**
   * Starting in `core` version `10.0.0`, `response.throwForStatus()`
   * was called by default. We introduced a per-request way to opt-out
   * of this behavior. This flag takes that a step further and
   * controls that behavior integration-wide **for requests made using
   * `z.request()`**. Unless they specify otherwise (per-request, or
   * via middleware), [Shorthand
   * requests](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#shorthand-http-requests)
   * _always_ call `throwForStatus()`. `z.request()` calls can also
   * ignore this flag if they set `skipThrowForStatus` directly. It is
   * important to note that for oauth2 or session auths with
   * `authRefresh:true`, `401` status codes will throw a
   * `RefreshAuthError` regardless of `skipThrowForStatus`, and will
   * need to be handled manually if intervention is required.
   */
  skipThrowForStatus?: boolean;

  /**
   * Starting in `core` version `18.0.0`, 429 (throttling) responses
   * throw a `ThrottledError` before `afterResponse` middleware runs
   * by default. Set this flag to `true` to preserve the old behavior
   * where `afterResponse` middleware can see and handle 429
   * responses. This flag can be overridden per-request by setting
   * `throwForThrottlingEarly` directly on the request options.
   */
  throwForThrottlingEarly?: boolean;

  /**
   * If true, Zapier removes empty strings, `null`, `undefined`, and
   * empty Arrays or objects from `bundle.inputData` recursively
   * before passing it to your `perform*` function. If you want to
   * handle empty values yourself in your code, explicitly set this to
   * false. This is a global flag that affects all the triggers and
   * actions in your integration. The `cleanInputData` flag in
   * `operation` takes precedence over this one.
   */
  cleanInputData?: boolean;
}

/**
 * Zapier uses this configuration to apply throttling when the limit
 * for the window is exceeded. **NOTE:** The final key used for the
 * throttling is formed as a combination of all the configurations;
 * key, window, limit, and scope. To share a limit across multiple
 * actions in an integration, each should have the same
 * configuration set without "action" in the scope.
 */
export interface ThrottleObject {
  /**
   * The timeframe, in seconds, within which the system tracks the
   * number of invocations for an action. The number of invocations
   * begins at zero at the start of each window.
   */
  window: number;

  /**
   * The maximum number of invocations for an action, allowed within
   * the timeframe window.
   */
  limit: number;

  /**
   * The key to throttle with in combination with the scope. User data
   * provided for the input fields can be used in the key with the use
   * of the curly braces referencing. For example, to access the user
   * data provided for the input field "test_field", use
   * `{{bundle.inputData.test_field}}`. Note that a required input
   * field should be referenced to get user data always.
   */
  key?: string;

  /**
   * The granularity to throttle by. You can set the scope to one or
   * more of the following: 'user' - Throttles based on user ids.
   * 'auth' - Throttles based on auth ids. 'account' - Throttles based
   * on account ids for all users under a single account. 'action' -
   * Throttles the action it is set on separately from other actions.
   * By default, throttling is scoped to the action and account.
   */
  scope?: ('user' | 'auth' | 'account' | 'action')[];

  /**
   * The effect of throttling on the tasks of the action. `true` means
   * throttled tasks are automatically retried after some delay, while
   * `false` means tasks are held without retry. It defaults to
   * `true`. NOTE that it has no effect on polling triggers and should
   * not be set.
   */
  retry?: boolean;

  /**
   * EXPERIMENTAL: Account-based attribute to override the throttle
   * by. You can set to one of the following: "free", "trial", "paid".
   * Therefore, the throttle scope would be automatically set to
   * "account" and ONLY the accounts based on the specified filter
   * will have their requests throttled based on the throttle
   * overrides while the rest are throttled based on the original
   * configuration.
   */
  filter?: 'free' | 'trial' | 'paid';

  /**
   * EXPERIMENTAL: Overrides the original throttle configuration based
   * on a Zapier account attribute.
   */
  overrides?: ThrottleOverrideObject[];
}

/**
 * Internal pointer to a function from the original source or the
 * source code itself. Encodes arity and if `arguments` is used in
 * the body. Note - just write normal functions and the system will
 * encode the pointers for you. Or, provide {source: "return 1 + 2"}
 * and the system will wrap in a function for you.
 *
 * @deprecated Prefer using the perform types from the `functions` module.
 */
export type Function = PerformFunction;

/** An array or collection of authentication fields. */
export type AuthFields = AuthField[];

/**
 * Config for Basic Authentication. No extra properties are required
 * to setup Basic Auth, so you can leave this empty if your app uses
 * Basic Auth.
 */
export interface AuthenticationBasicConfig {}

/**
 * Config for custom authentication (like API keys). No extra
 * properties are required to setup this auth type, so you can leave
 * this empty if your app uses a custom auth method.
 */
export interface AuthenticationCustomConfig {
  /**
   * EXPERIMENTAL: Define the call Zapier should make to send the OTP
   * code.
   */
  sendCode?: Request | Function;
}

/**
 * Config for Digest Authentication. No extra properties are
 * required to setup Digest Auth, so you can leave this empty if
 * your app uses Digets Auth.
 */
export interface AuthenticationDigestConfig {}

/** Config for OAuth1 authentication. */
export interface AuthenticationOAuth1Config {
  /**
   * Define where Zapier will acquire a request token which is used
   * for the rest of the three legged authentication process.
   */
  getRequestToken: Request | Function;

  /**
   * Define where Zapier will redirect the user to authorize our app.
   * Typically, you should append an `oauth_token` querystring
   * parameter to the request.
   */
  authorizeUrl: RedirectRequest | Function;

  /** Define how Zapier fetches an access token from the API */
  getAccessToken: Request | Function;
}

/** Config for OAuth2 authentication. */
export interface AuthenticationOAuth2Config {
  /**
   * Define where Zapier will redirect the user to authorize our app.
   * Note: we append the redirect URL and state parameters to return
   * value of this function.
   */
  authorizeUrl: RedirectRequest | Function;

  /** Define how Zapier fetches an access token from the API */
  getAccessToken: Request | Function;

  /** Define how Zapier will refresh the access token from the API */
  refreshAccessToken?: Request | Function;

  /** Define a non-standard code param Zapier should scrape instead. */
  codeParam?: string;

  /** What scope should Zapier request? */
  scope?: string;

  /**
   * Should Zapier invoke `refreshAccessToken` when we receive an
   * error for a 401 response?
   */
  autoRefresh?: boolean;

  /** Should Zapier use PKCE for OAuth2? */
  enablePkce?: boolean;
}

/** Config for session authentication. */
export interface AuthenticationSessionConfig {
  /**
   * Define how Zapier fetches the additional authData needed to make
   * API calls.
   */
  perform: Request | Function;
}

/** An object whose values can only be primitives */
export type FlatObject = Record<
  string,
  null | string | number | number | boolean
>;

/**
 * Represents a resource, which will in turn power triggers,
 * searches, or creates.
 */
export interface Resource {
  /** A key to uniquely identify this resource. */
  key: Key;

  /**
   * A noun for this resource that completes the sentence "create a
   * new XXX".
   */
  noun: string;

  /** How will we get a single object given a unique identifier/id? */
  get?: ResourceMethodGet;

  /**
   * How will we get notified of new objects? Will be turned into a
   * trigger automatically.
   */
  hook?: ResourceMethodHook;

  /**
   * How will we get a list of new objects? Will be turned into a
   * trigger automatically.
   */
  list?: ResourceMethodList;

  /**
   * How will we find a specific object given filters or search terms?
   * Will be turned into a search automatically.
   */
  search?: ResourceMethodSearch;

  /**
   * How will we find create a specific object given inputs? Will be
   * turned into a create automatically.
   */
  create?: ResourceMethodCreate;

  /** What fields of data will this return? */
  outputFields?: OutputFields;

  /** What does a sample of data look like? */
  sample?: Record<string, unknown>;
}

/** How will Zapier get notified of new objects? */
export interface Trigger<
  $Key extends string = string,
  $InputFields extends InputFields = InputFields,
> {
  /** A key to uniquely identify this trigger. */
  key: $Key;

  /**
   * A noun for this trigger that completes the sentence "triggers on
   * a new XXX".
   */
  noun: string;

  /** Configures the UI for this trigger. */
  display: BasicDisplay;

  /** Powers the functionality for this trigger. */
  operation:
    | BasicPollingOperation<$InputFields>
    | BasicHookOperation<$InputFields>
    | BasicHookToPollOperation<$InputFields>;
}

/** How will Zapier fetch resources from your application? */
export interface BulkRead {
  /** A key to uniquely identify a record. */
  key: Key;

  /**
   * A noun for this read that completes the sentence "reads all of
   * the XXX".
   */
  noun: string;

  /** Configures the UI for this read bulk. */
  display: BasicDisplay;

  /** Powers the functionality for this read bulk. */
  operation: BasicActionOperation;
}

/** How will Zapier search for existing objects? */
export interface Search<
  $Key extends string = string,
  $InputFields extends InputFields = InputFields,
> {
  /** A key to uniquely identify this search. */
  key: $Key;

  /**
   * A noun for this search that completes the sentence "finds a
   * specific XXX".
   */
  noun: string;

  /** Configures the UI for this search. */
  display: BasicDisplay;

  /** Powers the functionality for this search. */
  operation: BasicSearchOperation<$InputFields>;
}

/** How will Zapier create a new object? */
export interface Create<
  $Key extends string = string,
  $InputFields extends InputFields = InputFields,
> {
  /** A key to uniquely identify this create. */
  key: $Key;

  /**
   * A noun for this create that completes the sentence "creates a new
   * XXX".
   */
  noun: string;

  /** Configures the UI for this create. */
  display: BasicDisplay;

  /** Powers the functionality for this create. */
  operation: BasicCreateOperation<$InputFields>;
}

/**
 * Pair an existing search and a create to enable "Find or Create"
 * functionality in your app
 */
export interface SearchOrCreate {
  /**
   * A key to uniquely identify this search-or-create. Must match the
   * search key.
   */
  key: Key;

  /** Configures the UI for this search-or-create. */
  display: BasicDisplay;

  /** The key of the search that powers this search-or-create */
  search: Key;

  /** The key of the create that powers this search-or-create */
  create: Key;

  /**
   * EXPERIMENTAL: The key of the update action (in `creates`) that
   * will be used if a search succeeds.
   */
  update?: Key;

  /**
   * EXPERIMENTAL: A mapping where the key represents the input field
   * for the update action, and the value represents the field from
   * the search action's output that should be mapped to the update
   * action's input field.
   */
  updateInputFromSearchOutput?: FlatObject;

  /**
   * EXPERIMENTAL: A mapping where the key represents an input field
   * for the search action, and the value represents how that field's
   * value will be used to filter down the search output for an exact
   * match.
   */
  searchUniqueInputToOutputConstraint?: Record<string, unknown>;
}

/**
 * EXPERIMENTAL: Overrides the original throttle configuration based
 * on a Zapier account attribute.
 */
export interface ThrottleOverrideObject {
  /**
   * The timeframe, in seconds, within which the system tracks the
   * number of invocations for an action. The number of invocations
   * begins at zero at the start of each window.
   */
  window: number;

  /**
   * The maximum number of invocations for an action, allowed within
   * the timeframe window.
   */
  limit: number;

  /**
   * Account-based attribute to override the throttle by. You can set
   * to one of the following: "free", "trial", "paid". Therefore, the
   * throttle scope would be automatically set to "account" and ONLY
   * the accounts based on the specified filter will have their
   * requests throttled based on the throttle overrides while the rest
   * are throttled based on the original configuration.
   */
  filter: 'free' | 'trial' | 'paid';

  /**
   * The effect of throttling on the tasks of the action. `true` means
   * throttled tasks are automatically retried after some delay, while
   * `false` means tasks are held without retry. It defaults to
   * `true`. NOTE that it has no effect on polling triggers and should
   * not be set.
   */
  retry?: boolean;
}

/**
 * Field schema specialized for authentication fields. In addition
 * to the requirements below, the following keys are mutually
 * exclusive:
 *
 * * `children` & `list`
 * * `children` & `dict`
 * * `children` & `type`
 * * `children` & `placeholder`
 * * `children` & `helpText`
 * * `children` & `default`
 * * `dict` & `list`
 * * `dynamic` & `dict`
 * * `dynamic` & `choices`
 */
export interface AuthField {
  /** A unique machine readable key for this value (IE: "fname"). */
  key: string;

  /** A human readable label for this value (IE: "First Name"). */
  label?: string;

  /** The type of this value used to be. */
  type?:
    | 'string'
    | 'number'
    | 'boolean'
    | 'datetime'
    | 'copy'
    | 'password'
    | 'integer'
    | 'text';

  /** If this value is required or not. This defaults to `true`. */
  required?: boolean;

  /** A default value that is saved the first time a Zap is created. */
  default?: string;

  /**
   * Acts differently when used in inputFields vs. when used in
   * outputFields. In inputFields: Can a user provide multiples of
   * this field? In outputFields: Does this field return an array of
   * items of type `type`?
   */
  list?: boolean;

  /**
   * An array of child fields that define the structure of a
   * sub-object for this field. Usually used for line items.
   */
  children?: AuthField[];

  /** Is this field a key/value input? */
  dict?: boolean;

  /**
   * A human readable description of this value (IE: "The first part
   * of a full name."). You can use Markdown.
   */
  helpText?: string;

  /** An example value that is not saved. */
  placeholder?: string;

  /**
   * An object of machine keys and human values to populate a static
   * dropdown.
   */
  choices?: FieldChoices;

  /**
   * Is this field automatically populated (and hidden from the user)?
   * Note: Only OAuth and Session Auth support fields with this key.
   */
  computed?: boolean;

  /**
   * Useful when you expect the input to be part of a longer string.
   * Put "{{input}}" in place of the user's input (IE:
   * "https://{{input}}.yourdomain.com").
   */
  inputFormat?: string;

  /**
   * Indicates if this authentication field is safe to e.g. be stored
   * without encryption or displayed (not a secret).
   */
  isNoSecret?: boolean;
}

/**
 * A representation of a HTTP redirect - you can use the
 * `{{syntax}}` to inject authentication, field or global variables.
 */
export interface RedirectRequest {
  /** The HTTP method for the request. */
  method?: 'GET';

  /**
   * A URL for the request (we will parse the querystring and merge
   * with params). Keys and values will not be re-encoded.
   */
  url?: string;

  /**
   * A mapping of the querystring - will get merged with any query
   * params in the URL. Keys and values will be encoded.
   */
  params?: FlatObject;
}

/** A unique identifier for this item. */
export type Key = string;

/** How will we get a single object given a unique identifier/id? */
export interface ResourceMethodGet {
  /** Define how this get method will be exposed in the UI. */
  display: BasicDisplay;

  /** Define how this get method will work. */
  operation: BasicOperation;
}

/**
 * How will we get notified of new objects? Will be turned into a
 * trigger automatically.
 */
export interface ResourceMethodHook {
  /** Define how this hook/trigger method will be exposed in the UI. */
  display: BasicDisplay;

  /** Define how this hook/trigger method will work. */
  operation: BasicHookOperation;
}

/**
 * How will we get a list of new objects? Will be turned into a
 * trigger automatically.
 */
export interface ResourceMethodList {
  /** Define how this list/trigger method will be exposed in the UI. */
  display: BasicDisplay;

  /** Define how this list/trigger method will work. */
  operation: BasicPollingOperation;
}

/**
 * How will we find a specific object given filters or search terms?
 * Will be turned into a search automatically.
 */
export interface ResourceMethodSearch {
  /** Define how this search method will be exposed in the UI. */
  display: BasicDisplay;

  /** Define how this search method will work. */
  operation: BasicActionOperation;
}

/**
 * How will we find create a specific object given inputs? Will be
 * turned into a create automatically.
 */
export interface ResourceMethodCreate {
  /** Define how this create method will be exposed in the UI. */
  display: BasicDisplay;

  /** Define how this create method will work. */
  operation: BasicActionOperation;
}

/** An array or collection of output fields. */
export type OutputFields = (PlainOutputField | Function)[];

/** Represents user information for a trigger, search, or create. */
export interface BasicDisplay {
  /**
   * A short label like "New Record" or "Create Record in Project".
   * Optional if `hidden` is true.
   */
  label?: string;

  /**
   * A description of what this trigger, search, or create does.
   * Optional if `hidden` is true.
   */
  description?: string;

  /**
   * A short blurb that can explain how to get this working. EG: how
   * and where to copy-paste a static hook URL into your application.
   * Only evaluated for static webhooks.
   */
  directions?: string;

  /** Should this operation be unselectable by users? */
  hidden?: boolean;
}

/** Represents the fundamental mechanics of a trigger. */
export interface BasicPollingOperation<
  $InputFields extends InputFields = InputFields,
> {
  /**
   * Clarify how this operation works (polling == pull or hook ==
   * push).
   */
  type?: 'polling';

  /**
   * Optionally reference and extends a resource. Allows Zapier to
   * automatically tie together samples, lists and hooks, greatly
   * improving the UX. EG: if you had another trigger reusing a
   * resource but filtering the results.
   */
  resource?: Key;

  /**
   * How will Zapier get the data? This can be a function like `(z) =>
   * [{id: 123}]` or a request like `{url: 'http...'}`.
   */
  perform: Request | PollingTriggerPerform<InferInputData<$InputFields>>;

  /**
   * Does this endpoint support pagination via temporary cursor
   * storage?
   */
  canPaginate?: boolean;

  /** What should the form a user sees and configures look like? */
  inputFields?: $InputFields;

  /**
   * Defines groups for organizing input fields in the UI. Each group
   * can have a key, label, and emphasis styling.
   */
  inputFieldGroups?: InputFieldGroups;

  /**
   * What fields of data will this return? Will use resource
   * outputFields if missing, will also use sample if available.
   */
  outputFields?: OutputFields;

  /**
   * What does a sample of data look like? Will use resource sample if
   * missing. Requirement waived if `display.hidden` is true or if
   * this belongs to a resource that has a top-level sample
   */
  sample?: Record<string, unknown>;

  /**
   * Zapier uses this configuration to apply throttling when the limit
   * for the window is exceeded.
   */
  throttle?: ThrottleObject;

  /**
   * If true, Zapier removes empty strings, `null`, `undefined`, and
   * empty Arrays or objects from `bundle.inputData` recursively
   * before passing it to your `perform*` function. If you want to
   * handle empty values yourself in your code, explicitly set this to
   * false. There is also a global flag with the same name in
   * `App.flags`. This one takes precedence over the global one.
   */
  cleanInputData?: boolean;
}

/**
 * Represents the inbound mechanics of hooks with optional
 * subscribe/unsubscribe. Defers to list for fields.
 */
export interface BasicHookOperation<
  $InputFields extends InputFields = InputFields,
> {
  /**
   * Must be explicitly set to `"hook"` unless this hook is defined as
   * part of a resource, in which case it's optional.
   */
  type?: 'hook';

  /**
   * Optionally reference and extends a resource. Allows Zapier to
   * automatically tie together samples, lists and hooks, greatly
   * improving the UX. EG: if you had another trigger reusing a
   * resource but filtering the results.
   */
  resource?: Key;

  /** A function that processes the inbound webhook request. */
  perform: WebhookTriggerPerform<InferInputData<$InputFields>>;

  /**
   * Fetch a list of items on demand during testing instead of waiting
   * for a hook. You can also consider resources and their built-in
   * hook/list methods. Note: this is required for public apps to
   * ensure the best UX for the end-user. For private apps, this is
   * strongly recommended for testing REST Hooks. Otherwise, you can
   * ignore warnings about this property with the `--without-style`
   * flag during `zapier-platform push`.
   */
  performList?:
    | Request
    | WebhookTriggerPerformList<InferInputData<$InputFields>>;

  /**
   * Does this endpoint support pagination via temporary cursor
   * storage?
   */
  canPaginate?: boolean;

  /**
   * Takes a URL and any necessary data from the user and subscribes.
   * Note: this is required for public apps to ensure the best UX for
   * the end-user. For private apps, this is strongly recommended for
   * testing REST Hooks. Otherwise, you can ignore warnings about this
   * property with the `--without-style` flag during `zapier-platform
   * push`.
   */
  performSubscribe?:
    | Request
    | WebhookTriggerPerformSubscribe<InferInputData<$InputFields>>;

  /**
   * Takes a URL and data from a previous subscribe call and
   * unsubscribes. Note: this is required for public apps to ensure
   * the best UX for the end-user. For private apps, this is strongly
   * recommended for testing REST Hooks. Otherwise, you can ignore
   * warnings about this property with the `--without-style` flag
   * during `zapier-platform push`.
   */
  performUnsubscribe?:
    | Request
    | WebhookTriggerPerformUnsubscribe<InferInputData<$InputFields>>;

  /** What should the form a user sees and configures look like? */
  inputFields?: $InputFields;

  /**
   * Defines groups for organizing input fields in the UI. Each group
   * can have a key, label, and emphasis styling.
   */
  inputFieldGroups?: InputFieldGroups;

  /**
   * What fields of data will this return? Will use resource
   * outputFields if missing, will also use sample if available.
   */
  outputFields?: OutputFields;

  /**
   * What does a sample of data look like? Will use resource sample if
   * missing. Requirement waived if `display.hidden` is true or if
   * this belongs to a resource that has a top-level sample
   */
  sample?: Record<string, unknown>;

  /**
   * If true, Zapier removes empty strings, `null`, `undefined`, and
   * empty Arrays or objects from `bundle.inputData` recursively
   * before passing it to your `perform*` function. If you want to
   * handle empty values yourself in your code, explicitly set this to
   * false. There is also a global flag with the same name in
   * `App.flags`. This one takes precedence over the global one.
   */
  cleanInputData?: boolean;
}

/**
 * Represents the inbound mechanics of hook to poll style triggers.
 * Defers to list for fields.
 */
export interface BasicHookToPollOperation<
  $InputFields extends InputFields = InputFields,
> {
  /** Must be explicitly set to `"hook_to_poll"`. */
  type?: 'hook_to_poll';

  /**
   * Similar a polling trigger, but checks for new data when a webhook
   * is received, instead of every few minutes
   */
  performList:
    | Request
    | HookToPollTriggerPerformList<InferInputData<$InputFields>>;

  /**
   * Does this endpoint support pagination via temporary cursor
   * storage?
   */
  canPaginate?: boolean;

  /** Takes a URL and any necessary data from the user and subscribes. */
  performSubscribe:
    | Request
    | HookToPollTriggerPerformSubscribe<InferInputData<$InputFields>>;

  /**
   * Takes a URL and data from a previous subscribe call and
   * unsubscribes.
   */
  performUnsubscribe:
    | Request
    | HookToPollTriggerPerformUnsubscribe<InferInputData<$InputFields>>;

  /** What should the form a user sees and configures look like? */
  inputFields?: $InputFields;

  /**
   * Defines groups for organizing input fields in the UI. Each group
   * can have a key, label, and emphasis styling.
   */
  inputFieldGroups?: InputFieldGroups;

  /**
   * What fields of data will this return? Will use resource
   * outputFields if missing, will also use sample if available.
   */
  outputFields?: OutputFields;

  /**
   * What does a sample of data look like? Will use resource sample if
   * missing. Requirement waived if `display.hidden` is true or if
   * this belongs to a resource that has a top-level sample
   */
  sample?: Record<string, unknown>;

  /**
   * If true, Zapier removes empty strings, `null`, `undefined`, and
   * empty Arrays or objects from `bundle.inputData` recursively
   * before passing it to your `perform*` function. If you want to
   * handle empty values yourself in your code, explicitly set this to
   * false. There is also a global flag with the same name in
   * `App.flags`. This one takes precedence over the global one.
   */
  cleanInputData?: boolean;

  /**
   * The maximum amount of time to wait between polling requests in
   * seconds. Minimum value is 20s and will default to 20 if not set,
   * or set to a lower value.
   */
  maxPollingDelay?: number;
}

/** Represents the fundamental mechanics of a search/create. */
export interface BasicActionOperation {
  /**
   * Optionally reference and extends a resource. Allows Zapier to
   * automatically tie together samples, lists and hooks, greatly
   * improving the UX. EG: if you had another trigger reusing a
   * resource but filtering the results.
   */
  resource?: Key;

  /**
   * How will Zapier get the data? This can be a function like `(z) =>
   * [{id: 123}]` or a request like `{url: 'http...'}`.
   */
  perform: Request | Function;

  /**
   * A function that parses data from a perform (which uses
   * z.generateCallbackUrl()) and callback request to resume this
   * action.
   */
  performResume?: Function;

  /**
   * How will Zapier get a single record? If you find yourself
   * reaching for this - consider resources and their built-in get
   * methods.
   */
  performGet?: Request | Function;

  /** What should the form a user sees and configures look like? */
  inputFields?: InputFields;

  /**
   * Defines groups for organizing input fields in the UI. Each group
   * can have a key, label, and emphasis styling.
   */
  inputFieldGroups?: InputFieldGroups;

  /**
   * What fields of data will this return? Will use resource
   * outputFields if missing, will also use sample if available.
   */
  outputFields?: OutputFields;

  /**
   * What does a sample of data look like? Will use resource sample if
   * missing. Requirement waived if `display.hidden` is true or if
   * this belongs to a resource that has a top-level sample
   */
  sample?: Record<string, unknown>;

  /**
   * Zapier uses this configuration to ensure this action is performed
   * one at a time per scope (avoid concurrency).
   */
  lock?: LockObject;

  /**
   * Zapier uses this configuration to apply throttling when the limit
   * for the window is exceeded.
   */
  throttle?: ThrottleObject;

  /**
   * If true, Zapier removes empty strings, `null`, `undefined`, and
   * empty Arrays or objects from `bundle.inputData` recursively
   * before passing it to your `perform*` function. If you want to
   * handle empty values yourself in your code, explicitly set this to
   * false. There is also a global flag with the same name in
   * `App.flags`. This one takes precedence over the global one.
   */
  cleanInputData?: boolean;
}

/** Represents the fundamental mechanics of a search. */
export interface BasicSearchOperation<
  $InputFields extends InputFields = InputFields,
> {
  /**
   * Optionally reference and extends a resource. Allows Zapier to
   * automatically tie together samples, lists and hooks, greatly
   * improving the UX. EG: if you had another trigger reusing a
   * resource but filtering the results.
   */
  resource?: Key;

  /**
   * How will Zapier get the data? This can be a function like `(z) =>
   * [{id: 123}]` or a request like `{url: 'http...'}`.
   */
  perform: Request | SearchPerform<InferInputData<$InputFields>>;

  /**
   * A function that parses data from a perform (which uses
   * z.generateCallbackUrl()) and callback request to resume this
   * action.
   */
  performResume?: SearchPerformResume<InferInputData<$InputFields>>;

  /**
   * How will Zapier get a single record? If you find yourself
   * reaching for this - consider resources and their built-in get
   * methods.
   */
  performGet?: Request | SearchPerformGet<InferInputData<$InputFields>>;

  /** Does this search support pagination? */
  canPaginate?: boolean;

  /** What should the form a user sees and configures look like? */
  inputFields?: $InputFields;

  /**
   * Defines groups for organizing input fields in the UI. Each group
   * can have a key, label, and emphasis styling.
   */
  inputFieldGroups?: InputFieldGroups;

  /**
   * What fields of data will this return? Will use resource
   * outputFields if missing, will also use sample if available.
   */
  outputFields?: OutputFields;

  /**
   * What does a sample of data look like? Will use resource sample if
   * missing. Requirement waived if `display.hidden` is true or if
   * this belongs to a resource that has a top-level sample
   */
  sample?: Record<string, unknown>;

  /**
   * Zapier uses this configuration to ensure this action is performed
   * one at a time per scope (avoid concurrency).
   */
  lock?: LockObject;

  /**
   * Zapier uses this configuration to apply throttling when the limit
   * for the window is exceeded.
   */
  throttle?: ThrottleObject;

  /**
   * If true, Zapier removes empty strings, `null`, `undefined`, and
   * empty Arrays or objects from `bundle.inputData` recursively
   * before passing it to your `perform*` function. If you want to
   * handle empty values yourself in your code, explicitly set this to
   * false. There is also a global flag with the same name in
   * `App.flags`. This one takes precedence over the global one.
   */
  cleanInputData?: boolean;
}

/** Represents the fundamental mechanics of a create. */
export interface BasicCreateOperation<
  $InputFields extends InputFields = InputFields,
> {
  /**
   * Optionally reference and extends a resource. Allows Zapier to
   * automatically tie together samples, lists and hooks, greatly
   * improving the UX. EG: if you had another trigger reusing a
   * resource but filtering the results.
   */
  resource?: Key;

  /**
   * How will Zapier get the data? This can be a function like `(z) =>
   * [{id: 123}]` or a request like `{url: 'http...'}`. Exactly one of
   * `perform` or `performBuffer` must be defined. If you choose to
   * define `buffer` and `performBuffer`, you must omit `perform`.
   */
  perform?: Request | CreatePerform<InferInputData<$InputFields>>;

  /**
   * A function that parses data from a perform (which uses
   * z.generateCallbackUrl()) and callback request to resume this
   * action.
   */
  performResume?: CreatePerformResume<InferInputData<$InputFields>>;

  /**
   * How will Zapier get a single record? If you find yourself
   * reaching for this - consider resources and their built-in get
   * methods.
   */
  performGet?: Request | CreatePerformGet<InferInputData<$InputFields>>;

  /** What should the form a user sees and configures look like? */
  inputFields?: $InputFields;

  /**
   * Defines groups for organizing input fields in the UI. Each group
   * can have a key, label, and emphasis styling.
   */
  inputFieldGroups?: InputFieldGroups;

  /**
   * What fields of data will this return? Will use resource
   * outputFields if missing, will also use sample if available.
   */
  outputFields?: OutputFields;

  /**
   * What does a sample of data look like? Will use resource sample if
   * missing. Requirement waived if `display.hidden` is true or if
   * this belongs to a resource that has a top-level sample
   */
  sample?: Record<string, unknown>;

  /**
   * Zapier uses this configuration to ensure this action is performed
   * one at a time per scope (avoid concurrency).
   */
  lock?: LockObject;

  /**
   * Zapier uses this configuration to apply throttling when the limit
   * for the window is exceeded.
   */
  throttle?: ThrottleObject;

  /**
   * If true, Zapier removes empty strings, `null`, `undefined`, and
   * empty Arrays or objects from `bundle.inputData` recursively
   * before passing it to your `perform*` function. If you want to
   * handle empty values yourself in your code, explicitly set this to
   * false. There is also a global flag with the same name in
   * `App.flags`. This one takes precedence over the global one.
   */
  cleanInputData?: boolean;

  /**
   * Currently an **internal-only** feature. Zapier uses this
   * configuration for creating objects in bulk with `performBuffer`.
   */
  buffer?: BufferConfig;

  /**
   * Currently an **internal-only** feature. A function to create
   * objects in bulk with. `buffer` and `performBuffer` must either
   * both be defined or neither. Additionally, only one of `perform`
   * or `performBuffer` can be defined. If you choose to define
   * `perform`, you must omit `buffer` and `performBuffer`.
   */
  performBuffer?: Function;
}

/**
 * A static dropdown of options. Which you use depends on your order
 * and label requirements:
 *
 * Need a Label? | Does Order Matter? | Type to Use
 * ---|---|---
 * Yes | No | Object of value -> label
 * No | Yes | Array of Strings
 * Yes | Yes | Array of
 * [FieldChoiceWithLabel](#fieldchoicewithlabelschema)
 */
export type FieldChoices =
  | Record<string, unknown>
  | (string | FieldChoiceWithLabel)[];

/**
 * Represents the fundamental mechanics of triggers, searches, or
 * creates.
 */
export interface BasicOperation {
  /**
   * Optionally reference and extends a resource. Allows Zapier to
   * automatically tie together samples, lists and hooks, greatly
   * improving the UX. EG: if you had another trigger reusing a
   * resource but filtering the results.
   */
  resource?: Key;

  /**
   * How will Zapier get the data? This can be a function like `(z) =>
   * [{id: 123}]` or a request like `{url: 'http...'}`.
   */
  perform: Request | Function;

  /** What should the form a user sees and configures look like? */
  inputFields?: InputFields;

  /**
   * Defines groups for organizing input fields in the UI. Each group
   * can have a key, label, and emphasis styling.
   */
  inputFieldGroups?: InputFieldGroups;

  /**
   * What fields of data will this return? Will use resource
   * outputFields if missing, will also use sample if available.
   */
  outputFields?: OutputFields;

  /**
   * What does a sample of data look like? Will use resource sample if
   * missing. Requirement waived if `display.hidden` is true or if
   * this belongs to a resource that has a top-level sample
   */
  sample?: Record<string, unknown>;

  /**
   * Zapier uses this configuration to ensure this action is performed
   * one at a time per scope (avoid concurrency).
   */
  lock?: LockObject;

  /**
   * Zapier uses this configuration to apply throttling when the limit
   * for the window is exceeded.
   */
  throttle?: ThrottleObject;

  /**
   * If true, Zapier removes empty strings, `null`, `undefined`, and
   * empty Arrays or objects from `bundle.inputData` recursively
   * before passing it to your `perform*` function. If you want to
   * handle empty values yourself in your code, explicitly set this to
   * false. There is also a global flag with the same name in
   * `App.flags`. This one takes precedence over the global one.
   */
  cleanInputData?: boolean;
}

/**
 * Field schema specialized for output fields. In addition to the
 * requirements below, the following keys are mutually exclusive:
 *
 * * `children` & `list`
 * * `children` & `dict`
 * * `children` & `type`
 * * `children` & `placeholder`
 * * `children` & `helpText`
 * * `children` & `default`
 * * `dict` & `list`
 * * `dynamic` & `dict`
 * * `dynamic` & `choices`
 */
export interface PlainOutputField {
  /** A unique machine readable key for this value (IE: "fname"). */
  key: string;

  /** A human readable label for this value (IE: "First Name"). */
  label?: string;

  /**
   * The type of this value. Field type of `file` will accept either a
   * file object or a string. If a URL is provided in the string,
   * Zapier will automatically make a GET for that file. Otherwise, a
   * .txt file will be generated.
   */
  type?:
    | 'string'
    | 'number'
    | 'boolean'
    | 'datetime'
    | 'file'
    | 'password'
    | 'integer';

  /** If this value is required or not. */
  required?: boolean;

  /** A default value that is saved the first time a Zap is created. */
  default?: string;

  /**
   * Acts differently when used in inputFields vs. when used in
   * outputFields. In inputFields: Can a user provide multiples of
   * this field? In outputFields: Does this field return an array of
   * items of type `type`?
   */
  list?: boolean;

  /**
   * An array of child fields that define the structure of a
   * sub-object for this field. Usually used for line items.
   */
  children?: PlainOutputField[];

  /** Is this field a key/value input? */
  dict?: boolean;

  /**
   * Use this field as part of the primary key for deduplication. You
   * can set multiple fields as "primary", provided they are unique
   * together. If no fields are set, Zapier will default to using the
   * `id` field. `primary` only makes sense for `outputFields`. It
   * only works in static `outputFields`; will not work in
   * custom/dynamic `outputFields`. For more information, see [How
   * deduplication works in
   * Zapier](https://platform.zapier.com/build/deduplication).
   */
  primary?: boolean;

  /**
   * Prevents triggering on new output until all values for fields
   * with this property remain unchanged for 2 polls. It can be used
   * to, e.g., not trigger on a new contact until the contact has
   * completed typing their name. NOTE that this only applies to the
   * `outputFields` of polling triggers.
   */
  steadyState?: boolean;

  /**
   * An example value for this field. Can be any type (string, number,
   * boolean, object, array, null) to match the expected field output.
   * Values provided here will be combined with values in the
   * operation level `sample` field, with this field taking
   * precedence. This is most useful when using a function to generate
   * dynamic `outputFields`.
   */
  sample?:
    | string
    | number
    | boolean
    | Record<string, unknown>
    | unknown[]
    | null;
}

/** An array or collection of input field groups. */
export type InputFieldGroups = InputFieldGroup[];

/**
 * Zapier uses this configuration to ensure this action is performed
 * one at a time per scope (avoid concurrency).
 */
export interface LockObject {
  /**
   * The key to use for locking. This should be unique to the
   * operation. While actions of different integrations with the same
   * key and scope will never lock each other out, actions of the same
   * integration with the same key and scope will do. User data
   * provided for the input fields can be used in the key with the use
   * of the curly braces referencing. For example, to access the user
   * data provided for the input field "test_field", use
   * `{{bundle.inputData.test_field}}`. Note that a required input
   * field should be referenced to get user data always.
   */
  key: string;

  /**
   * By default, locks are scoped to the app. That is, all users of
   * the app will share the same locks. If you want to restrict serial
   * access to a specific user, auth, or account, you can set the
   * scope to one or more of the following: 'user' - Locks based on
   * user ids.  'auth' - Locks based on unique auth ids. 'account' -
   * Locks for all users under a single account. You may also combine
   * scopes. Note that "app" is included, always, in the scope
   * provided. For example, a scope of ['account', 'auth'] would
   * result to ['app', 'account', 'auth'].
   */
  scope?: ('user' | 'auth' | 'account')[];

  /**
   * The number of seconds to hold the lock before releasing it to
   * become accessible to other task invokes that need it. If not
   * provided, the default set by the app will be used. It cannot be
   * more than 180.
   */
  timeout?: number;
}

/**
 * Currently an **internal-only** feature. Zapier uses this
 * configuration for creating objects in bulk.
 */
export interface BufferConfig {
  /**
   * The list of keys of input fields to group bulk-create with. The
   * actual user data provided for the fields will be used during
   * execution. Note that a required input field should be referenced
   * to get user data always.
   */
  groupedBy: unknown[];

  /**
   * The maximum number of items to call `performBuffer` with.
   * **Note** that it is capped by the platform to prevent exceeding
   * the [AWS Lambda's request/response payload size quota of 6
   * MB](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html#function-configuration-deployment-and-execution).
   * Also, the execution is time-bound; we recommend reducing it upon
   * consistent timeout.
   */
  limit: number;
}

/**
 * An object describing a labeled choice in a static dropdown.
 * Useful if the value a user picks isn't exactly what the zap uses.
 * For instance, when they click on a nickname, but the zap uses the
 * user's full name
 * ([image](https://cdn.zapier.com/storage/photos/8ed01ac5df3a511ce93ed2dc43c7fbbc.png)).
 */
export interface FieldChoiceWithLabel {
  /**
   * The actual value that is sent into the Zap. This is displayed as
   * light grey text in the editor. Should match sample exactly.
   */
  value: string;

  /**
   * A legacy field that is no longer used by the editor, but it is
   * still required for now and should match the value.
   */
  sample: string;

  /** A human readable label for this value. */
  label: string;
}

/**
 * Field schema specialized for input fields. In addition to the
 * requirements below, the following keys are mutually exclusive:
 *
 * * `children` & `list`
 * * `children` & `dict`
 * * `children` & `type`
 * * `children` & `placeholder`
 * * `children` & `helpText`
 * * `children` & `default`
 * * `dict` & `list`
 * * `dynamic` & `dict`
 * * `dynamic` & `choices`
 */
export interface PlainInputField {
  /** A unique machine readable key for this value (IE: "fname"). */
  key: string;

  /** A human readable label for this value (IE: "First Name"). */
  label?: string;

  /**
   * The type of this value. Use `string` for basic text input, `text`
   * for a large, `<textarea>` style box, and `code` for a
   * `<textarea>` with a fixed-width font. Field type of `file` will
   * accept either a file object or a string. If a URL is provided in
   * the string, Zapier will automatically make a GET for that file.
   * Otherwise, a .txt file will be generated.
   */
  type?:
    | 'string'
    | 'text'
    | 'integer'
    | 'number'
    | 'boolean'
    | 'datetime'
    | 'file'
    | 'password'
    | 'copy'
    | 'code'
    | 'json';

  /** If this value is required or not. */
  required?: boolean;

  /** A default value that is saved the first time a Zap is created. */
  default?: string;

  /**
   * Acts differently when used in inputFields vs. when used in
   * outputFields. In inputFields: Can a user provide multiples of
   * this field? In outputFields: Does this field return an array of
   * items of type `type`?
   */
  list?: boolean;

  /**
   * An array of child fields that define the structure of a
   * sub-object for this field. Usually used for line items.
   */
  children?: PlainInputField[];

  /** Is this field a key/value input? */
  dict?: boolean;

  /**
   * A human readable description of this value (IE: "The first part
   * of a full name."). You can use Markdown.
   */
  helpText?: string;

  /**
   * A reference to a search that will guide the user to add a search
   * step to populate this field when creating a Zap.
   */
  search?: RefResource;

  /** A reference to a trigger that will power a dynamic dropdown. */
  dynamic?: RefResource;

  /**
   * Specifies which other input fields this field depends on. These
   * must be filled before this one becomes enabled, and when their
   * values change, this field's value should be cleared.
   */
  dependsOn?: string[];

  /**
   * Explicitly links this input field to a resource. Use the resource
   * key (e.g., "spreadsheet") or dot notation for resource fields
   * (e.g., "spreadsheet.url"). If not set for dynamic dropdowns, the
   * resource is derived implicitly from the `dynamic` property.
   */
  resource?: string;

  /**
   * Describes how to populate this dropdown. Can be a static list or
   * a dynamic object with pagination and search support.
   */
  choices?: FieldChoices | FieldDynamicChoices;

  /** An example value that is not saved. */
  placeholder?: string;

  /**
   * Does the value of this field affect the definitions of other
   * fields in the set?
   */
  altersDynamicFields?: boolean;

  /**
   * Is this field automatically populated (and hidden from the user)?
   * Note: Only OAuth, Session Auth, and certain internal use cases
   * support fields with this key.
   */
  computed?: boolean;

  /**
   * Useful when you expect the input to be part of a longer string.
   * Put "{{input}}" in place of the user's input (IE:
   * "https://{{input}}.yourdomain.com").
   */
  inputFormat?: string;

  /**
   * Allows for additional metadata to be stored on the field.
   * Supports simple key-values only (no sub-objects or arrays).
   */
  meta?: FieldMeta;

  /**
   * References a group key from the operation's inputFieldGroups to
   * organize this field with others.
   */
  group?: Key;

  /**
   * A JSON Schema object that describes the expected structure of the
   * JSON value. Only valid when `type` is `json`.
   */
  schema?: JsonSchema;
}

/** Object for visual grouping of input fields. */
export interface InputFieldGroup {
  /** The unique identifier for this group. */
  key: Key;

  /** The human-readable name for the group. */
  label?: string;

  /** Whether this group should be visually emphasized in the UI. */
  emphasize?: boolean;
}

/**
 * Reference a resource by key and the data it returns. In the
 * format of: `{resource_key}.{foreign_key}(.{human_label_key})`.
 */
export type RefResource = string;

/**
 * Describes dynamic dropdowns powered by a perform function or
 * request.
 */
export interface FieldDynamicChoices {
  /**
   * A function or request that returns choices for this dynamic
   * dropdown.
   */
  perform: Function | Request;
}

/** Allows for additional metadata to be stored on the field. */
export type FieldMeta = Record<string, string | number | boolean>;

/**
 * A JSON Schema object that describes the expected structure of a
 * JSON value. Validated against JSON Schema Draft 4, 6, or 7
 * meta-schema (based on the `$schema` field, defaulting to Draft 7)
 * via the validateJsonFieldSchema functional constraint.
 */
export type JsonSchema = Record<string, unknown>;
