@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.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/cli/generate-schemas.ts +1 -1
  3. package/dist/cli/generate-schemas.js +1 -1
  4. package/dist/src/FlinkApp.js +0 -1
  5. package/dist/src/FlinkHttpHandler.d.ts +4 -1
  6. package/dist/src/FlinkRepo.d.ts +1 -1
  7. package/dist/src/FlinkRepo.js +1 -1
  8. package/dist/src/FlinkResponse.d.ts +3 -0
  9. package/dist/src/FsUtils.js +1 -1
  10. package/dist/src/utils.js +12 -16
  11. package/package.json +64 -64
  12. package/spec/FlinkRepo.spec.ts +1 -1
  13. package/spec/mock-project/dist/src/handlers/GetCar.js +1 -1
  14. package/spec/mock-project/dist/src/handlers/GetCar2.js +1 -1
  15. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +1 -1
  16. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +1 -1
  17. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +1 -1
  18. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +1 -1
  19. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +1 -1
  20. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +1 -1
  21. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +1 -1
  22. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +1 -1
  23. package/spec/mock-project/dist/src/handlers/PostCar.js +1 -1
  24. package/spec/mock-project/dist/src/handlers/PutCar.js +1 -1
  25. package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js +2 -0
  26. package/spec/mock-project/src/schemas/Car.ts +3 -0
  27. package/spec/mock-project/src/schemas/DefaultExportSchema.ts +3 -0
  28. package/spec/mock-project/src/schemas/FileWithTwoSchemas.ts +3 -0
  29. package/spec/utils.spec.ts +58 -0
  30. package/src/FlinkApp.ts +1 -2
  31. package/src/FlinkHttpHandler.ts +4 -1
  32. package/src/FlinkRepo.ts +2 -3
  33. package/src/FlinkResponse.ts +4 -1
  34. package/src/FsUtils.ts +1 -1
  35. package/src/utils.ts +18 -18
  36. package/dist/src/schema/CustomJsonSchemaFormatter.d.ts +0 -8
  37. 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.
@@ -110,7 +110,7 @@ module.exports = async function run(args: string[]) {
110
110
  console.error(
111
111
  "Failed to generate schema in file",
112
112
  sf.getBaseName() + ":",
113
- err.message
113
+ err
114
114
  );
115
115
  }
116
116
  }
@@ -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.message);
109
+ console.error("Failed to generate schema in file", sf.getBaseName() + ":", err);
110
110
  }
111
111
  }
112
112
  mergedSchemas = jsonSchemas.reduce(function (out, schema) {
@@ -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.
@@ -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
- getBydId(id: string): Promise<Model | null>;
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;
@@ -64,7 +64,7 @@ var FlinkRepo = /** @class */ (function () {
64
64
  });
65
65
  });
66
66
  };
67
- FlinkRepo.prototype.getBydId = function (id) {
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;
@@ -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 new Error(err);
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
- var theSchemaToDeRef = schemaToDeRef;
154
- if (theSchemaToDeRef.type === "array") {
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
- theSchemaToDeRef.items = refedSchema;
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 (theSchemaToDeRef.properties) {
172
- for (var k in theSchemaToDeRef.properties) {
173
- var prop = theSchemaToDeRef.properties[k];
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
- theSchemaToDeRef.properties[k] = refedSchema;
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
- prop.items = refedSchema;
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 theSchemaToDeRef;
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
- "name": "@flink-app/flink",
3
- "version": "0.2.0-beta.9",
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.11",
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": "9ea7b28898b3f40b17fa43d5dbbcb1f7c84a4ed6"
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
  }
@@ -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.getBydId(insertedId + "");
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 };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,5 +1,8 @@
1
+ import Metadata from "./DefaultExportSchema";
2
+
1
3
  interface Car {
2
4
  model: string;
5
+ metadata?: Metadata;
3
6
  }
4
7
 
5
8
  export default Car;
@@ -0,0 +1,3 @@
1
+ export default interface Metadata {
2
+ created?: Date;
3
+ }
@@ -1,5 +1,8 @@
1
+ import Metadata from "./DefaultExportSchema";
2
+
1
3
  export interface CarModel {
2
4
  name: string;
5
+ metadata?: Metadata;
3
6
  }
4
7
 
5
8
  export interface CarEngine {
@@ -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)) {
@@ -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 getBydId(id: string): Promise<Model | null> {
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);
@@ -1,4 +1,4 @@
1
- import express from "express";
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
@@ -46,7 +46,7 @@ export async function writeJsonFile(
46
46
  jsonStr = JSON.stringify(content, null, 2);
47
47
  } catch (err) {
48
48
  console.error("Failed to parse content into json string");
49
- throw new Error(err);
49
+ throw err;
50
50
  }
51
51
 
52
52
  return fsPromises.writeFile(path, jsonStr);
package/src/utils.ts CHANGED
@@ -97,27 +97,27 @@ export function deRefSchema(
97
97
  return schemaToDeRef;
98
98
  }
99
99
 
100
- const theSchemaToDeRef = schemaToDeRef as JSONSchema7;
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
- theSchemaToDeRef.items = refedSchema as JSONSchema7;
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(items, jsonSchemas);
113
+ schemaToDeRef.items = deRefSchema(
114
+ schemaToDeRef.items as JSONSchema7,
115
+ jsonSchemas
116
+ );
117
117
  }
118
- } else if (theSchemaToDeRef.properties) {
119
- for (const k in theSchemaToDeRef.properties) {
120
- const prop = theSchemaToDeRef.properties[k];
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
- theSchemaToDeRef.properties[k] = refedSchema;
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
- prop.items = refedSchema;
140
- deRefSchema(refedSchema, jsonSchemas);
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;