@trayio/tray-openapi 0.0.1-beta
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/LICENSE.txt +22 -0
- package/README.md +39 -0
- package/dist/OpenApiCodecs.d.ts +5 -0
- package/dist/OpenApiCodecs.d.ts.map +1 -0
- package/dist/OpenApiCodecs.js +8 -0
- package/dist/OpenApiSchemaImporter.d.ts +17 -0
- package/dist/OpenApiSchemaImporter.d.ts.map +1 -0
- package/dist/OpenApiSchemaImporter.js +138 -0
- package/dist/OpenApiSchemaImporter.test.d.ts +2 -0
- package/dist/OpenApiSchemaImporter.test.d.ts.map +1 -0
- package/dist/OpenApiSchemaImporter.test.js +85 -0
- package/dist/OpenApiSchemaTransformer.d.ts +9 -0
- package/dist/OpenApiSchemaTransformer.d.ts.map +1 -0
- package/dist/OpenApiSchemaTransformer.js +68 -0
- package/dist/OpenApiSchemaTransformer.test.d.ts +2 -0
- package/dist/OpenApiSchemaTransformer.test.d.ts.map +1 -0
- package/dist/OpenApiSchemaTransformer.test.js +118 -0
- package/dist/OpenApiTypeDescriptors.d.ts +109 -0
- package/dist/OpenApiTypeDescriptors.d.ts.map +1 -0
- package/dist/OpenApiTypeDescriptors.js +107 -0
- package/dist/file-generators/GenerateHandler.d.ts +15 -0
- package/dist/file-generators/GenerateHandler.d.ts.map +1 -0
- package/dist/file-generators/GenerateHandler.js +110 -0
- package/dist/file-generators/GenerateHandler.test.d.ts +2 -0
- package/dist/file-generators/GenerateHandler.test.d.ts.map +1 -0
- package/dist/file-generators/GenerateHandler.test.js +427 -0
- package/dist/file-generators/GenerateHandlerTest.d.ts +9 -0
- package/dist/file-generators/GenerateHandlerTest.d.ts.map +1 -0
- package/dist/file-generators/GenerateHandlerTest.js +88 -0
- package/dist/file-generators/GenerateHandlerTest.test.d.ts +2 -0
- package/dist/file-generators/GenerateHandlerTest.test.d.ts.map +1 -0
- package/dist/file-generators/GenerateHandlerTest.test.js +640 -0
- package/dist/file-generators/GenerateOperationJson.d.ts +4 -0
- package/dist/file-generators/GenerateOperationJson.d.ts.map +1 -0
- package/dist/file-generators/GenerateOperationJson.js +44 -0
- package/dist/file-generators/GenerateOperationJson.test.d.ts +2 -0
- package/dist/file-generators/GenerateOperationJson.test.d.ts.map +1 -0
- package/dist/file-generators/GenerateOperationJson.test.js +78 -0
- package/dist/file-generators/types/GenerateInputSchema.d.ts +4 -0
- package/dist/file-generators/types/GenerateInputSchema.d.ts.map +1 -0
- package/dist/file-generators/types/GenerateInputSchema.js +131 -0
- package/dist/file-generators/types/GenerateInputSchema.test.d.ts +2 -0
- package/dist/file-generators/types/GenerateInputSchema.test.d.ts.map +1 -0
- package/dist/file-generators/types/GenerateInputSchema.test.js +260 -0
- 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 +447 -0
- package/dist/file-generators/types/GenerateInputTypes.d.ts +4 -0
- package/dist/file-generators/types/GenerateInputTypes.d.ts.map +1 -0
- package/dist/file-generators/types/GenerateInputTypes.js +45 -0
- package/dist/file-generators/types/GenerateOutput.d.ts +8 -0
- package/dist/file-generators/types/GenerateOutput.d.ts.map +1 -0
- package/dist/file-generators/types/GenerateOutput.js +81 -0
- package/dist/file-generators/types/GenerateOutput.test.d.ts +2 -0
- package/dist/file-generators/types/GenerateOutput.test.d.ts.map +1 -0
- package/dist/file-generators/types/GenerateOutput.test.js +213 -0
- package/dist/file-generators/types/JsonSchemaToTypescriptOptions.d.ts +9 -0
- package/dist/file-generators/types/JsonSchemaToTypescriptOptions.d.ts.map +1 -0
- package/dist/file-generators/types/JsonSchemaToTypescriptOptions.js +11 -0
- package/dist/templates/connector-template.zip +0 -0
- package/dist/test-openapi-spec.json +160 -0
- package/package.json +30 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Tray.io, Inc
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
This module speeds up the development process of creating a new Tray CDK connector by parsing an OpenAPI specification file for a given API and generating operation handlers, meta data, input and output types.
|
|
2
|
+
|
|
3
|
+
This beta functionality is available from the @trayio/cdk-cli module via the `tray-cdk import-openapi-spec` command. If you encounter any issues that you wish the team to investigate further please supply us with OpenApi specification you are importing and the `errors.json` that has been generated during the import process.
|
|
4
|
+
|
|
5
|
+
These are the features that are currently supported/unsupported:
|
|
6
|
+
- OpenAPI spec interpretation:
|
|
7
|
+
- Supported:
|
|
8
|
+
- schema internal component references
|
|
9
|
+
- JSON OpenAPI specification version 3
|
|
10
|
+
- If your version is older you can use this to update it: [Swagger Editor](https://editor.swagger.io/) (From the top menu bar, select edit, convert to Open API 3, you can also use this to convert from YAML to JSON)
|
|
11
|
+
- Unsupported:
|
|
12
|
+
- Swagger API version 2
|
|
13
|
+
- YAML spec files
|
|
14
|
+
- open API specs with multiple server URLs, manually edit the file to set your desired server to the first in the array
|
|
15
|
+
- recursive schema references
|
|
16
|
+
- external schema references
|
|
17
|
+
- schema references that target nested components
|
|
18
|
+
- Authentication
|
|
19
|
+
- Unsupported:
|
|
20
|
+
- generation of Auth type
|
|
21
|
+
- handlers utilising the auth token in handlers
|
|
22
|
+
- Input/output types:
|
|
23
|
+
- Supported:
|
|
24
|
+
- Primitive types: number, string, boolean
|
|
25
|
+
- Objects
|
|
26
|
+
- 2XX response schemas
|
|
27
|
+
- Empty input/output
|
|
28
|
+
- Unsupported:
|
|
29
|
+
- enum types
|
|
30
|
+
- array types
|
|
31
|
+
- non 2XX response schemas
|
|
32
|
+
- Request/Response types:
|
|
33
|
+
- Supported:
|
|
34
|
+
- Json request/response
|
|
35
|
+
- Unsupported:
|
|
36
|
+
- xml request/response
|
|
37
|
+
- text request/response
|
|
38
|
+
- file request/response
|
|
39
|
+
- form request/response
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { OpenAPISchema, Parameter, Path } from './OpenApiTypeDescriptors';
|
|
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>;
|
|
5
|
+
//# sourceMappingURL=OpenApiCodecs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parameterSchemaCodec = exports.pathCodec = exports.openApiSpecCodec = void 0;
|
|
4
|
+
const TypeCodec_1 = require("@trayio/commons/codec/TypeCodec");
|
|
5
|
+
const OpenApiTypeDescriptors_1 = require("./OpenApiTypeDescriptors");
|
|
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);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as TE from 'fp-ts/TaskEither';
|
|
2
|
+
import { FileStorage } from '@trayio/commons/file/File';
|
|
3
|
+
import { Generator } from '@trayio/generator/generator/Generator';
|
|
4
|
+
import { BuildConnectorResponse } from './OpenApiTypeDescriptors';
|
|
5
|
+
export declare class OpenApiSchemaImporter {
|
|
6
|
+
private generator;
|
|
7
|
+
private fileStorage;
|
|
8
|
+
constructor(generator: Generator, fileStorage: FileStorage);
|
|
9
|
+
buildConnector(openApiSpecPath: string, connectorName: string): TE.TaskEither<Error, BuildConnectorResponse>;
|
|
10
|
+
private generateOperationFromPath;
|
|
11
|
+
private decodeOperation;
|
|
12
|
+
private getOpenApiSpec;
|
|
13
|
+
private generateHandlerFilesAndOperationJson;
|
|
14
|
+
private generateConnectorDirectory;
|
|
15
|
+
private generateOperationDirectory;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=OpenApiSchemaImporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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;AAGlE,OAAO,EAEN,sBAAsB,EAMtB,MAAM,0BAA0B,CAAC;AAalC,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,sBAAsB,CAAC;IAoD/C,OAAO,CAAC,yBAAyB;IAyDjC,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,cAAc;IAoCtB,OAAO,CAAC,oCAAoC;IAgF5C,OAAO,CAAC,0BAA0B;IAwBlC,OAAO,CAAC,0BAA0B;CAclC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.OpenApiSchemaImporter = void 0;
|
|
27
|
+
const TE = __importStar(require("fp-ts/TaskEither"));
|
|
28
|
+
const E = __importStar(require("fp-ts/Either"));
|
|
29
|
+
const O = __importStar(require("fp-ts/Option"));
|
|
30
|
+
const function_1 = require("fp-ts/function");
|
|
31
|
+
const Array_1 = require("fp-ts/Array");
|
|
32
|
+
const Apply_1 = require("fp-ts/Apply");
|
|
33
|
+
const json_ref_resolver_1 = require("@stoplight/json-ref-resolver");
|
|
34
|
+
const StringExtensions_1 = require("@trayio/commons/string/StringExtensions");
|
|
35
|
+
const lodash_1 = require("lodash");
|
|
36
|
+
const BufferExtensions_1 = require("@trayio/commons/buffer/BufferExtensions");
|
|
37
|
+
const stream_1 = require("stream");
|
|
38
|
+
const OpenApiCodecs_1 = require("./OpenApiCodecs");
|
|
39
|
+
const GenerateHandler_1 = require("./file-generators/GenerateHandler");
|
|
40
|
+
const GenerateOutput_1 = require("./file-generators/types/GenerateOutput");
|
|
41
|
+
const GenerateInputTypes_1 = require("./file-generators/types/GenerateInputTypes");
|
|
42
|
+
const GenerateHandlerTest_1 = require("./file-generators/GenerateHandlerTest");
|
|
43
|
+
const GenerateOperationJson_1 = require("./file-generators/GenerateOperationJson");
|
|
44
|
+
const GenerateInputSchema_1 = require("./file-generators/types/GenerateInputSchema");
|
|
45
|
+
const OpenApiSchemaTransformer_1 = require("./OpenApiSchemaTransformer");
|
|
46
|
+
class OpenApiSchemaImporter {
|
|
47
|
+
constructor(generator, fileStorage) {
|
|
48
|
+
this.generator = generator;
|
|
49
|
+
this.fileStorage = fileStorage;
|
|
50
|
+
}
|
|
51
|
+
buildConnector(openApiSpecPath, connectorName) {
|
|
52
|
+
return (0, function_1.pipe)(this.generateConnectorDirectory(connectorName), TE.bindTo('connectorPath'), TE.bind('openApiSpec', () => this.getOpenApiSpec(openApiSpecPath)), TE.bind('paths', ({ openApiSpec }) => {
|
|
53
|
+
if (openApiSpec.paths === undefined) {
|
|
54
|
+
return TE.left(new Error('OpenAPI spec does not contain any paths'));
|
|
55
|
+
}
|
|
56
|
+
return TE.right(Object.keys(openApiSpec.paths).map((path) => ({
|
|
57
|
+
path,
|
|
58
|
+
routes: Object.keys(openApiSpec.paths[path]).map((route) => ({
|
|
59
|
+
method: route,
|
|
60
|
+
path: openApiSpec.paths[path][route],
|
|
61
|
+
})),
|
|
62
|
+
})));
|
|
63
|
+
}), TE.chain(({ openApiSpec, connectorPath, paths }) => (0, Array_1.traverse)(TE.ApplicativeSeq)((path) => this.generateOperationFromPath(path, connectorPath, openApiSpec.servers[0].url, connectorName))(paths)), TE.map((operation) => {
|
|
64
|
+
const flatOperations = operation.flat();
|
|
65
|
+
const buildConnectorResponse = flatOperations.reduce((acc, curr) => {
|
|
66
|
+
if (curr.tag === 'error') {
|
|
67
|
+
return Object.assign(Object.assign({}, acc), { errors: [...acc.errors, curr] });
|
|
68
|
+
}
|
|
69
|
+
return Object.assign(Object.assign({}, acc), { successes: [...acc.successes, curr] });
|
|
70
|
+
}, { successes: [], errors: [] });
|
|
71
|
+
return buildConnectorResponse;
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
generateOperationFromPath(path, connectorPath, baseUrl, connectorName) {
|
|
75
|
+
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.fromEither((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)), TE.map(() => ({
|
|
76
|
+
tag: 'success',
|
|
77
|
+
httpMethod: route.method,
|
|
78
|
+
path: path.path,
|
|
79
|
+
})), TE.orElseW((error) => TE.right({
|
|
80
|
+
tag: 'error',
|
|
81
|
+
httpMethod: route.method,
|
|
82
|
+
path: path.path,
|
|
83
|
+
errorMessage: error.message,
|
|
84
|
+
}))))(path.routes));
|
|
85
|
+
}
|
|
86
|
+
decodeOperation(path, httpPath, method) {
|
|
87
|
+
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}`)));
|
|
88
|
+
}
|
|
89
|
+
getOpenApiSpec(openApiSpecPath) {
|
|
90
|
+
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(() => {
|
|
91
|
+
const resolver = new json_ref_resolver_1.Resolver({});
|
|
92
|
+
const resolvedOpenApiSpec = resolver.resolve(openApiSpec, {});
|
|
93
|
+
return resolvedOpenApiSpec;
|
|
94
|
+
}, (reason) => new Error(`Failed to resolve references in schema: ${reason}`))), TE.chain((openApiSpec) => TE.fromEither((0, OpenApiSchemaTransformer_1.mergePathLevelParamsIntoHttpMethod)(openApiSpec.result))));
|
|
95
|
+
}
|
|
96
|
+
generateHandlerFilesAndOperationJson(method, path, operationPath, baseUrl, httpPath, connectorName, input, output) {
|
|
97
|
+
const writeFile = (content, fileName) => this.fileStorage.write({
|
|
98
|
+
content: stream_1.Readable.from(content),
|
|
99
|
+
key: `${operationPath}/${fileName}`,
|
|
100
|
+
metadata: { name: fileName },
|
|
101
|
+
}, O.none);
|
|
102
|
+
const operationName = path.operationId;
|
|
103
|
+
const operationFileGenerationTasks = {
|
|
104
|
+
handler: (0, function_1.pipe)(TE.fromEither((0, GenerateHandler_1.generateHandler)({
|
|
105
|
+
connectorNamePascalCase: StringExtensions_1.StringExtensions.pascalCase(connectorName),
|
|
106
|
+
operationNameCamelCase: (0, lodash_1.camelCase)(operationName),
|
|
107
|
+
operationNamePascalCase: StringExtensions_1.StringExtensions.pascalCase(operationName),
|
|
108
|
+
httpMethod: method,
|
|
109
|
+
baseUrl,
|
|
110
|
+
httpPath,
|
|
111
|
+
input,
|
|
112
|
+
})),
|
|
113
|
+
// TODO: Why does this throw unhelpful errors?
|
|
114
|
+
TE.chain((handlerInput) => writeFile(handlerInput, 'handler.ts'))),
|
|
115
|
+
handlerTest: (0, function_1.pipe)(TE.fromEither((0, GenerateHandlerTest_1.generateHandlerTest)({
|
|
116
|
+
operationNameCamelCase: (0, lodash_1.camelCase)(operationName),
|
|
117
|
+
input,
|
|
118
|
+
output,
|
|
119
|
+
})), TE.chain((handlerInput) => writeFile(handlerInput, 'handler.test.ts'))),
|
|
120
|
+
generateOutputType: (0, function_1.pipe)((0, GenerateOutput_1.generateOutputTypes)(operationName, output), TE.chain((outputType) => writeFile(outputType, 'output.ts'))),
|
|
121
|
+
generateInputType: (0, function_1.pipe)((0, GenerateInputTypes_1.generateInputTypes)(operationName, input), TE.chain((inputType) => writeFile(inputType, 'input.ts'))),
|
|
122
|
+
operationJson: (0, GenerateOperationJson_1.generateOperationJson)(this.fileStorage, operationPath, operationName, (0, lodash_1.kebabCase)(operationName), path.description),
|
|
123
|
+
};
|
|
124
|
+
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));
|
|
125
|
+
}
|
|
126
|
+
generateConnectorDirectory(connectorName) {
|
|
127
|
+
return (0, function_1.pipe)(TE.right({
|
|
128
|
+
connectorNameTitleCase: StringExtensions_1.StringExtensions.titleCase(connectorName),
|
|
129
|
+
connectorNameKebabCase: (0, lodash_1.kebabCase)(connectorName),
|
|
130
|
+
connectorNamePascalCase: StringExtensions_1.StringExtensions.pascalCase(connectorName),
|
|
131
|
+
connectorNameCamelCase: (0, lodash_1.camelCase)(connectorName),
|
|
132
|
+
}), TE.chain((parameters) => this.generator.generate(`${__dirname}/templates/connector-template.zip`, process.cwd(), parameters)), TE.map(() => `/${(0, lodash_1.kebabCase)(connectorName)}`), TE.mapLeft((error) => new Error(`Failed to generate connector directory: ${error}`)));
|
|
133
|
+
}
|
|
134
|
+
generateOperationDirectory(connectorPath, operationName) {
|
|
135
|
+
return (0, function_1.pipe)(TE.tryCatch(this.fileStorage.createDirectory(`${connectorPath}/src/${(0, lodash_1.kebabCase)(operationName)}`), (error) => new Error(`Failed to create operation directory: ${error}`)), TE.map(() => `${connectorPath}/src/${(0, lodash_1.kebabCase)(operationName)}`));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.OpenApiSchemaImporter = OpenApiSchemaImporter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenApiSchemaImporter.test.d.ts","sourceRoot":"","sources":["../src/OpenApiSchemaImporter.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
const NodeFsGenerator_1 = require("@trayio/generator/generator/NodeFsGenerator");
|
|
36
|
+
const FakeFileStorage_1 = require("@trayio/commons/file/FakeFileStorage");
|
|
37
|
+
const stream_1 = require("stream");
|
|
38
|
+
const E = __importStar(require("fp-ts/Either"));
|
|
39
|
+
const fs = __importStar(require("fs-extra"));
|
|
40
|
+
const OpenApiSchemaImporter_1 = require("./OpenApiSchemaImporter");
|
|
41
|
+
const openApiSpec = __importStar(require("./test-openapi-spec.json"));
|
|
42
|
+
describe('openApiSchemaImporter', () => {
|
|
43
|
+
const generator = new NodeFsGenerator_1.NodeFsGenerator();
|
|
44
|
+
const fileStorage = new FakeFileStorage_1.FakeFileStorage();
|
|
45
|
+
const openApiSchemaImporter = new OpenApiSchemaImporter_1.OpenApiSchemaImporter(generator, fileStorage);
|
|
46
|
+
let result;
|
|
47
|
+
const spec = 'test-openapi-spec.json';
|
|
48
|
+
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
fileStorage.write({
|
|
50
|
+
key: `${__dirname}/${spec}`,
|
|
51
|
+
metadata: { name: spec },
|
|
52
|
+
content: stream_1.Readable.from(Buffer.from(JSON.stringify(openApiSpec))),
|
|
53
|
+
});
|
|
54
|
+
result = yield openApiSchemaImporter.buildConnector(`${__dirname}/${spec}`, 'testConnector')();
|
|
55
|
+
}));
|
|
56
|
+
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
+
yield fs.rm(`${process.cwd()}/test/`, { recursive: true, force: true });
|
|
58
|
+
}));
|
|
59
|
+
it('should import successfully', () => {
|
|
60
|
+
const buildConnectorResponse = E.getOrElse((error) => {
|
|
61
|
+
console.error(error);
|
|
62
|
+
throw new Error('Should have been right');
|
|
63
|
+
})(result);
|
|
64
|
+
expect(buildConnectorResponse.successes.length).toEqual(1);
|
|
65
|
+
expect(buildConnectorResponse.errors.length).toEqual(1);
|
|
66
|
+
});
|
|
67
|
+
it('should generate a operation handler', () => {
|
|
68
|
+
expect(fileStorage.files.has(`/test-connector/src/get-post/handler.ts`)).toEqual(true);
|
|
69
|
+
});
|
|
70
|
+
it('should generate an operation handler test', () => {
|
|
71
|
+
expect(fileStorage.files.has(`/test-connector/src/get-post/handler.test.ts`)).toEqual(true);
|
|
72
|
+
});
|
|
73
|
+
it('should generate an operation.json', () => {
|
|
74
|
+
expect(fileStorage.files.has(`/test-connector/src/get-post/operation.json`)).toEqual(true);
|
|
75
|
+
});
|
|
76
|
+
it('should generate an output.ts', () => {
|
|
77
|
+
expect(fileStorage.files.has(`/test-connector/src/get-post/output.ts`)).toEqual(true);
|
|
78
|
+
});
|
|
79
|
+
it('should generate a operation directory', () => {
|
|
80
|
+
expect(fileStorage.files.has(`/test-connector/src/get-post`)).toEqual(true);
|
|
81
|
+
});
|
|
82
|
+
it('should not generate a operation directory when failing to decode', () => {
|
|
83
|
+
expect(fileStorage.files.has(`/test-connector/src/update-post`)).toEqual(false);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as E from 'fp-ts/Either';
|
|
2
|
+
import { BaseOpenApiSpec } from './OpenApiTypeDescriptors';
|
|
3
|
+
export declare const isObject: (value: unknown) => value is Record<string, unknown>;
|
|
4
|
+
export declare const isObjectWithParameters: (value: unknown) => value is Record<string, unknown> & {
|
|
5
|
+
parameters: unknown[];
|
|
6
|
+
};
|
|
7
|
+
export declare const getMergedParameters: (pathValue: Record<string, unknown>, httpMethodValue: Record<string, unknown>) => unknown[];
|
|
8
|
+
export declare const mergePathLevelParamsIntoHttpMethod: (openApiSpec: BaseOpenApiSpec) => E.Either<Error, BaseOpenApiSpec>;
|
|
9
|
+
//# sourceMappingURL=OpenApiSchemaTransformer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenApiSchemaTransformer.d.ts","sourceRoot":"","sources":["../src/OpenApiSchemaTransformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,eAAO,MAAM,QAAQ,UAAW,OAAO,qCACK,CAAC;AAE7C,eAAO,MAAM,sBAAsB,UAC3B,OAAO;gBACqC,OAAO,EAAE;CACpB,CAAC;AAE1C,eAAO,MAAM,mBAAmB,cACpB,OAAO,MAAM,EAAE,OAAO,CAAC,mBACjB,OAAO,MAAM,EAAE,OAAO,CAAC,KACtC,OAAO,EAcT,CAAC;AAEF,eAAO,MAAM,kCAAkC,gBACjC,eAAe,KAC1B,EAAE,MAAM,CAAC,KAAK,EAAE,eAAe,CAkCjC,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.mergePathLevelParamsIntoHttpMethod = exports.getMergedParameters = exports.isObjectWithParameters = exports.isObject = void 0;
|
|
27
|
+
const E = __importStar(require("fp-ts/Either"));
|
|
28
|
+
const isObject = (value) => typeof value === 'object' && value !== null;
|
|
29
|
+
exports.isObject = isObject;
|
|
30
|
+
const isObjectWithParameters = (value) => (0, exports.isObject)(value) && 'parameters' in value;
|
|
31
|
+
exports.isObjectWithParameters = isObjectWithParameters;
|
|
32
|
+
const getMergedParameters = (pathValue, httpMethodValue) => {
|
|
33
|
+
if (!Array.isArray(pathValue.parameters)) {
|
|
34
|
+
throw new Error('Path parameters is not an array');
|
|
35
|
+
}
|
|
36
|
+
// if the method contains existing parameters, we merge them with the path parameters
|
|
37
|
+
if ('parameters' in httpMethodValue &&
|
|
38
|
+
Array.isArray(httpMethodValue.parameters)) {
|
|
39
|
+
return [...httpMethodValue.parameters, ...pathValue.parameters];
|
|
40
|
+
}
|
|
41
|
+
return pathValue.parameters;
|
|
42
|
+
};
|
|
43
|
+
exports.getMergedParameters = getMergedParameters;
|
|
44
|
+
const mergePathLevelParamsIntoHttpMethod = (openApiSpec) => {
|
|
45
|
+
const paths = Object.entries(openApiSpec.paths).reduce((pathAcc, [pathName, pathValue]) => {
|
|
46
|
+
// if the path doesn't contain top level params, we just return it
|
|
47
|
+
if (!(0, exports.isObjectWithParameters)(pathValue)) {
|
|
48
|
+
pathAcc[pathName] = pathValue;
|
|
49
|
+
return pathAcc;
|
|
50
|
+
}
|
|
51
|
+
const updatedPathValue = Object.entries(pathValue).reduce((methodAcc, [httpMethodName, httpMethodValue]) => {
|
|
52
|
+
if (!(0, exports.isObject)(httpMethodValue)) {
|
|
53
|
+
throw new Error('Http method value is not an object');
|
|
54
|
+
}
|
|
55
|
+
// we skip adding the parameters object to the path object
|
|
56
|
+
if (httpMethodName === 'parameters') {
|
|
57
|
+
return methodAcc;
|
|
58
|
+
}
|
|
59
|
+
const parameters = (0, exports.getMergedParameters)(pathValue, httpMethodValue);
|
|
60
|
+
methodAcc[httpMethodName] = Object.assign(Object.assign({}, httpMethodValue), { parameters });
|
|
61
|
+
return methodAcc;
|
|
62
|
+
}, {});
|
|
63
|
+
pathAcc[pathName] = updatedPathValue;
|
|
64
|
+
return pathAcc;
|
|
65
|
+
}, {});
|
|
66
|
+
return E.right(Object.assign(Object.assign({}, openApiSpec), { paths }));
|
|
67
|
+
};
|
|
68
|
+
exports.mergePathLevelParamsIntoHttpMethod = mergePathLevelParamsIntoHttpMethod;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenApiSchemaTransformer.test.d.ts","sourceRoot":"","sources":["../src/OpenApiSchemaTransformer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const E = __importStar(require("fp-ts/Either"));
|
|
27
|
+
const OpenApiSchemaTransformer_1 = require("./OpenApiSchemaTransformer");
|
|
28
|
+
describe('mergePathLevelParamsIntoHttpMethod', () => {
|
|
29
|
+
it('should merge path level parameters into HTTP methods', () => {
|
|
30
|
+
const openApiSpec = {
|
|
31
|
+
openapi: '3.0.0',
|
|
32
|
+
info: {
|
|
33
|
+
version: '1.0.0',
|
|
34
|
+
title: 'JSON Placeholder API',
|
|
35
|
+
description: 'See https://jsonplaceholder.typicode.com/',
|
|
36
|
+
},
|
|
37
|
+
servers: [
|
|
38
|
+
{
|
|
39
|
+
url: 'https://jsonplaceholder.typicode.com',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
paths: {
|
|
43
|
+
'/path': {
|
|
44
|
+
parameters: [{ name: 'param1', in: 'query', required: false }],
|
|
45
|
+
get: {
|
|
46
|
+
parameters: [{ name: 'param2', in: 'query', required: true }],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
const result = (0, OpenApiSchemaTransformer_1.mergePathLevelParamsIntoHttpMethod)(openApiSpec);
|
|
52
|
+
E.fold((error) => {
|
|
53
|
+
throw new Error(`Test failed with error: ${error.message}`);
|
|
54
|
+
}, (updatedOpenApiSpec) => {
|
|
55
|
+
expect(updatedOpenApiSpec.paths['/path'].get.parameters).toEqual([
|
|
56
|
+
{ name: 'param2', in: 'query', required: true },
|
|
57
|
+
{ name: 'param1', in: 'query', required: false },
|
|
58
|
+
]);
|
|
59
|
+
})(result);
|
|
60
|
+
});
|
|
61
|
+
it('should return the original spec if no top level parameters', () => {
|
|
62
|
+
const openApiSpec = {
|
|
63
|
+
openapi: '3.0.0',
|
|
64
|
+
info: {
|
|
65
|
+
version: '1.0.0',
|
|
66
|
+
title: 'JSON Placeholder API',
|
|
67
|
+
description: 'See https://jsonplaceholder.typicode.com/',
|
|
68
|
+
},
|
|
69
|
+
servers: [
|
|
70
|
+
{
|
|
71
|
+
url: 'https://jsonplaceholder.typicode.com',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
paths: {
|
|
75
|
+
'/path': {
|
|
76
|
+
get: {
|
|
77
|
+
parameters: [{ name: 'param2', in: 'query', required: true }],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
const result = (0, OpenApiSchemaTransformer_1.mergePathLevelParamsIntoHttpMethod)(openApiSpec);
|
|
83
|
+
E.fold((error) => {
|
|
84
|
+
throw new Error(`Test failed with error: ${error.message}`);
|
|
85
|
+
}, (updatedOpenApiSpec) => {
|
|
86
|
+
expect(updatedOpenApiSpec).toEqual(openApiSpec);
|
|
87
|
+
})(result);
|
|
88
|
+
});
|
|
89
|
+
it('should add path level parameters into HTTP methods, if no method params already exist', () => {
|
|
90
|
+
const openApiSpec = {
|
|
91
|
+
openapi: '3.0.0',
|
|
92
|
+
info: {
|
|
93
|
+
version: '1.0.0',
|
|
94
|
+
title: 'JSON Placeholder API',
|
|
95
|
+
description: 'See https://jsonplaceholder.typicode.com/',
|
|
96
|
+
},
|
|
97
|
+
servers: [
|
|
98
|
+
{
|
|
99
|
+
url: 'https://jsonplaceholder.typicode.com',
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
paths: {
|
|
103
|
+
'/path': {
|
|
104
|
+
parameters: [{ name: 'param1', in: 'query', required: false }],
|
|
105
|
+
get: {},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
const result = (0, OpenApiSchemaTransformer_1.mergePathLevelParamsIntoHttpMethod)(openApiSpec);
|
|
110
|
+
E.fold((error) => {
|
|
111
|
+
throw new Error(`Test failed with error: ${error.message}`);
|
|
112
|
+
}, (updatedOpenApiSpec) => {
|
|
113
|
+
expect(updatedOpenApiSpec.paths['/path'].get.parameters).toEqual([
|
|
114
|
+
{ name: 'param1', in: 'query', required: false },
|
|
115
|
+
]);
|
|
116
|
+
})(result);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import * as t from 'io-ts';
|
|
2
|
+
import * as O from 'fp-ts/Option';
|
|
3
|
+
export type FlatPath = {
|
|
4
|
+
path: string;
|
|
5
|
+
routes: {
|
|
6
|
+
method: OpenApiHttpMethod;
|
|
7
|
+
path: unknown;
|
|
8
|
+
}[];
|
|
9
|
+
};
|
|
10
|
+
export type Server = {
|
|
11
|
+
url: string;
|
|
12
|
+
};
|
|
13
|
+
export type BaseOpenApiSpec = {
|
|
14
|
+
openapi: string;
|
|
15
|
+
info: {
|
|
16
|
+
version: string;
|
|
17
|
+
title: string;
|
|
18
|
+
description: string;
|
|
19
|
+
};
|
|
20
|
+
servers: Server[];
|
|
21
|
+
paths: Record<string, Record<string, unknown>>;
|
|
22
|
+
};
|
|
23
|
+
export type BaseOperation = {
|
|
24
|
+
httpMethod: OpenApiHttpMethod;
|
|
25
|
+
path: string;
|
|
26
|
+
};
|
|
27
|
+
export type OperationError = BaseOperation & {
|
|
28
|
+
tag: 'error';
|
|
29
|
+
errorMessage: string;
|
|
30
|
+
};
|
|
31
|
+
export type OperationSuccess = BaseOperation & {
|
|
32
|
+
tag: 'success';
|
|
33
|
+
};
|
|
34
|
+
export type Operation = OperationError | OperationSuccess;
|
|
35
|
+
export type BuildConnectorResponse = {
|
|
36
|
+
successes: OperationSuccess[];
|
|
37
|
+
errors: OperationError[];
|
|
38
|
+
};
|
|
39
|
+
export type Path = {
|
|
40
|
+
description: string;
|
|
41
|
+
tags: O.Option<string[]>;
|
|
42
|
+
operationId: string;
|
|
43
|
+
parameters: O.Option<Parameter[]>;
|
|
44
|
+
requestBody: O.Option<RequestBody>;
|
|
45
|
+
responses: O.Option<Responses>;
|
|
46
|
+
};
|
|
47
|
+
export type Parameter = {
|
|
48
|
+
name: string;
|
|
49
|
+
in: string;
|
|
50
|
+
description: string;
|
|
51
|
+
required: O.Option<boolean>;
|
|
52
|
+
schema: SchemaObject;
|
|
53
|
+
};
|
|
54
|
+
export type RequestBody = {
|
|
55
|
+
content: Record<string, MediaTypeObject>;
|
|
56
|
+
};
|
|
57
|
+
export interface MediaTypeObject {
|
|
58
|
+
schema: O.Option<SchemaObject>;
|
|
59
|
+
}
|
|
60
|
+
export type Responses = Record<string, Response>;
|
|
61
|
+
export type Response = {
|
|
62
|
+
description: string;
|
|
63
|
+
content: O.Option<Record<string, MediaTypeObject>>;
|
|
64
|
+
};
|
|
65
|
+
export type OpenApiHttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
66
|
+
type ComponentSchema = {
|
|
67
|
+
schemas: O.Option<Record<string, SchemaObject>>;
|
|
68
|
+
};
|
|
69
|
+
export type OpenAPISchema = {
|
|
70
|
+
openapi: string;
|
|
71
|
+
info: {
|
|
72
|
+
title: string;
|
|
73
|
+
description: string;
|
|
74
|
+
version: string;
|
|
75
|
+
};
|
|
76
|
+
servers: {
|
|
77
|
+
url: string;
|
|
78
|
+
}[];
|
|
79
|
+
paths: Record<string, Partial<Record<OpenApiHttpMethod, Path>>>;
|
|
80
|
+
components: ComponentSchema;
|
|
81
|
+
};
|
|
82
|
+
export type SchemaObject = ArraySchemaObject | NonArraySchemaObject;
|
|
83
|
+
export interface ArraySchemaObject extends BaseSchemaObject {
|
|
84
|
+
type: 'array';
|
|
85
|
+
items: SchemaObject;
|
|
86
|
+
}
|
|
87
|
+
export type NonArraySchemaObjectType = 'boolean' | 'object' | 'number' | 'string' | 'integer';
|
|
88
|
+
export interface NonArraySchemaObject extends BaseSchemaObject {
|
|
89
|
+
type: O.Option<NonArraySchemaObjectType>;
|
|
90
|
+
}
|
|
91
|
+
export type BaseSchemaObject = {
|
|
92
|
+
title: O.Option<string>;
|
|
93
|
+
additionalProperties: O.Option<boolean | SchemaObject>;
|
|
94
|
+
properties: O.Option<Record<string, SchemaObject>>;
|
|
95
|
+
required: O.Option<string[]>;
|
|
96
|
+
allOf: O.Option<SchemaObject[]>;
|
|
97
|
+
oneOf: O.Option<SchemaObject[]>;
|
|
98
|
+
anyOf: O.Option<SchemaObject[]>;
|
|
99
|
+
not: O.Option<SchemaObject>;
|
|
100
|
+
in: O.Option<string>;
|
|
101
|
+
};
|
|
102
|
+
export declare const baseSchemaObjectSchemaTypeDescriptor: t.Type<BaseSchemaObject, unknown>;
|
|
103
|
+
export declare const schemaObjectTypeDescriptor: t.Type<SchemaObject, unknown>;
|
|
104
|
+
export declare const schemaObjectTypeCodec: import("commons/dist/codec/Codec").Codec<SchemaObject>;
|
|
105
|
+
export declare const parameterSchemaTypeDescriptor: t.Type<Parameter, unknown>;
|
|
106
|
+
export declare const openApiSpecPathTypeDescriptor: t.Type<Path, unknown>;
|
|
107
|
+
export declare const openApiSpecTypeDescriptor: t.Type<OpenAPISchema, unknown>;
|
|
108
|
+
export {};
|
|
109
|
+
//# sourceMappingURL=OpenApiTypeDescriptors.d.ts.map
|