@prismatic-io/spectral 10.15.0 → 10.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clients/http/index.d.ts +5 -1
- package/dist/clients/http/index.js +7 -3
- package/dist/serverTypes/context.js +1 -4
- package/dist/serverTypes/convertIntegration.d.ts +5 -1
- package/dist/serverTypes/convertIntegration.js +31 -4
- package/dist/types/IntegrationDefinition.d.ts +21 -2
- package/package.json +13 -11
|
@@ -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
|
-
/**
|
|
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
|
|
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,8 +1,12 @@
|
|
|
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. */
|
|
@@ -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
|
|
@@ -279,6 +281,30 @@ const flowUsesWrapperTrigger = (flow) => {
|
|
|
279
281
|
flow.onInstanceDeploy ||
|
|
280
282
|
flow.webhookLifecycleHandlers);
|
|
281
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
|
+
}
|
|
306
|
+
};
|
|
307
|
+
exports.convertQueueConfig = convertQueueConfig;
|
|
282
308
|
const convertFlowSchemas = (flowKey, schemas) => {
|
|
283
309
|
return Object.entries(schemas).reduce((acc, [key, value]) => {
|
|
284
310
|
var _a;
|
|
@@ -356,7 +382,7 @@ const convertFlow = (flow, componentRegistry, referenceKey) => {
|
|
|
356
382
|
throw new Error(`${flow.name} is marked as a polling trigger but has no schedule. Polling triggers require a schedule.`);
|
|
357
383
|
}
|
|
358
384
|
if ("queueConfig" in flow && typeof flow.queueConfig === "object") {
|
|
359
|
-
const
|
|
385
|
+
const queueConfig = (0, exports.convertQueueConfig)(flow.queueConfig);
|
|
360
386
|
if (hasSchedule && queueConfig.usesFifoQueue) {
|
|
361
387
|
throw new Error(`${flow.name} has a schedule & usesFifoQueue set to true. FIFO queues cannot be used with scheduled flows.`);
|
|
362
388
|
}
|
|
@@ -367,8 +393,9 @@ const convertFlow = (flow, componentRegistry, referenceKey) => {
|
|
|
367
393
|
throw new Error(`${flow.name} is configured for both FIFO queues and singleton executions, but these options are mutually exclusive. Please choose one.`);
|
|
368
394
|
}
|
|
369
395
|
if (queueConfig.concurrencyLimit !== undefined &&
|
|
370
|
-
(queueConfig.concurrencyLimit <
|
|
371
|
-
|
|
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}.`);
|
|
372
399
|
}
|
|
373
400
|
result.queueConfig = Object.assign(Object.assign({ usesFifoQueue: false }, queueConfig), (queueConfig.dedupeIdField
|
|
374
401
|
? {
|
|
@@ -198,16 +198,35 @@ export type RetryConfig = {
|
|
|
198
198
|
uniqueRequestIdField?: string;
|
|
199
199
|
};
|
|
200
200
|
/** Defines attributes of a queue configuration used by a flow of an integration. */
|
|
201
|
-
export type
|
|
201
|
+
export type StandardQueueConfig = {
|
|
202
202
|
/** Determines whether the flow should be executed using FIFO ordering. Not valid for synchronous or scheduled flows. */
|
|
203
203
|
usesFifoQueue?: boolean;
|
|
204
204
|
/** Reference to the field in the flow's trigger return payload; used to determine whether to queue the execution. */
|
|
205
205
|
dedupeIdField?: string;
|
|
206
206
|
/** Determines whether the flow should be setup for singleton executions. Only valid for scheduled/polling trigger-based flows. */
|
|
207
207
|
singletonExecutions?: boolean;
|
|
208
|
-
/** The maximum number of concurrent executions for this flow. Must be between 2 and
|
|
208
|
+
/** The maximum number of concurrent executions for this flow. Must be between 2 and 15. */
|
|
209
209
|
concurrencyLimit?: number;
|
|
210
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. */
|
|
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;
|
|
228
|
+
};
|
|
229
|
+
export type QueueConfig = ParallelQueueConfig | ThrottledQueueConfig | SequentialQueueConfig | StandardQueueConfig;
|
|
211
230
|
/** Defines attributes of a step error configuration used to determine how to handle errors during flow step execution. */
|
|
212
231
|
export type StepErrorConfig = {
|
|
213
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.
|
|
3
|
+
"version": "10.16.2",
|
|
4
4
|
"description": "Utility library for building Prismatic connectors and code-native integrations",
|
|
5
5
|
"keywords": ["prismatic"],
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -34,18 +34,20 @@
|
|
|
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": "
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest",
|
|
39
|
+
"test:ui": "vitest --ui"
|
|
38
40
|
},
|
|
39
41
|
"files": ["dist/"],
|
|
40
42
|
"dependencies": {
|
|
41
|
-
"axios": "1.
|
|
43
|
+
"axios": "1.13.5",
|
|
42
44
|
"axios-retry": "4.5.0",
|
|
43
45
|
"date-fns": "2.30.0",
|
|
44
46
|
"ejs": "^3.1.10",
|
|
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.
|
|
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/
|
|
63
|
-
"@types/
|
|
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": "
|
|
72
|
-
"
|
|
73
|
-
"
|
|
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
|
}
|