@prismatic-io/spectral 10.14.0 → 10.16.1

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.
@@ -11,7 +11,10 @@ interface RetryConfig extends Omit<IAxiosRetryConfig, "retryDelay"> {
11
11
  * a retryCondition function to determine when retries should occur.
12
12
  */
13
13
  retryAllErrors?: boolean;
14
- /** When true, double the retry delay after each attempt (e.g. 1000ms, 2000ms, 4000ms, 8000ms, etc.). */
14
+ /**
15
+ * When true, double the retryDelay after each attempt (e.g. 1000ms, 2000ms, 4000ms, 8000ms, etc.).
16
+ * If no retryDelay is specified, defaults to axios-retry's exponentialDelay function.
17
+ */
15
18
  useExponentialBackoff?: boolean;
16
19
  }
17
20
  export interface ClientProps {
@@ -30,6 +33,7 @@ export interface ClientProps {
30
33
  /** Configuration used to determine if and how failed HTTP requests should be retried. */
31
34
  retryConfig?: RetryConfig;
32
35
  }
36
+ export declare const toAxiosRetryConfig: ({ retryDelay, retryAllErrors, retryCondition, useExponentialBackoff, ...rest }: RetryConfig) => IAxiosRetryConfig;
33
37
  /**
34
38
  * Creates a reusable Axios HTTP client. See
35
39
  * https://prismatic.io/docs/custom-connectors/connections/#using-the-built-in-createclient-http-client
@@ -46,7 +46,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
46
46
  return (mod && mod.__esModule) ? mod : { "default": mod };
47
47
  };
48
48
  Object.defineProperty(exports, "__esModule", { value: true });
49
- exports.inputs = exports.buildRawRequestAction = exports.sendRawRequest = exports.handleErrors = exports.createClient = void 0;
49
+ exports.inputs = exports.buildRawRequestAction = exports.sendRawRequest = exports.handleErrors = exports.createClient = exports.toAxiosRetryConfig = void 0;
50
50
  const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
51
51
  const axios_1 = __importDefault(require("axios"));
52
52
  const axios_retry_1 = __importStar(require("axios-retry"));
@@ -84,8 +84,11 @@ const toFormData = (formData, fileData, fileDataFileNames = {}) => {
84
84
  };
85
85
  const computeRetryDelay = (retryDelay, useExponentialBackoff) => {
86
86
  if (useExponentialBackoff) {
87
- return axios_retry_1.exponentialDelay;
87
+ return typeof retryDelay === "number"
88
+ ? (retryCount) => Math.pow(2, (retryCount - 1)) * retryDelay
89
+ : axios_retry_1.exponentialDelay;
88
90
  }
91
+ // retryDelay is either a number or a function
89
92
  return typeof retryDelay === "number" ? () => retryDelay : retryDelay;
90
93
  };
91
94
  const toAxiosRetryConfig = (_a) => {
@@ -96,6 +99,7 @@ const toAxiosRetryConfig = (_a) => {
96
99
  ? retryCondition
97
100
  : axios_retry_1.isNetworkOrIdempotentRequestError }));
98
101
  };
102
+ exports.toAxiosRetryConfig = toAxiosRetryConfig;
99
103
  /**
100
104
  * Creates a reusable Axios HTTP client. See
101
105
  * https://prismatic.io/docs/custom-connectors/connections/#using-the-built-in-createclient-http-client
@@ -141,7 +145,7 @@ const createClient = ({ baseUrl, responseType, headers, timeout, params, debug =
141
145
  }
142
146
  if (retryConfig) {
143
147
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
144
- (0, axios_retry_1.default)(client, toAxiosRetryConfig(retryConfig));
148
+ (0, axios_retry_1.default)(client, (0, exports.toAxiosRetryConfig)(retryConfig));
145
149
  }
146
150
  return client;
147
151
  };
@@ -81,10 +81,7 @@ function createDebugContext(context) {
81
81
  },
82
82
  memoryUsage: (actionContext, label, showDetail) => {
83
83
  if (globalDebug) {
84
- const usage = showDetail
85
- ? memoryUsageInMB()
86
- : // @ts-expect-error: memoryUsage.rss() is documented but not typed
87
- node_process_1.memoryUsage.rss() / MEMORY_USAGE_CONVERSION;
84
+ const usage = showDetail ? memoryUsageInMB() : node_process_1.memoryUsage.rss() / MEMORY_USAGE_CONVERSION;
88
85
  actionContext.debug.results.memoryUsage.push({
89
86
  mark: label,
90
87
  rss: typeof usage === "number" ? usage : usage.rss,
@@ -1,15 +1,19 @@
1
- import { IntegrationDefinition, ConfigVar, Flow, ConfigPages, ComponentRegistry, TriggerReference, CollectionType, Inputs, TriggerResult as TriggerPerformResult, ConfigVarResultCollection } from "../types";
1
+ import { IntegrationDefinition, ConfigVar, Flow, ConfigPages, ComponentRegistry, TriggerReference, CollectionType, Inputs, TriggerResult as TriggerPerformResult, ConfigVarResultCollection, QueueConfig, StandardQueueConfig } from "../types";
2
2
  import { Component as ServerComponent, ActionContext, TriggerPayload, TriggerResult } from ".";
3
3
  import { RequiredConfigVariable as ServerRequiredConfigVariable, ConfigPage as ServerConfigPage, ComponentReference as ServerComponentReference } from "./integration";
4
+ export declare const CONCURRENCY_LIMIT_MAX = 15;
5
+ export declare const CONCURRENCY_LIMIT_MIN = 2;
4
6
  export declare const convertIntegration: <TInputs extends Inputs, TActionInputs extends Inputs, TPayload extends TriggerPayload = TriggerPayload, TAllowsBranching extends boolean = boolean, TResult extends TriggerPerformResult<TAllowsBranching, TPayload> = TriggerPerformResult<TAllowsBranching, TPayload>>(definition: IntegrationDefinition<TInputs, TActionInputs, TPayload, TAllowsBranching, TResult>) => ServerComponent<TInputs, TActionInputs, ConfigVarResultCollection, TPayload, TAllowsBranching, TResult>;
5
7
  export declare const convertConfigPages: (pages: ConfigPages | undefined, userLevelConfigured: boolean) => ServerConfigPage[];
8
+ /** Converts typed QueueConfig to legacy format with usesFifoQueue and concurrencyLimit. */
9
+ export declare const convertQueueConfig: (queueConfig: QueueConfig) => StandardQueueConfig;
6
10
  /** Converts a Flow into the structure necessary for YAML generation. */
7
11
  export declare const convertFlow: <TInputs extends Inputs, TActionInputs extends Inputs, TPayload extends TriggerPayload = TriggerPayload, TAllowsBranching extends boolean = boolean, TResult extends TriggerPerformResult<TAllowsBranching, TPayload> = TriggerPerformResult<TAllowsBranching, TPayload>>(flow: Flow<TInputs, TActionInputs, TPayload, TAllowsBranching, TResult>, componentRegistry: ComponentRegistry, referenceKey: string) => Record<string, unknown>;
8
12
  /** Converts an input value to the expected server type by its collection type. */
9
13
  export declare const convertInputValue: (value: unknown, collectionType: CollectionType | undefined) => unknown;
10
14
  /** Converts a Config Var into the structure necessary for YAML generation. */
11
15
  export declare const convertConfigVar: (key: string, configVar: ConfigVar, referenceKey: string, componentRegistry: ComponentRegistry) => ServerRequiredConfigVariable;
12
- export declare const invokeTriggerComponentInput: (componentRef: ServerComponentReference, onTrigger: TriggerReference | undefined, eventName: "perform" | "onInstanceDeploy" | "onInstanceDelete") => {
16
+ export declare const invokeTriggerComponentInput: (componentRef: ServerComponentReference, onTrigger: TriggerReference | undefined, eventName: "perform" | "onInstanceDeploy" | "onInstanceDelete" | "webhookCreate" | "webhookDelete") => {
13
17
  component: {
14
18
  key: string;
15
19
  version: number | "LATEST";
@@ -20,10 +24,10 @@ export declare const invokeTriggerComponentInput: (componentRef: ServerComponent
20
24
  isPublic: boolean;
21
25
  };
22
26
  key: string;
23
- triggerEventFunctionName: "perform" | "onInstanceDeploy" | "onInstanceDelete";
27
+ triggerEventFunctionName: "perform" | "onInstanceDeploy" | "onInstanceDelete" | "webhookCreate" | "webhookDelete";
24
28
  };
25
29
  export type TriggerActionInvokeFunction = (ref: {
26
30
  component: ServerComponentReference["component"];
27
31
  key: string;
28
- triggerEventFunctionName: "perform" | "onInstanceDeploy" | "onInstanceDelete";
32
+ triggerEventFunctionName: "perform" | "onInstanceDeploy" | "onInstanceDelete" | "webhookCreate" | "webhookDelete";
29
33
  }, context: ActionContext, payload: TriggerPayload | null, params: Record<string, unknown>) => Promise<TriggerResult>;
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.invokeTriggerComponentInput = exports.convertConfigVar = exports.convertInputValue = exports.convertFlow = exports.convertConfigPages = exports.convertIntegration = void 0;
15
+ exports.invokeTriggerComponentInput = exports.convertConfigVar = exports.convertInputValue = exports.convertFlow = exports.convertQueueConfig = exports.convertConfigPages = exports.convertIntegration = exports.CONCURRENCY_LIMIT_MIN = exports.CONCURRENCY_LIMIT_MAX = void 0;
16
16
  const yaml_1 = __importDefault(require("yaml"));
17
17
  const uuid_1 = require("uuid");
18
18
  const assign_1 = __importDefault(require("lodash/assign"));
@@ -27,6 +27,8 @@ const context_1 = require("./context");
27
27
  const asyncContext_1 = require("./asyncContext");
28
28
  const path_1 = __importDefault(require("path"));
29
29
  const fs_1 = require("fs");
30
+ exports.CONCURRENCY_LIMIT_MAX = 15;
31
+ exports.CONCURRENCY_LIMIT_MIN = 2;
30
32
  const convertIntegration = (definition) => {
31
33
  var _a, _b, _c;
32
34
  // Generate a unique reference key that will be used to reference the
@@ -92,7 +94,7 @@ const convertConfigPages = (pages, userLevelConfigured) => {
92
94
  }) })));
