@trayio/tray-openapi 2.8.0 → 2.10.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/OpenApiCodecs.d.ts +3 -1
- package/dist/OpenApiCodecs.d.ts.map +1 -1
- package/dist/OpenApiCodecs.js +3 -1
- package/dist/OpenApiSchemaImporter.d.ts +1 -0
- package/dist/OpenApiSchemaImporter.d.ts.map +1 -1
- package/dist/OpenApiSchemaImporter.js +27 -16
- package/dist/OpenApiTypeDescriptors.d.ts +32 -20
- package/dist/OpenApiTypeDescriptors.d.ts.map +1 -1
- package/dist/OpenApiTypeDescriptors.js +59 -36
- package/dist/file-generators/GenerateHandler.d.ts +4 -4
- package/dist/file-generators/GenerateHandler.d.ts.map +1 -1
- package/dist/file-generators/GenerateHandler.js +43 -46
- package/dist/file-generators/GenerateHandler.test.js +194 -38
- package/dist/file-generators/GenerateHandlerTest.d.ts +3 -3
- package/dist/file-generators/GenerateHandlerTest.d.ts.map +1 -1
- package/dist/file-generators/GenerateHandlerTest.js +33 -21
- package/dist/file-generators/GenerateHandlerTest.test.js +313 -61
- package/dist/file-generators/GenerateOperationJson.d.ts.map +1 -1
- package/dist/file-generators/GenerateOperationJson.js +2 -1
- package/dist/file-generators/GenerateOperationJson.test.js +2 -1
- package/dist/file-generators/types/GenerateInputSchema.d.ts +2 -3
- package/dist/file-generators/types/GenerateInputSchema.d.ts.map +1 -1
- package/dist/file-generators/types/GenerateInputSchema.js +63 -28
- package/dist/file-generators/types/GenerateInputSchema.test.js +72 -104
- package/dist/file-generators/types/GenerateInputType.test.d.ts +2 -0
- package/dist/file-generators/types/GenerateInputType.test.d.ts.map +1 -0
- package/dist/file-generators/types/GenerateInputType.test.js +400 -0
- package/dist/file-generators/types/GenerateInputTypes.d.ts +2 -2
- package/dist/file-generators/types/GenerateInputTypes.d.ts.map +1 -1
- package/dist/file-generators/types/GenerateInputTypes.js +10 -8
- package/dist/file-generators/types/GenerateOutput.d.ts +4 -5
- package/dist/file-generators/types/GenerateOutput.d.ts.map +1 -1
- package/dist/file-generators/types/GenerateOutput.js +31 -5
- package/dist/file-generators/types/GenerateOutput.test.js +94 -88
- package/package.json +1 -1
- package/dist/ResolveOptionValues.d.ts +0 -3
- package/dist/ResolveOptionValues.d.ts.map +0 -1
- package/dist/ResolveOptionValues.js +0 -43
- package/dist/ResolveOptionValues.test.d.ts +0 -2
- package/dist/ResolveOptionValues.test.d.ts.map +0 -1
- package/dist/ResolveOptionValues.test.js +0 -91
package/dist/OpenApiCodecs.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
import { OpenAPISchema } from './OpenApiTypeDescriptors';
|
|
1
|
+
import { OpenAPISchema, Parameter, Path } from './OpenApiTypeDescriptors';
|
|
2
2
|
export declare const openApiSpecCodec: import("commons/dist/codec/Codec").Codec<OpenAPISchema>;
|
|
3
|
+
export declare const pathCodec: import("commons/dist/codec/Codec").Codec<Path>;
|
|
4
|
+
export declare const parameterSchemaCodec: import("commons/dist/codec/Codec").Codec<Parameter>;
|
|
3
5
|
//# sourceMappingURL=OpenApiCodecs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenApiCodecs.d.ts","sourceRoot":"","sources":["../src/OpenApiCodecs.ts"],"names":[],"mappings":"AACA,OAAO,EACN,aAAa,
|
|
1
|
+
{"version":3,"file":"OpenApiCodecs.d.ts","sourceRoot":"","sources":["../src/OpenApiCodecs.ts"],"names":[],"mappings":"AACA,OAAO,EACN,aAAa,EACb,SAAS,EACT,IAAI,EAIJ,MAAM,0BAA0B,CAAC;AAElC,eAAO,MAAM,gBAAgB,yDAE5B,CAAC;AAEF,eAAO,MAAM,SAAS,gDAErB,CAAC;AAEF,eAAO,MAAM,oBAAoB,qDAEhC,CAAC"}
|
package/dist/OpenApiCodecs.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.openApiSpecCodec = void 0;
|
|
3
|
+
exports.parameterSchemaCodec = exports.pathCodec = exports.openApiSpecCodec = void 0;
|
|
4
4
|
const TypeCodec_1 = require("@trayio/commons/codec/TypeCodec");
|
|
5
5
|
const OpenApiTypeDescriptors_1 = require("./OpenApiTypeDescriptors");
|
|
6
6
|
exports.openApiSpecCodec = TypeCodec_1.TypeCodec.fromDescriptor(OpenApiTypeDescriptors_1.openApiSpecTypeDescriptor);
|
|
7
|
+
exports.pathCodec = TypeCodec_1.TypeCodec.fromDescriptor(OpenApiTypeDescriptors_1.openApiSpecPathTypeDescriptor);
|
|
8
|
+
exports.parameterSchemaCodec = TypeCodec_1.TypeCodec.fromDescriptor(OpenApiTypeDescriptors_1.parameterSchemaTypeDescriptor);
|
|
@@ -7,6 +7,7 @@ export declare class OpenApiSchemaImporter {
|
|
|
7
7
|
constructor(generator: Generator, fileStorage: FileStorage);
|
|
8
8
|
buildConnector(openApiSpecPath: string, connectorName: string): TE.TaskEither<Error, undefined>;
|
|
9
9
|
private generateOperationFromPath;
|
|
10
|
+
private decodeOperation;
|
|
10
11
|
private getOpenApiSpec;
|
|
11
12
|
private generateHandlerFilesAndOperationJson;
|
|
12
13
|
private generateConnectorDirectory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenApiSchemaImporter.d.ts","sourceRoot":"","sources":["../src/OpenApiSchemaImporter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OpenApiSchemaImporter.d.ts","sourceRoot":"","sources":["../src/OpenApiSchemaImporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AASvC,OAAO,EAAQ,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAyClE,qBAAa,qBAAqB;IACrB,OAAO,CAAC,SAAS;IAAa,OAAO,CAAC,WAAW;gBAAzC,SAAS,EAAE,SAAS,EAAU,WAAW,EAAE,WAAW;IAE1E,cAAc,CACb,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,GACnB,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;IAiClC,OAAO,CAAC,yBAAyB;IA6CjC,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,oCAAoC;IAgF5C,OAAO,CAAC,0BAA0B;IAwBlC,OAAO,CAAC,0BAA0B;CAclC"}
|
|
@@ -26,6 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.OpenApiSchemaImporter = void 0;
|
|
27
27
|
const TE = __importStar(require("fp-ts/TaskEither"));
|
|
28
28
|
const E = __importStar(require("fp-ts/Either"));
|
|
29
|
+
const O = __importStar(require("fp-ts/Option"));
|
|
29
30
|
const function_1 = require("fp-ts/function");
|
|
30
31
|
const Array_1 = require("fp-ts/Array");
|
|
31
32
|
const Apply_1 = require("fp-ts/Apply");
|
|
@@ -47,31 +48,39 @@ class OpenApiSchemaImporter {
|
|
|
47
48
|
this.fileStorage = fileStorage;
|
|
48
49
|
}
|
|
49
50
|
buildConnector(openApiSpecPath, connectorName) {
|
|
50
|
-
return (0, function_1.pipe)(this.generateConnectorDirectory(connectorName), TE.bindTo('connectorPath'), TE.bind('openApiSpec', () => this.getOpenApiSpec(openApiSpecPath)), TE.bind('paths', ({ openApiSpec }) =>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
return (0, function_1.pipe)(this.generateConnectorDirectory(connectorName), TE.bindTo('connectorPath'), TE.bind('openApiSpec', () => this.getOpenApiSpec(openApiSpecPath)), TE.bind('paths', ({ openApiSpec }) => {
|
|
52
|
+
if (openApiSpec.paths === undefined) {
|
|
53
|
+
return TE.left(new Error('OpenAPI spec does not contain any paths'));
|
|
54
|
+
}
|
|
55
|
+
return TE.right(Object.keys(openApiSpec.paths).map((path) => ({
|
|
56
|
+
path,
|
|
57
|
+
routes: Object.keys(openApiSpec.paths[path]).map((route) => ({
|
|
58
|
+
method: route,
|
|
59
|
+
path: openApiSpec.paths[path][route],
|
|
60
|
+
})),
|
|
61
|
+
})));
|
|
62
|
+
}), TE.chain(({ openApiSpec, connectorPath, paths }) => (0, Array_1.traverse)(TE.ApplicativeSeq)((path) => this.generateOperationFromPath(path, connectorPath, openApiSpec.servers[0].url, connectorName))(paths)), TE.map(() => undefined));
|
|
57
63
|
}
|
|
58
64
|
generateOperationFromPath(path, connectorPath, baseUrl, connectorName) {
|
|
59
|
-
return (0, function_1.pipe)((0, Array_1.traverse)(TE.ApplicativeSeq)((route) => (0, function_1.pipe)(this.generateOperationDirectory(connectorPath,
|
|
65
|
+
return (0, function_1.pipe)((0, Array_1.traverse)(TE.ApplicativeSeq)((route) => (0, function_1.pipe)(this.decodeOperation(route.path, path.path, route.method), TE.bindTo('decodedPath'), TE.chain(({ decodedPath }) => (0, function_1.pipe)(this.generateOperationDirectory(connectorPath, decodedPath.operationId), TE.bind('inputs', () => TE.right((0, GenerateInputSchema_1.generateInputSchema)(decodedPath))), TE.bind('outputs', () => (0, GenerateOutput_1.generateOutputSchema)(decodedPath.responses)), TE.bind('decodedPath', () => TE.right(decodedPath)))), TE.chain(({ inputs, outputs, decodedPath }) => this.generateHandlerFilesAndOperationJson(route.method, decodedPath, `${connectorPath}/src/${(0, lodash_1.kebabCase)(decodedPath.operationId)}`, baseUrl, path.path, connectorName, inputs, outputs))))(path.routes), TE.map(() => undefined));
|
|
66
|
+
}
|
|
67
|
+
decodeOperation(path, httpPath, method) {
|
|
68
|
+
return (0, function_1.pipe)(TE.fromEither(OpenApiCodecs_1.pathCodec.decode(path)), TE.mapLeft((error) => new Error(`Failed to decode httpPath: ${httpPath} and method: ${method} : ${error}`)));
|
|
60
69
|
}
|
|
61
70
|
getOpenApiSpec(openApiSpecPath) {
|
|
62
71
|
return (0, function_1.pipe)(this.fileStorage.read(openApiSpecPath), TE.chain((openApiSpec) => BufferExtensions_1.BufferExtensions.readableToArrayBuffer(openApiSpec.content)), TE.chain((openApiSpec) => TE.fromEither(E.tryCatch(() => JSON.parse(Buffer.from(openApiSpec).toString('utf-8')), (error) => new Error(`Failed to parse OpenAPI spec as JSON from path ${openApiSpecPath}: ${error}`)))), TE.chain((openApiSpec) => TE.tryCatch(() => {
|
|
63
72
|
const resolver = new json_ref_resolver_1.Resolver({});
|
|
64
73
|
const resolvedOpenApiSpec = resolver.resolve(openApiSpec, {});
|
|
65
74
|
return resolvedOpenApiSpec;
|
|
66
|
-
}, (reason) => new Error(`Failed to resolve references in schema: ${reason}`))), TE.chain((openApiSpec) => TE.
|
|
75
|
+
}, (reason) => new Error(`Failed to resolve references in schema: ${reason}`))), TE.chain((openApiSpec) => TE.right(openApiSpec.result)));
|
|
67
76
|
}
|
|
68
|
-
generateHandlerFilesAndOperationJson(
|
|
69
|
-
const { method, path: { operationId: operationName, description }, } = route;
|
|
77
|
+
generateHandlerFilesAndOperationJson(method, path, operationPath, baseUrl, httpPath, connectorName, input, output) {
|
|
70
78
|
const writeFile = (content, fileName) => this.fileStorage.write({
|
|
71
79
|
content: stream_1.Readable.from(content),
|
|
72
80
|
key: `${operationPath}/${fileName}`,
|
|
73
81
|
metadata: { name: fileName },
|
|
74
|
-
});
|
|
82
|
+
}, O.none);
|
|
83
|
+
const operationName = path.operationId;
|
|
75
84
|
const operationFileGenerationTasks = {
|
|
76
85
|
handler: (0, function_1.pipe)(TE.fromEither((0, GenerateHandler_1.generateHandler)({
|
|
77
86
|
connectorNamePascalCase: StringExtensions_1.StringExtensions.pascalCase(connectorName),
|
|
@@ -79,9 +88,11 @@ class OpenApiSchemaImporter {
|
|
|
79
88
|
operationNamePascalCase: StringExtensions_1.StringExtensions.pascalCase(operationName),
|
|
80
89
|
httpMethod: method,
|
|
81
90
|
baseUrl,
|
|
82
|
-
|
|
91
|
+
httpPath,
|
|
83
92
|
input,
|
|
84
|
-
})),
|
|
93
|
+
})),
|
|
94
|
+
// TODO: Why does this throw unhelpful errors?
|
|
95
|
+
TE.chain((handlerInput) => writeFile(handlerInput, 'handler.ts'))),
|
|
85
96
|
handlerTest: (0, function_1.pipe)(TE.fromEither((0, GenerateHandlerTest_1.generateHandlerTest)({
|
|
86
97
|
operationNameCamelCase: (0, lodash_1.camelCase)(operationName),
|
|
87
98
|
input,
|
|
@@ -89,9 +100,9 @@ class OpenApiSchemaImporter {
|
|
|
89
100
|
})), TE.chain((handlerInput) => writeFile(handlerInput, 'handler.test.ts'))),
|
|
90
101
|
generateOutputType: (0, function_1.pipe)((0, GenerateOutput_1.generateOutputTypes)(operationName, output), TE.chain((outputType) => writeFile(outputType, 'output.ts'))),
|
|
91
102
|
generateInputType: (0, function_1.pipe)((0, GenerateInputTypes_1.generateInputTypes)(operationName, input), TE.chain((inputType) => writeFile(inputType, 'input.ts'))),
|
|
92
|
-
operationJson: (0, GenerateOperationJson_1.generateOperationJson)(this.fileStorage, operationPath, operationName, (0, lodash_1.kebabCase)(operationName), description),
|
|
103
|
+
operationJson: (0, GenerateOperationJson_1.generateOperationJson)(this.fileStorage, operationPath, operationName, (0, lodash_1.kebabCase)(operationName), path.description),
|
|
93
104
|
};
|
|
94
|
-
return (0, function_1.pipe)((0, Apply_1.sequenceS)(TE.ApplicativePar)(operationFileGenerationTasks), TE.mapLeft((error) => new Error(`Failed to generate files for operation: ${error}`)), TE.map(() => undefined));
|
|
105
|
+
return (0, function_1.pipe)((0, Apply_1.sequenceS)(TE.ApplicativePar)(operationFileGenerationTasks), TE.mapLeft((error) => new Error(`Failed to generate files for operation: ${operationName}: ${error}`)), TE.map(() => undefined));
|
|
95
106
|
}
|
|
96
107
|
generateConnectorDirectory(connectorName) {
|
|
97
108
|
return (0, function_1.pipe)(TE.right({
|
|
@@ -2,7 +2,7 @@ import * as t from 'io-ts';
|
|
|
2
2
|
import * as O from 'fp-ts/Option';
|
|
3
3
|
export type Path = {
|
|
4
4
|
description: string;
|
|
5
|
-
tags: string[]
|
|
5
|
+
tags: O.Option<string[]>;
|
|
6
6
|
operationId: string;
|
|
7
7
|
parameters: O.Option<Parameter[]>;
|
|
8
8
|
requestBody: O.Option<RequestBody>;
|
|
@@ -16,35 +16,23 @@ export type Parameter = {
|
|
|
16
16
|
schema: {
|
|
17
17
|
type: string;
|
|
18
18
|
format: O.Option<string>;
|
|
19
|
+
items: O.Option<SchemaObject>;
|
|
19
20
|
};
|
|
20
21
|
};
|
|
21
22
|
export type RequestBody = {
|
|
22
|
-
content: Record<string,
|
|
23
|
-
};
|
|
24
|
-
export type MediaType = {
|
|
25
|
-
schema: ArraySchema | ObjectSchema;
|
|
23
|
+
content: Record<string, MediaTypeObject>;
|
|
26
24
|
};
|
|
25
|
+
export interface MediaTypeObject {
|
|
26
|
+
schema: O.Option<SchemaObject>;
|
|
27
|
+
}
|
|
27
28
|
export type Responses = Record<string, Response>;
|
|
28
29
|
export type Response = {
|
|
29
30
|
description: string;
|
|
30
|
-
content: O.Option<Record<string,
|
|
31
|
+
content: O.Option<Record<string, MediaTypeObject>>;
|
|
31
32
|
};
|
|
32
33
|
export type OpenApiHttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
33
|
-
type ArraySchema = {
|
|
34
|
-
type: 'array';
|
|
35
|
-
items: PropertySchema;
|
|
36
|
-
};
|
|
37
|
-
type ObjectSchema = {
|
|
38
|
-
type: 'object';
|
|
39
|
-
required?: string[];
|
|
40
|
-
properties: Record<string, PropertySchema>;
|
|
41
|
-
additionalProperties: O.Option<boolean>;
|
|
42
|
-
};
|
|
43
|
-
export type PropertySchema = {
|
|
44
|
-
type: string;
|
|
45
|
-
} | ArraySchema | ObjectSchema;
|
|
46
34
|
type ComponentSchema = {
|
|
47
|
-
schemas: Record<string,
|
|
35
|
+
schemas: O.Option<Record<string, SchemaObject>>;
|
|
48
36
|
};
|
|
49
37
|
export type OpenAPISchema = {
|
|
50
38
|
openapi: string;
|
|
@@ -59,6 +47,30 @@ export type OpenAPISchema = {
|
|
|
59
47
|
paths: Record<string, Partial<Record<OpenApiHttpMethod, Path>>>;
|
|
60
48
|
components: ComponentSchema;
|
|
61
49
|
};
|
|
50
|
+
export type SchemaObject = ArraySchemaObject | NonArraySchemaObject;
|
|
51
|
+
export interface ArraySchemaObject extends BaseSchemaObject {
|
|
52
|
+
type: 'array';
|
|
53
|
+
items: SchemaObject;
|
|
54
|
+
}
|
|
55
|
+
export type NonArraySchemaObjectType = 'boolean' | 'object' | 'number' | 'string' | 'integer';
|
|
56
|
+
export interface NonArraySchemaObject extends BaseSchemaObject {
|
|
57
|
+
type: O.Option<NonArraySchemaObjectType>;
|
|
58
|
+
}
|
|
59
|
+
export type BaseSchemaObject = {
|
|
60
|
+
additionalProperties: O.Option<boolean | SchemaObject>;
|
|
61
|
+
properties: O.Option<Record<string, SchemaObject>>;
|
|
62
|
+
required: O.Option<string[]>;
|
|
63
|
+
allOf: O.Option<SchemaObject[]>;
|
|
64
|
+
oneOf: O.Option<SchemaObject[]>;
|
|
65
|
+
anyOf: O.Option<SchemaObject[]>;
|
|
66
|
+
not: O.Option<SchemaObject>;
|
|
67
|
+
in: O.Option<string>;
|
|
68
|
+
};
|
|
69
|
+
export declare const baseSchemaObjectSchemaTypeDescriptor: t.Type<BaseSchemaObject, unknown>;
|
|
70
|
+
export declare const schemaObjectTypeDescriptor: t.Type<SchemaObject, unknown>;
|
|
71
|
+
export declare const schemaObjectTypeCodec: import("commons/dist/codec/Codec").Codec<SchemaObject>;
|
|
72
|
+
export declare const parameterSchemaTypeDescriptor: t.Type<Parameter, unknown>;
|
|
73
|
+
export declare const openApiSpecPathTypeDescriptor: t.Type<Path, unknown>;
|
|
62
74
|
export declare const openApiSpecTypeDescriptor: t.Type<OpenAPISchema, unknown>;
|
|
63
75
|
export {};
|
|
64
76
|
//# sourceMappingURL=OpenApiTypeDescriptors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenApiTypeDescriptors.d.ts","sourceRoot":"","sources":["../src/OpenApiTypeDescriptors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,OAAO,CAAC;AAE3B,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAGlC,MAAM,MAAM,IAAI,GAAG;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"OpenApiTypeDescriptors.d.ts","sourceRoot":"","sources":["../src/OpenApiTypeDescriptors.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,54 +23,77 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.openApiSpecTypeDescriptor = void 0;
|
|
26
|
+
exports.openApiSpecTypeDescriptor = exports.openApiSpecPathTypeDescriptor = exports.parameterSchemaTypeDescriptor = exports.schemaObjectTypeCodec = exports.schemaObjectTypeDescriptor = exports.baseSchemaObjectSchemaTypeDescriptor = void 0;
|
|
27
27
|
const t = __importStar(require("io-ts"));
|
|
28
28
|
const io_ts_types_1 = require("io-ts-types");
|
|
29
29
|
const TypeCodec_1 = require("@trayio/commons/codec/TypeCodec");
|
|
30
30
|
// Codecs
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
const nonArraySchemaObjectType = t.keyof({
|
|
32
|
+
boolean: null,
|
|
33
|
+
object: null,
|
|
34
|
+
number: null,
|
|
35
|
+
string: null,
|
|
36
|
+
integer: null,
|
|
36
37
|
});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
exports.baseSchemaObjectSchemaTypeDescriptor = t.recursion('baseSchema', () => t.type({
|
|
39
|
+
additionalProperties: (0, io_ts_types_1.optionFromNullable)(t.union([t.boolean, exports.schemaObjectTypeDescriptor])),
|
|
40
|
+
properties: (0, io_ts_types_1.optionFromNullable)(t.record(t.string, exports.schemaObjectTypeDescriptor)),
|
|
41
|
+
required: (0, io_ts_types_1.optionFromNullable)(t.array(t.string)),
|
|
42
|
+
allOf: (0, io_ts_types_1.optionFromNullable)(t.array(exports.schemaObjectTypeDescriptor)),
|
|
43
|
+
oneOf: (0, io_ts_types_1.optionFromNullable)(t.array(exports.schemaObjectTypeDescriptor)),
|
|
44
|
+
anyOf: (0, io_ts_types_1.optionFromNullable)(t.array(exports.schemaObjectTypeDescriptor)),
|
|
45
|
+
not: (0, io_ts_types_1.optionFromNullable)(exports.schemaObjectTypeDescriptor),
|
|
46
|
+
in: (0, io_ts_types_1.optionFromNullable)(t.string),
|
|
47
|
+
}));
|
|
48
|
+
const arraySchemaObjectSchemaTypeDescriptor = t.recursion('ArraySchema', () => t.intersection([
|
|
49
|
+
exports.baseSchemaObjectSchemaTypeDescriptor,
|
|
50
|
+
t.type({ type: t.literal('array'), items: exports.schemaObjectTypeDescriptor }),
|
|
51
|
+
]));
|
|
52
|
+
const nonArraySchemaObjectSchemaTypeDescriptor = t.recursion('nonArraySchema', () => t.intersection([
|
|
53
|
+
exports.baseSchemaObjectSchemaTypeDescriptor,
|
|
54
|
+
t.type({
|
|
55
|
+
type: (0, io_ts_types_1.optionFromNullable)(nonArraySchemaObjectType),
|
|
56
|
+
}),
|
|
57
|
+
]));
|
|
58
|
+
// TODO: do we need the schemaObjectTypeDescriptor AND the schemaObjectTypeCodec?
|
|
59
|
+
// Added the schemaObjectTypeCodec in order to use the RemoveNullValuesCodec to remove O.none values instead of sestting them to null
|
|
60
|
+
exports.schemaObjectTypeDescriptor = t.recursion('schemaObject', () => t.union([
|
|
61
|
+
arraySchemaObjectSchemaTypeDescriptor,
|
|
62
|
+
nonArraySchemaObjectSchemaTypeDescriptor,
|
|
63
|
+
]));
|
|
64
|
+
exports.schemaObjectTypeCodec = TypeCodec_1.TypeCodec.fromDescriptor(t.recursion('schemaObject', () => t.union([
|
|
65
|
+
arraySchemaObjectSchemaTypeDescriptor,
|
|
66
|
+
nonArraySchemaObjectSchemaTypeDescriptor,
|
|
67
|
+
])));
|
|
68
|
+
const componentSchemaTypeDescriptor = t.type({
|
|
69
|
+
schemas: (0, io_ts_types_1.optionFromNullable)(t.record(t.string, exports.schemaObjectTypeDescriptor)),
|
|
46
70
|
});
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
openApiSpecObjectSchemaTypeDescriptor,
|
|
50
|
-
openApiSpecArraySchemaTypeDescriptor,
|
|
51
|
-
])),
|
|
71
|
+
const mediaTypeTypeDescriptor = t.type({
|
|
72
|
+
schema: (0, io_ts_types_1.optionFromNullable)(exports.schemaObjectTypeDescriptor),
|
|
52
73
|
});
|
|
53
74
|
const openApiSpecRequestBodyTypeDescriptor = t.type({
|
|
54
|
-
content: t.record(t.string,
|
|
75
|
+
content: t.record(t.string, mediaTypeTypeDescriptor),
|
|
55
76
|
});
|
|
56
77
|
const openApiSpecResponsesTypeDescriptor = t.record(t.string, t.type({
|
|
57
78
|
description: t.string,
|
|
58
|
-
content: (0, io_ts_types_1.optionFromNullable)(t.record(t.string,
|
|
79
|
+
content: (0, io_ts_types_1.optionFromNullable)(t.record(t.string, mediaTypeTypeDescriptor)),
|
|
59
80
|
}));
|
|
60
|
-
|
|
81
|
+
exports.parameterSchemaTypeDescriptor = t.type({
|
|
82
|
+
name: t.string,
|
|
83
|
+
in: t.string,
|
|
84
|
+
description: t.string,
|
|
85
|
+
required: t.boolean,
|
|
86
|
+
schema: t.type({
|
|
87
|
+
type: t.string,
|
|
88
|
+
format: (0, io_ts_types_1.optionFromNullable)(t.string),
|
|
89
|
+
items: (0, io_ts_types_1.optionFromNullable)(exports.schemaObjectTypeDescriptor),
|
|
90
|
+
}),
|
|
91
|
+
});
|
|
92
|
+
exports.openApiSpecPathTypeDescriptor = t.type({
|
|
61
93
|
description: t.string,
|
|
62
|
-
tags: t.array(t.string),
|
|
94
|
+
tags: (0, io_ts_types_1.optionFromNullable)(t.array(t.string)),
|
|
63
95
|
operationId: t.string,
|
|
64
|
-
parameters: (0, io_ts_types_1.optionFromNullable)(t.array(
|
|
65
|
-
name: t.string,
|
|
66
|
-
in: t.string,
|
|
67
|
-
description: t.string,
|
|
68
|
-
required: t.boolean,
|
|
69
|
-
schema: t.type({
|
|
70
|
-
type: t.string,
|
|
71
|
-
format: (0, io_ts_types_1.optionFromNullable)(t.string),
|
|
72
|
-
}),
|
|
73
|
-
}))),
|
|
96
|
+
parameters: (0, io_ts_types_1.optionFromNullable)(t.array(exports.parameterSchemaTypeDescriptor)),
|
|
74
97
|
requestBody: (0, io_ts_types_1.optionFromNullable)(openApiSpecRequestBodyTypeDescriptor),
|
|
75
98
|
responses: (0, io_ts_types_1.optionFromNullable)(openApiSpecResponsesTypeDescriptor),
|
|
76
99
|
});
|
|
@@ -85,6 +108,6 @@ exports.openApiSpecTypeDescriptor = t.type({
|
|
|
85
108
|
openapi: t.string,
|
|
86
109
|
info: t.type({ title: t.string, description: t.string, version: t.string }),
|
|
87
110
|
servers: t.array(t.type({ url: t.string })),
|
|
88
|
-
paths: t.record(t.string, TypeCodec_1.TypeCodec.partialRecord(httpKeys, openApiSpecPathTypeDescriptor)),
|
|
89
|
-
components:
|
|
111
|
+
paths: t.record(t.string, TypeCodec_1.TypeCodec.partialRecord(httpKeys, exports.openApiSpecPathTypeDescriptor)),
|
|
112
|
+
components: componentSchemaTypeDescriptor,
|
|
90
113
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as E from 'fp-ts/Either';
|
|
2
|
-
import {
|
|
2
|
+
import { SchemaObject } from '../OpenApiTypeDescriptors';
|
|
3
3
|
type HandlerHttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
4
4
|
export type GenerateHandlerInput = {
|
|
5
5
|
connectorNamePascalCase: string;
|
|
@@ -7,9 +7,9 @@ export type GenerateHandlerInput = {
|
|
|
7
7
|
operationNameCamelCase: string;
|
|
8
8
|
httpMethod: HandlerHttpMethod;
|
|
9
9
|
baseUrl: string;
|
|
10
|
-
|
|
11
|
-
input:
|
|
10
|
+
httpPath: string;
|
|
11
|
+
input: SchemaObject;
|
|
12
12
|
};
|
|
13
|
-
export declare const generateHandler: ({ connectorNamePascalCase, operationNamePascalCase, operationNameCamelCase, httpMethod, baseUrl,
|
|
13
|
+
export declare const generateHandler: ({ connectorNamePascalCase, operationNamePascalCase, operationNameCamelCase, httpMethod, baseUrl, httpPath, input, }: GenerateHandlerInput) => E.Either<Error, string>;
|
|
14
14
|
export {};
|
|
15
15
|
//# sourceMappingURL=GenerateHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenerateHandler.d.ts","sourceRoot":"","sources":["../../src/file-generators/GenerateHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GenerateHandler.d.ts","sourceRoot":"","sources":["../../src/file-generators/GenerateHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAEN,YAAY,EACZ,MAAM,2BAA2B,CAAC;AAEnC,KAAK,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErE,MAAM,MAAM,oBAAoB,GAAG;IAClC,uBAAuB,EAAE,MAAM,CAAC;IAChC,uBAAuB,EAAE,MAAM,CAAC;IAChC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;CACpB,CAAC;AAsHF,eAAO,MAAM,eAAe,wHAQzB,oBAAoB,KAAG,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAoB9C,CAAC"}
|
|
@@ -24,12 +24,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.generateHandler = void 0;
|
|
27
|
+
const O = __importStar(require("fp-ts/Option"));
|
|
27
28
|
const E = __importStar(require("fp-ts/Either"));
|
|
28
|
-
const getInputVariable = (name, type) => {
|
|
29
|
-
|
|
30
|
-
return `input.${name}`;
|
|
31
|
-
}
|
|
32
|
-
switch (type) {
|
|
29
|
+
const getInputVariable = (name, type) => O.fold(() => `input.${name}`, (inputType) => {
|
|
30
|
+
switch (inputType) {
|
|
33
31
|
case 'integer':
|
|
34
32
|
case 'boolean':
|
|
35
33
|
case 'number':
|
|
@@ -37,40 +35,13 @@ const getInputVariable = (name, type) => {
|
|
|
37
35
|
default:
|
|
38
36
|
return `input.${name}`;
|
|
39
37
|
}
|
|
40
|
-
};
|
|
41
|
-
const handleInput = (inputs) => {
|
|
42
|
-
if (inputs.properties === undefined ||
|
|
43
|
-
Object.keys(inputs.properties).length === 0) {
|
|
44
|
-
return 'request.withoutBody()';
|
|
45
|
-
}
|
|
46
|
-
const inputsArray = Object.entries(inputs.properties);
|
|
47
|
-
const bodyInputs = [];
|
|
48
|
-
const handlerInput = inputsArray.map(([name, input], index) => {
|
|
49
|
-
const prefix = index === 0 ? 'request.' : '';
|
|
50
|
-
let inputMapping = '';
|
|
51
|
-
switch (input.in) {
|
|
52
|
-
case 'body':
|
|
53
|
-
bodyInputs.push(`${name}: input.${name}`);
|
|
54
|
-
break;
|
|
55
|
-
case 'path':
|
|
56
|
-
inputMapping = `addPathParameter("${name}", ${getInputVariable(name, input.type)})`;
|
|
57
|
-
break;
|
|
58
|
-
case 'query':
|
|
59
|
-
inputMapping = `addQueryString("${name}", ${getInputVariable(name, input.type)})`;
|
|
60
|
-
break;
|
|
61
|
-
case 'header':
|
|
62
|
-
inputMapping = `addHeader("${name}", ${getInputVariable(name, input.type)})`;
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
return prefix + inputMapping;
|
|
66
|
-
});
|
|
67
|
-
return generateRequestHandlerInputs(handlerInput, bodyInputs);
|
|
68
|
-
};
|
|
38
|
+
})(type);
|
|
69
39
|
const generateRequestHandlerInputs = (inputs, bodyInputs) => {
|
|
70
40
|
if (bodyInputs.length > 0) {
|
|
71
41
|
const constructedBodyProperty = `withBodyAsJson({ ${bodyInputs.join(',')} })`;
|
|
72
42
|
if (inputs[0] === 'request.') {
|
|
73
|
-
|
|
43
|
+
const cleanInput = inputs.filter((item) => item !== '');
|
|
44
|
+
return cleanInput
|
|
74
45
|
.join('.')
|
|
75
46
|
.replace('request.', `request.${constructedBodyProperty}`);
|
|
76
47
|
}
|
|
@@ -82,18 +53,44 @@ const generateRequestHandlerInputs = (inputs, bodyInputs) => {
|
|
|
82
53
|
const cleanInput = inputs.filter((item) => item !== '');
|
|
83
54
|
return cleanInput.join('.');
|
|
84
55
|
};
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
56
|
+
const constructInputs = (properties) => {
|
|
57
|
+
const inputsArray = Object.entries(properties);
|
|
58
|
+
const bodyInputs = [];
|
|
59
|
+
const handlerInput = inputsArray.map(([name, input], index) => {
|
|
60
|
+
const prefix = index === 0 ? 'request.' : '';
|
|
61
|
+
let inputMapping = '';
|
|
62
|
+
if (input.type === 'array') {
|
|
63
|
+
// TODO: improve error message and ideally handle this more gracefully, do we expect array types at the root level?
|
|
64
|
+
throw new Error('Array type not yet supported');
|
|
92
65
|
}
|
|
93
|
-
return
|
|
94
|
-
|
|
66
|
+
return O.fold(() => '', (inputIn) => {
|
|
67
|
+
switch (inputIn) {
|
|
68
|
+
case 'body':
|
|
69
|
+
bodyInputs.push(`${name}: input.${name}`);
|
|
70
|
+
break;
|
|
71
|
+
case 'path':
|
|
72
|
+
inputMapping = `addPathParameter("${name}", ${getInputVariable(name, input.type)})`;
|
|
73
|
+
break;
|
|
74
|
+
case 'query':
|
|
75
|
+
inputMapping = `addQueryString("${name}", ${getInputVariable(name, input.type)})`;
|
|
76
|
+
break;
|
|
77
|
+
case 'header':
|
|
78
|
+
inputMapping = `addHeader("${name}", ${getInputVariable(name, input.type)})`;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
return prefix + inputMapping;
|
|
82
|
+
})(input.in);
|
|
83
|
+
});
|
|
84
|
+
return generateRequestHandlerInputs(handlerInput, bodyInputs);
|
|
95
85
|
};
|
|
96
|
-
const
|
|
86
|
+
const handleInput = (inputs) => O.fold(() => 'request.withoutBody()', (properties) => constructInputs(properties))(inputs.properties);
|
|
87
|
+
const generatePath = (path, inputs) => O.fold(() => path, (properties) => Object.entries(properties).reduce((acc, [name, input]) => O.fold(() => acc, (inValue) => {
|
|
88
|
+
if (inValue === 'path') {
|
|
89
|
+
return acc.replace(`{${name}}`, `:${name}`);
|
|
90
|
+
}
|
|
91
|
+
return acc;
|
|
92
|
+
})(input.in), path))(inputs.properties);
|
|
93
|
+
const generateHandler = ({ connectorNamePascalCase, operationNamePascalCase, operationNameCamelCase, httpMethod, baseUrl, httpPath, input, }) => E.tryCatch(() => `import { OperationHandlerSetup } from "@trayio/cdk-dsl/connector/operation/OperationHandlerSetup";
|
|
97
94
|
import { ${connectorNamePascalCase}Auth } from "../${connectorNamePascalCase}Auth";
|
|
98
95
|
import { ${operationNamePascalCase}Input } from "./input";
|
|
99
96
|
import { ${operationNamePascalCase}Output } from "./output";
|
|
@@ -105,7 +102,7 @@ const generateHandler = ({ connectorNamePascalCase, operationNamePascalCase, ope
|
|
|
105
102
|
>((handler) =>
|
|
106
103
|
handler.usingHttp((http) =>
|
|
107
104
|
http
|
|
108
|
-
.${httpMethod}("${baseUrl}${generatePath(
|
|
105
|
+
.${httpMethod}("${baseUrl}${generatePath(httpPath, input)}")
|
|
109
106
|
.handleRequest((ctx, input, request) => ${handleInput(input)})
|
|
110
107
|
.handleResponse((ctx, input, response) => response.parseWithBodyAsJson())
|
|
111
108
|
)
|