@trayio/tray-openapi 2.6.0 → 2.7.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.
@@ -0,0 +1,11 @@
1
+ import { JSONSchema4 } from 'json-schema';
2
+ import * as E from 'fp-ts/Either';
3
+ type Prop = Record<string, JSONSchema4>;
4
+ export type GenerateHandlerTestInput = {
5
+ operationNameCamelCase: string;
6
+ input: Prop[];
7
+ output: Prop[];
8
+ };
9
+ export declare const generateHandlerTest: ({ operationNameCamelCase, input, output, }: GenerateHandlerTestInput) => E.Either<Error, string>;
10
+ export {};
11
+ //# sourceMappingURL=GenerateHandlerTest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenerateHandlerTest.d.ts","sourceRoot":"","sources":["../src/GenerateHandlerTest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAElC,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAExC,MAAM,MAAM,wBAAwB,GAAG;IACtC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,MAAM,EAAE,IAAI,EAAE,CAAC;CACf,CAAC;AA+CF,eAAO,MAAM,mBAAmB,+CAI7B,wBAAwB,KAAG,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CA2BlD,CAAC"}
@@ -0,0 +1,87 @@
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.generateHandlerTest = void 0;
27
+ const E = __importStar(require("fp-ts/Either"));
28
+ const getDefaultValue = (prop) => {
29
+ switch (prop.type) {
30
+ case 'string':
31
+ return `'test'`;
32
+ case 'number':
33
+ case 'integer':
34
+ return 2;
35
+ case 'boolean':
36
+ return 'true';
37
+ case 'array':
38
+ return prop.items ? `[${getDefaultValue(prop.items)}]` : '[]';
39
+ case 'object':
40
+ return prop.properties
41
+ ? handleInput(convertPropertiesToPropArray(prop.properties))
42
+ : '{}';
43
+ default:
44
+ return `'test_value'`;
45
+ }
46
+ };
47
+ const convertPropertiesToPropArray = (properties) => Object.entries(properties).map(([name, schema]) => ({
48
+ [name]: schema,
49
+ }));
50
+ const handleInput = (inputs) => {
51
+ const populatedTestInputs = inputs.map((prop) => {
52
+ const propName = Object.keys(prop)[0];
53
+ return `${propName}: ${getDefaultValue(prop[propName])}`;
54
+ });
55
+ return `{ ${populatedTestInputs.join(', ')} }`;
56
+ };
57
+ const handleOutput = (outputs) => {
58
+ const expectations = outputs.map((prop) => {
59
+ const propName = Object.keys(prop)[0];
60
+ return `expect(outputValue.${propName}).toEqual(${getDefaultValue(prop[propName])});`;
61
+ });
62
+ return expectations.join('\n');
63
+ };
64
+ const generateHandlerTest = ({ operationNameCamelCase, input, output, }) => E.tryCatch(() => `import { OperationHandlerTestSetup } from '@trayio/cdk-dsl/connector/operation/OperationHandlerTest';
65
+ import { OperationHandlerResult } from '@trayio/cdk-dsl/connector/operation/OperationHandler';
66
+ import { ${operationNameCamelCase}Handler } from './handler';
67
+ import '@trayio/cdk-runtime/connector/operation/OperationHandlerTestRunner';
68
+
69
+ OperationHandlerTestSetup.configureHandlerTest(${operationNameCamelCase}Handler, (handlerTest) =>
70
+ handlerTest
71
+ .usingHandlerContext('test')
72
+ .nothingBeforeAll()
73
+ .testCase('should ${operationNameCamelCase}', (testCase) =>
74
+ testCase
75
+ .givenNothing()
76
+ .when(() => (${handleInput(input)}))
77
+ .then(({ output }) => {
78
+ // console.log(output);
79
+ const outputValue =
80
+ OperationHandlerResult.getSuccessfulValueOrFail(output);
81
+ ${handleOutput(output)}
82
+ })
83
+ .finallyDoNothing()
84
+ )
85
+ .nothingAfterAll()
86
+ );`, (e) => new Error(`Failed to generate handler test: ${e}`));
87
+ exports.generateHandlerTest = generateHandlerTest;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=GenerateHandlerTest.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenerateHandlerTest.test.d.ts","sourceRoot":"","sources":["../src/GenerateHandlerTest.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,342 @@
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 GenerateHandlerTest_1 = require("./GenerateHandlerTest");
28
+ describe('GenerateHandlerTest', () => {
29
+ it('should generate a handler test with inputs and outputs', () => {
30
+ const input = {
31
+ operationNameCamelCase: 'getItem',
32
+ input: [
33
+ {
34
+ id: {
35
+ type: 'integer',
36
+ },
37
+ },
38
+ {
39
+ name: {
40
+ type: 'string',
41
+ },
42
+ },
43
+ ],
44
+ output: [
45
+ {
46
+ id: {
47
+ type: 'integer',
48
+ },
49
+ },
50
+ {
51
+ name: {
52
+ type: 'string',
53
+ },
54
+ },
55
+ ],
56
+ };
57
+ const result = (0, GenerateHandlerTest_1.generateHandlerTest)(input);
58
+ if (E.isLeft(result)) {
59
+ console.log(result.left);
60
+ throw new Error('Expected right');
61
+ }
62
+ expect(`import { OperationHandlerTestSetup } from '@trayio/cdk-dsl/connector/operation/OperationHandlerTest';
63
+ import { OperationHandlerResult } from '@trayio/cdk-dsl/connector/operation/OperationHandler';
64
+ import { getItemHandler } from './handler';
65
+ import '@trayio/cdk-runtime/connector/operation/OperationHandlerTestRunner';
66
+
67
+ OperationHandlerTestSetup.configureHandlerTest(getItemHandler, (handlerTest) =>
68
+ handlerTest
69
+ .usingHandlerContext('test')
70
+ .nothingBeforeAll()
71
+ .testCase('should ${input.operationNameCamelCase}', (testCase) =>
72
+ testCase
73
+ .givenNothing()
74
+ .when(() => ({ id: 2, name: 'test' }))
75
+ .then(({ output }) => {
76
+ // console.log(output);
77
+ const outputValue =
78
+ OperationHandlerResult.getSuccessfulValueOrFail(output);
79
+ expect(outputValue.id).toEqual(2);
80
+ expect(outputValue.name).toEqual('test');
81
+ })
82
+ .finallyDoNothing()
83
+ )
84
+ .nothingAfterAll()
85
+ );`.replace(/\s/g, '')).toEqual(result.right.replace(/\s/g, ''));
86
+ });
87
+ it('should generate a handler test with empty inputs', () => {
88
+ const input = {
89
+ operationNameCamelCase: 'getItem',
90
+ input: [],
91
+ output: [
92
+ {
93
+ success: {
94
+ type: 'boolean',
95
+ },
96
+ },
97
+ ],
98
+ };
99
+ const result = (0, GenerateHandlerTest_1.generateHandlerTest)(input);
100
+ if (E.isLeft(result)) {
101
+ console.log(result.left);
102
+ throw new Error('Expected right');
103
+ }
104
+ expect(`import { OperationHandlerTestSetup } from '@trayio/cdk-dsl/connector/operation/OperationHandlerTest';
105
+ import { OperationHandlerResult } from '@trayio/cdk-dsl/connector/operation/OperationHandler';
106
+ import { getItemHandler } from './handler';
107
+ import '@trayio/cdk-runtime/connector/operation/OperationHandlerTestRunner';
108
+
109
+ OperationHandlerTestSetup.configureHandlerTest(getItemHandler, (handlerTest) =>
110
+ handlerTest
111
+ .usingHandlerContext('test')
112
+ .nothingBeforeAll()
113
+ .testCase('should ${input.operationNameCamelCase}', (testCase) =>
114
+ testCase
115
+ .givenNothing()
116
+ .when(() => ({}))
117
+ .then(({ output }) => {
118
+ // console.log(output);
119
+ const outputValue =
120
+ OperationHandlerResult.getSuccessfulValueOrFail(output);
121
+ expect(outputValue.success).toEqual(true);
122
+ })
123
+ .finallyDoNothing()
124
+ )
125
+ .nothingAfterAll()
126
+ );`.replace(/\s/g, '')).toEqual(result.right.replace(/\s/g, ''));
127
+ });
128
+ it('should generate a handler test with a basic object input and output type', () => {
129
+ const input = {
130
+ operationNameCamelCase: 'createPerson',
131
+ input: [
132
+ {
133
+ metadata: {
134
+ type: 'object',
135
+ properties: {
136
+ name: {
137
+ type: 'string',
138
+ },
139
+ age: {
140
+ type: 'integer',
141
+ },
142
+ },
143
+ },
144
+ },
145
+ ],
146
+ output: [
147
+ {
148
+ parents: {
149
+ type: 'object',
150
+ properties: {
151
+ child: {
152
+ type: 'string',
153
+ },
154
+ },
155
+ },
156
+ },
157
+ ],
158
+ };
159
+ const result = (0, GenerateHandlerTest_1.generateHandlerTest)(input);
160
+ if (E.isLeft(result)) {
161
+ console.log(result.left);
162
+ throw new Error('Expected right');
163
+ }
164
+ expect(`import { OperationHandlerTestSetup } from '@trayio/cdk-dsl/connector/operation/OperationHandlerTest';
165
+ import { OperationHandlerResult } from '@trayio/cdk-dsl/connector/operation/OperationHandler';
166
+ import { createPersonHandler } from './handler';
167
+ import '@trayio/cdk-runtime/connector/operation/OperationHandlerTestRunner';
168
+
169
+ OperationHandlerTestSetup.configureHandlerTest(createPersonHandler, (handlerTest) =>
170
+ handlerTest
171
+ .usingHandlerContext('test')
172
+ .nothingBeforeAll()
173
+ .testCase('should ${input.operationNameCamelCase}', (testCase) =>
174
+ testCase
175
+ .givenNothing()
176
+ .when(() => ({ metadata: { name: 'test', age: 2 }}))
177
+ .then(({ output }) => {
178
+ // console.log(output);
179
+ const outputValue =
180
+ OperationHandlerResult.getSuccessfulValueOrFail(output);
181
+ expect(outputValue.parents).toEqual({child: 'test'});
182
+ })
183
+ .finallyDoNothing()
184
+ )
185
+ .nothingAfterAll()
186
+ );`.replace(/\s/g, '')).toEqual(result.right.replace(/\s/g, ''));
187
+ });
188
+ it('should generate a handler test with a basic array input and output type', () => {
189
+ const input = {
190
+ operationNameCamelCase: 'listItems',
191
+ input: [
192
+ {
193
+ ids: {
194
+ type: 'array',
195
+ items: {
196
+ type: 'integer',
197
+ },
198
+ },
199
+ },
200
+ ],
201
+ output: [
202
+ {
203
+ parents: {
204
+ type: 'array',
205
+ items: {
206
+ type: 'string',
207
+ },
208
+ },
209
+ },
210
+ ],
211
+ };
212
+ const result = (0, GenerateHandlerTest_1.generateHandlerTest)(input);
213
+ if (E.isLeft(result)) {
214
+ console.log(result.left);
215
+ throw new Error('Expected right');
216
+ }
217
+ expect(`import { OperationHandlerTestSetup } from '@trayio/cdk-dsl/connector/operation/OperationHandlerTest';
218
+ import { OperationHandlerResult } from '@trayio/cdk-dsl/connector/operation/OperationHandler';
219
+ import { listItemsHandler } from './handler';
220
+ import '@trayio/cdk-runtime/connector/operation/OperationHandlerTestRunner';
221
+
222
+ OperationHandlerTestSetup.configureHandlerTest(listItemsHandler, (handlerTest) =>
223
+ handlerTest
224
+ .usingHandlerContext('test')
225
+ .nothingBeforeAll()
226
+ .testCase('should ${input.operationNameCamelCase}', (testCase) =>
227
+ testCase
228
+ .givenNothing()
229
+ .when(() => ({ ids: [2] }))
230
+ .then(({ output }) => {
231
+ // console.log(output);
232
+ const outputValue =
233
+ OperationHandlerResult.getSuccessfulValueOrFail(output);
234
+ expect(outputValue.parents).toEqual(['test']);
235
+ })
236
+ .finallyDoNothing()
237
+ )
238
+ .nothingAfterAll()
239
+ );`.replace(/\s/g, '')).toEqual(result.right.replace(/\s/g, ''));
240
+ });
241
+ it('should generate a handler test with a complex object output type', () => {
242
+ const input = {
243
+ operationNameCamelCase: 'listItems',
244
+ input: [],
245
+ output: [
246
+ {
247
+ parents: {
248
+ type: 'object',
249
+ properties: {
250
+ child: {
251
+ type: 'string',
252
+ },
253
+ valueList: {
254
+ type: 'array',
255
+ items: {
256
+ type: 'string',
257
+ },
258
+ },
259
+ },
260
+ },
261
+ },
262
+ ],
263
+ };
264
+ const result = (0, GenerateHandlerTest_1.generateHandlerTest)(input);
265
+ if (E.isLeft(result)) {
266
+ console.log(result.left);
267
+ throw new Error('Expected right');
268
+ }
269
+ expect(`import { OperationHandlerTestSetup } from '@trayio/cdk-dsl/connector/operation/OperationHandlerTest';
270
+ import { OperationHandlerResult } from '@trayio/cdk-dsl/connector/operation/OperationHandler';
271
+ import { listItemsHandler } from './handler';
272
+ import '@trayio/cdk-runtime/connector/operation/OperationHandlerTestRunner';
273
+
274
+ OperationHandlerTestSetup.configureHandlerTest(listItemsHandler, (handlerTest) =>
275
+ handlerTest
276
+ .usingHandlerContext('test')
277
+ .nothingBeforeAll()
278
+ .testCase('should ${input.operationNameCamelCase}', (testCase) =>
279
+ testCase
280
+ .givenNothing()
281
+ .when(() => ({}))
282
+ .then(({ output }) => {
283
+ // console.log(output);
284
+ const outputValue =
285
+ OperationHandlerResult.getSuccessfulValueOrFail(output);
286
+ expect(outputValue.parents).toEqual({child: 'test', valueList: ['test']});
287
+ })
288
+ .finallyDoNothing()
289
+ )
290
+ .nothingAfterAll()
291
+ );`.replace(/\s/g, '')).toEqual(result.right.replace(/\s/g, ''));
292
+ });
293
+ it('should generate a handler test with a complex array output type', () => {
294
+ const input = {
295
+ operationNameCamelCase: 'listItems',
296
+ input: [],
297
+ output: [
298
+ {
299
+ parents: {
300
+ type: 'array',
301
+ items: {
302
+ type: 'object',
303
+ properties: {
304
+ child: {
305
+ type: 'string',
306
+ },
307
+ },
308
+ },
309
+ },
310
+ },
311
+ ],
312
+ };
313
+ const result = (0, GenerateHandlerTest_1.generateHandlerTest)(input);
314
+ if (E.isLeft(result)) {
315
+ console.log(result.left);
316
+ throw new Error('Expected right');
317
+ }
318
+ expect(`import { OperationHandlerTestSetup } from '@trayio/cdk-dsl/connector/operation/OperationHandlerTest';
319
+ import { OperationHandlerResult } from '@trayio/cdk-dsl/connector/operation/OperationHandler';
320
+ import { listItemsHandler } from './handler';
321
+ import '@trayio/cdk-runtime/connector/operation/OperationHandlerTestRunner';
322
+
323
+ OperationHandlerTestSetup.configureHandlerTest(listItemsHandler, (handlerTest) =>
324
+ handlerTest
325
+ .usingHandlerContext('test')
326
+ .nothingBeforeAll()
327
+ .testCase('should ${input.operationNameCamelCase}', (testCase) =>
328
+ testCase
329
+ .givenNothing()
330
+ .when(() => ({}))
331
+ .then(({ output }) => {
332
+ // console.log(output);
333
+ const outputValue =
334
+ OperationHandlerResult.getSuccessfulValueOrFail(output);
335
+ expect(outputValue.parents).toEqual([{child: 'test'}]);
336
+ })
337
+ .finallyDoNothing()
338
+ )
339
+ .nothingAfterAll()
340
+ );`.replace(/\s/g, '')).toEqual(result.right.replace(/\s/g, ''));
341
+ });
342
+ });
@@ -1,8 +1,10 @@
1
1
  import * as TE from 'fp-ts/TaskEither';
