@prismatic-io/spectral 10.19.1-preview.0 → 10.21.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/cniComponentManifest/types.d.ts +4 -1
- package/dist/generators/componentManifest/createActions.js +1 -1
- package/dist/generators/componentManifest/templates/actions/action.ts.ejs +3 -0
- package/dist/index.d.ts +33 -1
- package/dist/index.js +34 -1
- package/dist/serverTypes/convertComponent.js +15 -3
- package/dist/serverTypes/index.d.ts +18 -0
- package/dist/types/ActionDefinition.d.ts +15 -0
- package/dist/types/ComponentManifest.d.ts +3 -0
- package/dist/types/OutputSchema.d.ts +35 -0
- package/dist/types/OutputSchema.js +2 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/package.json +1 -1
|
@@ -47,7 +47,10 @@ export interface InputNode {
|
|
|
47
47
|
shown: boolean;
|
|
48
48
|
onPremiseControlled: boolean;
|
|
49
49
|
}
|
|
50
|
-
export type FormattedAction = Pick<Action, "key" | "display" | "inputs" | "examplePayload"
|
|
50
|
+
export type FormattedAction = Pick<Action, "key" | "display" | "inputs" | "examplePayload"> & {
|
|
51
|
+
/** Emitted verbatim into the generated manifest; shape mirrors `examplePayload`. */
|
|
52
|
+
outputSchema?: unknown;
|
|
53
|
+
};
|
|
51
54
|
export type FormattedTrigger<TInputs extends Inputs, TActionInputs extends Inputs, TConfigVars extends ConfigVarResultCollection = ConfigVarResultCollection, TPayload extends TriggerPayload = TriggerPayload, TAllowsBranching extends boolean = boolean, TResult extends TriggerResult<TAllowsBranching, TPayload> = TriggerResult<TAllowsBranching, TPayload>> = Pick<Trigger<TInputs, TActionInputs, TConfigVars, TPayload, TAllowsBranching, TResult>, "key" | "display" | "inputs">;
|
|
52
55
|
export type FormattedDataSource = Pick<DataSource, "key" | "display" | "inputs" | "dataSourceType" | "examplePayload">;
|
|
53
56
|
export type ComponentForManifest<TInputs extends Inputs, TActionInputs extends Inputs, TConfigVars extends ConfigVarResultCollection = ConfigVarResultCollection, TPayload extends TriggerPayload = TriggerPayload, TAllowsBranching extends boolean = boolean, TResult extends TriggerResult<TAllowsBranching, TPayload> = TriggerResult<TAllowsBranching, TPayload>> = Pick<Component<TInputs, TActionInputs, TConfigVars, TPayload, TAllowsBranching, TResult>, "key" | "public" | "display" | "connections"> & {
|
|
@@ -44,7 +44,7 @@ const createActions = (_a) => __awaiter(void 0, [_a], void 0, function* ({ compo
|
|
|
44
44
|
});
|
|
45
45
|
const imports = (0, getImports_1.getImports)({ inputs });
|
|
46
46
|
return yield renderAction({
|
|
47
|
-
action: Object.assign(Object.assign({ typeInterface: (0, createTypeInterface_1.createTypeInterface)((_b = action.key) !== null && _b !== void 0 ? _b : actionKey), import: (0, createImport_1.createImport)((_c = action.key) !== null && _c !== void 0 ? _c : actionKey), key: action.key || actionKey, label: action.display.label, description: action.display.description, inputs }, (action.examplePayload ? { examplePayload: action.examplePayload } : {})), { componentKey: component.key }),
|
|
47
|
+
action: Object.assign(Object.assign(Object.assign({ typeInterface: (0, createTypeInterface_1.createTypeInterface)((_b = action.key) !== null && _b !== void 0 ? _b : actionKey), import: (0, createImport_1.createImport)((_c = action.key) !== null && _c !== void 0 ? _c : actionKey), key: action.key || actionKey, label: action.display.label, description: action.display.description, inputs }, (action.examplePayload ? { examplePayload: action.examplePayload } : {})), (action.outputSchema ? { outputSchema: action.outputSchema } : {})), { componentKey: component.key }),
|
|
48
48
|
imports,
|
|
49
49
|
dryRun,
|
|
50
50
|
verbose,
|
|
@@ -25,4 +25,7 @@ export const <%= action.import %> = {
|
|
|
25
25
|
<%_ if (action.examplePayload) { -%>
|
|
26
26
|
examplePayload: <%- typeof action.examplePayload === 'string' ? action.examplePayload : JSON.stringify(action.examplePayload, null, 2) %>,
|
|
27
27
|
<%_ } -%>
|
|
28
|
+
<%_ if (action.outputSchema) { -%>
|
|
29
|
+
outputSchema: <%- typeof action.outputSchema === 'string' ? action.outputSchema : JSON.stringify(action.outputSchema, null, 2) %>,
|
|
30
|
+
<%_ } -%>
|
|
28
31
|
} as const;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { convertComponent } from "./serverTypes/convertComponent";
|
|
7
7
|
import { convertIntegration } from "./serverTypes/convertIntegration";
|
|
8
|
-
import type { ActionDefinition, ActionPerformReturn, BatchTrigger, ComponentDefinition, ComponentManifest, ConfigPage, ConfigVarResultCollection, ConnectionConfigVar, CustomerActivatedConnectionConfigVar, DataSourceConfigVar, DataSourceDefinition, DataSourceType, DefaultConnectionDefinition, DynamicObjectInputField, Flow, InputFieldDefinition, Inputs, IntegrationDefinition, OAuth2ConnectionDefinition, OnPremConnectionDefinition, OrganizationActivatedConnectionConfigVar, StandardConfigVar, StructuredObjectInputField, TriggerDefinition, TriggerPayload, TriggerResult } from "./types";
|
|
8
|
+
import type { ActionDefinition, ActionPerformReturn, BatchTrigger, ComponentDefinition, ComponentManifest, ConfigPage, ConfigVarResultCollection, ConnectionConfigVar, CustomerActivatedConnectionConfigVar, DataSourceConfigVar, DataSourceDefinition, DataSourceType, DefaultConnectionDefinition, DynamicObjectInputField, Flow, InputFieldDefinition, Inputs, IntegrationDefinition, OAuth2ConnectionDefinition, OnPremConnectionDefinition, OrganizationActivatedConnectionConfigVar, OutputSchema, StandardConfigVar, StructuredObjectInputField, TriggerDefinition, TriggerPayload, TriggerResult } from "./types";
|
|
9
9
|
import type { PollingTriggerDefinition } from "./types/PollingTriggerDefinition";
|
|
10
10
|
/**
|
|
11
11
|
* This function creates a code-native integration object that can be
|
|
@@ -383,6 +383,38 @@ export declare const component: <TPublic extends boolean, TKey extends string>(d
|
|
|
383
383
|
* });
|
|
384
384
|
*/
|
|
385
385
|
export declare const action: <TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection, TAllowsBranching extends boolean, TReturn extends ActionPerformReturn<TAllowsBranching, unknown>>(definition: ActionDefinition<TInputs, TConfigVars, TAllowsBranching, TReturn>) => ActionDefinition<TInputs, TConfigVars, TAllowsBranching, TReturn>;
|
|
386
|
+
/**
|
|
387
|
+
* Declares the output schema for an action and preserves its literal types,
|
|
388
|
+
* so authors don't need a trailing `as const` (or `satisfies OutputSchema`)
|
|
389
|
+
* to keep the `type` discriminant from widening to `string`.
|
|
390
|
+
*
|
|
391
|
+
* Wrapping the schema in this helper lets it be hoisted into a standalone
|
|
392
|
+
* variable and still satisfy the {@link OutputSchema} discriminated union:
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* import { action, outputSchema } from "@prismatic-io/spectral";
|
|
396
|
+
*
|
|
397
|
+
* // Hoisted out of the action — no `as const` needed.
|
|
398
|
+
* const listItemsOutput = outputSchema({
|
|
399
|
+
* type: "actionOutput",
|
|
400
|
+
* schema: {
|
|
401
|
+
* type: "object",
|
|
402
|
+
* properties: { items: { type: "array" } },
|
|
403
|
+
* },
|
|
404
|
+
* });
|
|
405
|
+
*
|
|
406
|
+
* export const listItems = action({
|
|
407
|
+
* display: { label: "List Items", description: "..." },
|
|
408
|
+
* inputs: {},
|
|
409
|
+
* perform: async () => ({ data: { items: [] } }),
|
|
410
|
+
* outputSchema: listItemsOutput,
|
|
411
|
+
* });
|
|
412
|
+
*
|
|
413
|
+
* @param definition An {@link OutputSchema} object — either an `actionOutput`
|
|
414
|
+
* single-payload schema or a `branchingOutput` per-branch map.
|
|
415
|
+
* @returns The same object, typed with its literal discriminant preserved.
|
|
416
|
+
*/
|
|
417
|
+
export declare const outputSchema: <const TOutputSchema extends OutputSchema>(definition: TOutputSchema) => TOutputSchema;
|
|
386
418
|
/**
|
|
387
419
|
* This function creates a trigger object that can be referenced
|
|
388
420
|
* by a custom component. It helps ensure that the shape of the
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.util = exports.testing = exports.componentManifests = exports.oauth2Connection = exports.onPremConnection = exports.connection = exports.dynamicObjectInput = exports.structuredObjectInput = exports.input = exports.dataSource = exports.pollingTrigger = exports.trigger = exports.action = exports.component = exports.componentManifest = exports.organizationActivatedConnection = exports.customerActivatedConnection = exports.connectionConfigVar = exports.dataSourceConfigVar = exports.configVar = exports.configPage = exports.batchFlowTrigger = exports.flow = exports.integration = void 0;
|
|
25
|
+
exports.util = exports.testing = exports.componentManifests = exports.oauth2Connection = exports.onPremConnection = exports.connection = exports.dynamicObjectInput = exports.structuredObjectInput = exports.input = exports.dataSource = exports.pollingTrigger = exports.trigger = exports.outputSchema = exports.action = exports.component = exports.componentManifest = exports.organizationActivatedConnection = exports.customerActivatedConnection = exports.connectionConfigVar = exports.dataSourceConfigVar = exports.configVar = exports.configPage = exports.batchFlowTrigger = exports.flow = exports.integration = void 0;
|
|
26
26
|
const serverTypes_1 = require("./serverTypes");
|
|
27
27
|
const convertComponent_1 = require("./serverTypes/convertComponent");
|
|
28
28
|
const convertIntegration_1 = require("./serverTypes/convertIntegration");
|
|
@@ -426,6 +426,39 @@ exports.component = component;
|
|
|
426
426
|
*/
|
|
427
427
|
const action = (definition) => definition;
|
|
428
428
|
exports.action = action;
|
|
429
|
+
/**
|
|
430
|
+
* Declares the output schema for an action and preserves its literal types,
|
|
431
|
+
* so authors don't need a trailing `as const` (or `satisfies OutputSchema`)
|
|
432
|
+
* to keep the `type` discriminant from widening to `string`.
|
|
433
|
+
*
|
|
434
|
+
* Wrapping the schema in this helper lets it be hoisted into a standalone
|
|
435
|
+
* variable and still satisfy the {@link OutputSchema} discriminated union:
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* import { action, outputSchema } from "@prismatic-io/spectral";
|
|
439
|
+
*
|
|
440
|
+
* // Hoisted out of the action — no `as const` needed.
|
|
441
|
+
* const listItemsOutput = outputSchema({
|
|
442
|
+
* type: "actionOutput",
|
|
443
|
+
* schema: {
|
|
444
|
+
* type: "object",
|
|
445
|
+
* properties: { items: { type: "array" } },
|
|
446
|
+
* },
|
|
447
|
+
* });
|
|
448
|
+
*
|
|
449
|
+
* export const listItems = action({
|
|
450
|
+
* display: { label: "List Items", description: "..." },
|
|
451
|
+
* inputs: {},
|
|
452
|
+
* perform: async () => ({ data: { items: [] } }),
|
|
453
|
+
* outputSchema: listItemsOutput,
|
|
454
|
+
* });
|
|
455
|
+
*
|
|
456
|
+
* @param definition An {@link OutputSchema} object — either an `actionOutput`
|
|
457
|
+
* single-payload schema or a `branchingOutput` per-branch map.
|
|
458
|
+
* @returns The same object, typed with its literal discriminant preserved.
|
|
459
|
+
*/
|
|
460
|
+
const outputSchema = (definition) => definition;
|
|
461
|
+
exports.outputSchema = outputSchema;
|
|
429
462
|
/**
|
|
430
463
|
* This function creates a trigger object that can be referenced
|
|
431
464
|
* by a custom component. It helps ensure that the shape of the
|
|
@@ -213,14 +213,26 @@ const convertTemplateInput = (key, _a, inputs) => {
|
|
|
213
213
|
return Object.assign(Object.assign({}, (0, omit_1.default)(rest, ["permissionAndVisibilityType", "visibleToOrgDeployer", "writeOnly"])), { key, type: "template", default: templateValue !== null && templateValue !== void 0 ? templateValue : "", label: typeof label === "string" ? label : label.value, shown: false });
|
|
214
214
|
};
|
|
215
215
|
exports.convertTemplateInput = convertTemplateInput;
|
|
216
|
+
const convertOutputSchema = (outputSchema) => {
|
|
217
|
+
if (outputSchema.type === "actionOutput") {
|
|
218
|
+
return { type: "actionOutput", schema: JSON.stringify(outputSchema.schema) };
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
type: "branchingOutput",
|
|
222
|
+
branchSchemas: Object.entries(outputSchema.branchSchemas).map(([name, schema]) => ({
|
|
223
|
+
name,
|
|
224
|
+
schema: JSON.stringify(schema),
|
|
225
|
+
})),
|
|
226
|
+
};
|
|
227
|
+
};
|
|
216
228
|
const convertAction = (actionKey, _a, hooks) => {
|
|
217
|
-
var { inputs = {}, perform } = _a, action = __rest(_a, ["inputs", "perform"]);
|
|
229
|
+
var { inputs = {}, perform, outputSchema } = _a, action = __rest(_a, ["inputs", "perform", "outputSchema"]);
|
|
218
230
|
const convertedInputs = Object.entries(inputs).map(([key, value]) => (0, exports.convertInput)(key, value));
|
|
219
231
|
const inputCleaners = Object.entries(inputs).reduce((result, [key, value]) => (Object.assign(Object.assign({}, result), { [key]: (0, exports.cleanerFor)(value) })), {});
|
|
220
|
-
return Object.assign(Object.assign({}, action), { key: actionKey, inputs: convertedInputs, perform: (0, perform_1.createPerform)(perform, {
|
|
232
|
+
return Object.assign(Object.assign(Object.assign({}, action), { key: actionKey, inputs: convertedInputs, perform: (0, perform_1.createPerform)(perform, {
|
|
221
233
|
inputCleaners,
|
|
222
234
|
errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
|
|
223
|
-
}) });
|
|
235
|
+
}) }), (outputSchema ? { outputSchema: convertOutputSchema(outputSchema) } : {}));
|
|
224
236
|
};
|
|
225
237
|
const convertTrigger = (triggerKey,
|
|
226
238
|
// `any` is load-bearing: the user-facing TriggerDefinition / PollingTriggerDefinition
|
|
@@ -40,7 +40,25 @@ export interface Action {
|
|
|
40
40
|
dynamicBranchInput?: string;
|
|
41
41
|
perform: ActionPerformFunction;
|
|
42
42
|
examplePayload?: unknown;
|
|
43
|
+
/**
|
|
44
|
+
* The on-the-wire form of an action's `outputSchema`, as accepted by the
|
|
45
|
+
* `PublishComponent` mutation. JSON Schemas are serialized to strings and the
|
|
46
|
+
* branching variant's per-branch map is flattened to a `{ name, schema }`
|
|
47
|
+
* list (GraphQL input has no map type). Produced by `convertOutputSchema`
|
|
48
|
+
* from the author-facing `OutputSchema`.
|
|
49
|
+
*/
|
|
50
|
+
outputSchema?: ServerOutputSchema;
|
|
43
51
|
}
|
|
52
|
+
export type ServerOutputSchema = {
|
|
53
|
+
type: "actionOutput";
|
|
54
|
+
schema: string;
|
|
55
|
+
} | {
|
|
56
|
+
type: "branchingOutput";
|
|
57
|
+
branchSchemas: Array<{
|
|
58
|
+
name: string;
|
|
59
|
+
schema: string;
|
|
60
|
+
}>;
|
|
61
|
+
};
|
|
44
62
|
export type ActionLoggerFunction = (...args: unknown[]) => void;
|
|
45
63
|
export interface ActionLogger {
|
|
46
64
|
metric: ActionLoggerFunction;
|
|
@@ -3,6 +3,7 @@ import type { ActionPerformReturn } from "./ActionPerformReturn";
|
|
|
3
3
|
import type { ComponentManifestAction } from "./ComponentManifest";
|
|
4
4
|
import type { ActionDisplayDefinition } from "./DisplayDefinition";
|
|
5
5
|
import type { ConfigVarResultCollection, Inputs } from "./Inputs";
|
|
6
|
+
import type { OutputSchema } from "./OutputSchema";
|
|
6
7
|
/**
|
|
7
8
|
* ActionDefinition is the type of the object that is passed in to `action` function to
|
|
8
9
|
* define a component action. See
|
|
@@ -37,4 +38,18 @@ export interface ActionDefinition<TInputs extends Inputs = Inputs, TConfigVars e
|
|
|
37
38
|
dynamicBranchInput?: string;
|
|
38
39
|
/** An example of the payload output by this action. */
|
|
39
40
|
examplePayload?: Awaited<ReturnType<this["perform"]>>;
|
|
41
|
+
/**
|
|
42
|
+
* Declares the shape of this action's output `data` as a JSON Schema, used by
|
|
43
|
+
* the Prismatic UI to let integration authors reference this step's output
|
|
44
|
+
* before a real execution has produced data. A discriminated union:
|
|
45
|
+
* `{ type: "actionOutput", schema }` for a single payload shape, or
|
|
46
|
+
* `{ type: "branchingOutput", branchSchemas }` for a per-branch map of shapes.
|
|
47
|
+
* Descriptive only — it is not enforced at runtime.
|
|
48
|
+
*
|
|
49
|
+
* @remarks
|
|
50
|
+
* Describes the `data` payload only, not the full return envelope
|
|
51
|
+
* (`statusCode`, `contentType`, state fields). `branchingOutput` requires
|
|
52
|
+
* `staticBranchNames`; it is not supported with `dynamicBranchInput`.
|
|
53
|
+
*/
|
|
54
|
+
outputSchema?: OutputSchema;
|
|
40
55
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CollectionType } from "./ConfigVars";
|
|
2
2
|
import type { DataSourceType } from "./DataSourceResult";
|
|
3
3
|
import type { InputFieldType } from "./Inputs";
|
|
4
|
+
import type { OutputSchema } from "./OutputSchema";
|
|
4
5
|
export interface ComponentManifest {
|
|
5
6
|
key: string;
|
|
6
7
|
public: boolean;
|
|
@@ -21,6 +22,8 @@ export interface ComponentManifestAction {
|
|
|
21
22
|
perform: (values: any) => Promise<unknown>;
|
|
22
23
|
inputs: Record<string, BaseInput>;
|
|
23
24
|
examplePayload?: unknown;
|
|
25
|
+
/** Declares the shape of this action's output `data` as a JSON Schema (discriminated union: actionOutput | branchingOutput). */
|
|
26
|
+
outputSchema?: OutputSchema;
|
|
24
27
|
}
|
|
25
28
|
export interface ComponentManifestTrigger {
|
|
26
29
|
key?: string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { JsonSchema } from "./jsonforms/JsonSchema";
|
|
2
|
+
/**
|
|
3
|
+
* Describes the shape of a non-branching action's output `data` payload as a
|
|
4
|
+
* JSON Schema. Used by the Prismatic UI to let integration authors reference a
|
|
5
|
+
* step's output before a real execution has produced data. Descriptive only —
|
|
6
|
+
* it is not enforced at runtime.
|
|
7
|
+
*/
|
|
8
|
+
export interface ActionOutputSchema {
|
|
9
|
+
type: "actionOutput";
|
|
10
|
+
schema: JsonSchema;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Describes the output `data` payload of a branching action, one JSON Schema
|
|
14
|
+
* per branch keyed by branch name. A branching action returns `{ branch, data }`,
|
|
15
|
+
* and the `data` shape may differ per branch, so each branch carries its own
|
|
16
|
+
* schema. Descriptive only — not enforced at runtime.
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* Valid only for actions with `staticBranchNames` — a closed, build-time list.
|
|
20
|
+
* NOT supported with `dynamicBranchInput`, where branch names are computed at
|
|
21
|
+
* runtime and cannot be enumerated; publishing such a component is rejected
|
|
22
|
+
* server-side. (Unrelated to `dynamicObject` *inputs*, whose `configurations`
|
|
23
|
+
* are fully declared at build time — that's an input feature and does not
|
|
24
|
+
* affect `outputSchema`.)
|
|
25
|
+
*/
|
|
26
|
+
export interface BranchingOutputSchema {
|
|
27
|
+
type: "branchingOutput";
|
|
28
|
+
branchSchemas: Record<string, JsonSchema>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The output-schema contract declared on an action via `outputSchema`. A
|
|
32
|
+
* discriminated union on `type`: `actionOutput` for a single payload shape,
|
|
33
|
+
* `branchingOutput` for a per-branch map of payload shapes.
|
|
34
|
+
*/
|
|
35
|
+
export type OutputSchema = ActionOutputSchema | BranchingOutputSchema;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -27,9 +27,9 @@ export * from "./Inputs";
|
|
|
27
27
|
export * from "./InstanceAttributes";
|
|
28
28
|
export * from "./IntegrationAttributes";
|
|
29
29
|
export * from "./IntegrationDefinition";
|
|
30
|
+
export * from "./OutputSchema";
|
|
30
31
|
export * from "./PollingTriggerDefinition";
|
|
31
32
|
export * from "./ScopedConfigVars";
|
|
32
|
-
export * from "./ScopedConfigVars";
|
|
33
33
|
export * from "./TriggerDefinition";
|
|
34
34
|
export * from "./TriggerEventFunction";
|
|
35
35
|
export * from "./TriggerPayload";
|
package/dist/types/index.js
CHANGED
|
@@ -43,9 +43,9 @@ __exportStar(require("./Inputs"), exports);
|
|
|
43
43
|
__exportStar(require("./InstanceAttributes"), exports);
|
|
44
44
|
__exportStar(require("./IntegrationAttributes"), exports);
|
|
45
45
|
__exportStar(require("./IntegrationDefinition"), exports);
|
|
46
|
+
__exportStar(require("./OutputSchema"), exports);
|
|
46
47
|
__exportStar(require("./PollingTriggerDefinition"), exports);
|
|
47
48
|
__exportStar(require("./ScopedConfigVars"), exports);
|
|
48
|
-
__exportStar(require("./ScopedConfigVars"), exports);
|
|
49
49
|
__exportStar(require("./TriggerDefinition"), exports);
|
|
50
50
|
__exportStar(require("./TriggerEventFunction"), exports);
|
|
51
51
|
__exportStar(require("./TriggerPayload"), exports);
|