93
95
  };
94
96
  exports.convertConfigPages = convertConfigPages;
95
- const codeNativeIntegrationYaml = ({ name, description, category, documentation, version, labels, endpointType, triggerPreprocessFlowConfig, flows, configPages, userLevelConfigPages, scopedConfigVars, instanceProfile = "Default Instance Profile", componentRegistry = {}, }, referenceKey, configVars, metadata) => {
97
+ const codeNativeIntegrationYaml = ({ name, description, category, documentation, version, labels, endpointType, triggerPreprocessFlowConfig, flows, configPages, userLevelConfigPages, scopedConfigVars, instanceProfile, componentRegistry = {}, }, referenceKey, configVars, metadata) => {
96
98
  // Find the preprocess flow config on the flow, if one exists.
97
99
  const preprocessFlows = flows.filter((flow) => flow.preprocessFlowConfig);
98
100
  // Do some validation of preprocess flow configs.
@@ -125,29 +127,17 @@ const codeNativeIntegrationYaml = ({ name, description, category, documentation,
125
127
  // Transform the IntegrationDefinition into the structure that is appropriate
126
128
  // for generating YAML, which will then be used by the Prismatic API to import
127
129
  // the integration as a Code Native Integration.
128
- const result = {
129
- definitionVersion: integration_1.DefinitionVersion,
130
- isCodeNative: true,
131
- name,
130
+ const result = Object.assign(Object.assign({ definitionVersion: integration_1.DefinitionVersion, isCodeNative: true, name,
132
131
  description,
133
132
  category,
134
133
  documentation,
135
134
  version,
136
135
  labels,
137
136
  requiredConfigVars,
138
- endpointType,
139
- preprocessFlowName: hasPreprocessFlow ? preprocessFlows[0].name : undefined,
140
- externalCustomerIdField: fieldNameToReferenceInput(hasPreprocessFlow ? "onExecution" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.externalCustomerIdField),
141
- externalCustomerUserIdField: fieldNameToReferenceInput(hasPreprocessFlow ? "onExecution" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.externalCustomerUserIdField),
142
- flowNameField: fieldNameToReferenceInput(hasPreprocessFlow ? "onExecution" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.flowNameField),
143
- flows: flows.map((flow) => (0, exports.convertFlow)(flow, componentRegistry, referenceKey)),
144
- defaultInstanceProfile: instanceProfile,
145
- configPages: [
137
+ endpointType, preprocessFlowName: hasPreprocessFlow ? preprocessFlows[0].name : undefined, externalCustomerIdField: fieldNameToReferenceInput(hasPreprocessFlow ? "onExecution" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.externalCustomerIdField), externalCustomerUserIdField: fieldNameToReferenceInput(hasPreprocessFlow ? "onExecution" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.externalCustomerUserIdField), flowNameField: fieldNameToReferenceInput(hasPreprocessFlow ? "onExecution" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.flowNameField), flows: flows.map((flow) => (0, exports.convertFlow)(flow, componentRegistry, referenceKey)) }, (instanceProfile && { defaultInstanceProfile: instanceProfile })), { configPages: [
146
138
  ...(0, exports.convertConfigPages)(configPages, false),
147
139
  ...(0, exports.convertConfigPages)(userLevelConfigPages, true),
148
- ],
149
- importMetadata: metadata,
150
- };
140
+ ], importMetadata: metadata });
151
141
  return yaml_1.default.stringify(result);
152
142
  };
153
143
  const permissionAndVisibilityTypeValueMap = {
@@ -283,11 +273,38 @@ const codeNativeIntegrationComponentReference = (referenceKey) => ({
283
273
  isPublic: false,
284
274
  });
285
275
  /* A flow's trigger gets wrapped in a custom component if there's a defined
286
- * onTrigger function, or if any custom onInstance behavior is defined.
276
+ * onTrigger function, or if any custom onInstance or webhook lifecycle behavior is defined.
287
277
  * */
288
278
  const flowUsesWrapperTrigger = (flow) => {
289
- return typeof flow.onTrigger === "function" || flow.onInstanceDelete || flow.onInstanceDeploy;
279
+ return (typeof flow.onTrigger === "function" ||
280
+ flow.onInstanceDelete ||
281
+ flow.onInstanceDeploy ||
282
+ flow.webhookLifecycleHandlers);
283
+ };
284
+ /** Converts typed QueueConfig to legacy format with usesFifoQueue and concurrencyLimit. */
285
+ const convertQueueConfig = (queueConfig) => {
286
+ if (!("type" in queueConfig)) {
287
+ return queueConfig;
288
+ }
289
+ switch (queueConfig.type) {
290
+ case "parallel":
291
+ return { usesFifoQueue: false };
292
+ case "throttled":
293
+ return {
294
+ usesFifoQueue: true,
295
+ concurrencyLimit: queueConfig.concurrencyLimit,
296
+ dedupeIdField: queueConfig.dedupeIdField,
297
+ };
298
+ case "sequential":
299
+ return {
300
+ usesFifoQueue: true,
301
+ dedupeIdField: queueConfig.dedupeIdField,
302
+ };
303
+ default:
304
+ return queueConfig;
305
+ }
290
306
  };
307
+ exports.convertQueueConfig = convertQueueConfig;
291
308
  const convertFlowSchemas = (flowKey, schemas) => {
292
309
  return Object.entries(schemas).reduce((acc, [key, value]) => {
293
310
  var _a;
@@ -303,6 +320,7 @@ const convertFlow = (flow, componentRegistry, referenceKey) => {
303
320
  result.trigger = undefined;
304
321
  result.onInstanceDeploy = undefined;
305
322
  result.onInstanceDelete = undefined;
323
+ result.webhookLifecycleHandlers = undefined;
306
324
  result.onExecution = undefined;
307
325
  result.preprocessFlowConfig = undefined;
308
326
  result.errorConfig = undefined;
@@ -364,7 +382,7 @@ const convertFlow = (flow, componentRegistry, referenceKey) => {
364
382
  throw new Error(`${flow.name} is marked as a polling trigger but has no schedule. Polling triggers require a schedule.`);
365
383
  }
366
384
  if ("queueConfig" in flow && typeof flow.queueConfig === "object") {
367
- const { queueConfig } = flow;
385
+ const queueConfig = (0, exports.convertQueueConfig)(flow.queueConfig);
368
386
  if (hasSchedule && queueConfig.usesFifoQueue) {
369
387
  throw new Error(`${flow.name} has a schedule & usesFifoQueue set to true. FIFO queues cannot be used with scheduled flows.`);
370
388
  }
@@ -375,8 +393,9 @@ const convertFlow = (flow, componentRegistry, referenceKey) => {
375
393
  throw new Error(`${flow.name} is configured for both FIFO queues and singleton executions, but these options are mutually exclusive. Please choose one.`);
376
394
  }
377
395
  if (queueConfig.concurrencyLimit !== undefined &&
378
- (queueConfig.concurrencyLimit < 2 || queueConfig.concurrencyLimit > 10)) {
379
- throw new Error(`${flow.name} has an invalid concurrencyLimit of ${queueConfig.concurrencyLimit}. concurrencyLimit must be between 2 and 10.`);
396
+ (queueConfig.concurrencyLimit < exports.CONCURRENCY_LIMIT_MIN ||
397
+ queueConfig.concurrencyLimit > exports.CONCURRENCY_LIMIT_MAX)) {
398
+ throw new Error(`${flow.name} has an invalid concurrencyLimit of ${queueConfig.concurrencyLimit}. concurrencyLimit must be between ${exports.CONCURRENCY_LIMIT_MIN} and ${exports.CONCURRENCY_LIMIT_MAX}.`);
380
399
  }
381
400
  result.queueConfig = Object.assign(Object.assign({ usesFifoQueue: false }, queueConfig), (queueConfig.dedupeIdField
382
401
  ? {
@@ -647,11 +666,12 @@ function generateTriggerPerformFn(params) {
647
666
  throw new Error(`Invalid trigger configuration detected: ${JSON.stringify(params, null, 2)}`);
648
667
  }
649
668
  }
650
- /** Generates a wrapper function that calls an existing component's onInstanceDeploy
651
- * or onInstanceDelete, then calls the flow-defined version if it exists.
669
+ /** Generates a wrapper function that calls an existing component's trigger event function
670
+ * (onInstanceDeploy, onInstanceDelete, webhookCreate, or webhookDelete), then calls
671
+ * the flow-defined version if it exists.
652
672
  * Returns the deep-merged results of the two, prioritizing the custom response
653
673
  * if there's a conflict. */
654
- const generateOnInstanceWrapperFn = (componentRef, onTrigger, eventName, componentRegistry, customFn) => {
674
+ const generateTriggerEventWrapperFn = (componentRef, onTrigger, eventName, componentRegistry, customFn) => {
655
675
  const usesComponentRef = componentRef && typeof onTrigger !== "function";
656
676
  if (usesComponentRef) {
657
677
  return (context, params) => __awaiter(void 0, void 0, void 0, function* () {
@@ -710,11 +730,12 @@ const codeNativeIntegrationComponent = ({ name, iconPath, description, flows = [
710
730
  inputs: [],
711
731
  } });
712
732
  }, {});
713
- const convertedTriggers = flows.reduce((result, { name, onTrigger, onInstanceDeploy, onInstanceDelete, schedule, triggerType }) => {
733
+ const convertedTriggers = flows.reduce((result, { name, onTrigger, onInstanceDeploy, onInstanceDelete, webhookLifecycleHandlers, schedule, triggerType, }) => {
714
734
  if (!flowUsesWrapperTrigger({
715
735
  onTrigger,
716
736
  onInstanceDelete,
717
737
  onInstanceDeploy,
738
+ webhookLifecycleHandlers,
718
739
  })) {
719
740
  // In this scenario, the user has defined an existing component trigger
720
741
  // without any custom behavior, so we don't need to wrap anything.
@@ -740,8 +761,10 @@ const codeNativeIntegrationComponent = ({ name, iconPath, description, flows = [
740
761
  componentRegistry,
741
762
  triggerType,
742
763
  });
743
- const deleteFn = generateOnInstanceWrapperFn(ref, onTrigger, "onInstanceDelete", componentRegistry, onInstanceDelete);
744
- const deployFn = generateOnInstanceWrapperFn(ref, onTrigger, "onInstanceDeploy", componentRegistry, onInstanceDeploy);
764
+ const deleteFn = generateTriggerEventWrapperFn(ref, onTrigger, "onInstanceDelete", componentRegistry, onInstanceDelete);
765
+ const deployFn = generateTriggerEventWrapperFn(ref, onTrigger, "onInstanceDeploy", componentRegistry, onInstanceDeploy);
766
+ const webhookCreateFn = generateTriggerEventWrapperFn(ref, onTrigger, "webhookCreate", componentRegistry, webhookLifecycleHandlers === null || webhookLifecycleHandlers === void 0 ? void 0 : webhookLifecycleHandlers.create);
767
+ const webhookDeleteFn = generateTriggerEventWrapperFn(ref, onTrigger, "webhookDelete", componentRegistry, webhookLifecycleHandlers === null || webhookLifecycleHandlers === void 0 ? void 0 : webhookLifecycleHandlers.delete);
745
768
  return Object.assign(Object.assign({}, result), { [key]: {
746
769
  key,
747
770
  display: {
@@ -753,6 +776,10 @@ const codeNativeIntegrationComponent = ({ name, iconPath, description, flows = [
753
776
  hasOnInstanceDeploy: !!deployFn,
754
777
  onInstanceDelete: deleteFn,
755
778
  hasOnInstanceDelete: !!deleteFn,
779
+ webhookCreate: webhookCreateFn,
780
+ hasWebhookCreateFunction: !!webhookCreateFn,
781
+ webhookDelete: webhookDeleteFn,
782
+ hasWebhookDeleteFunction: !!webhookDeleteFn,
756
783
  inputs: [],
757
784
  scheduleSupport: triggerType === "polling" ? "required" : "valid",
758
785
  synchronousResponseSupport: "valid",
@@ -61,7 +61,7 @@ export type IntegrationDefinition<TInputs extends Inputs = Inputs, TActionInputs
61
61
  /** Scoped ConfigVars for this integration. */
62
62
  scopedConfigVars?: ScopedConfigVarMap;
63
63
  /** Instance Profile used for this integration.
64
- * @default "Default Instance Profile"
64
+ * If not specified, the tenant's default Instance Profile will be used.
65
65
  */
66
66
  instanceProfile?: string;
67
67
  /**
@@ -133,6 +133,16 @@ interface FlowBase<TTriggerPayload extends TriggerPayload = TriggerPayload> {
133
133
  * https://prismatic.io/docs/custom-connectors/triggers/#instance-deploy-and-delete-events-for-triggers
134
134
  */
135
135
  onInstanceDelete?: TriggerEventFunction<Inputs, ConfigVars>;
136
+ /**
137
+ * Optional webhook lifecycle handlers for create and delete operations. See
138
+ * https://prismatic.io/docs/custom-connectors/triggers/#webhook-lifecycle-events
139
+ */
140
+ webhookLifecycleHandlers?: {
141
+ /** Function to execute to configure a webhook. */
142
+ create: TriggerEventFunction<Inputs, ConfigVars>;
143
+ /** Function to execute for webhook teardown. */
144
+ delete: TriggerEventFunction<Inputs, ConfigVars>;
145
+ };
136
146
  /** Specifies the main function for this flow which is run when this flow is invoked. */
137
147
  onExecution: FlowOnExecution<TTriggerPayload>;
138
148
  }
@@ -188,16 +198,35 @@ export type RetryConfig = {
188
198
  uniqueRequestIdField?: string;
189
199
  };
190
200
  /** Defines attributes of a queue configuration used by a flow of an integration. */
191
- export type QueueConfig = {
201
+ export type StandardQueueConfig = {
192
202
  /** Determines whether the flow should be executed using FIFO ordering. Not valid for synchronous or scheduled flows. */
193
203
  usesFifoQueue?: boolean;
194
204
  /** Reference to the field in the flow's trigger return payload; used to determine whether to queue the execution. */
195
205
  dedupeIdField?: string;
196
206
  /** Determines whether the flow should be setup for singleton executions. Only valid for scheduled/polling trigger-based flows. */
197
207
  singletonExecutions?: boolean;
198
- /** The maximum number of concurrent executions for this flow. Must be between 2 and 10. */
208
+ /** The maximum number of concurrent executions for this flow. Must be between 2 and 15. */
209
+ concurrencyLimit?: number;
210
+ };
211
+ export type ParallelQueueConfig = {
212
+ /** No limits. All requests processed simultaneously. */
213
+ type: "parallel";
214
+ };
215
+ export type ThrottledQueueConfig = {
216
+ /** Set the max concurrent executions per instance. */
217
+ type: "throttled";
218
+ /** The maximum number of concurrent executions for this flow. Must be between 2 and 15. */
199
219
  concurrencyLimit?: number;
220
+ /** Reference to the field in the flow's trigger return payload; used to determine whether to queue the execution. */
221
+ dedupeIdField?: string;
222
+ };
223
+ export type SequentialQueueConfig = {
224
+ /** Processed one at a time, in order received. */
225
+ type: "sequential";
226
+ /** Reference to the field in the flow's trigger return payload; used to determine whether to queue the execution. */
227
+ dedupeIdField?: string;
200
228
  };
229
+ export type QueueConfig = ParallelQueueConfig | ThrottledQueueConfig | SequentialQueueConfig | StandardQueueConfig;
201
230
  /** Defines attributes of a step error configuration used to determine how to handle errors during flow step execution. */
202
231
  export type StepErrorConfig = {
203
232
  /** Defines the type of error handler. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismatic-io/spectral",
3
- "version": "10.14.0",
3
+ "version": "10.16.1",
4
4
  "description": "Utility library for building Prismatic connectors and code-native integrations",
5
5
  "keywords": ["prismatic"],
6
6
  "main": "dist/index.js",
@@ -34,7 +34,9 @@
34
34
  "format": "yarn run lint-fix && biome format --write .",
35
35
  "check-format": "biome format .",
36
36
  "check": "yarn run check-format && yarn run lint",
37
- "test": "jest"
37
+ "test": "vitest run",
38
+ "test:watch": "vitest",
39
+ "test:ui": "vitest --ui"
38
40
  },
39
41
  "files": ["dist/"],
40
42
  "dependencies": {
@@ -45,7 +47,7 @@
45
47
  "form-data": "4.0.4",
46
48
  "fs-extra": "^11.2.0",
47
49
  "jest-mock": "29.7.0",
48
- "lodash": "4.17.21",
50
+ "lodash": "4.17.23",
49
51
  "object-sizeof": "^2.6.4",
50
52
  "prettier": "2.6.2",
51
53
  "safe-stable-stringify": "2.3.1",
@@ -57,20 +59,20 @@
57
59
  },
58
60
  "devDependencies": {
59
61
  "@biomejs/biome": "1.6.3",
62
+ "@fast-check/vitest": "^0.2.4",
60
63
  "@types/ejs": "3.1.5",
61
64
  "@types/fs-extra": "11.0.4",
62
- "@types/jest": "29.5.12",
63
- "@types/lodash": "4.17.0",
64
- "@types/node": "14.14.35",
65
+ "@types/lodash": "4.17.23",
66
+ "@types/node": "^22.19.7",
65
67
  "@types/prettier": "2.6.2",
66
68
  "@types/sax": "1.2.4",
67
69
  "@types/url-join": "4.0.1",
68
70
  "@types/uuid": "8.3.4",
69
71
  "@types/valid-url": "1.0.3",
72
+ "@vitest/ui": "^4.0.18",
70
73
  "copyfiles": "2.4.1",
71
- "fast-check": "2.16.0",
72
- "jest": "29.7.0",
73
- "ts-jest": "29.1.2",
74
- "typescript": "5.5.3"
74
+ "fast-check": "^4.5.3",
75
+ "typescript": "5.5.3",
76
+ "vitest": "^4.0.18"
75
77
  }
76
78
  }