@prismatic-io/spectral 4.0.6 → 4.1.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/README.md +9 -8
- package/dist/testing.js +7 -2
- package/dist/types/ActionDefinition.d.ts +2 -0
- package/dist/types/ActionLogger.d.ts +2 -0
- package/dist/types/ActionPerformFunction.d.ts +2 -0
- package/dist/types/ActionPerformReturn.d.ts +3 -1
- package/dist/types/TriggerDefinition.d.ts +2 -0
- package/dist/types/TriggerPayload.d.ts +5 -0
- package/dist/types/TriggerResult.d.ts +3 -1
- package/dist/types/server-types.d.ts +8 -2
- package/dist/util.d.ts +11 -0
- package/dist/util.js +16 -1
- package/dist/util.test.js +19 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,22 +14,23 @@ Please see our [documentation](https://prismatic.io/docs/custom-components/writi
|
|
|
14
14
|
|
|
15
15
|
## What is Prismatic?
|
|
16
16
|
|
|
17
|
-
Prismatic is the
|
|
17
|
+
Prismatic is the integration platform for B2B software companies. It's the quickest way to build integrations to the other apps your customers use and to add a native integration marketplace to your product.
|
|
18
18
|
|
|
19
|
-
Prismatic reduces integration effort and
|
|
19
|
+
Prismatic significantly reduces overall integration effort and enables non-dev teams to take on more of the integration workload, so that you can deliver integrations faster and spend more time on core product innovation.
|
|
20
20
|
|
|
21
21
|
With Prismatic, you can:
|
|
22
22
|
|
|
23
|
-
- Build reusable [integrations](https://prismatic.io/docs/integrations) in
|
|
23
|
+
- Build reusable [integrations](https://prismatic.io/docs/integrations) in a low-code integration designer that's tailored for your product
|
|
24
|
+
- Use [pre-built components](https://prismatic.io/docs/components/component-catalog) to handle most of your integrations' functionality, and write [custom components](https://prismatic.io/docs/custom-components/writing-custom-components) when needed
|
|
25
|
+
- Quickly add an [integration marketplace](https://prismatic.io/docs/integration-marketplace) to your product so customers can explore, activate, and monitor integrations
|
|
24
26
|
- Easily deploy customer-specific integration [instances](https://prismatic.io/docs/instances) with unique configurations and credentials
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- Mold the platform to your product, industry, and the way you build software
|
|
27
|
+
- Provide better support with tools like [logging](https://prismatic.io/docs/logging) and [alerting](https://prismatic.io/docs/monitoring-and-alerting)
|
|
28
|
+
- Run your integrations in a purpose-built environment designed for security and scalability
|
|
29
|
+
- Use powerful dev tools to mold the platform to your product, industry, and the way you build software
|
|
29
30
|
|
|
30
31
|
## Who uses Prismatic?
|
|
31
32
|
|
|
32
|
-
Prismatic is for B2B (business-to-business) software companies, meaning software companies that provide applications used by businesses. It's a good fit for products/teams
|
|
33
|
+
Prismatic is for B2B (business-to-business) software companies, meaning software companies that provide applications used by businesses. It's a good fit for products/teams ranging from early-stage and growing SaaS startups to large, established software companies looking to improve the way they do integrations.
|
|
33
34
|
|
|
34
35
|
Many B2B software teams serve customers in niche vertical markets, and we designed Prismatic with that in mind. We provide powerful and flexible tools so you can build exactly the integrations your customers need, no matter who your customers are, no matter what systems you need to connect to, no matter how "non-standard" your integration scenario.
|
|
35
36
|
|
package/dist/testing.js
CHANGED
|
@@ -99,6 +99,8 @@ exports.credentials = {
|
|
|
99
99
|
* See https://prismatic.io/docs/custom-components/writing-custom-components/#verifying-correct-logging-in-action-tests for information on testing correct logging behavior in your custom component.
|
|
100
100
|
*/
|
|
101
101
|
const loggerMock = () => ({
|
|
102
|
+
metric: console.log,
|
|
103
|
+
trace: jest_mock_1.spyOn(console, "trace"),
|
|
102
104
|
debug: jest_mock_1.spyOn(console, "debug"),
|
|
103
105
|
info: jest_mock_1.spyOn(console, "info"),
|
|
104
106
|
log: jest_mock_1.spyOn(console, "log"),
|
|
@@ -114,7 +116,7 @@ exports.loggerMock = loggerMock;
|
|
|
114
116
|
*/
|
|
115
117
|
const invoke = (actionBase, params, context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
116
118
|
const action = (actionBase.perform ? actionBase : Object.values(actionBase)[0]);
|
|
117
|
-
const realizedContext = Object.assign({ credential: undefined, logger: exports.loggerMock(), instanceState: {}, stepId: "mockStepId", executionId: "mockExecutionId" }, context);
|
|
119
|
+
const realizedContext = Object.assign({ credential: undefined, logger: exports.loggerMock(), instanceState: {}, executionState: {}, stepId: "mockStepId", executionId: "mockExecutionId" }, context);
|
|
118
120
|
const result = yield action.perform(realizedContext, params);
|
|
119
121
|
return {
|
|
120
122
|
result,
|
|
@@ -141,6 +143,9 @@ const defaultTriggerPayload = () => {
|
|
|
141
143
|
webhookUrls: {
|
|
142
144
|
"Flow 1": "https://example.com",
|
|
143
145
|
},
|
|
146
|
+
webhookApiKeys: {
|
|
147
|
+
"Flow 1": ["example-123", "example-456"],
|
|
148
|
+
},
|
|
144
149
|
customer: {
|
|
145
150
|
name: "Customer 1",
|
|
146
151
|
externalId: "1234",
|
|
@@ -156,7 +161,7 @@ exports.defaultTriggerPayload = defaultTriggerPayload;
|
|
|
156
161
|
*/
|
|
157
162
|
const invokeTrigger = (triggerBase, context, payload, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
163
|
const trigger = (triggerBase.perform ? triggerBase : Object.values(triggerBase)[0]);
|
|
159
|
-
const realizedContext = Object.assign({ credential: undefined, logger: exports.loggerMock(), instanceState: {}, stepId: "mockStepId", executionId: "mockExecutionId" }, context);
|
|
164
|
+
const realizedContext = Object.assign({ credential: undefined, logger: exports.loggerMock(), instanceState: {}, executionState: {}, stepId: "mockStepId", executionId: "mockExecutionId" }, context);
|
|
160
165
|
const realizedPayload = Object.assign(Object.assign({}, exports.defaultTriggerPayload()), payload);
|
|
161
166
|
const realizedParams = params || {};
|
|
162
167
|
const result = yield trigger.perform(realizedContext, realizedPayload, realizedParams);
|
|
@@ -14,6 +14,8 @@ export interface ActionDefinition<T extends Inputs, AllowsBranching extends bool
|
|
|
14
14
|
authorization?: AuthorizationDefinition;
|
|
15
15
|
/** Optional attribute that specifies whether an Action will terminate execution.*/
|
|
16
16
|
terminateExecution?: boolean;
|
|
17
|
+
/** Specifies whether an Action will break out of a loop. */
|
|
18
|
+
breakLoop?: boolean;
|
|
17
19
|
/** Determines whether an Action will allow Conditional Branching.*/
|
|
18
20
|
allowsBranching?: AllowsBranching;
|
|
19
21
|
/** Static Branch names associated with an Action. */
|
|
@@ -12,6 +12,8 @@ export declare type ActionLoggerFunction = (...args: unknown[]) => void;
|
|
|
12
12
|
* An object containing logger functions.
|
|
13
13
|
*/
|
|
14
14
|
export interface ActionLogger {
|
|
15
|
+
metric: ActionLoggerFunction;
|
|
16
|
+
trace: ActionLoggerFunction;
|
|
15
17
|
debug: ActionLoggerFunction;
|
|
16
18
|
info: ActionLoggerFunction;
|
|
17
19
|
log: ActionLoggerFunction;
|
|
@@ -9,6 +9,8 @@ export interface ActionContext {
|
|
|
9
9
|
logger: ActionLogger;
|
|
10
10
|
/** A key/value store that may be used to store small amounts of data that is persisted between Instance executions */
|
|
11
11
|
instanceState: Record<string, unknown>;
|
|
12
|
+
/** A key/value store that may be used to store small amounts of data for use later during the execution */
|
|
13
|
+
executionState: Record<string, unknown>;
|
|
12
14
|
/** A unique id that corresponds to the step on the Integration */
|
|
13
15
|
stepId: string;
|
|
14
16
|
/** A unique id that corresponds to the specific execution of the Integration */
|
|
@@ -7,7 +7,9 @@ export interface ActionPerformDataReturn<ReturnData> {
|
|
|
7
7
|
/** The HTTP Status code that will be used if this terminates a synchronous invocation */
|
|
8
8
|
statusCode?: number;
|
|
9
9
|
/** An optional object, the keys and values of which will be persisted in the instanceState and available for subsequent actions and executions */
|
|
10
|
-
|
|
10
|
+
instanceState?: Record<string, unknown>;
|
|
11
|
+
/** An optional object, the keys and values of which will be persisted in the executionState and available for the duration of the execution */
|
|
12
|
+
executionState?: Record<string, unknown>;
|
|
11
13
|
}
|
|
12
14
|
/** Used to represent a branching return of conventional data and does not require content type to be specified */
|
|
13
15
|
/** Used to represent a binary or serialized data branching return as content type must be specified */
|
|
@@ -21,6 +21,8 @@ export interface TriggerDefinition<T extends Inputs, AllowsBranching extends boo
|
|
|
21
21
|
authorization?: AuthorizationDefinition;
|
|
22
22
|
/** Optional attribute that specifies whether this Trigger will terminate execution. */
|
|
23
23
|
terminateExecution?: boolean;
|
|
24
|
+
/** Specifies whether an Action will break out of a loop. */
|
|
25
|
+
breakLoop?: boolean;
|
|
24
26
|
/** Determines whether this Trigger allows Conditional Branching. */
|
|
25
27
|
allowsBranching?: AllowsBranching;
|
|
26
28
|
/** Static Branch names associated with this Trigger. */
|
|
@@ -14,9 +14,14 @@ export interface TriggerPayload {
|
|
|
14
14
|
data: unknown;
|
|
15
15
|
contentType?: string;
|
|
16
16
|
};
|
|
17
|
+
/** The webhook URLs assigned to this integration's flows upon instance deploy */
|
|
17
18
|
webhookUrls: {
|
|
18
19
|
[key: string]: string;
|
|
19
20
|
};
|
|
21
|
+
/** The optional API keys assigned to the flows of this integration. These may be unique per integration instance and per flow. */
|
|
22
|
+
webhookApiKeys: {
|
|
23
|
+
[key: string]: string[];
|
|
24
|
+
};
|
|
20
25
|
customer: {
|
|
21
26
|
externalId: string | null;
|
|
22
27
|
name: string | null;
|
|
@@ -7,7 +7,9 @@ export interface TriggerBaseResult {
|
|
|
7
7
|
/** Optional HTTP response to the request that invoked the integration. */
|
|
8
8
|
response?: HttpResponse;
|
|
9
9
|
/** An optional object, the keys and values of which will be persisted in the instanceState and available for subsequent actions and executions */
|
|
10
|
-
|
|
10
|
+
instanceState?: Record<string, unknown>;
|
|
11
|
+
/** An optional object, the keys and values of which will be persisted in the executionState and available for the duration of the execution */
|
|
12
|
+
executionState?: Record<string, unknown>;
|
|
11
13
|
}
|
|
12
14
|
/** Represents the result of a Trigger action that uses branching. */
|
|
13
15
|
export interface TriggerBranchingResult extends TriggerBaseResult {
|
|
@@ -47,6 +47,8 @@ interface BaseAction {
|
|
|
47
47
|
authorization?: AuthorizationDefinition;
|
|
48
48
|
/** Optional attribute that specifies whether an Action will terminate execution. */
|
|
49
49
|
terminateExecution?: boolean;
|
|
50
|
+
/** Specifies whether an Action will break out of a loop. */
|
|
51
|
+
breakLoop?: boolean;
|
|
50
52
|
/** Determines whether an Action will allow Conditional Branching. */
|
|
51
53
|
allowsBranching?: boolean;
|
|
52
54
|
/** Static Branch names associated with an Action. */
|
|
@@ -87,7 +89,9 @@ export interface ServerPerformDataStructureReturn {
|
|
|
87
89
|
/** The HTTP Status code that will be used if this terminates a synchronous invocation */
|
|
88
90
|
statusCode?: number;
|
|
89
91
|
/** An optional object, the keys and values of which will be persisted in the instanceState and available for subsequent actions and executions */
|
|
90
|
-
|
|
92
|
+
instanceState?: Record<string, unknown>;
|
|
93
|
+
/** An optional object, the keys and values of which will be persisted in the executionState and available for the duration of the execution */
|
|
94
|
+
executionState?: Record<string, unknown>;
|
|
91
95
|
}
|
|
92
96
|
/** Used to represent a binary or serialized data return as content type must be specified */
|
|
93
97
|
interface ServerPerformDataReturn {
|
|
@@ -98,7 +102,9 @@ interface ServerPerformDataReturn {
|
|
|
98
102
|
/** The HTTP Status code that will be used if this terminates a synchronous invocation */
|
|
99
103
|
statusCode?: number;
|
|
100
104
|
/** An optional object, the keys and values of which will be persisted in the instanceState and available for subsequent actions and executions */
|
|
101
|
-
|
|
105
|
+
instanceState?: Record<string, unknown>;
|
|
106
|
+
/** An optional object, the keys and values of which will be persisted in the executionState and available for the duration of the execution */
|
|
107
|
+
executionState?: Record<string, unknown>;
|
|
102
108
|
}
|
|
103
109
|
/** Used to represent a branching return of conventional data and does not require content type to be specified */
|
|
104
110
|
export interface ServerPerformBranchingDataStructureReturn extends ServerPerformDataStructureReturn {
|
package/dist/util.d.ts
CHANGED
|
@@ -5,6 +5,16 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { DataPayload } from "./types/server-types";
|
|
7
7
|
import { KeyValuePair } from "./types";
|
|
8
|
+
/**
|
|
9
|
+
* This function returns a lower cased version of the headers passed to it.
|
|
10
|
+
*
|
|
11
|
+
* - `lowerCaseHeaders({"Content-Type": "Application/JSON"}) will return {"content-type": "Application/JSON"}`
|
|
12
|
+
* - `lowerCaseHeaders({"Cache-Control": "max-age=604800"}) will return {"cache-control": "max-age=604800"}`
|
|
13
|
+
* - `lowerCaseHeaders({"Accept-Language": "en-us"}) will return {"accept-language": "en-us"}`
|
|
14
|
+
* @param headers The headers to convert to lower case
|
|
15
|
+
* @returns This function returns a header object
|
|
16
|
+
* */
|
|
17
|
+
export declare const lowerCaseHeaders: (headers: Record<string, string>) => Record<string, string>;
|
|
8
18
|
declare const _default: {
|
|
9
19
|
types: {
|
|
10
20
|
isBool: (value: unknown) => value is boolean;
|
|
@@ -25,6 +35,7 @@ declare const _default: {
|
|
|
25
35
|
toString: (value: unknown, defaultValue?: string) => string;
|
|
26
36
|
keyValPairListToObject: (kvpList?: KeyValuePair<unknown>[]) => Record<string, unknown>;
|
|
27
37
|
isJSON: (value: string) => boolean;
|
|
38
|
+
lowerCaseHeaders: (headers: Record<string, string>) => Record<string, string>;
|
|
28
39
|
};
|
|
29
40
|
docs: {
|
|
30
41
|
formatJsonExample: (input: unknown) => string;
|
package/dist/util.js
CHANGED
|
@@ -8,6 +8,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
8
8
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
9
|
};
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.lowerCaseHeaders = void 0;
|
|
11
12
|
/** */
|
|
12
13
|
const parseISO_1 = __importDefault(require("date-fns/parseISO"));
|
|
13
14
|
const isValid_1 = __importDefault(require("date-fns/isValid"));
|
|
@@ -97,7 +98,7 @@ const toInt = (value, defaultValue) => {
|
|
|
97
98
|
* - `util.types.isBool("5.5")` will return `true`, since the string `"5.5"` can easily be coerced into a number.
|
|
98
99
|
* - `util.types.isBool("Hello")` will return `false`, since `"Hello"` is not a number.
|
|
99
100
|
*
|
|
100
|
-
* @param value The
|
|
101
|
+
* @param value The variable to test.
|
|
101
102
|
* @returns This function returns true if `value` can easily be coerced into a number, and false otherwise.
|
|
102
103
|
*/
|
|
103
104
|
const isNumber = (value) => !Number.isNaN(Number(value));
|
|
@@ -310,6 +311,19 @@ const isJSON = (value) => {
|
|
|
310
311
|
return false;
|
|
311
312
|
}
|
|
312
313
|
};
|
|
314
|
+
/**
|
|
315
|
+
* This function returns a lower cased version of the headers passed to it.
|
|
316
|
+
*
|
|
317
|
+
* - `lowerCaseHeaders({"Content-Type": "Application/JSON"}) will return {"content-type": "Application/JSON"}`
|
|
318
|
+
* - `lowerCaseHeaders({"Cache-Control": "max-age=604800"}) will return {"cache-control": "max-age=604800"}`
|
|
319
|
+
* - `lowerCaseHeaders({"Accept-Language": "en-us"}) will return {"accept-language": "en-us"}`
|
|
320
|
+
* @param headers The headers to convert to lower case
|
|
321
|
+
* @returns This function returns a header object
|
|
322
|
+
* */
|
|
323
|
+
const lowerCaseHeaders = (headers) => Object.entries(headers).reduce((result, [key, val]) => {
|
|
324
|
+
return Object.assign(Object.assign({}, result), { [key.toLowerCase()]: val });
|
|
325
|
+
}, {});
|
|
326
|
+
exports.lowerCaseHeaders = lowerCaseHeaders;
|
|
313
327
|
exports.default = {
|
|
314
328
|
types: {
|
|
315
329
|
isBool,
|
|
@@ -330,6 +344,7 @@ exports.default = {
|
|
|
330
344
|
toString,
|
|
331
345
|
keyValPairListToObject,
|
|
332
346
|
isJSON,
|
|
347
|
+
lowerCaseHeaders: exports.lowerCaseHeaders,
|
|
333
348
|
},
|
|
334
349
|
docs: {
|
|
335
350
|
formatJsonExample,
|
package/dist/util.test.js
CHANGED
|
@@ -283,4 +283,23 @@ describe("util", () => {
|
|
|
283
283
|
}));
|
|
284
284
|
});
|
|
285
285
|
});
|
|
286
|
+
const validJSON = fast_check_1.default.jsonObject().map((x) => JSON.stringify(x));
|
|
287
|
+
const invalidJSON = fast_check_1.default.constantFrom("", "['']", "someString", null, undefined);
|
|
288
|
+
describe("JSON", () => {
|
|
289
|
+
it("returns true in the case of actual JSON", () => {
|
|
290
|
+
fast_check_1.default.assert(fast_check_1.default.property(validJSON, (v) => {
|
|
291
|
+
expect(util_1.default.types.isJSON(v)).toStrictEqual(true);
|
|
292
|
+
}));
|
|
293
|
+
});
|
|
294
|
+
it("returns false in the case of invalid JSON", () => {
|
|
295
|
+
fast_check_1.default.assert(fast_check_1.default.property(invalidJSON, (v) => {
|
|
296
|
+
expect(util_1.default.types.isJSON(util_1.default.types.toString(v))).toStrictEqual(false);
|
|
297
|
+
}));
|
|
298
|
+
});
|
|
299
|
+
describe("JSON", () => {
|
|
300
|
+
it("returns true in the case of actual JSON", () => {
|
|
301
|
+
expect(util_1.default.types.lowerCaseHeaders({ "Content-Type": "Application/Json" })).toStrictEqual({ "content-type": "Application/Json" });
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
});
|
|
286
305
|
});
|