2
+ import { FileStorage } from '@trayio/commons/file/File';
2
3
  import { Generator } from '@trayio/generator/generator/Generator';
3
4
  export declare class OpenApiSchemaImporter {
4
5
  private generator;
5
- constructor(generator: Generator);
6
+ private fileStorage;
7
+ constructor(generator: Generator, fileStorage: FileStorage);
6
8
  buildConnector(openApiSpecPath: string, connectorName: string): TE.TaskEither<Error, undefined>;
7
9
  private generateOperationFromPath;
8
10
  private getOpenApiSpec;
@@ -1 +1 @@
1
- {"version":3,"file":"OpenApiSchemaImporter.d.ts","sourceRoot":"","sources":["../src/OpenApiSchemaImporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAQvC,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAclE,qBAAa,qBAAqB;IACrB,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAExC,cAAc,CACb,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,GACnB,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;IAoClC,OAAO,CAAC,yBAAyB;IA+BjC,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,mBAAmB;IAoC3B,OAAO,CAAC,0BAA0B;IAwBlC,OAAO,CAAC,0BAA0B;CAalC"}
1
+ {"version":3,"file":"OpenApiSchemaImporter.d.ts","sourceRoot":"","sources":["../src/OpenApiSchemaImporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAMvC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAelE,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;IAgClC,OAAO,CAAC,yBAAyB;IA8BjC,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,mBAAmB;IAoC3B,OAAO,CAAC,0BAA0B;IAwBlC,OAAO,CAAC,0BAA0B;CAclC"}
@@ -22,39 +22,52 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
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
+ };
25
34
  Object.defineProperty(exports, "__esModule", { value: true });
26
35
  exports.OpenApiSchemaImporter = void 0;
27
36
  const TE = __importStar(require("fp-ts/TaskEither"));
28
- const E = __importStar(require("fp-ts/Either"));
29
37
  const function_1 = require("fp-ts/function");
30
- const fse = __importStar(require("fs-extra"));
31
38
  const Array_1 = require("fp-ts/Array");
32
39
  const StringExtensions_1 = require("@trayio/commons/string/StringExtensions");
33
40
  const lodash_1 = require("lodash");
34
- const Task_1 = require("@trayio/commons/task/Task");
41
+ const stream_1 = require("stream");
35
42
  const OpenApiCodecs_1 = require("./OpenApiCodecs");
36
43
  const GenerateHandler_1 = require("./GenerateHandler");
37
44
  class OpenApiSchemaImporter {
38
- constructor(generator) {
45
+ constructor(generator, fileStorage) {
39
46
  this.generator = generator;
47
+ this.fileStorage = fileStorage;
40
48
  }
41
49
  buildConnector(openApiSpecPath, connectorName) {
42
- return (0, function_1.pipe)(this.generateConnectorDirectory(connectorName), TE.bindTo('connectorPath'), TE.bind('openApiSpec', () => (0, Task_1.createTaskEitherFromEither)(this.getOpenApiSpec(openApiSpecPath))), TE.bind('paths', ({ openApiSpec }) => TE.right(Object.keys(openApiSpec.paths).map((path) => ({
50
+ return (0, function_1.pipe)(this.generateConnectorDirectory(connectorName), TE.bindTo('connectorPath'), TE.bind('openApiSpec', () => this.getOpenApiSpec(openApiSpecPath)), TE.bind('paths', ({ openApiSpec }) => TE.right(Object.keys(openApiSpec.paths).map((path) => ({
43
51
  path,
44
52
  routes: Object.keys(openApiSpec.paths[path]).map((route) => ({
45
53
  method: route,
46
54
  path: openApiSpec.paths[path][route],
47
55
  })),
48
- })))), TE.map(({ openApiSpec, connectorPath, paths }) => (0, Array_1.traverse)(TE.ApplicativeSeq)((path) => (0, Task_1.createTaskEitherFromEither)(this.generateOperationFromPath(path, connectorPath, openApiSpec.servers[0].url, connectorName)))(paths)), TE.map(() => undefined));
56
+ })))), 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));
49
57
  }
50
58
  generateOperationFromPath(path, connectorPath, baseUrl, connectorName) {
51
- return (0, function_1.pipe)((0, Array_1.traverse)(E.Applicative)((route) => (0, function_1.pipe)(this.generateOperationDirectory(connectorPath, route.path.operationId), E.chain((operationPath) => this.generateHandlerFile(operationPath, route.method, baseUrl, path.path, connectorName, route.path.operationId)), E.map(() => undefined)))(path.routes), E.map(() => undefined));
59
+ return (0, function_1.pipe)((0, Array_1.traverse)(TE.ApplicativeSeq)((route) => (0, function_1.pipe)(this.generateOperationDirectory(connectorPath, route.path.operationId), TE.chain(() => this.generateHandlerFile(`${connectorPath}/src/${(0, lodash_1.kebabCase)(route.path.operationId)}`, route.method, baseUrl, path.path, connectorName, route.path.operationId))))(path.routes), TE.map(() => undefined));
52
60
  }
53
61
  getOpenApiSpec(openApiSpecPath) {
54
- return (0, function_1.pipe)(E.tryCatch(() => fse.readFileSync(openApiSpecPath, 'utf-8'), (error) => new Error(`Failed to read OpenAPI spec from path ${openApiSpecPath}: ${error}`)), E.chain((openApiSpec) => E.tryCatch(() => JSON.parse(openApiSpec), (error) => new Error(`Failed to parse OpenAPI spec as JSON from path ${openApiSpecPath}: ${error}`))), E.chain((openApiSpec) => OpenApiCodecs_1.openApiSpecCodec.decode(openApiSpec)));
62
+ return (0, function_1.pipe)(this.fileStorage.read(openApiSpecPath), TE.chain((openApiSpec) => TE.tryCatch(() => __awaiter(this, void 0, void 0, function* () { return JSON.parse(openApiSpec.content.read()); }), (error) => new Error(`Failed to parse OpenAPI spec as JSON from path ${openApiSpecPath}: ${error}`))), TE.chain((openApiSpec) => TE.fromEither(OpenApiCodecs_1.openApiSpecCodec.decode(openApiSpec))));
55
63
  }
56
64
  generateHandlerFile(operationPath, httpMethod, baseUrl, path, connectorName, operationName) {
57
- return (0, function_1.pipe)(E.right({
65
+ const writeHandler = (handler) => this.fileStorage.write({
66
+ content: stream_1.Readable.from(handler),
67
+ key: `${operationPath}/handler.ts`,
68
+ metadata: { name: 'handler.ts' },
69
+ });
70
+ const generateHandlerContent = (0, GenerateHandler_1.generateHandler)({
58
71
  connectorNamePascalCase: StringExtensions_1.StringExtensions.pascalCase(connectorName),
59
72
  operationNameCamelCase: (0, lodash_1.camelCase)(operationName),
60
73
  operationNamePascalCase: StringExtensions_1.StringExtensions.pascalCase(operationName),
@@ -62,9 +75,8 @@ class OpenApiSchemaImporter {
62
75
  baseUrl,
63
76
  path,
64
77
  input: [],
65
- }), E.chain((parameters) => (0, GenerateHandler_1.generateHandler)(parameters)), E.chain((handler) => E.tryCatch(() => {
66
- fse.writeFileSync(`${operationPath}/handler.ts`, handler, 'utf-8');
67
- }, (error) => new Error(`Failed to write handler to file system: ${error}`))), E.map(() => undefined), E.mapLeft((error) => new Error(`Failed to generate handler for operation: ${error}`)));
78
+ });
79
+ return (0, function_1.pipe)(TE.fromEither(generateHandlerContent), TE.chain(writeHandler), TE.mapLeft((error) => new Error(`Failed to generate handler for operation: ${error}`)), TE.map(() => undefined));
68
80
  }
69
81
  generateConnectorDirectory(connectorName) {
70
82
  return (0, function_1.pipe)(TE.right({
@@ -75,7 +87,7 @@ class OpenApiSchemaImporter {
75
87
  }), TE.chain((parameters) => this.generator.generate(`${__dirname}/templates/connector-template.zip`, `${process.cwd()}/test`, parameters)), TE.map(() => `${process.cwd()}/test/${(0, lodash_1.kebabCase)(connectorName)}`), TE.mapLeft((error) => new Error(`Failed to generate connector directory: ${error}`)));
76
88
  }
77
89
  generateOperationDirectory(connectorPath, operationName) {
78
- return (0, function_1.pipe)(E.tryCatch(() => fse.ensureDirSync(`${connectorPath}/src/${(0, lodash_1.kebabCase)(operationName)}`), (error) => new Error(`Failed to create operation directory: ${error}`)), E.map(() => `${connectorPath}/src/${(0, lodash_1.kebabCase)(operationName)}`));
90
+ 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)}`));
79
91
  }
80
92
  }
81
93
  exports.OpenApiSchemaImporter = OpenApiSchemaImporter;
@@ -1,4 +1,27 @@
1
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
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -10,12 +33,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
33
  };
11
34
  Object.defineProperty(exports, "__esModule", { value: true });
12
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 fs = __importStar(require("fs-extra"));
13
39
  const OpenApiSchemaImporter_1 = require("./OpenApiSchemaImporter");
40
+ const openApiSpec = __importStar(require("./single-get-openapi.json"));
14
41
  describe('openApiSchemaImporter', () => {
15
42
  const generator = new NodeFsGenerator_1.NodeFsGenerator();
16
- const openApiSchemaImporter = new OpenApiSchemaImporter_1.OpenApiSchemaImporter(generator);
17
- it('should decode the openApiSpec', () => __awaiter(void 0, void 0, void 0, function* () {
18
- const schema = yield openApiSchemaImporter.buildConnector(`${__dirname}/single-get-openapi.json`, 'testConnector')();
19
- expect(schema._tag).toEqual('Right');
43
+ const fileStorage = new FakeFileStorage_1.FakeFileStorage();
44
+ const openApiSchemaImporter = new OpenApiSchemaImporter_1.OpenApiSchemaImporter(generator, fileStorage);
45
+ let result;
46
+ beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
47
+ fileStorage.write({
48
+ key: `${__dirname}/single-get-openapi.json`,
49
+ metadata: { name: 'single-get-openapi.json' },
50
+ content: stream_1.Readable.from(JSON.stringify(openApiSpec)),
51
+ });
52
+ result = yield openApiSchemaImporter.buildConnector(`${__dirname}/single-get-openapi.json`, 'testConnector')();
53
+ }));
54
+ afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
55
+ yield fs.rm(`${process.cwd()}/test/`, { recursive: true, force: true });
20
56
  }));
57
+ it('should import successfully', () => {
58
+ expect(result._tag).toEqual('Right');
59
+ });
60
+ it('should generate a operation handler', () => {
61
+ expect(fileStorage.files.has(`${process.cwd()}/test/test-connector/src/get-post/handler.ts`)).toEqual(true);
62
+ });
63
+ it('should generate a operation directory', () => {
64
+ expect(fileStorage.files.has(`${process.cwd()}/test/test-connector/src/get-post`)).toEqual(true);
65
+ });
21
66
  });
@@ -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;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAClC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KACzB,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC,CAAC;AAEF,KAAK,SAAS,GAAG;IAChB,MAAM,EAAE,WAAW,GAAG,YAAY,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5E,KAAK,WAAW,GAAG;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACb,CAAC;CACF,CAAC;AAEF,KAAK,YAAY,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,KAAK,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,GAAG,YAAY,CAAC;AAEpE,KAAK,eAAe,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,YAAY,CAAC,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;KACZ,EAAE,CAAC;IACJ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAChE,UAAU,EAAE,eAAe,CAAC;CAC5B,CAAC;AAoEF,eAAO,MAAM,yBAAyB,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAWpE,CAAC"}
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;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAClC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KACzB,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC,CAAC;AAEF,KAAK,SAAS,GAAG;IAChB,MAAM,EAAE,WAAW,GAAG,YAAY,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5E,KAAK,WAAW,GAAG;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACb,CAAC;CACF,CAAC;AAEF,KAAK,YAAY,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,KAAK,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,GAAG,YAAY,CAAC;AAEpE,KAAK,eAAe,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,YAAY,CAAC,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;KACZ,EAAE,CAAC;IACJ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAChE,UAAU,EAAE,eAAe,CAAC;CAC5B,CAAC;AAsEF,eAAO,MAAM,yBAAyB,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAWpE,CAAC"}
@@ -27,6 +27,7 @@ exports.openApiSpecTypeDescriptor = 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
+ // Codecs
30
31
  const openApiSpecPropertySchemaTypeDescriptor = t.type({ type: t.string });
31
32
  const openApiSpecObjectSchemaTypeDescriptor = t.type({
32
33
  type: t.literal('object'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trayio/tray-openapi",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "Creating CDK Projects from OpenAPI 3.0 Schemas",
5
5
  "exports": {
6
6
  "./*": "./dist/*.js"