@flink-app/flink 0.4.5 → 0.4.7
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/src/FlinkApp.d.ts +6 -0
- package/dist/src/FlinkApp.js +33 -16
- package/dist/src/TypeScriptCompiler.js +12 -11
- package/dist/src/utils.d.ts +0 -10
- package/dist/src/utils.js +1 -81
- package/package.json +2 -2
- package/spec/mock-project/dist/src/handlers/GetCar.js +1 -1
- package/spec/mock-project/dist/src/handlers/GetCar2.js +1 -1
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +1 -1
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +1 -1
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +1 -1
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +1 -1
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +1 -1
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js +1 -1
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +1 -1
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +1 -1
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +1 -1
- package/spec/mock-project/dist/src/handlers/PostCar.js +1 -1
- package/spec/mock-project/dist/src/handlers/PutCar.js +1 -1
- package/spec/utils.spec.ts +1 -83
- package/src/FlinkApp.ts +37 -16
- package/src/TypeScriptCompiler.ts +9 -9
- package/src/utils.ts +0 -79
package/dist/src/FlinkApp.d.ts
CHANGED
|
@@ -107,6 +107,11 @@ export interface FlinkOptions {
|
|
|
107
107
|
*/
|
|
108
108
|
enabled?: boolean;
|
|
109
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* If true, the HTTP server will be disabled.
|
|
112
|
+
* Only useful when starting a Flink app for testing purposes.
|
|
113
|
+
*/
|
|
114
|
+
disableHttpServer?: boolean;
|
|
110
115
|
}
|
|
111
116
|
export interface HandlerConfig {
|
|
112
117
|
schema?: {
|
|
@@ -145,6 +150,7 @@ export declare class FlinkApp<C extends FlinkContext> {
|
|
|
145
150
|
private routingConfigured;
|
|
146
151
|
private jsonOptions?;
|
|
147
152
|
private schedulingOptions?;
|
|
153
|
+
private disableHttpServer;
|
|
148
154
|
private repos;
|
|
149
155
|
/**
|
|
150
156
|
* Internal cache used to track registered handlers and potentially any overlapping routes
|
package/dist/src/FlinkApp.js
CHANGED
|
@@ -93,6 +93,7 @@ var FlinkApp = /** @class */ (function () {
|
|
|
93
93
|
this.debug = false;
|
|
94
94
|
this.plugins = [];
|
|
95
95
|
this.routingConfigured = false;
|
|
96
|
+
this.disableHttpServer = false;
|
|
96
97
|
this.repos = {};
|
|
97
98
|
/**
|
|
98
99
|
* Internal cache used to track registered handlers and potentially any overlapping routes
|
|
@@ -108,6 +109,7 @@ var FlinkApp = /** @class */ (function () {
|
|
|
108
109
|
this.auth = opts.auth;
|
|
109
110
|
this.jsonOptions = opts.jsonOptions || { limit: "1mb" };
|
|
110
111
|
this.schedulingOptions = opts.scheduling;
|
|
112
|
+
this.disableHttpServer = !!opts.disableHttpServer;
|
|
111
113
|
}
|
|
112
114
|
Object.defineProperty(FlinkApp.prototype, "ctx", {
|
|
113
115
|
get: function () {
|
|
@@ -146,13 +148,18 @@ var FlinkApp = /** @class */ (function () {
|
|
|
146
148
|
if (this.isSchedulingEnabled) {
|
|
147
149
|
this.scheduler = new toad_scheduler_1.ToadScheduler();
|
|
148
150
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
this.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
else {
|
|
152
|
+
FlinkLog_1.log.info("🚫 Scheduling is disabled");
|
|
153
|
+
}
|
|
154
|
+
if (!this.disableHttpServer) {
|
|
155
|
+
this.expressApp = express_1.default();
|
|
156
|
+
this.expressApp.use(cors_1.default(this.corsOpts));
|
|
157
|
+
this.expressApp.use(body_parser_1.default.json(this.jsonOptions));
|
|
158
|
+
this.expressApp.use(function (req, res, next) {
|
|
159
|
+
req.reqId = uuid_1.v4();
|
|
160
|
+
next();
|
|
161
|
+
});
|
|
162
|
+
}
|
|
156
163
|
_i = 0, _b = this.plugins;
|
|
157
164
|
_c.label = 3;
|
|
158
165
|
case 3:
|
|
@@ -196,15 +203,23 @@ var FlinkApp = /** @class */ (function () {
|
|
|
196
203
|
// Register 404 with slight delay to allow all manually added routes to be added
|
|
197
204
|
// TODO: Is there a better solution to force this handler to always run last?
|
|
198
205
|
setTimeout(function () {
|
|
199
|
-
_this.
|
|
200
|
-
|
|
201
|
-
|
|
206
|
+
if (!_this.disableHttpServer) {
|
|
207
|
+
_this.expressApp.use(function (req, res, next) {
|
|
208
|
+
res.status(404).json(FlinkErrors_1.notFound());
|
|
209
|
+
});
|
|
210
|
+
}
|
|
202
211
|
_this.routingConfigured = true;
|
|
203
212
|
});
|
|
204
|
-
|
|
205
|
-
FlinkLog_1.log.
|
|
206
|
-
|
|
207
|
-
}
|
|
213
|
+
if (this.disableHttpServer) {
|
|
214
|
+
FlinkLog_1.log.info("🚧 HTTP server is disabled, but flink app is running");
|
|
215
|
+
this.started = true;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
(_a = this.expressApp) === null || _a === void 0 ? void 0 : _a.listen(this.port, function () {
|
|
219
|
+
FlinkLog_1.log.fontColorLog("magenta", "\u26A1\uFE0F HTTP server '" + _this.name + "' is running and waiting for connections on " + _this.port);
|
|
220
|
+
_this.started = true;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
208
223
|
return [2 /*return*/, this];
|
|
209
224
|
}
|
|
210
225
|
});
|
|
@@ -258,13 +273,15 @@ var FlinkApp = /** @class */ (function () {
|
|
|
258
273
|
this.handlers.push(handlerConfig);
|
|
259
274
|
var routeProps = handlerConfig.routeProps, _a = handlerConfig.schema, schema = _a === void 0 ? {} : _a;
|
|
260
275
|
var method = routeProps.method;
|
|
261
|
-
var app = this.expressApp;
|
|
262
276
|
if (!method) {
|
|
263
277
|
FlinkLog_1.log.error("Route " + routeProps.path + " is missing http method");
|
|
264
278
|
}
|
|
265
279
|
if (method) {
|
|
266
280
|
var methodAndRoute_1 = method.toUpperCase() + " " + routeProps.path;
|
|
267
|
-
|
|
281
|
+
if (this.disableHttpServer) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
this.expressApp[method](routeProps.path, function (req, res) { return __awaiter(_this, void 0, void 0, function () {
|
|
268
285
|
var validate, valid, data, handlerRes, err_1, validate, valid;
|
|
269
286
|
return __generator(this, function (_a) {
|
|
270
287
|
switch (_a.label) {
|
|
@@ -475,8 +475,8 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
475
475
|
};
|
|
476
476
|
TypeScriptCompiler.prototype.initJsonSchemaGenerator = function () {
|
|
477
477
|
var conf = {
|
|
478
|
-
|
|
479
|
-
|
|
478
|
+
expose: "none",
|
|
479
|
+
topRef: false, // Removes the wrapper object around the schema.
|
|
480
480
|
};
|
|
481
481
|
var formatter = ts_json_schema_generator_1.createFormatter(conf);
|
|
482
482
|
var parser = ts_json_schema_generator_1.createParser(this.project.getProgram().compilerObject, conf);
|
|
@@ -486,17 +486,18 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
486
486
|
TypeScriptCompiler.prototype.generateAndSaveJsonSchemas = function (schemas) {
|
|
487
487
|
return __awaiter(this, void 0, void 0, function () {
|
|
488
488
|
var jsonSchemas, _i, schemas_1, _a, reqSchemaType, resSchemaType, mergedSchemas, filePath;
|
|
489
|
-
|
|
490
|
-
|
|
489
|
+
var _b, _c;
|
|
490
|
+
return __generator(this, function (_d) {
|
|
491
|
+
switch (_d.label) {
|
|
491
492
|
case 0:
|
|
492
493
|
jsonSchemas = [];
|
|
493
494
|
for (_i = 0, schemas_1 = schemas; _i < schemas_1.length; _i++) {
|
|
494
495
|
_a = schemas_1[_i], reqSchemaType = _a.reqSchemaType, resSchemaType = _a.resSchemaType;
|
|
495
496
|
if (reqSchemaType) {
|
|
496
|
-
jsonSchemas.push(this.generateJsonSchema(reqSchemaType));
|
|
497
|
+
jsonSchemas.push({ definitions: (_b = {}, _b[reqSchemaType] = this.generateJsonSchema(reqSchemaType), _b) });
|
|
497
498
|
}
|
|
498
499
|
if (resSchemaType) {
|
|
499
|
-
jsonSchemas.push(this.generateJsonSchema(resSchemaType));
|
|
500
|
+
jsonSchemas.push({ definitions: (_c = {}, _c[resSchemaType] = this.generateJsonSchema(resSchemaType), _c) });
|
|
500
501
|
}
|
|
501
502
|
}
|
|
502
503
|
mergedSchemas = jsonSchemas.reduce(function (out, schema) {
|
|
@@ -512,7 +513,7 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
512
513
|
filePath = path_1.join(this.cwd, ".flink", "schemas", "schemas.json");
|
|
513
514
|
return [4 /*yield*/, FsUtils_1.writeJsonFile(filePath, mergedSchemas)];
|
|
514
515
|
case 1:
|
|
515
|
-
|
|
516
|
+
_d.sent();
|
|
516
517
|
this.project.addSourceFileAtPath(filePath);
|
|
517
518
|
return [2 /*return*/, mergedSchemas];
|
|
518
519
|
}
|
|
@@ -612,15 +613,15 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
612
613
|
for (var _i = 0, handlers_1 = handlers; _i < handlers_1.length; _i++) {
|
|
613
614
|
var _a = handlers_1[_i], sourceFile = _a.sourceFile, reqSchemaType = _a.reqSchemaType, resSchemaType = _a.resSchemaType;
|
|
614
615
|
if (reqSchemaType && !jsonSchemaDefs[reqSchemaType]) {
|
|
615
|
-
console.error("Handler " + sourceFile.getBaseName + " has request schema\u00A0(" + reqSchemaType + ") defined, but JSON schema has been generated");
|
|
616
|
+
console.error("Handler " + sourceFile.getBaseName() + " has request schema\u00A0(" + reqSchemaType + ") defined, but no JSON schema has been generated");
|
|
616
617
|
continue;
|
|
617
618
|
}
|
|
618
619
|
if (resSchemaType && !jsonSchemaDefs[resSchemaType]) {
|
|
619
|
-
console.error("Handler " + sourceFile.getBaseName + " has response schema\u00A0(" + resSchemaType + ") defined, but JSON schema has been generated");
|
|
620
|
+
console.error("Handler " + sourceFile.getBaseName() + " has response schema\u00A0(" + resSchemaType + ") defined, but no JSON schema has been generated");
|
|
620
621
|
continue;
|
|
621
622
|
}
|
|
622
|
-
var reqJsonSchema = JSON.stringify(reqSchemaType ?
|
|
623
|
-
var resJsonSchema = JSON.stringify(resSchemaType ?
|
|
623
|
+
var reqJsonSchema = JSON.stringify(reqSchemaType ? jsonSchemaDefs[reqSchemaType] : undefined);
|
|
624
|
+
var resJsonSchema = JSON.stringify(resSchemaType ? jsonSchemaDefs[resSchemaType] : undefined);
|
|
624
625
|
sourceFile.addVariableStatement({
|
|
625
626
|
declarationKind: ts_morph_1.VariableDeclarationKind.Const,
|
|
626
627
|
isExported: true,
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Request } from "express";
|
|
2
|
-
import { JSONSchema7, JSONSchema7Definition } from "json-schema";
|
|
3
2
|
import { HttpMethod } from "./FlinkHttpHandler";
|
|
4
3
|
import { FlinkResponse } from "./FlinkResponse";
|
|
5
4
|
export declare function handlersPath(appRoot: string): string;
|
|
@@ -18,13 +17,4 @@ export declare function getRepoInstanceName(fn: string): string;
|
|
|
18
17
|
* if it starts with i.e "GetFoo"
|
|
19
18
|
*/
|
|
20
19
|
export declare function getHttpMethodFromHandlerName(handlerFilename: string): HttpMethod | undefined;
|
|
21
|
-
/**
|
|
22
|
-
* Recursively iterates thru json schema properties and replaces any $ref
|
|
23
|
-
* with the actual definiton if it exists withing provided `jsonSchemas`.
|
|
24
|
-
*
|
|
25
|
-
* @param schemaToDeRef
|
|
26
|
-
* @param jsonSchemas
|
|
27
|
-
* @returns
|
|
28
|
-
*/
|
|
29
|
-
export declare function deRefSchema(schemaToDeRef: JSONSchema7Definition, jsonSchemas: JSONSchema7): boolean | JSONSchema7;
|
|
30
20
|
export declare function getJsDocComment(comment: string): string;
|
package/dist/src/utils.js
CHANGED
|
@@ -39,7 +39,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
40
|
};
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.getJsDocComment = exports.
|
|
42
|
+
exports.getJsDocComment = exports.getHttpMethodFromHandlerName = exports.getRepoInstanceName = exports.getCollectionNameForRepo = exports.getSchemaFiles = exports.getHandlerFiles = exports.isError = exports.isRouteMatch = exports.schemasPath = exports.handlersPath = void 0;
|
|
43
43
|
var path_1 = require("path");
|
|
44
44
|
var tiny_glob_1 = __importDefault(require("tiny-glob"));
|
|
45
45
|
var FlinkHttpHandler_1 = require("./FlinkHttpHandler");
|
|
@@ -138,86 +138,6 @@ function getHttpMethodFromHandlerName(handlerFilename) {
|
|
|
138
138
|
return FlinkHttpHandler_1.HttpMethod.delete;
|
|
139
139
|
}
|
|
140
140
|
exports.getHttpMethodFromHandlerName = getHttpMethodFromHandlerName;
|
|
141
|
-
/**
|
|
142
|
-
* Recursively iterates thru json schema properties and replaces any $ref
|
|
143
|
-
* with the actual definiton if it exists withing provided `jsonSchemas`.
|
|
144
|
-
*
|
|
145
|
-
* @param schemaToDeRef
|
|
146
|
-
* @param jsonSchemas
|
|
147
|
-
* @returns
|
|
148
|
-
*/
|
|
149
|
-
function deRefSchema(schemaToDeRef, jsonSchemas) {
|
|
150
|
-
if (typeof schemaToDeRef === "boolean") {
|
|
151
|
-
return schemaToDeRef;
|
|
152
|
-
}
|
|
153
|
-
if (schemaToDeRef.type === "array") {
|
|
154
|
-
var items = schemaToDeRef.items;
|
|
155
|
-
if (items.$ref) {
|
|
156
|
-
var _a = items.$ref.split("/"), _0 = _a[0], _1 = _a[1], defKey = _a[2];
|
|
157
|
-
var refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
158
|
-
if (refedSchema) {
|
|
159
|
-
schemaToDeRef.items = deRefSchema(refedSchema, jsonSchemas);
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
console.warn("Failed to find deref " + schemaToDeRef.$ref);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
schemaToDeRef.items = deRefSchema(schemaToDeRef.items, jsonSchemas);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else if (schemaToDeRef.properties) {
|
|
170
|
-
for (var k in schemaToDeRef.properties) {
|
|
171
|
-
var prop = schemaToDeRef.properties[k];
|
|
172
|
-
if (typeof prop === "boolean") {
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
if (prop.$ref) {
|
|
176
|
-
var _b = prop.$ref.split("/"), _0 = _b[0], _1 = _b[1], defKey = _b[2];
|
|
177
|
-
var refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
178
|
-
if (refedSchema) {
|
|
179
|
-
schemaToDeRef.properties[k] = deRefSchema(refedSchema, jsonSchemas);
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
console.warn("Failed to find deref " + prop.$ref);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
else if (prop.type === "array" && prop.items.$ref) {
|
|
186
|
-
var _c = prop.items.$ref.split("/"), _0 = _c[0], _1 = _c[1], defKey = _c[2];
|
|
187
|
-
var refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
188
|
-
if (refedSchema) {
|
|
189
|
-
schemaToDeRef.properties[k].items = deRefSchema(refedSchema, jsonSchemas);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
console.warn("Failed to find deref " + prop.$ref);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
else if (prop.type === "object" || prop.type === "array") {
|
|
196
|
-
schemaToDeRef.properties[k] = deRefSchema(prop, jsonSchemas);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
else if (schemaToDeRef.anyOf) {
|
|
201
|
-
var i = 0;
|
|
202
|
-
for (var _i = 0, _d = schemaToDeRef.anyOf; _i < _d.length; _i++) {
|
|
203
|
-
var anyOf = _d[_i];
|
|
204
|
-
var anyOfSchema = anyOf;
|
|
205
|
-
if (anyOfSchema.$ref) {
|
|
206
|
-
var _e = anyOfSchema.$ref.split("/"), _0 = _e[0], _1 = _e[1], defKey = _e[2];
|
|
207
|
-
var refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
208
|
-
if (refedSchema) {
|
|
209
|
-
schemaToDeRef.anyOf[i] = deRefSchema(refedSchema, jsonSchemas);
|
|
210
|
-
}
|
|
211
|
-
else {
|
|
212
|
-
console.warn("Failed to find deref " + anyOfSchema.$ref);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
i++;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return schemaToDeRef;
|
|
219
|
-
}
|
|
220
|
-
exports.deRefSchema = deRefSchema;
|
|
221
141
|
function getJsDocComment(comment) {
|
|
222
142
|
var rows = comment.split("\n").map(function (line) {
|
|
223
143
|
line = line.trim();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flink-app/flink",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"description": "Typescript only framework for creating REST-like APIs on top of Express and mongodb",
|
|
5
5
|
"types": "dist/src/index.d.ts",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"rimraf": "^3.0.2",
|
|
66
66
|
"ts-node": "^9.1.1"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "b565d5987e08ba3aba3653325e935e6c56cab24c"
|
|
69
69
|
}
|
|
@@ -56,4 +56,4 @@ var GetCar = function (_a) {
|
|
|
56
56
|
};
|
|
57
57
|
exports.default = GetCar;
|
|
58
58
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCar.ts", exports.__query = [{ description: "For pagination", name: "page" }], exports.__params = [{ description: "", name: "id" }];
|
|
59
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"] } };
|
|
59
|
+
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "definitions": {} } };
|
|
@@ -58,4 +58,4 @@ var GetCar2 = function (_a) {
|
|
|
58
58
|
};
|
|
59
59
|
exports.default = GetCar2;
|
|
60
60
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCar2.ts", exports.__query = [], exports.__params = [];
|
|
61
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "type": "object", "properties": { "model": { "type": "object", "properties": { "name": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["name"], "additionalProperties": false }, "engine": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"], "additionalProperties": false } }, "required": ["model", "engine"], "additionalProperties": false } };
|
|
61
|
+
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "model": { "type": "object", "properties": { "name": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["name"], "additionalProperties": false }, "engine": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"], "additionalProperties": false } }, "required": ["model", "engine"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -52,4 +52,4 @@ var GetCarWithArraySchema = function (_a) {
|
|
|
52
52
|
};
|
|
53
53
|
exports.default = GetCarWithArraySchema;
|
|
54
54
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithArraySchema.ts", exports.__query = [], exports.__params = [];
|
|
55
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "type": "array", "items": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } } };
|
|
55
|
+
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false }, "definitions": {} } };
|
|
@@ -52,4 +52,4 @@ var GetCarWithArraySchema2 = function (_a) {
|
|
|
52
52
|
};
|
|
53
53
|
exports.default = GetCarWithArraySchema2;
|
|
54
54
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithArraySchema2.ts", exports.__query = [], exports.__params = [];
|
|
55
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "type": "array", "items": { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false } } };
|
|
55
|
+
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false }, "definitions": {} } };
|
|
@@ -52,4 +52,4 @@ var GetCarWithArraySchema3 = function (_a) {
|
|
|
52
52
|
};
|
|
53
53
|
exports.default = GetCarWithArraySchema3;
|
|
54
54
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithArraySchema3.ts", exports.__query = [], exports.__params = [];
|
|
55
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "type": "array", "items": { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false }, "year": { "type": "number" } }, "required": ["car", "year"], "additionalProperties": false } } };
|
|
55
|
+
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false }, "year": { "type": "number" } }, "required": ["car", "year"], "additionalProperties": false }, "definitions": {} } };
|
|
@@ -54,4 +54,4 @@ var GetCarWithLiteralSchema = function (_a) {
|
|
|
54
54
|
};
|
|
55
55
|
exports.default = GetCarWithLiteralSchema;
|
|
56
56
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithLiteralSchema.ts", exports.__query = [], exports.__params = [];
|
|
57
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false } };
|
|
57
|
+
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -54,4 +54,4 @@ var GetCarWithLiteralSchema2 = function (_a) {
|
|
|
54
54
|
};
|
|
55
55
|
exports.default = GetCarWithLiteralSchema2;
|
|
56
56
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithLiteralSchema2.ts", exports.__query = [], exports.__params = [];
|
|
57
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "type": "object", "properties": { "car": { "type": "object", "properties": { "nestedCar": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["nestedCar"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false } };
|
|
57
|
+
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "car": { "type": "object", "properties": { "nestedCar": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["nestedCar"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -57,4 +57,4 @@ var GetCarWithSchemaInFile = function (_a) {
|
|
|
57
57
|
};
|
|
58
58
|
exports.default = GetCarWithSchemaInFile;
|
|
59
59
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithSchemaInFile.ts", exports.__query = [], exports.__params = [];
|
|
60
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "type": "object", "properties": { "model": { "type": "string" } }, "required": ["model"], "additionalProperties": false } };
|
|
60
|
+
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "model": { "type": "string" } }, "required": ["model"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -57,4 +57,4 @@ var GetCarWithSchemaInFile2 = function (_a) {
|
|
|
57
57
|
};
|
|
58
58
|
exports.default = GetCarWithSchemaInFile2;
|
|
59
59
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithSchemaInFile2.ts", exports.__query = [], exports.__params = [];
|
|
60
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false } };
|
|
60
|
+
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -53,4 +53,4 @@ var manuallyAddedHandler = function (_a) {
|
|
|
53
53
|
};
|
|
54
54
|
exports.default = manuallyAddedHandler;
|
|
55
55
|
exports.__assumedHttpMethod = "", exports.__file = "ManuallyAddedHandler.ts", exports.__query = [], exports.__params = [];
|
|
56
|
-
exports.__schemas = { reqSchema: { "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"] }, resSchema: undefined };
|
|
56
|
+
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "definitions": {} }, resSchema: undefined };
|
|
@@ -55,4 +55,4 @@ var manuallyAddedHandler = function (_a) {
|
|
|
55
55
|
};
|
|
56
56
|
exports.default = manuallyAddedHandler;
|
|
57
57
|
exports.__assumedHttpMethod = "", exports.__file = "ManuallyAddedHandler2.ts", exports.__query = [], exports.__params = [];
|
|
58
|
-
exports.__schemas = { reqSchema: { "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"] }, resSchema: undefined };
|
|
58
|
+
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "definitions": {} }, resSchema: undefined };
|
|
@@ -54,4 +54,4 @@ var PostCar = function (_a) {
|
|
|
54
54
|
};
|
|
55
55
|
exports.default = PostCar;
|
|
56
56
|
exports.__assumedHttpMethod = "post", exports.__file = "PostCar.ts", exports.__query = [], exports.__params = [];
|
|
57
|
-
exports.__schemas = { reqSchema: { "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"] }, resSchema: { "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"] } };
|
|
57
|
+
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "definitions": {} }, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "definitions": {} } };
|
|
@@ -54,4 +54,4 @@ var PutCar = function (_a) {
|
|
|
54
54
|
};
|
|
55
55
|
exports.default = PutCar;
|
|
56
56
|
exports.__assumedHttpMethod = "put", exports.__file = "PutCar.ts", exports.__query = [], exports.__params = [];
|
|
57
|
-
exports.__schemas = { reqSchema: { "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"] }, resSchema: undefined };
|
|
57
|
+
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "definitions": {} }, resSchema: undefined };
|
package/spec/utils.spec.ts
CHANGED
|
@@ -1,89 +1,7 @@
|
|
|
1
1
|
import { JSONSchema7 } from "json-schema";
|
|
2
|
-
import {
|
|
2
|
+
import { getJsDocComment } from "../src/utils";
|
|
3
3
|
|
|
4
4
|
describe("Utils", () => {
|
|
5
|
-
describe("deref", () => {
|
|
6
|
-
it("should de-ref json schema", () => {
|
|
7
|
-
const dereffedSchema = deRefSchema(jsonSchemas.definitions!.GetCar2_10_ResSchema, jsonSchemas);
|
|
8
|
-
|
|
9
|
-
const schema = dereffedSchema as JSONSchema7;
|
|
10
|
-
|
|
11
|
-
// @ts-ignore
|
|
12
|
-
expect(schema.properties.engine.type).toBe("object");
|
|
13
|
-
|
|
14
|
-
// @ts-ignore
|
|
15
|
-
expect(schema.properties.model.properties.engine.type).toBe("object");
|
|
16
|
-
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
expect(schema.properties.tires.items.type).toBe("object");
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("should de-ref json schema (nested prop)", () => {
|
|
22
|
-
const dereffedSchema = deRefSchema(jsonSchemas.definitions!.Login, jsonSchemas);
|
|
23
|
-
|
|
24
|
-
const schema = dereffedSchema as JSONSchema7;
|
|
25
|
-
|
|
26
|
-
// @ts-ignore
|
|
27
|
-
expect(schema.properties.user.properties.profile.type).toBe("object");
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it("should de-ref json schema which is an array", () => {
|
|
31
|
-
const dereffedSchema = deRefSchema(jsonSchemas.definitions!.Cars, jsonSchemas);
|
|
32
|
-
|
|
33
|
-
const schema = dereffedSchema as JSONSchema7;
|
|
34
|
-
|
|
35
|
-
expect(schema.type).toBe("array");
|
|
36
|
-
|
|
37
|
-
// @ts-ignore
|
|
38
|
-
expect(schema.items.type).toBe("object");
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("should de-ref json schema which is an array 2", () => {
|
|
42
|
-
const dereffedSchema = deRefSchema(jsonSchemas.definitions!.Cars2, jsonSchemas);
|
|
43
|
-
|
|
44
|
-
const schema = dereffedSchema as JSONSchema7;
|
|
45
|
-
|
|
46
|
-
expect(schema.type).toBe("array");
|
|
47
|
-
|
|
48
|
-
// @ts-ignore
|
|
49
|
-
expect(schema.items.type).toBe("object");
|
|
50
|
-
|
|
51
|
-
// @ts-ignore
|
|
52
|
-
expect(schema.items.properties.model.type).toBe("object");
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should de-ref complex json schema", () => {
|
|
56
|
-
const dereffedSchema = deRefSchema(jsonSchemasSet2.definitions!.GetStorages_9_ResSchema, jsonSchemasSet2);
|
|
57
|
-
|
|
58
|
-
const schema = dereffedSchema as JSONSchema7;
|
|
59
|
-
|
|
60
|
-
expect(schema.type).toBe("object");
|
|
61
|
-
|
|
62
|
-
// @ts-ignore
|
|
63
|
-
expect(schema.properties.storages.type).toBe("array");
|
|
64
|
-
|
|
65
|
-
// @ts-ignore
|
|
66
|
-
expect(schema.properties.storages.items.properties.metadata.type).toBe("object");
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it("should de-ref with anyOf in array", () => {
|
|
70
|
-
const dereffedSchema = deRefSchema(jsonSchemaSet3.definitions!.GetStorages_9_ResSchema, jsonSchemaSet3);
|
|
71
|
-
|
|
72
|
-
const schema = dereffedSchema as JSONSchema7;
|
|
73
|
-
|
|
74
|
-
expect(schema.type).toBe("object");
|
|
75
|
-
|
|
76
|
-
// @ts-ignore
|
|
77
|
-
expect(schema.properties.storages.type).toBe("array");
|
|
78
|
-
|
|
79
|
-
// @ts-ignore
|
|
80
|
-
expect(schema.properties.storages.items.anyOf[0].type).toBe("object");
|
|
81
|
-
|
|
82
|
-
// @ts-ignore
|
|
83
|
-
expect(schema.properties.storages.items.anyOf[1].type).toBe("object");
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
5
|
describe("getJsDocComment", () => {
|
|
88
6
|
it("should strip comment chars and return string", () => {
|
|
89
7
|
const comment = `
|
package/src/FlinkApp.ts
CHANGED
|
@@ -162,6 +162,12 @@ export interface FlinkOptions {
|
|
|
162
162
|
// */
|
|
163
163
|
// autoAssignCollection?: string;
|
|
164
164
|
};
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* If true, the HTTP server will be disabled.
|
|
168
|
+
* Only useful when starting a Flink app for testing purposes.
|
|
169
|
+
*/
|
|
170
|
+
disableHttpServer?: boolean;
|
|
165
171
|
}
|
|
166
172
|
|
|
167
173
|
export interface HandlerConfig {
|
|
@@ -203,6 +209,7 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
203
209
|
private routingConfigured = false;
|
|
204
210
|
private jsonOptions?: OptionsJson;
|
|
205
211
|
private schedulingOptions?: FlinkOptions["scheduling"];
|
|
212
|
+
private disableHttpServer = false;
|
|
206
213
|
|
|
207
214
|
private repos: { [x: string]: FlinkRepo<C> } = {};
|
|
208
215
|
|
|
@@ -224,6 +231,7 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
224
231
|
this.auth = opts.auth;
|
|
225
232
|
this.jsonOptions = opts.jsonOptions || { limit: "1mb" };
|
|
226
233
|
this.schedulingOptions = opts.scheduling;
|
|
234
|
+
this.disableHttpServer = !!opts.disableHttpServer;
|
|
227
235
|
}
|
|
228
236
|
|
|
229
237
|
get ctx() {
|
|
@@ -253,18 +261,22 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
253
261
|
|
|
254
262
|
if (this.isSchedulingEnabled) {
|
|
255
263
|
this.scheduler = new ToadScheduler();
|
|
264
|
+
} else {
|
|
265
|
+
log.info("🚫 Scheduling is disabled");
|
|
256
266
|
}
|
|
257
267
|
|
|
258
|
-
this.
|
|
268
|
+
if (!this.disableHttpServer) {
|
|
269
|
+
this.expressApp = express();
|
|
259
270
|
|
|
260
|
-
|
|
271
|
+
this.expressApp.use(cors(this.corsOpts));
|
|
261
272
|
|
|
262
|
-
|
|
273
|
+
this.expressApp.use(bodyParser.json(this.jsonOptions));
|
|
263
274
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
275
|
+
this.expressApp.use((req, res, next) => {
|
|
276
|
+
req.reqId = v4();
|
|
277
|
+
next();
|
|
278
|
+
});
|
|
279
|
+
}
|
|
268
280
|
|
|
269
281
|
// TODO: Add better more fine grained control when plugins are initialized, i.e. in what order
|
|
270
282
|
|
|
@@ -301,18 +313,24 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
301
313
|
// Register 404 with slight delay to allow all manually added routes to be added
|
|
302
314
|
// TODO: Is there a better solution to force this handler to always run last?
|
|
303
315
|
setTimeout(() => {
|
|
304
|
-
this.
|
|
305
|
-
|
|
306
|
-
|
|
316
|
+
if (!this.disableHttpServer) {
|
|
317
|
+
this.expressApp!.use((req, res, next) => {
|
|
318
|
+
res.status(404).json(notFound());
|
|
319
|
+
});
|
|
320
|
+
}
|
|
307
321
|
|
|
308
322
|
this.routingConfigured = true;
|
|
309
323
|
});
|
|
310
324
|
|
|
311
|
-
|
|
312
|
-
log.
|
|
313
|
-
|
|
325
|
+
if (this.disableHttpServer) {
|
|
326
|
+
log.info("🚧 HTTP server is disabled, but flink app is running");
|
|
314
327
|
this.started = true;
|
|
315
|
-
}
|
|
328
|
+
} else {
|
|
329
|
+
this.expressApp?.listen(this.port, () => {
|
|
330
|
+
log.fontColorLog("magenta", `⚡️ HTTP server '${this.name}' is running and waiting for connections on ${this.port}`);
|
|
331
|
+
this.started = true;
|
|
332
|
+
});
|
|
333
|
+
}
|
|
316
334
|
|
|
317
335
|
return this;
|
|
318
336
|
}
|
|
@@ -381,7 +399,6 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
381
399
|
|
|
382
400
|
const { routeProps, schema = {} } = handlerConfig;
|
|
383
401
|
const { method } = routeProps;
|
|
384
|
-
const app = this.expressApp!;
|
|
385
402
|
|
|
386
403
|
if (!method) {
|
|
387
404
|
log.error(`Route ${routeProps.path} is missing http method`);
|
|
@@ -390,7 +407,11 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
390
407
|
if (method) {
|
|
391
408
|
const methodAndRoute = `${method.toUpperCase()} ${routeProps.path}`;
|
|
392
409
|
|
|
393
|
-
|
|
410
|
+
if (this.disableHttpServer) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
this.expressApp => {
|
|
394
415
|
if (routeProps.permissions) {
|
|
395
416
|
if (!(await this.authenticate(req, routeProps.permissions))) {
|
|
396
417
|
return res.status(401).json(unauthorized());
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "ts-morph";
|
|
20
20
|
import { writeJsonFile } from "./FsUtils";
|
|
21
21
|
import { addImports, getDefaultExport, getInterfaceName, getTypeMetadata, getTypesToImport } from "./TypeScriptUtils";
|
|
22
|
-
import {
|
|
22
|
+
import { getCollectionNameForRepo, getHttpMethodFromHandlerName, getRepoInstanceName } from "./utils";
|
|
23
23
|
|
|
24
24
|
class TypeScriptCompiler {
|
|
25
25
|
private project: Project;
|
|
@@ -438,8 +438,8 @@ import "..${appEntryScript.replace(/\.ts/g, "")}";
|
|
|
438
438
|
|
|
439
439
|
private initJsonSchemaGenerator() {
|
|
440
440
|
const conf: Config = {
|
|
441
|
-
|
|
442
|
-
|
|
441
|
+
expose: "none", // Do not create shared $ref definitions.
|
|
442
|
+
topRef: false, // Removes the wrapper object around the schema.
|
|
443
443
|
};
|
|
444
444
|
const formatter = createFormatter(conf);
|
|
445
445
|
const parser = createParser(this.project.getProgram().compilerObject, conf);
|
|
@@ -453,10 +453,10 @@ import "..${appEntryScript.replace(/\.ts/g, "")}";
|
|
|
453
453
|
|
|
454
454
|
for (const { reqSchemaType, resSchemaType } of schemas) {
|
|
455
455
|
if (reqSchemaType) {
|
|
456
|
-
jsonSchemas.push(this.generateJsonSchema(reqSchemaType));
|
|
456
|
+
jsonSchemas.push({ definitions: { [reqSchemaType]: this.generateJsonSchema(reqSchemaType) } });
|
|
457
457
|
}
|
|
458
458
|
if (resSchemaType) {
|
|
459
|
-
jsonSchemas.push(this.generateJsonSchema(resSchemaType));
|
|
459
|
+
jsonSchemas.push({ definitions: { [resSchemaType]: this.generateJsonSchema(resSchemaType) } });
|
|
460
460
|
}
|
|
461
461
|
}
|
|
462
462
|
|
|
@@ -594,17 +594,17 @@ ${this.parsedTsSchemas.join("\n\n")}`
|
|
|
594
594
|
|
|
595
595
|
for (const { sourceFile, reqSchemaType, resSchemaType } of handlers) {
|
|
596
596
|
if (reqSchemaType && !jsonSchemaDefs[reqSchemaType]) {
|
|
597
|
-
console.error(`Handler ${sourceFile.getBaseName} has request schema (${reqSchemaType}) defined, but JSON schema has been generated`);
|
|
597
|
+
console.error(`Handler ${sourceFile.getBaseName()} has request schema (${reqSchemaType}) defined, but no JSON schema has been generated`);
|
|
598
598
|
continue;
|
|
599
599
|
}
|
|
600
600
|
|
|
601
601
|
if (resSchemaType && !jsonSchemaDefs[resSchemaType]) {
|
|
602
|
-
console.error(`Handler ${sourceFile.getBaseName} has response schema (${resSchemaType}) defined, but JSON schema has been generated`);
|
|
602
|
+
console.error(`Handler ${sourceFile.getBaseName()} has response schema (${resSchemaType}) defined, but no JSON schema has been generated`);
|
|
603
603
|
continue;
|
|
604
604
|
}
|
|
605
605
|
|
|
606
|
-
const reqJsonSchema = JSON.stringify(reqSchemaType ?
|
|
607
|
-
const resJsonSchema = JSON.stringify(resSchemaType ?
|
|
606
|
+
const reqJsonSchema = JSON.stringify(reqSchemaType ? jsonSchemaDefs[reqSchemaType] : undefined);
|
|
607
|
+
const resJsonSchema = JSON.stringify(resSchemaType ? jsonSchemaDefs[resSchemaType] : undefined);
|
|
608
608
|
|
|
609
609
|
sourceFile.addVariableStatement({
|
|
610
610
|
declarationKind: VariableDeclarationKind.Const,
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Request } from "express";
|
|
2
|
-
import { JSONSchema7, JSONSchema7Definition } from "json-schema";
|
|
3
2
|
import { join, sep } from "path";
|
|
4
3
|
import tinyGlob from "tiny-glob";
|
|
5
4
|
import { HttpMethod } from "./FlinkHttpHandler";
|
|
@@ -78,84 +77,6 @@ export function getHttpMethodFromHandlerName(handlerFilename: string) {
|
|
|
78
77
|
if (handlerFilename.startsWith(HttpMethod.delete)) return HttpMethod.delete;
|
|
79
78
|
}
|
|
80
79
|
|
|
81
|
-
/**
|
|
82
|
-
* Recursively iterates thru json schema properties and replaces any $ref
|
|
83
|
-
* with the actual definiton if it exists withing provided `jsonSchemas`.
|
|
84
|
-
*
|
|
85
|
-
* @param schemaToDeRef
|
|
86
|
-
* @param jsonSchemas
|
|
87
|
-
* @returns
|
|
88
|
-
*/
|
|
89
|
-
export function deRefSchema(schemaToDeRef: JSONSchema7Definition, jsonSchemas: JSONSchema7) {
|
|
90
|
-
if (typeof schemaToDeRef === "boolean") {
|
|
91
|
-
return schemaToDeRef;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (schemaToDeRef.type === "array") {
|
|
95
|
-
const items = schemaToDeRef.items as JSONSchema7;
|
|
96
|
-
|
|
97
|
-
if (items.$ref) {
|
|
98
|
-
const [_0, _1, defKey] = items.$ref.split("/");
|
|
99
|
-
const refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
100
|
-
|
|
101
|
-
if (refedSchema) {
|
|
102
|
-
schemaToDeRef.items = deRefSchema(refedSchema, jsonSchemas);
|
|
103
|
-
} else {
|
|
104
|
-
console.warn(`Failed to find deref ${schemaToDeRef.$ref}`);
|
|
105
|
-
}
|
|
106
|
-
} else {
|
|
107
|
-
schemaToDeRef.items = deRefSchema(schemaToDeRef.items as JSONSchema7, jsonSchemas);
|
|
108
|
-
}
|
|
109
|
-
} else if (schemaToDeRef.properties) {
|
|
110
|
-
for (const k in schemaToDeRef.properties) {
|
|
111
|
-
let prop = schemaToDeRef.properties[k];
|
|
112
|
-
|
|
113
|
-
if (typeof prop === "boolean") {
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (prop.$ref) {
|
|
118
|
-
const [_0, _1, defKey] = prop.$ref.split("/");
|
|
119
|
-
const refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
120
|
-
if (refedSchema) {
|
|
121
|
-
schemaToDeRef.properties[k] = deRefSchema(refedSchema, jsonSchemas);
|
|
122
|
-
} else {
|
|
123
|
-
console.warn(`Failed to find deref ${prop.$ref}`);
|
|
124
|
-
}
|
|
125
|
-
} else if (prop.type === "array" && (prop.items as JSONSchema7).$ref) {
|
|
126
|
-
const [_0, _1, defKey] = (prop.items as JSONSchema7).$ref!.split("/");
|
|
127
|
-
const refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
128
|
-
if (refedSchema) {
|
|
129
|
-
(schemaToDeRef.properties[k] as JSONSchema7).items = deRefSchema(refedSchema, jsonSchemas);
|
|
130
|
-
} else {
|
|
131
|
-
console.warn(`Failed to find deref ${prop.$ref}`);
|
|
132
|
-
}
|
|
133
|
-
} else if (prop.type === "object" || prop.type === "array") {
|
|
134
|
-
schemaToDeRef.properties[k] = deRefSchema(prop, jsonSchemas);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
} else if (schemaToDeRef.anyOf) {
|
|
138
|
-
let i = 0;
|
|
139
|
-
for (const anyOf of schemaToDeRef.anyOf) {
|
|
140
|
-
const anyOfSchema = anyOf as JSONSchema7;
|
|
141
|
-
|
|
142
|
-
if (anyOfSchema.$ref) {
|
|
143
|
-
const [_0, _1, defKey] = anyOfSchema.$ref.split("/");
|
|
144
|
-
const refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
145
|
-
if (refedSchema) {
|
|
146
|
-
schemaToDeRef.anyOf[i] = deRefSchema(refedSchema, jsonSchemas);
|
|
147
|
-
} else {
|
|
148
|
-
console.warn(`Failed to find deref ${anyOfSchema.$ref}`);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
i++;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return schemaToDeRef;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
80
|
export function getJsDocComment(comment: string) {
|
|
160
81
|
const rows = comment.split("\n").map((line) => {
|
|
161
82
|
line = line.trim();
|