@flink-app/flink 0.2.0-beta.9 → 0.3.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/LICENSE +21 -0
- package/cli/generate-schemas.ts +1 -1
- package/dist/cli/generate-schemas.js +1 -1
- package/dist/src/FlinkApp.js +0 -1
- package/dist/src/FlinkHttpHandler.d.ts +4 -1
- package/dist/src/FlinkRepo.d.ts +1 -1
- package/dist/src/FlinkRepo.js +1 -1
- package/dist/src/FlinkResponse.d.ts +3 -0
- package/dist/src/FsUtils.js +1 -1
- package/dist/src/utils.js +12 -16
- package/package.json +64 -64
- package/spec/FlinkRepo.spec.ts +1 -1
- 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/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/mock-project/dist/src/schemas/DefaultExportSchema.js +2 -0
- package/spec/mock-project/src/schemas/Car.ts +3 -0
- package/spec/mock-project/src/schemas/DefaultExportSchema.ts +3 -0
- package/spec/mock-project/src/schemas/FileWithTwoSchemas.ts +3 -0
- package/spec/utils.spec.ts +58 -0
- package/src/FlinkApp.ts +1 -2
- package/src/FlinkHttpHandler.ts +4 -1
- package/src/FlinkRepo.ts +2 -3
- package/src/FlinkResponse.ts +4 -1
- package/src/FsUtils.ts +1 -1
- package/src/utils.ts +18 -18
- package/dist/src/schema/CustomJsonSchemaFormatter.d.ts +0 -8
- package/dist/src/schema/CustomJsonSchemaFormatter.js +0 -36
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Frost Experience AB https://www.frost.se
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/cli/generate-schemas.ts
CHANGED
|
@@ -106,7 +106,7 @@ module.exports = function run(args) {
|
|
|
106
106
|
// console.log("Created schemas");
|
|
107
107
|
}
|
|
108
108
|
catch (err) {
|
|
109
|
-
console.error("Failed to generate schema in file", sf.getBaseName() + ":", err
|
|
109
|
+
console.error("Failed to generate schema in file", sf.getBaseName() + ":", err);
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
mergedSchemas = jsonSchemas.reduce(function (out, schema) {
|
package/dist/src/FlinkApp.js
CHANGED
|
@@ -198,7 +198,6 @@ var FlinkApp = /** @class */ (function () {
|
|
|
198
198
|
* Typescript compiler will scan handler function and set schemas
|
|
199
199
|
* which are derived from handler function type arguments.
|
|
200
200
|
*/
|
|
201
|
-
// TODO: Rename to addHandler
|
|
202
201
|
FlinkApp.prototype.addHandler = function (handler, routePropsOverride) {
|
|
203
202
|
var _a, _b, _c, _d, _e, _f;
|
|
204
203
|
if (this.routingConfigured) {
|
|
@@ -11,6 +11,9 @@ export declare enum HttpMethod {
|
|
|
11
11
|
}
|
|
12
12
|
declare type Params = Request["params"];
|
|
13
13
|
declare type Query = Request["query"];
|
|
14
|
+
/**
|
|
15
|
+
* Flink request extends express Request but adds reqId and user object.
|
|
16
|
+
*/
|
|
14
17
|
export declare type FlinkRequest<T = any, P = Params, Q = Query> = Request<P, any, T, Q> & {
|
|
15
18
|
reqId: string;
|
|
16
19
|
user?: any;
|
|
@@ -84,7 +87,7 @@ export declare type GetHandler<Ctx extends FlinkContext, ResSchema = any, P exte
|
|
|
84
87
|
* `import * as FooHandler from "./src/handlers/FooHandler"
|
|
85
88
|
*/
|
|
86
89
|
export declare type HandlerFile = {
|
|
87
|
-
default: Handler<any>;
|
|
90
|
+
default: Handler<any, any, any, any, any>;
|
|
88
91
|
Route?: RouteProps;
|
|
89
92
|
/**
|
|
90
93
|
* Name of schemas, is set at compile time by Flink compiler.
|
package/dist/src/FlinkRepo.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare abstract class FlinkRepo<C extends FlinkContext, Model = any> {
|
|
|
9
9
|
get ctx(): FlinkContext;
|
|
10
10
|
constructor(collectionName: string, db: Db);
|
|
11
11
|
findAll(query?: {}): Promise<Model[]>;
|
|
12
|
-
|
|
12
|
+
getById(id: string): Promise<Model | null>;
|
|
13
13
|
getOne(query?: {}): Promise<Model | null>;
|
|
14
14
|
create<C = Omit<Model, "_id">>(model: C): Promise<C & {
|
|
15
15
|
_id: string;
|
package/dist/src/FlinkRepo.js
CHANGED
|
@@ -64,7 +64,7 @@ var FlinkRepo = /** @class */ (function () {
|
|
|
64
64
|
});
|
|
65
65
|
});
|
|
66
66
|
};
|
|
67
|
-
FlinkRepo.prototype.
|
|
67
|
+
FlinkRepo.prototype.getById = function (id) {
|
|
68
68
|
return __awaiter(this, void 0, void 0, function () {
|
|
69
69
|
return __generator(this, function (_a) {
|
|
70
70
|
return [2 /*return*/, this.collection.findOne({ _id: new mongodb_1.ObjectID(id) })];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Response, Request } from "express";
|
|
1
2
|
export interface FlinkResponse<T = any> {
|
|
2
3
|
/**
|
|
3
4
|
* Unique id of request.
|
|
@@ -36,3 +37,5 @@ export interface FlinkResponse<T = any> {
|
|
|
36
37
|
[x: string]: string;
|
|
37
38
|
};
|
|
38
39
|
}
|
|
40
|
+
export declare type ExpressResponse = Response;
|
|
41
|
+
export declare type ExpressRequest = Request;
|
package/dist/src/FsUtils.js
CHANGED
|
@@ -110,7 +110,7 @@ function writeJsonFile(path, content, opts) {
|
|
|
110
110
|
}
|
|
111
111
|
catch (err) {
|
|
112
112
|
console.error("Failed to parse content into json string");
|
|
113
|
-
throw
|
|
113
|
+
throw err;
|
|
114
114
|
}
|
|
115
115
|
return [2 /*return*/, fs_1.promises.writeFile(path, jsonStr)];
|
|
116
116
|
}
|
package/dist/src/utils.js
CHANGED
|
@@ -150,27 +150,25 @@ function deRefSchema(schemaToDeRef, jsonSchemas) {
|
|
|
150
150
|
if (typeof schemaToDeRef === "boolean") {
|
|
151
151
|
return schemaToDeRef;
|
|
152
152
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
var items = theSchemaToDeRef.items;
|
|
153
|
+
if (schemaToDeRef.type === "array") {
|
|
154
|
+
var items = schemaToDeRef.items;
|
|
156
155
|
if (items.$ref) {
|
|
157
156
|
var _a = items.$ref.split("/"), _0 = _a[0], _1 = _a[1], defKey = _a[2];
|
|
158
157
|
var refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
159
158
|
if (refedSchema) {
|
|
160
|
-
|
|
161
|
-
deRefSchema(refedSchema, jsonSchemas);
|
|
159
|
+
schemaToDeRef.items = deRefSchema(refedSchema, jsonSchemas);
|
|
162
160
|
}
|
|
163
161
|
else {
|
|
164
162
|
console.warn("Failed to find deref " + schemaToDeRef.$ref);
|
|
165
163
|
}
|
|
166
164
|
}
|
|
167
165
|
else {
|
|
168
|
-
deRefSchema(items, jsonSchemas);
|
|
166
|
+
schemaToDeRef.items = deRefSchema(schemaToDeRef.items, jsonSchemas);
|
|
169
167
|
}
|
|
170
168
|
}
|
|
171
|
-
else if (
|
|
172
|
-
for (var k in
|
|
173
|
-
var prop =
|
|
169
|
+
else if (schemaToDeRef.properties) {
|
|
170
|
+
for (var k in schemaToDeRef.properties) {
|
|
171
|
+
var prop = schemaToDeRef.properties[k];
|
|
174
172
|
if (typeof prop === "boolean") {
|
|
175
173
|
continue;
|
|
176
174
|
}
|
|
@@ -178,8 +176,7 @@ function deRefSchema(schemaToDeRef, jsonSchemas) {
|
|
|
178
176
|
var _b = prop.$ref.split("/"), _0 = _b[0], _1 = _b[1], defKey = _b[2];
|
|
179
177
|
var refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
180
178
|
if (refedSchema) {
|
|
181
|
-
|
|
182
|
-
deRefSchema(refedSchema, jsonSchemas);
|
|
179
|
+
schemaToDeRef.properties[k] = deRefSchema(refedSchema, jsonSchemas);
|
|
183
180
|
}
|
|
184
181
|
else {
|
|
185
182
|
console.warn("Failed to find deref " + prop.$ref);
|
|
@@ -189,19 +186,18 @@ function deRefSchema(schemaToDeRef, jsonSchemas) {
|
|
|
189
186
|
var _c = prop.items.$ref.split("/"), _0 = _c[0], _1 = _c[1], defKey = _c[2];
|
|
190
187
|
var refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
191
188
|
if (refedSchema) {
|
|
192
|
-
|
|
193
|
-
deRefSchema(refedSchema, jsonSchemas);
|
|
189
|
+
schemaToDeRef.properties[k].items = deRefSchema(refedSchema, jsonSchemas);
|
|
194
190
|
}
|
|
195
191
|
else {
|
|
196
192
|
console.warn("Failed to find deref " + prop.$ref);
|
|
197
193
|
}
|
|
198
194
|
}
|
|
199
|
-
else if (prop.type === "object") {
|
|
200
|
-
deRefSchema(prop, jsonSchemas);
|
|
195
|
+
else if (prop.type === "object" || prop.type === "array") {
|
|
196
|
+
schemaToDeRef.properties[k] = deRefSchema(prop, jsonSchemas);
|
|
201
197
|
}
|
|
202
198
|
}
|
|
203
199
|
}
|
|
204
|
-
return
|
|
200
|
+
return schemaToDeRef;
|
|
205
201
|
}
|
|
206
202
|
exports.deRefSchema = deRefSchema;
|
|
207
203
|
function getJsDocComment(comment) {
|
package/package.json
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
2
|
+
"name": "@flink-app/flink",
|
|
3
|
+
"version": "0.3.7",
|
|
4
|
+
"description": "Typescript only framework for creating REST-like APIs on top of Express and mongodb",
|
|
5
|
+
"types": "dist/src/index.d.ts",
|
|
6
|
+
"main": "dist/src/index.js",
|
|
7
|
+
"repository": "FrostDigital/flink",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "jasmine-ts --preserve-symlinks --config=./spec/support/jasmine.json",
|
|
10
|
+
"test:watch": "nodemon --ext ts --exec 'jasmine-ts --config=./spec/support/jasmine.json'",
|
|
11
|
+
"start": "ts-node src/index.ts",
|
|
12
|
+
"postinstall": "npm run build",
|
|
13
|
+
"prepublish": "npm run build",
|
|
14
|
+
"build": "tsc --project tsconfig.dist.json",
|
|
15
|
+
"watch": "nodemon --exec 'tsc --project tsconfig.dist.json'",
|
|
16
|
+
"clean": "rimraf dist"
|
|
17
|
+
},
|
|
18
|
+
"bin": {
|
|
19
|
+
"flink": "./dist/bin/flink.js"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@types/cors": "^2.8.10",
|
|
28
|
+
"@types/express": "^4.17.13",
|
|
29
|
+
"@types/fs-extra": "^9.0.12",
|
|
30
|
+
"@types/mongodb": "3.6.12",
|
|
31
|
+
"@types/uuid": "^8.3.0",
|
|
32
|
+
"ajv": "^8.2.0",
|
|
33
|
+
"ajv-formats": "^2.1.0",
|
|
34
|
+
"body-parser": "^1.19.0",
|
|
35
|
+
"cors": "^2.8.5",
|
|
36
|
+
"express": "^4.17.1",
|
|
37
|
+
"folder-hash": "^4.0.1",
|
|
38
|
+
"fs-extra": "^10.0.0",
|
|
39
|
+
"mkdirp": "^1.0.4",
|
|
40
|
+
"mock-json-schema": "^1.0.8",
|
|
41
|
+
"mongodb": "^3.6.6",
|
|
42
|
+
"node-color-log": "^5.2.0",
|
|
43
|
+
"passport": "^0.4.1",
|
|
44
|
+
"passport-jwt": "^4.0.0",
|
|
45
|
+
"reflect-metadata": "^0.1.13",
|
|
46
|
+
"tiny-glob": "^0.2.9",
|
|
47
|
+
"ts-json-schema-generator": "0.94.1",
|
|
48
|
+
"ts-morph": "11.0.0",
|
|
49
|
+
"typescript": "4.2.3",
|
|
50
|
+
"uuid": "^8.3.2"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/folder-hash": "^4.0.0",
|
|
54
|
+
"@types/jasmine": "^3.7.1",
|
|
55
|
+
"@types/json-schema": "^7.0.7",
|
|
56
|
+
"@types/mkdirp": "^1.0.1",
|
|
57
|
+
"@types/node": "^15.0.1",
|
|
58
|
+
"jasmine": "^3.7.0",
|
|
59
|
+
"jasmine-spec-reporter": "^7.0.0",
|
|
60
|
+
"jasmine-ts": "^0.3.3",
|
|
61
|
+
"nodemon": "^2.0.7",
|
|
62
|
+
"rimraf": "^3.0.2",
|
|
63
|
+
"ts-node": "^9.1.1"
|
|
64
|
+
},
|
|
65
|
+
"gitHead": "e61be35839aa8d459dc07613d9bfa919570361f2"
|
|
66
66
|
}
|
package/spec/FlinkRepo.spec.ts
CHANGED
|
@@ -31,7 +31,7 @@ describe("FlinkRepo", () => {
|
|
|
31
31
|
it("should get document by id", async () => {
|
|
32
32
|
const { insertedId } = await collection.insertOne({ name: "foo" });
|
|
33
33
|
|
|
34
|
-
const doc = await repo.
|
|
34
|
+
const doc = await repo.getById(insertedId + "");
|
|
35
35
|
|
|
36
36
|
expect(doc).toBeDefined();
|
|
37
37
|
expect(doc?.name).toBe("foo");
|
|
@@ -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" } }, "required": ["model"] } };
|
|
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"] } };
|
|
@@ -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" } }, "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: { "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 } };
|
|
@@ -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" } }, "required": ["model"], "additionalProperties": false } } };
|
|
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 } } };
|
|
@@ -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" } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false } } };
|
|
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 } } };
|
|
@@ -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" } }, "required": ["model"], "additionalProperties": false }, "year": { "type": "number" } }, "required": ["car", "year"], "additionalProperties": false } } };
|
|
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 } } };
|
|
@@ -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" } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false } };
|
|
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 } };
|
|
@@ -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" } }, "required": ["model"], "additionalProperties": false } }, "required": ["nestedCar"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false } };
|
|
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,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" } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false } };
|
|
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 } };
|
|
@@ -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" } }, "required": ["model"] }, resSchema: undefined };
|
|
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 };
|
|
@@ -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" } }, "required": ["model"] }, resSchema: undefined };
|
|
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 };
|
|
@@ -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" } }, "required": ["model"] }, resSchema: { "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" } }, "required": ["model"] } };
|
|
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"] } };
|
|
@@ -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" } }, "required": ["model"] }, resSchema: undefined };
|
|
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 };
|
package/spec/utils.spec.ts
CHANGED
|
@@ -63,6 +63,25 @@ describe("Utils", () => {
|
|
|
63
63
|
// @ts-ignore
|
|
64
64
|
expect(schema.items.properties.model.type).toBe("object");
|
|
65
65
|
});
|
|
66
|
+
|
|
67
|
+
it("should de-ref complex json schema", () => {
|
|
68
|
+
const dereffedSchema = deRefSchema(
|
|
69
|
+
jsonSchemasSet2.definitions!.GetStorages_9_ResSchema,
|
|
70
|
+
jsonSchemasSet2
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const schema = dereffedSchema as JSONSchema7;
|
|
74
|
+
|
|
75
|
+
expect(schema.type).toBe("object");
|
|
76
|
+
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
expect(schema.properties.storages.type).toBe("array");
|
|
79
|
+
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
expect(schema.properties.storages.items.properties.metadata.type).toBe(
|
|
82
|
+
"object"
|
|
83
|
+
);
|
|
84
|
+
});
|
|
66
85
|
});
|
|
67
86
|
|
|
68
87
|
describe("getJsDocComment", () => {
|
|
@@ -205,3 +224,42 @@ const jsonSchemas: JSONSchema7 = {
|
|
|
205
224
|
},
|
|
206
225
|
},
|
|
207
226
|
};
|
|
227
|
+
|
|
228
|
+
const jsonSchemasSet2: JSONSchema7 = {
|
|
229
|
+
// $schema: "http://json-schema.org/draft-07/schema#",
|
|
230
|
+
// $ref: "#/definitions/Schemas",
|
|
231
|
+
definitions: {
|
|
232
|
+
Metadata: {
|
|
233
|
+
type: "object",
|
|
234
|
+
properties: {
|
|
235
|
+
created: { type: "string", format: "date-time" },
|
|
236
|
+
updated: { type: "string", format: "date-time" },
|
|
237
|
+
},
|
|
238
|
+
required: ["created"],
|
|
239
|
+
additionalProperties: false,
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
GetStorages_9_ResSchema: {
|
|
243
|
+
type: "object",
|
|
244
|
+
additionalProperties: false,
|
|
245
|
+
properties: {
|
|
246
|
+
storages: {
|
|
247
|
+
type: "array",
|
|
248
|
+
items: {
|
|
249
|
+
type: "object",
|
|
250
|
+
properties: {
|
|
251
|
+
_id: { type: "string" },
|
|
252
|
+
name: { type: "string" },
|
|
253
|
+
metadata: { $ref: "#/definitions/Metadata" },
|
|
254
|
+
},
|
|
255
|
+
required: ["_id", "name", "metadata"],
|
|
256
|
+
additionalProperties: false,
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
required: ["storages"],
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
UserRole: { type: "string", enum: ["user", "admin", "teamLeader"] },
|
|
264
|
+
},
|
|
265
|
+
};
|
package/src/FlinkApp.ts
CHANGED
|
@@ -288,7 +288,6 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
288
288
|
* Typescript compiler will scan handler function and set schemas
|
|
289
289
|
* which are derived from handler function type arguments.
|
|
290
290
|
*/
|
|
291
|
-
// TODO: Rename to addHandler
|
|
292
291
|
public addHandler(
|
|
293
292
|
handler: HandlerFile,
|
|
294
293
|
routePropsOverride?: Partial<HandlerConfig["routeProps"]>
|
|
@@ -433,7 +432,7 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
433
432
|
log.warn(
|
|
434
433
|
`Handler '${methodAndRoute}' threw unhandled exception ${err}`
|
|
435
434
|
);
|
|
436
|
-
return res.status(500).json(internalServerError(err));
|
|
435
|
+
return res.status(500).json(internalServerError(err as any));
|
|
437
436
|
}
|
|
438
437
|
|
|
439
438
|
if (schema.resSchema && !isError(handlerRes)) {
|
package/src/FlinkHttpHandler.ts
CHANGED
|
@@ -14,6 +14,9 @@ export enum HttpMethod {
|
|
|
14
14
|
type Params = Request["params"];
|
|
15
15
|
type Query = Request["query"];
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Flink request extends express Request but adds reqId and user object.
|
|
19
|
+
*/
|
|
17
20
|
export type FlinkRequest<T = any, P = Params, Q = Query> = Request<
|
|
18
21
|
P,
|
|
19
22
|
any,
|
|
@@ -110,7 +113,7 @@ export type GetHandler<
|
|
|
110
113
|
* `import * as FooHandler from "./src/handlers/FooHandler"
|
|
111
114
|
*/
|
|
112
115
|
export type HandlerFile = {
|
|
113
|
-
default: Handler<any>;
|
|
116
|
+
default: Handler<any, any, any, any, any>;
|
|
114
117
|
Route?: RouteProps;
|
|
115
118
|
/**
|
|
116
119
|
* Name of schemas, is set at compile time by Flink compiler.
|
package/src/FlinkRepo.ts
CHANGED
|
@@ -23,14 +23,13 @@ export abstract class FlinkRepo<C extends FlinkContext, Model = any> {
|
|
|
23
23
|
return this.collection.find(query).toArray();
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
async
|
|
26
|
+
async getById(id: string): Promise<Model | null> {
|
|
27
27
|
return this.collection.findOne({ _id: new ObjectID(id) });
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
30
|
async getOne(query = {}): Promise<Model | null> {
|
|
32
31
|
return this.collection.findOne(query);
|
|
33
|
-
}
|
|
32
|
+
}
|
|
34
33
|
|
|
35
34
|
async create<C = Omit<Model, "_id">>(model: C): Promise<C & { _id: string }> {
|
|
36
35
|
const { ops } = await this.collection.insertOne(model);
|
package/src/FlinkResponse.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Response, Request } from "express";
|
|
2
2
|
|
|
3
3
|
export interface FlinkResponse<T = any> {
|
|
4
4
|
/**
|
|
@@ -43,3 +43,6 @@ export interface FlinkResponse<T = any> {
|
|
|
43
43
|
[x: string]: string;
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
+
|
|
47
|
+
export type ExpressResponse = Response;
|
|
48
|
+
export type ExpressRequest = Request;
|
package/src/FsUtils.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -97,27 +97,27 @@ export function deRefSchema(
|
|
|
97
97
|
return schemaToDeRef;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (theSchemaToDeRef.type === "array") {
|
|
103
|
-
const items = theSchemaToDeRef.items as JSONSchema7;
|
|
100
|
+
if (schemaToDeRef.type === "array") {
|
|
101
|
+
const items = schemaToDeRef.items as JSONSchema7;
|
|
104
102
|
|
|
105
103
|
if (items.$ref) {
|
|
106
104
|
const [_0, _1, defKey] = items.$ref.split("/");
|
|
107
105
|
const refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
108
106
|
|
|
109
107
|
if (refedSchema) {
|
|
110
|
-
|
|
111
|
-
deRefSchema(refedSchema, jsonSchemas);
|
|
108
|
+
schemaToDeRef.items = deRefSchema(refedSchema, jsonSchemas);
|
|
112
109
|
} else {
|
|
113
110
|
console.warn(`Failed to find deref ${schemaToDeRef.$ref}`);
|
|
114
111
|
}
|
|
115
112
|
} else {
|
|
116
|
-
deRefSchema(
|
|
113
|
+
schemaToDeRef.items = deRefSchema(
|
|
114
|
+
schemaToDeRef.items as JSONSchema7,
|
|
115
|
+
jsonSchemas
|
|
116
|
+
);
|
|
117
117
|
}
|
|
118
|
-
} else if (
|
|
119
|
-
for (const k in
|
|
120
|
-
|
|
118
|
+
} else if (schemaToDeRef.properties) {
|
|
119
|
+
for (const k in schemaToDeRef.properties) {
|
|
120
|
+
let prop = schemaToDeRef.properties[k];
|
|
121
121
|
|
|
122
122
|
if (typeof prop === "boolean") {
|
|
123
123
|
continue;
|
|
@@ -127,8 +127,7 @@ export function deRefSchema(
|
|
|
127
127
|
const [_0, _1, defKey] = prop.$ref.split("/");
|
|
128
128
|
const refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
129
129
|
if (refedSchema) {
|
|
130
|
-
|
|
131
|
-
deRefSchema(refedSchema, jsonSchemas);
|
|
130
|
+
schemaToDeRef.properties[k] = deRefSchema(refedSchema, jsonSchemas);
|
|
132
131
|
} else {
|
|
133
132
|
console.warn(`Failed to find deref ${prop.$ref}`);
|
|
134
133
|
}
|
|
@@ -136,18 +135,19 @@ export function deRefSchema(
|
|
|
136
135
|
const [_0, _1, defKey] = (prop.items as JSONSchema7).$ref!.split("/");
|
|
137
136
|
const refedSchema = (jsonSchemas.definitions || {})[defKey];
|
|
138
137
|
if (refedSchema) {
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
(schemaToDeRef.properties[k] as JSONSchema7).items = deRefSchema(
|
|
139
|
+
refedSchema,
|
|
140
|
+
jsonSchemas
|
|
141
|
+
);
|
|
141
142
|
} else {
|
|
142
143
|
console.warn(`Failed to find deref ${prop.$ref}`);
|
|
143
144
|
}
|
|
144
|
-
} else if (prop.type === "object") {
|
|
145
|
-
deRefSchema(prop, jsonSchemas);
|
|
145
|
+
} else if (prop.type === "object" || prop.type === "array") {
|
|
146
|
+
schemaToDeRef.properties[k] = deRefSchema(prop, jsonSchemas);
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
149
|
}
|
|
149
|
-
|
|
150
|
-
return theSchemaToDeRef;
|
|
150
|
+
return schemaToDeRef;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
export function getJsDocComment(comment: string) {
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { BaseType, Definition, FunctionType, SubTypeFormatter, TypeFormatter } from "ts-json-schema-generator";
|
|
2
|
-
export declare class CustomRefFormatter implements SubTypeFormatter {
|
|
3
|
-
private childTypeFormatter;
|
|
4
|
-
constructor(childTypeFormatter: TypeFormatter);
|
|
5
|
-
supportsType(type: FunctionType): boolean;
|
|
6
|
-
getDefinition(type: FunctionType): Definition;
|
|
7
|
-
getChildren(type: FunctionType): BaseType[];
|
|
8
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CustomRefFormatter = void 0;
|
|
4
|
-
var ts_json_schema_generator_1 = require("ts-json-schema-generator");
|
|
5
|
-
var CustomRefFormatter = /** @class */ (function () {
|
|
6
|
-
// You can skip this line if you don't need childTypeFormatter
|
|
7
|
-
function CustomRefFormatter(childTypeFormatter) {
|
|
8
|
-
this.childTypeFormatter = childTypeFormatter;
|
|
9
|
-
}
|
|
10
|
-
CustomRefFormatter.prototype.supportsType = function (type) {
|
|
11
|
-
return type instanceof ts_json_schema_generator_1.FunctionType;
|
|
12
|
-
};
|
|
13
|
-
CustomRefFormatter.prototype.getDefinition = function (type) {
|
|
14
|
-
// Return a custom schema for the function property.
|
|
15
|
-
return {
|
|
16
|
-
type: "object",
|
|
17
|
-
properties: {
|
|
18
|
-
isFunction: {
|
|
19
|
-
type: "boolean",
|
|
20
|
-
const: true,
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
// If this type does NOT HAVE children, generally all you need is:
|
|
26
|
-
CustomRefFormatter.prototype.getChildren = function (type) {
|
|
27
|
-
return [];
|
|
28
|
-
};
|
|
29
|
-
// However, if children ARE supported, you'll need something similar to
|
|
30
|
-
// this (see src/TypeFormatter/{Array,Definition,etc}.ts for some examples):
|
|
31
|
-
CustomRefFormatter.prototype.getChildren = function (type) {
|
|
32
|
-
return this.childTypeFormatter.getChildren(type.getType());
|
|
33
|
-
};
|
|
34
|
-
return CustomRefFormatter;
|
|
35
|
-
}());
|
|
36
|
-
exports.CustomRefFormatter = CustomRefFormatter;
|