@prismatic-io/spectral 10.18.7 → 10.18.9-preview.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generators/componentManifest/getInputs.js +82 -7
- package/dist/index.d.ts +106 -2
- package/dist/index.js +104 -2
- package/dist/serverTypes/convertComponent.d.ts +19 -1
- package/dist/serverTypes/convertComponent.js +180 -14
- package/dist/serverTypes/convertIntegration.d.ts +1 -1
- package/dist/serverTypes/convertIntegration.js +136 -23
- package/dist/serverTypes/index.d.ts +35 -4
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +5 -1
- package/dist/types/ActionInputParameters.d.ts +31 -2
- package/dist/types/Inputs.d.ts +47 -1
- package/dist/types/Inputs.js +2 -0
- package/dist/types/IntegrationDefinition.d.ts +135 -11
- package/dist/types/PollingTriggerDefinition.d.ts +13 -1
- package/dist/types/TriggerDefinition.d.ts +99 -2
- package/dist/types/TriggerPayload.d.ts +11 -2
- package/dist/types/TriggerPerformFunction.d.ts +1 -1
- package/package.json +6 -6
|
@@ -8,7 +8,7 @@ export declare const convertConfigPages: (pages: ConfigPages | undefined, userLe
|
|
|
8
8
|
/** Converts typed QueueConfig to legacy format with usesFifoQueue and concurrencyLimit. */
|
|
9
9
|
export declare const convertQueueConfig: (queueConfig: QueueConfig) => StandardQueueConfig;
|
|
10
10
|
/** Converts a Flow into the structure necessary for YAML generation. */
|
|
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>>(
|
|
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>>(rawFlow: Flow<TInputs, TActionInputs, TPayload, TAllowsBranching, TResult>, componentRegistry: ComponentRegistry, referenceKey: string) => Record<string, unknown>;
|
|
12
12
|
/** Converts an input value to the expected server type by its collection type. */
|
|
13
13
|
export declare const convertInputValue: (value: unknown, collectionType: CollectionType | undefined) => unknown;
|
|
14
14
|
/** Converts a Config Var into the structure necessary for YAML generation. */
|
|
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
11
22
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
23
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
24
|
};
|
|
@@ -29,6 +40,46 @@ const integration_1 = require("./integration");
|
|
|
29
40
|
const perform_1 = require("./perform");
|
|
30
41
|
exports.CONCURRENCY_LIMIT_MAX = 15;
|
|
31
42
|
exports.CONCURRENCY_LIMIT_MIN = 2;
|
|
43
|
+
/**
|
|
44
|
+
* Default `resolveItems`: a batched `trigger`'s fires return their records under
|
|
45
|
+
* `payload.body.data` (the wrapper {@link normalizeBatchedFlow} builds writes them there),
|
|
46
|
+
* so extraction is just reading that array back. Authors never write this themselves.
|
|
47
|
+
*/
|
|
48
|
+
const defaultResolveItems = (_context, result) => result.payload.body.data;
|
|
49
|
+
/**
|
|
50
|
+
* Expands a flow's batched `trigger` (built with `batchFlowTrigger`) into the flat
|
|
51
|
+
* `onTrigger`/`onDeployTrigger`/`triggerResolver`/`onDeployResolver` shape the rest of the
|
|
52
|
+
* conversion pipeline already understands. The trigger fires return just `{ items }`; here we
|
|
53
|
+
* wrap each into a `TriggerPerformFunction` that emits `{ payload: { …payload, body: { data:
|
|
54
|
+
* items } } }`, synthesize the default `resolveItems`, and map the pagination callbacks onto
|
|
55
|
+
* the resolver `getNextDiscoveryState`. Flows without a `trigger` pass through unchanged.
|
|
56
|
+
*
|
|
57
|
+
* Returns the same `Flow` type it received; the synthesized `triggerResolver`/`onDeployResolver`
|
|
58
|
+
* are wire-only fields (not on the author-facing `Flow`), read downstream via `"x" in flow` checks.
|
|
59
|
+
*/
|
|
60
|
+
const normalizeBatchedFlow = (flow) => {
|
|
61
|
+
const trigger = "trigger" in flow ? flow.trigger : undefined;
|
|
62
|
+
if (!trigger) {
|
|
63
|
+
return flow;
|
|
64
|
+
}
|
|
65
|
+
const { onTrigger, onDeploy, getNextOnTriggerPaginationState, getNextOnDeployPaginationState } = trigger;
|
|
66
|
+
// Wrap a batched fire (returns `{ items, response? }`) into a TriggerPerformFunction that
|
|
67
|
+
// emits the wire payload shape (`body.data = items`), preserving the incoming payload fields.
|
|
68
|
+
const wrapFire = (fire) => (context, payload) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
const { items, response } = yield fire(context, payload);
|
|
70
|
+
return Object.assign({ payload: Object.assign(Object.assign({}, payload), { body: { data: items, contentType: "application/json" } }) }, (response ? { response } : {}));
|
|
71
|
+
});
|
|
72
|
+
const _a = flow, { trigger: _omitTrigger } = _a, rest = __rest(_a, ["trigger"]);
|
|
73
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, rest), { onTrigger: wrapFire(onTrigger) }), (onDeploy ? { onDeployTrigger: wrapFire(onDeploy) } : {})), { triggerResolver: Object.assign({ resolveItems: defaultResolveItems }, (getNextOnTriggerPaginationState
|
|
74
|
+
? { getNextDiscoveryState: getNextOnTriggerPaginationState }
|
|
75
|
+
: {})) }), (onDeploy
|
|
76
|
+
? {
|
|
77
|
+
onDeployResolver: Object.assign({ resolveItems: defaultResolveItems }, (getNextOnDeployPaginationState
|
|
78
|
+
? { getNextDiscoveryState: getNextOnDeployPaginationState }
|
|
79
|
+
: {})),
|
|
80
|
+
}
|
|
81
|
+
: {}));
|
|
82
|
+
};
|
|
32
83
|
const convertIntegration = (definition) => {
|
|
33
84
|
var _a, _b, _c;
|
|
34
85
|
// Generate a unique reference key that will be used to reference the
|
|
@@ -94,7 +145,11 @@ const convertConfigPages = (pages, userLevelConfigured) => {
|
|
|
94
145
|
}) })));
|
|
95
146
|
};
|
|
96
147
|
exports.convertConfigPages = convertConfigPages;
|
|
97
|
-
const codeNativeIntegrationYaml = ({ name, description, category, documentation, version, labels, endpointType, triggerPreprocessFlowConfig, flows, configPages, userLevelConfigPages, scopedConfigVars, instanceProfile, componentRegistry = {}, }, referenceKey, configVars, metadata) => {
|
|
148
|
+
const codeNativeIntegrationYaml = ({ name, description, category, documentation, version, labels, endpointType, triggerPreprocessFlowConfig, flows: rawFlows, configPages, userLevelConfigPages, scopedConfigVars, instanceProfile, componentRegistry = {}, }, referenceKey, configVars, metadata) => {
|
|
149
|
+
// Expand any batched `trigger` (built with `batchFlowTrigger`) into the flat
|
|
150
|
+
// onTrigger/onDeployTrigger/triggerResolver/onDeployResolver shape the rest of this
|
|
151
|
+
// pipeline (convertFlow + the trigger reducer) already handles.
|
|
152
|
+
const flows = rawFlows.map((flow) => normalizeBatchedFlow(flow));
|
|
98
153
|
// Find the preprocess flow config on the flow, if one exists.
|
|
99
154
|
const preprocessFlows = flows.filter((flow) => flow.preprocessFlowConfig);
|
|
100
155
|
// Do some validation of preprocess flow configs.
|
|
@@ -310,8 +365,11 @@ const convertFlowSchemas = (flowKey, schemas) => {
|
|
|
310
365
|
}, {});
|
|
311
366
|
};
|
|
312
367
|
/** Converts a Flow into the structure necessary for YAML generation. */
|
|
313
|
-
const convertFlow = (
|
|
368
|
+
const convertFlow = (rawFlow, componentRegistry, referenceKey) => {
|
|
314
369
|
var _a;
|
|
370
|
+
// Expand a batched `trigger` into the flat shape this function serializes. Idempotent: a flow
|
|
371
|
+
// that already lacks `trigger` (including one pre-normalized by `convertIntegration`) is returned as-is.
|
|
372
|
+
const flow = normalizeBatchedFlow(rawFlow);
|
|
315
373
|
const result = Object.assign({}, flow);
|
|
316
374
|
result.onTrigger = undefined;
|
|
317
375
|
result.trigger = undefined;
|
|
@@ -319,6 +377,7 @@ const convertFlow = (flow, componentRegistry, referenceKey) => {
|
|
|
319
377
|
result.onInstanceDelete = undefined;
|
|
320
378
|
result.webhookLifecycleHandlers = undefined;
|
|
321
379
|
result.onExecution = undefined;
|
|
380
|
+
result.onDeployTrigger = undefined;
|
|
322
381
|
result.preprocessFlowConfig = undefined;
|
|
323
382
|
result.errorConfig = undefined;
|
|
324
383
|
result.testApiKeys = undefined;
|
|
@@ -412,6 +471,30 @@ const convertFlow = (flow, componentRegistry, referenceKey) => {
|
|
|
412
471
|
}
|
|
413
472
|
: {}));
|
|
414
473
|
}
|
|
474
|
+
const triggerResolver = "triggerResolver" in flow ? flow.triggerResolver : undefined;
|
|
475
|
+
const onDeployResolver = "onDeployResolver" in flow ? flow.onDeployResolver : undefined;
|
|
476
|
+
const batchConfig = "batchConfig" in flow ? flow.batchConfig : undefined;
|
|
477
|
+
// Resolver behaviors (resolveItems/getNextDiscoveryState) are serialized onto the
|
|
478
|
+
// synthesized trigger below. On the flow wire we emit only `triggerResolver`, the single
|
|
479
|
+
// config the platform reads (`trigger_resolver_batch_size` / `trigger_resolver_enabled`)
|
|
480
|
+
// and shares between the normal and on-deploy fires. `batchConfig`/`onDeployResolver` are
|
|
481
|
+
// author-side only — clear them out of the `{ ...flow }` spread.
|
|
482
|
+
result.triggerResolver = undefined;
|
|
483
|
+
result.onDeployResolver = undefined;
|
|
484
|
+
result.batchConfig = undefined;
|
|
485
|
+
if (triggerResolver || onDeployResolver) {
|
|
486
|
+
if (!batchConfig) {
|
|
487
|
+
throw new Error(`${flow.name} defines a triggerResolver/onDeployResolver but no batchConfig. Add \`batchConfig: { batchSize }\` to the flow.`);
|
|
488
|
+
}
|
|
489
|
+
if (onDeployResolver &&
|
|
490
|
+
(!("onDeployTrigger" in flow) || typeof flow.onDeployTrigger !== "function")) {
|
|
491
|
+
throw new Error(`${flow.name} declares onDeployResolver without onDeployTrigger. Set onDeployTrigger to handle the initial-deploy fire that the resolver fans out.`);
|
|
492
|
+
}
|
|
493
|
+
// `enabled: true` is required: for a "valid"-support trigger (which CNI synthesized
|
|
494
|
+
// triggers are) the platform only batches when the flow's resolver is enabled.
|
|
495
|
+
const concurrentBatchLimit = (0, convertComponent_1.validateConcurrentBatchLimit)(flow.name, "batchConfig", batchConfig.concurrentBatchLimit);
|
|
496
|
+
result.triggerResolver = Object.assign({ batchSize: (0, convertComponent_1.validateBatchSize)(flow.name, "batchConfig", batchConfig.batchSize), enabled: true }, (concurrentBatchLimit !== undefined ? { concurrentBatchLimit } : {}));
|
|
497
|
+
}
|
|
415
498
|
const actionStep = {
|
|
416
499
|
action: {
|
|
417
500
|
key: flowFunctionKey(flow.name, "onExecution"),
|
|
@@ -695,7 +778,11 @@ function generateTriggerPerformFn(params) {
|
|
|
695
778
|
case "standard":
|
|
696
779
|
return (0, perform_1.createCNIPerform)({ componentRegistry, onTrigger });
|
|
697
780
|
case "component-ref":
|
|
698
|
-
return (0, perform_1.createCNIComponentRefPerform)({
|
|
781
|
+
return (0, perform_1.createCNIComponentRefPerform)({
|
|
782
|
+
componentRegistry,
|
|
783
|
+
componentRef,
|
|
784
|
+
onTrigger,
|
|
785
|
+
});
|
|
699
786
|
default:
|
|
700
787
|
throw new Error(`Invalid trigger configuration detected: ${JSON.stringify(params, null, 2)}`);
|
|
701
788
|
}
|
|
@@ -751,7 +838,9 @@ const convertOnExecution = (onExecution, componentRegistry) => (context, params)
|
|
|
751
838
|
});
|
|
752
839
|
/** Creates the structure necessary to import a Component as part of a
|
|
753
840
|
* Code Native integration. */
|
|
754
|
-
const codeNativeIntegrationComponent = ({ name, iconPath, description, flows = [], componentRegistry = {}, }, referenceKey, configVars) => {
|
|
841
|
+
const codeNativeIntegrationComponent = ({ name, iconPath, description, flows: rawFlows = [], componentRegistry = {}, }, referenceKey, configVars) => {
|
|
842
|
+
// Expand any batched `trigger` so the action/trigger reducers below see the flat shape.
|
|
843
|
+
const flows = rawFlows.map((flow) => normalizeBatchedFlow(flow));
|
|
755
844
|
const convertedActions = flows.reduce((result, { name, onExecution }) => {
|
|
756
845
|
const key = flowFunctionKey(name, "onExecution");
|
|
757
846
|
return Object.assign(Object.assign({}, result), { [key]: {
|
|
@@ -764,7 +853,12 @@ const codeNativeIntegrationComponent = ({ name, iconPath, description, flows = [
|
|
|
764
853
|
inputs: [],
|
|
765
854
|
} });
|
|
766
855
|
}, {});
|
|
767
|
-
const convertedTriggers = flows.reduce((result,
|
|
856
|
+
const convertedTriggers = flows.reduce((result, flow) => {
|
|
857
|
+
var _a;
|
|
858
|
+
const { name, onTrigger, onInstanceDeploy, onInstanceDelete, webhookLifecycleHandlers, schedule, triggerType, onDeployTrigger, } = flow;
|
|
859
|
+
// `batchConfig`/`triggerResolver`/`onDeployResolver` are wire-only fields synthesized by
|
|
860
|
+
// `normalizeBatchedFlow`; they aren't on the author-facing `Flow` type, so read via cast.
|
|
861
|
+
const { batchConfig, triggerResolver, onDeployResolver } = flow;
|
|
768
862
|
if (!flowUsesWrapperTrigger({
|
|
769
863
|
onTrigger,
|
|
770
864
|
onInstanceDelete,
|
|
@@ -799,26 +893,45 @@ const codeNativeIntegrationComponent = ({ name, iconPath, description, flows = [
|
|
|
799
893
|
const deployFn = generateTriggerEventWrapperFn(ref, onTrigger, "onInstanceDeploy", componentRegistry, onInstanceDeploy);
|
|
800
894
|
const webhookCreateFn = generateTriggerEventWrapperFn(ref, onTrigger, "webhookCreate", componentRegistry, webhookLifecycleHandlers === null || webhookLifecycleHandlers === void 0 ? void 0 : webhookLifecycleHandlers.create);
|
|
801
895
|
const webhookDeleteFn = generateTriggerEventWrapperFn(ref, onTrigger, "webhookDelete", componentRegistry, webhookLifecycleHandlers === null || webhookLifecycleHandlers === void 0 ? void 0 : webhookLifecycleHandlers.delete);
|
|
802
|
-
return Object.assign(Object.assign({}, result), { [key]: {
|
|
803
|
-
key,
|
|
804
|
-
display: {
|
|
896
|
+
return Object.assign(Object.assign({}, result), { [key]: Object.assign(Object.assign(Object.assign(Object.assign({ key, display: {
|
|
805
897
|
label: `${name} - onTrigger`,
|
|
806
898
|
description: "The function that will be executed by the flow to return an HTTP response.",
|
|
807
|
-
},
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
899
|
+
}, perform: performFn, onInstanceDeploy: deployFn, hasOnInstanceDeploy: !!deployFn, onInstanceDelete: deleteFn, hasOnInstanceDelete: !!deleteFn, webhookCreate: webhookCreateFn, hasWebhookCreateFunction: !!webhookCreateFn, webhookDelete: webhookDeleteFn, hasWebhookDeleteFunction: !!webhookDeleteFn, inputs: wrapperTriggerInputsFromReference(onTrigger, componentRegistry), scheduleSupport: triggerType === "polling" ? "required" : "valid", synchronousResponseSupport: "valid", isPollingTrigger: triggerType === "polling", triggerResolverSupport: triggerResolver ? "valid" : "invalid" }, (triggerResolver || onDeployResolver
|
|
900
|
+
? Object.assign({ triggerResolverDefaultBatchSize: (_a = batchConfig === null || batchConfig === void 0 ? void 0 : batchConfig.batchSize) !== null && _a !== void 0 ? _a : 1 }, ((batchConfig === null || batchConfig === void 0 ? void 0 : batchConfig.concurrentBatchLimit) !== undefined
|
|
901
|
+
? {
|
|
902
|
+
triggerResolverDefaultConcurrentBatchLimit: batchConfig.concurrentBatchLimit,
|
|
903
|
+
}
|
|
904
|
+
: {})) : {})), (triggerResolver
|
|
905
|
+
? Object.assign(Object.assign({}, (triggerResolver.resolveItems
|
|
906
|
+
? {
|
|
907
|
+
resolveTriggerItems: triggerResolver.resolveItems,
|
|
908
|
+
hasResolveTriggerItems: true,
|
|
909
|
+
}
|
|
910
|
+
: {})), (triggerResolver.getNextDiscoveryState
|
|
911
|
+
? {
|
|
912
|
+
getNextDiscoveryState: triggerResolver.getNextDiscoveryState,
|
|
913
|
+
hasGetNextDiscoveryState: true,
|
|
914
|
+
}
|
|
915
|
+
: {})) : {})), (onDeployTrigger
|
|
916
|
+
? {
|
|
917
|
+
onDeployPerform: (0, perform_1.createCNIPerform)({
|
|
918
|
+
componentRegistry,
|
|
919
|
+
onTrigger: onDeployTrigger,
|
|
920
|
+
}),
|
|
921
|
+
hasOnDeployPerform: true,
|
|
922
|
+
}
|
|
923
|
+
: {})), (onDeployResolver
|
|
924
|
+
? Object.assign(Object.assign({}, (onDeployResolver.resolveItems
|
|
925
|
+
? {
|
|
926
|
+
resolveOnDeployItems: onDeployResolver.resolveItems,
|
|
927
|
+
hasResolveOnDeployItems: true,
|
|
928
|
+
}
|
|
929
|
+
: {})), (onDeployResolver.getNextDiscoveryState
|
|
930
|
+
? {
|
|
931
|
+
getOnDeployNextDiscoveryState: onDeployResolver.getNextDiscoveryState,
|
|
932
|
+
hasGetOnDeployNextDiscoveryState: true,
|
|
933
|
+
}
|
|
934
|
+
: {})) : {})) });
|
|
822
935
|
}, {});
|
|
823
936
|
const convertedDataSources = Object.entries(configVars).reduce((result, [key, configVar]) => {
|
|
824
937
|
if (!(0, types_1.isDataSourceDefinitionConfigVar)(configVar)) {
|
|
@@ -112,8 +112,8 @@ interface HttpResponse {
|
|
|
112
112
|
headers?: Record<string, string>;
|
|
113
113
|
body?: string;
|
|
114
114
|
}
|
|
115
|
-
interface TriggerBaseResult {
|
|
116
|
-
payload:
|
|
115
|
+
interface TriggerBaseResult<TPayload extends TriggerPayload = TriggerPayload> {
|
|
116
|
+
payload: TPayload;
|
|
117
117
|
response?: HttpResponse;
|
|
118
118
|
instanceState?: Record<string, unknown>;
|
|
119
119
|
crossFlowState?: Record<string, unknown>;
|
|
@@ -122,12 +122,23 @@ interface TriggerBaseResult {
|
|
|
122
122
|
failed?: boolean;
|
|
123
123
|
error?: Record<string, unknown>;
|
|
124
124
|
}
|
|
125
|
-
interface TriggerBranchingResult extends TriggerBaseResult {
|
|
125
|
+
interface TriggerBranchingResult<TPayload extends TriggerPayload = TriggerPayload> extends TriggerBaseResult<TPayload> {
|
|
126
126
|
branch: string;
|
|
127
127
|
}
|
|
128
|
-
export type TriggerResult = TriggerBranchingResult | TriggerBaseResult | undefined;
|
|
128
|
+
export type TriggerResult<TPayload extends TriggerPayload = TriggerPayload> = TriggerBranchingResult<TPayload> | TriggerBaseResult<TPayload> | undefined;
|
|
129
129
|
export type TriggerEventFunctionResult = TriggerEventFunctionReturn | void;
|
|
130
130
|
export type TriggerEventFunction = (context: ActionContext, params: Record<string, unknown>) => Promise<TriggerEventFunctionResult>;
|
|
131
|
+
/**
|
|
132
|
+
* Wire format the platform expects for a trigger. Note: function references
|
|
133
|
+
* (perform, resolveTriggerItems, getNextDiscoveryState, ...) don't survive JSON
|
|
134
|
+
* serialization, so each callback has a paired `hasXxx: boolean` flag the
|
|
135
|
+
* server reads to detect presence. Keep the flag and its callback in sync.
|
|
136
|
+
*
|
|
137
|
+
* The on-deploy fire is named asymmetrically by intent: CNI flow authors set
|
|
138
|
+
* `onDeployTrigger` (sibling to `onTrigger`), component-trigger authors set
|
|
139
|
+
* `onDeployPerform` (sibling to `perform`), and both flatten to
|
|
140
|
+
* `onDeployPerform` here on the wire.
|
|
141
|
+
*/
|
|
131
142
|
export interface Trigger<TInputs extends Inputs, TActionInputs extends Inputs, TConfigVars extends ConfigVarResultCollection = ConfigVarResultCollection, TPayload extends TriggerPayload = TriggerPayload, TAllowsBranching extends boolean = boolean, TResult extends TriggerPerformResult<TAllowsBranching, TPayload> = TriggerPerformResult<TAllowsBranching, TPayload>> {
|
|
132
143
|
key: string;
|
|
133
144
|
display: DisplayDefinition & {
|
|
@@ -155,6 +166,23 @@ export interface Trigger<TInputs extends Inputs, TActionInputs extends Inputs, T
|
|
|
155
166
|
hasWebhookDeleteFunction?: boolean;
|
|
156
167
|
scheduleSupport: TriggerOptionChoice;
|
|
157
168
|
synchronousResponseSupport: TriggerOptionChoice;
|
|
169
|
+
triggerResolverSupport?: TriggerOptionChoice;
|
|
170
|
+
/**
|
|
171
|
+
* The single default batch size shared by the trigger and on-deploy resolvers. The
|
|
172
|
+
* platform reads only this field for both paths; there is no separate on-deploy default.
|
|
173
|
+
*/
|
|
174
|
+
triggerResolverDefaultBatchSize?: number;
|
|
175
|
+
triggerResolverDefaultConcurrentBatchLimit?: number;
|
|
176
|
+
resolveTriggerItems?: (context: ActionContext<TConfigVars>, result: TriggerBaseResult<TPayload>) => unknown[];
|
|
177
|
+
hasResolveTriggerItems?: boolean;
|
|
178
|
+
getNextDiscoveryState?: (context: ActionContext<TConfigVars>, result: TriggerBaseResult<TPayload>) => Record<string, unknown> | null;
|
|
179
|
+
hasGetNextDiscoveryState?: boolean;
|
|
180
|
+
onDeployPerform?: TriggerPerformFunction<TInputs, TConfigVars, TAllowsBranching, TResult> | PollingTriggerPerformFunction<TInputs, TActionInputs, TConfigVars, TPayload, TAllowsBranching, TResult> | CNIPollingPerformFunction<TInputs, TConfigVars, TPayload, TAllowsBranching> | ComponentRefTriggerPerformFunction<TInputs, TConfigVars>;
|
|
181
|
+
hasOnDeployPerform?: boolean;
|
|
182
|
+
resolveOnDeployItems?: (context: ActionContext<TConfigVars>, result: TriggerBaseResult<TPayload>) => unknown[];
|
|
183
|
+
hasResolveOnDeployItems?: boolean;
|
|
184
|
+
getOnDeployNextDiscoveryState?: (context: ActionContext<TConfigVars>, result: TriggerBaseResult<TPayload>) => Record<string, unknown> | null;
|
|
185
|
+
hasGetOnDeployNextDiscoveryState?: boolean;
|
|
158
186
|
examplePayload?: unknown;
|
|
159
187
|
isCommonTrigger?: boolean;
|
|
160
188
|
isPollingTrigger?: boolean;
|
|
@@ -262,5 +290,8 @@ export interface Input {
|
|
|
262
290
|
onPremiseControlled?: boolean;
|
|
263
291
|
dataSource?: string;
|
|
264
292
|
shown?: boolean;
|
|
293
|
+
/** Nested children. For `structuredObject`, the declared inputs; for
|
|
294
|
+
* `dynamicObject`, one `structuredObject` per configuration. */
|
|
295
|
+
inputs?: Input[];
|
|
265
296
|
}
|
|
266
297
|
export * from "./asyncContext";
|
package/dist/testing.d.ts
CHANGED
|
@@ -217,7 +217,7 @@ type ToTestValues<TConfigVars extends ConfigVarResultCollection> = {
|
|
|
217
217
|
* expect(result.data).toBeDefined();
|
|
218
218
|
* });
|
|
219
219
|
*/
|
|
220
|
-
export declare const invokeFlow: <TInputs extends Inputs, TActionInputs extends Inputs, TConfigVars extends ConfigVarResultCollection = ConfigVarResultCollection, TConfigVarValues extends TestConfigVarValues = ToTestValues<TConfigVars>, TPayload extends TriggerPayload = TriggerPayload, TAllowsBranching extends boolean = boolean, TResult extends InvokeTriggerResult<TAllowsBranching, TPayload> = InvokeTriggerResult<TAllowsBranching, TPayload>>(flow: Flow<TInputs, TActionInputs, TPayload, TAllowsBranching, TResult>, { configVars, context, payload, }?: {
|
|
220
|
+
export declare const invokeFlow: <TInputs extends Inputs, TActionInputs extends Inputs, TConfigVars extends ConfigVarResultCollection = ConfigVarResultCollection, TConfigVarValues extends TestConfigVarValues = ToTestValues<TConfigVars>, TPayload extends TriggerPayload = TriggerPayload, TAllowsBranching extends boolean = boolean, TResult extends InvokeTriggerResult<TAllowsBranching, TPayload> = InvokeTriggerResult<TAllowsBranching, TPayload>>(flow: Flow<TInputs, TActionInputs, TPayload, TAllowsBranching, TResult, any, any, any>, { configVars, context, payload, }?: {
|
|
221
221
|
configVars?: TConfigVarValues;
|
|
222
222
|
context?: Partial<ActionContext<TConfigVars>>;
|
|
223
223
|
payload?: Partial<TriggerPayload>;
|
package/dist/testing.js
CHANGED
|
@@ -408,7 +408,11 @@ const createConfigVars = (values) => {
|
|
|
408
408
|
* expect(result.data).toBeDefined();
|
|
409
409
|
* });
|
|
410
410
|
*/
|
|
411
|
-
const invokeFlow = (flow_1, ...args_1) => __awaiter(void 0, [flow_1, ...args_1], void 0, function* (
|
|
411
|
+
const invokeFlow = (flow_1, ...args_1) => __awaiter(void 0, [flow_1, ...args_1], void 0, function* (
|
|
412
|
+
// `any` for TItem/TDiscoveryState/TTriggerPayload: the tester accepts a flow with any
|
|
413
|
+
// resolver item and cursor typing; it drives the flow dynamically and does not rely on
|
|
414
|
+
// the precise `onExecution` param type.
|
|
415
|
+
flow, { configVars, context, payload, } = {}) {
|
|
412
416
|
const realizedConfigVars = createConfigVars(configVars);
|
|
413
417
|
const realizedContext = createActionContext(Object.assign(Object.assign({}, context), { configVars: realizedConfigVars }));
|
|
414
418
|
const realizedPayload = Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload);
|
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
import type { ConditionalExpression } from "./conditional-logic";
|
|
2
|
-
import type { Connection, InputCleanFunction, InputFieldCollection, Inputs, KeyValuePair } from "./Inputs";
|
|
2
|
+
import type { Connection, DynamicObjectInputField, InputCleanFunction, InputFieldCollection, Inputs, KeyValuePair, StructuredObjectInputField } from "./Inputs";
|
|
3
|
+
/** Resolves a single InputFieldDefinition's runtime value type.
|
|
4
|
+
* - structuredObject: record of declared children's resolved value types.
|
|
5
|
+
* - dynamicObject: discriminated union keyed by the selected configuration,
|
|
6
|
+
* with the configuration's resolved inputs nested under `values` to avoid
|
|
7
|
+
* collisions with the `configuration` discriminant key.
|
|
8
|
+
* The depth caps (`LeafInputFieldDefinition`, `StructuredOrLeafInputFieldDefinition`)
|
|
9
|
+
* prevent unbounded recursion. */
|
|
10
|
+
type InputValue<T> = T extends StructuredObjectInputField ? {
|
|
11
|
+
[K in keyof T["inputs"]]: InputValue<T["inputs"][K]>;
|
|
12
|
+
} : T extends DynamicObjectInputField ? {
|
|
13
|
+
[C in keyof T["configurations"]]: {
|
|
14
|
+
configuration: C;
|
|
15
|
+
values: {
|
|
16
|
+
[K in keyof T["configurations"][C]["inputs"]]: InputValue<T["configurations"][C]["inputs"][K]>;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}[keyof T["configurations"]] : T extends {
|
|
20
|
+
clean: InputCleanFunction<any>;
|
|
21
|
+
} ? ReturnType<T["clean"]> : T extends {
|
|
22
|
+
type: "connection";
|
|
23
|
+
collection?: InputFieldCollection;
|
|
24
|
+
} ? ExtractValue<Connection, T["collection"]> : T extends {
|
|
25
|
+
type: "conditional";
|
|
26
|
+
collection?: InputFieldCollection;
|
|
27
|
+
} ? ExtractValue<ConditionalExpression, T["collection"]> : T extends {
|
|
28
|
+
default?: unknown;
|
|
29
|
+
collection?: InputFieldCollection;
|
|
30
|
+
} ? ExtractValue<T["default"], T["collection"]> : unknown;
|
|
3
31
|
/**
|
|
4
32
|
* Collection of input parameters.
|
|
5
33
|
* Inputs can be static values, references to config variables, or
|
|
6
34
|
* references to previous steps' outputs.
|
|
7
35
|
*/
|
|
8
36
|
export type ActionInputParameters<TInputs extends Inputs> = {
|
|
9
|
-
[Property in keyof TInputs]:
|
|
37
|
+
[Property in keyof TInputs]: InputValue<TInputs[Property]>;
|
|
10
38
|
};
|
|
11
39
|
export type ExtractValue<TType, TCollection extends InputFieldCollection | undefined> = TCollection extends "keyvaluelist" ? KeyValuePair<TType>[] : TCollection extends "valuelist" ? TType[] : TType;
|
|
40
|
+
export {};
|
package/dist/types/Inputs.d.ts
CHANGED
|
@@ -63,6 +63,8 @@ export type JSONForm = {
|
|
|
63
63
|
};
|
|
64
64
|
export type DynamicObjectSelection = string;
|
|
65
65
|
export type DynamicFieldSelection = string;
|
|
66
|
+
export type StructuredObject = Record<string, unknown>;
|
|
67
|
+
export type DynamicObject = Record<string, unknown>;
|
|
66
68
|
/** InputField type enumeration. */
|
|
67
69
|
export type InputFieldType = InputFieldDefinition["type"];
|
|
68
70
|
export declare const InputFieldDefaultMap: Record<InputFieldType, string | undefined>;
|
|
@@ -83,7 +85,7 @@ export type OnPremConnectionInput = {
|
|
|
83
85
|
*/
|
|
84
86
|
onPremControlled: true;
|
|
85
87
|
} & ConnectionInput;
|
|
86
|
-
export type InputFieldDefinition = StringInputField | DataInputField | TextInputField | PasswordInputField | BooleanInputField | CodeInputField | ConditionalInputField | ConnectionInputField | ConnectionTemplateInputField | ObjectSelectionInputField | ObjectFieldMapInputField | JSONFormInputField | DynamicObjectSelectionInputField | DynamicFieldSelectionInputField | DateInputField | DateTimeInputField | FlowInputField;
|
|
88
|
+
export type InputFieldDefinition = StringInputField | DataInputField | TextInputField | PasswordInputField | BooleanInputField | CodeInputField | ConditionalInputField | ConnectionInputField | ConnectionTemplateInputField | ObjectSelectionInputField | ObjectFieldMapInputField | JSONFormInputField | DynamicObjectSelectionInputField | DynamicFieldSelectionInputField | DateInputField | DateTimeInputField | FlowInputField | StructuredObjectInputField | DynamicObjectInputField;
|
|
87
89
|
export type InputCleanFunction<TValue, TResult = TValue> = (value: TValue) => TResult;
|
|
88
90
|
interface BaseInputField {
|
|
89
91
|
/** Name of this field to present in the UI. */
|
|
@@ -289,6 +291,50 @@ export type DateTimeInputField = BaseInputField & {
|
|
|
289
291
|
/** Clean function. */
|
|
290
292
|
clean?: InputCleanFunction<unknown>;
|
|
291
293
|
} & CollectionOptions<string>;
|
|
294
|
+
/** `InputFieldDefinition` minus container input types and connection
|
|
295
|
+
* pickers. Connections resolve to config-var references outside the
|
|
296
|
+
* parent's value tree, so they're only valid at the top level — never as
|
|
297
|
+
* a child of a structuredObject or a dynamicObject configuration. */
|
|
298
|
+
export type LeafInputFieldDefinition = Exclude<InputFieldDefinition, StructuredObjectInputField | DynamicObjectInputField | ConnectionInputField | ConnectionTemplateInputField>;
|
|
299
|
+
/** `LeafInputFieldDefinition` plus `StructuredObjectInputField`; used
|
|
300
|
+
* inside a dynamicObject's `configurations.<key>.inputs` to allow leaves
|
|
301
|
+
* and structuredObject children while still rejecting nested
|
|
302
|
+
* dynamicObjects and connection pickers. */
|
|
303
|
+
export type StructuredOrLeafInputFieldDefinition = LeafInputFieldDefinition | StructuredObjectInputField;
|
|
304
|
+
/** Groups related primitive inputs under a single named container.
|
|
305
|
+
* Nesting is capped at one level. Connection pickers are rejected as
|
|
306
|
+
* children — they may only appear at the top level. */
|
|
307
|
+
export type StructuredObjectInputField = Omit<BaseInputField, "dataSource" | "example" | "placeholder" | "required"> & {
|
|
308
|
+
/** Data type the input will collect. */
|
|
309
|
+
type: "structuredObject";
|
|
310
|
+
/** Nested input fields keyed by their local key. */
|
|
311
|
+
inputs: Record<string, LeafInputFieldDefinition>;
|
|
312
|
+
};
|
|
313
|
+
/** A single configuration within a dynamicObject. Each configuration declares
|
|
314
|
+
* a labeled set of inputs that become available when this configuration is
|
|
315
|
+
* selected at runtime. */
|
|
316
|
+
export interface DynamicObjectConfiguration {
|
|
317
|
+
/** Name of this configuration to present in the UI. */
|
|
318
|
+
label: {
|
|
319
|
+
key: string;
|
|
320
|
+
value: string;
|
|
321
|
+
} | string;
|
|
322
|
+
/** Additional text to give guidance to the user when this configuration is selected. */
|
|
323
|
+
comments?: string;
|
|
324
|
+
/** Inputs that become available when this configuration is selected. */
|
|
325
|
+
inputs: Record<string, StructuredOrLeafInputFieldDefinition>;
|
|
326
|
+
}
|
|
327
|
+
/** Presents a discriminated set of input groups; the user picks a configuration
|
|
328
|
+
* at integration-build time and that configuration's inputs become available.
|
|
329
|
+
* Nesting is capped: configurations may contain structuredObject children
|
|
330
|
+
* (depth-1) but never another dynamicObject. */
|
|
331
|
+
export type DynamicObjectInputField = Omit<BaseInputField, "dataSource" | "example" | "placeholder"> & {
|
|
332
|
+
/** Data type the input will collect. */
|
|
333
|
+
type: "dynamicObject";
|
|
334
|
+
/** Available configurations keyed by their local key (used as the
|
|
335
|
+
* runtime discriminant). */
|
|
336
|
+
configurations: Record<string, DynamicObjectConfiguration>;
|
|
337
|
+
};
|
|
292
338
|
/** Defines a single Choice option for a InputField. */
|
|
293
339
|
export interface InputFieldChoice {
|
|
294
340
|
/** Label to display for this Choice. */
|