@flink-app/flink 0.7.0-alpha.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/flink.ts +0 -0
- package/dist/src/FlinkApp.d.ts +4 -5
- package/dist/src/FlinkApp.js +16 -15
- package/dist/src/FlinkHttpHandler.d.ts +4 -6
- package/dist/src/TypeScriptCompiler.d.ts +1 -1
- package/dist/src/TypeScriptCompiler.js +88 -81
- package/dist/src/utils.js +0 -17
- package/package.json +2 -2
- package/spec/TypeScriptCompiler.spec.ts +42 -39
- package/src/FlinkApp.ts +18 -17
- package/src/FlinkHttpHandler.ts +95 -103
- package/src/TypeScriptCompiler.ts +93 -89
- package/src/utils.ts +0 -20
- package/.vscode/notes.txt +0 -11
- package/spec/mock-project/dist/src/handlers/GetCar.js +0 -57
- package/spec/mock-project/dist/src/handlers/GetCar2.js +0 -59
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +0 -53
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +0 -53
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +0 -53
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +0 -55
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +0 -55
- package/spec/mock-project/dist/src/handlers/GetCarWithOmitSchema.js +0 -59
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js +0 -58
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +0 -58
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +0 -53
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +0 -56
- package/spec/mock-project/dist/src/handlers/PostCar.js +0 -55
- package/spec/mock-project/dist/src/handlers/PostLogin.js +0 -56
- package/spec/mock-project/dist/src/handlers/PutCar.js +0 -55
- package/spec/mock-project/dist/src/index.js +0 -79
- package/spec/mock-project/dist/src/repos/CarRepo.js +0 -26
- package/spec/mock-project/dist/src/schemas/Car.js +0 -2
- package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js +0 -2
- package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js +0 -2
package/bin/flink.ts
CHANGED
|
File without changes
|
package/dist/src/FlinkApp.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Db } from "mongodb";
|
|
|
5
5
|
import { ToadScheduler } from "toad-scheduler";
|
|
6
6
|
import { FlinkAuthPlugin } from "./auth/FlinkAuthPlugin";
|
|
7
7
|
import { FlinkContext } from "./FlinkContext";
|
|
8
|
-
import {
|
|
8
|
+
import { HandlerFile, HttpMethod, QueryParamMetadata, RouteProps } from "./FlinkHttpHandler";
|
|
9
9
|
import { FlinkJobFile } from "./FlinkJob";
|
|
10
10
|
import { FlinkPlugin } from "./FlinkPlugin";
|
|
11
11
|
import { FlinkRepo } from "./FlinkRepo";
|
|
@@ -14,11 +14,10 @@ export declare type JSONSchema = JSONSchema7;
|
|
|
14
14
|
* This will be populated at compile time when the apps handlers
|
|
15
15
|
* are picked up by TypeScript compiler
|
|
16
16
|
*/
|
|
17
|
-
export declare const autoRegisteredHandlers:
|
|
17
|
+
export declare const autoRegisteredHandlers: {
|
|
18
18
|
handler: HandlerFile;
|
|
19
19
|
assumedHttpMethod: HttpMethod;
|
|
20
|
-
|
|
21
|
-
} & FlinkCompileTimeHandlerDetails)[];
|
|
20
|
+
}[];
|
|
22
21
|
/**
|
|
23
22
|
* This will be populated at compile time when the apps repos
|
|
24
23
|
* are picked up by TypeScript compiler
|
|
@@ -183,7 +182,7 @@ export declare class FlinkApp<C extends FlinkContext> {
|
|
|
183
182
|
* Typescript compiler will scan handler function and set schemas
|
|
184
183
|
* which are derived from handler function type arguments.
|
|
185
184
|
*/
|
|
186
|
-
addHandler(handler: HandlerFile
|
|
185
|
+
addHandler(handler: HandlerFile, routePropsOverride?: Partial<HandlerConfig["routeProps"]>): void;
|
|
187
186
|
private registerHandler;
|
|
188
187
|
/**
|
|
189
188
|
* Register handlers found within the `/src/handlers`
|
package/dist/src/FlinkApp.js
CHANGED
|
@@ -400,40 +400,41 @@ var FlinkApp = /** @class */ (function () {
|
|
|
400
400
|
* Will not register any handlers added programmatically.
|
|
401
401
|
*/
|
|
402
402
|
FlinkApp.prototype.registerAutoRegisterableHandlers = function () {
|
|
403
|
+
var _a, _b, _c;
|
|
403
404
|
return __awaiter(this, void 0, void 0, function () {
|
|
404
|
-
var _i, autoRegisteredHandlers_1,
|
|
405
|
-
return __generator(this, function (
|
|
405
|
+
var _i, autoRegisteredHandlers_1, _d, handler, assumedHttpMethod, pathParams, _e, _f, param;
|
|
406
|
+
return __generator(this, function (_g) {
|
|
406
407
|
for (_i = 0, autoRegisteredHandlers_1 = exports.autoRegisteredHandlers; _i < autoRegisteredHandlers_1.length; _i++) {
|
|
407
|
-
|
|
408
|
+
_d = autoRegisteredHandlers_1[_i], handler = _d.handler, assumedHttpMethod = _d.assumedHttpMethod;
|
|
408
409
|
if (!handler.Route) {
|
|
409
|
-
FlinkLog_1.log.error("Missing Props in handler " + __file);
|
|
410
|
+
FlinkLog_1.log.error("Missing Props in handler " + handler.__file);
|
|
410
411
|
continue;
|
|
411
412
|
}
|
|
412
413
|
if (!handler.default) {
|
|
413
|
-
FlinkLog_1.log.error("Missing exported handler function in handler " + __file);
|
|
414
|
+
FlinkLog_1.log.error("Missing exported handler function in handler " + handler.__file);
|
|
414
415
|
continue;
|
|
415
416
|
}
|
|
416
|
-
if (!!(__params === null ||
|
|
417
|
+
if (!!((_a = handler.__params) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
417
418
|
pathParams = utils_1.getPathParams(handler.Route.path);
|
|
418
|
-
for (
|
|
419
|
-
param =
|
|
419
|
+
for (_e = 0, _f = handler.__params; _e < _f.length; _e++) {
|
|
420
|
+
param = _f[_e];
|
|
420
421
|
if (!pathParams.includes(param.name)) {
|
|
421
|
-
FlinkLog_1.log.error("Handler " + __file + " has param " + param.name + " but it is not present in the path '" + handler.Route.path + "'");
|
|
422
|
+
FlinkLog_1.log.error("Handler " + handler.__file + " has param " + param.name + " but it is not present in the path '" + handler.Route.path + "'");
|
|
422
423
|
throw new Error("Invalid/missing handler path param");
|
|
423
424
|
}
|
|
424
425
|
}
|
|
425
|
-
if (pathParams.length !== __params.length) {
|
|
426
|
-
FlinkLog_1.log.warn("Handler " + __file + " has " + __params.length + " typed params but the path '" + handler.Route.path + "' has " + pathParams.length + " params");
|
|
426
|
+
if (pathParams.length !== handler.__params.length) {
|
|
427
|
+
FlinkLog_1.log.warn("Handler " + handler.__file + " has " + handler.__params.length + " typed params but the path '" + handler.Route.path + "' has " + pathParams.length + " params");
|
|
427
428
|
}
|
|
428
429
|
}
|
|
429
430
|
this.registerHandler({
|
|
430
431
|
routeProps: __assign(__assign({}, handler.Route), { method: handler.Route.method || assumedHttpMethod, origin: this.name }),
|
|
431
432
|
schema: {
|
|
432
|
-
reqSchema: __schemas === null ||
|
|
433
|
-
resSchema: __schemas === null ||
|
|
433
|
+
reqSchema: (_b = handler.__schemas) === null || _b === void 0 ? void 0 : _b.reqSchema,
|
|
434
|
+
resSchema: (_c = handler.__schemas) === null || _c === void 0 ? void 0 : _c.resSchema,
|
|
434
435
|
},
|
|
435
|
-
queryMetadata: __query || [],
|
|
436
|
-
paramsMetadata: __params || [],
|
|
436
|
+
queryMetadata: handler.__query || [],
|
|
437
|
+
paramsMetadata: handler.__params || [],
|
|
437
438
|
}, handler.default);
|
|
438
439
|
}
|
|
439
440
|
return [2 /*return*/];
|
|
@@ -89,12 +89,6 @@ export declare type GetHandler<Ctx extends FlinkContext, ResSchema = any, P exte
|
|
|
89
89
|
export declare type HandlerFile = {
|
|
90
90
|
default: Handler<any, any, any, any, any>;
|
|
91
91
|
Route?: RouteProps;
|
|
92
|
-
};
|
|
93
|
-
export declare type QueryParamMetadata = {
|
|
94
|
-
name: string;
|
|
95
|
-
description: string;
|
|
96
|
-
};
|
|
97
|
-
export declare type FlinkCompileTimeHandlerDetails = {
|
|
98
92
|
/**
|
|
99
93
|
* Name of schemas, is set at compile time by Flink compiler.
|
|
100
94
|
*/
|
|
@@ -115,4 +109,8 @@ export declare type FlinkCompileTimeHandlerDetails = {
|
|
|
115
109
|
*/
|
|
116
110
|
__params?: QueryParamMetadata[];
|
|
117
111
|
};
|
|
112
|
+
export declare type QueryParamMetadata = {
|
|
113
|
+
name: string;
|
|
114
|
+
description: string;
|
|
115
|
+
};
|
|
118
116
|
export {};
|
|
@@ -103,7 +103,7 @@ declare class TypeScriptCompiler {
|
|
|
103
103
|
* @param handlers
|
|
104
104
|
* @param jsonSchemas
|
|
105
105
|
*/
|
|
106
|
-
private
|
|
106
|
+
private appendSchemasToHandlerSourceFiles;
|
|
107
107
|
/**
|
|
108
108
|
* Scans project for jobs so they can be registered during start.
|
|
109
109
|
*/
|
|
@@ -46,17 +46,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
50
|
-
var t = {};
|
|
51
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
52
|
-
t[p] = s[p];
|
|
53
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
54
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
55
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
56
|
-
t[p[i]] = s[p[i]];
|
|
57
|
-
}
|
|
58
|
-
return t;
|
|
59
|
-
};
|
|
60
49
|
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
61
50
|
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
62
51
|
to[j] = from[i];
|
|
@@ -190,37 +179,26 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
190
179
|
TypeScriptCompiler.prototype.parseHandlers = function (excludeDirs) {
|
|
191
180
|
if (excludeDirs === void 0) { excludeDirs = []; }
|
|
192
181
|
return __awaiter(this, void 0, void 0, function () {
|
|
193
|
-
var generatedFile,
|
|
182
|
+
var generatedFile, handlersArr, handlers, jsonSchemas;
|
|
194
183
|
return __generator(this, function (_a) {
|
|
195
184
|
switch (_a.label) {
|
|
196
185
|
case 0:
|
|
197
186
|
generatedFile = this.createSourceFile(["generatedHandlers.ts"], "// Generated " + new Date() + "\nimport { autoRegisteredHandlers, HttpMethod } from \"@flink-app/flink\";\nexport const handlers = [];\nautoRegisteredHandlers.push(...handlers);\n ");
|
|
198
|
-
|
|
187
|
+
handlersArr = generatedFile.getVariableDeclarationOrThrow("handlers").getFirstDescendantByKindOrThrow(ts_morph_1.SyntaxKind.ArrayLiteralExpression);
|
|
188
|
+
return [4 /*yield*/, this.parseHandlerDir(generatedFile, handlersArr)];
|
|
199
189
|
case 1:
|
|
200
|
-
|
|
201
|
-
|
|
190
|
+
handlers = _a.sent();
|
|
191
|
+
generatedFile.addImportDeclarations(handlers.imports);
|
|
192
|
+
return [4 /*yield*/, generatedFile.save()];
|
|
202
193
|
case 2:
|
|
203
194
|
_a.sent();
|
|
204
|
-
|
|
205
|
-
return [4 /*yield*/, this.generateAndSaveJsonSchemas(schemas)];
|
|
195
|
+
return [4 /*yield*/, this.createIntermediateSchemaFile()];
|
|
206
196
|
case 3:
|
|
207
|
-
jsonSchemas = _a.sent();
|
|
208
|
-
this.appendSchemasToHandlers(parseResult, jsonSchemas);
|
|
209
|
-
generatedFile.addImportDeclarations(parseResult.map(function (h) { return ({ namespaceImport: h.importName, moduleSpecifier: h.moduleSpecifier }); }));
|
|
210
|
-
if (parseResult.length > 0) {
|
|
211
|
-
handlersArr = generatedFile.getVariableDeclarationOrThrow("handlers").getFirstDescendantByKindOrThrow(ts_morph_1.SyntaxKind.ArrayLiteralExpression);
|
|
212
|
-
handlersArr.insertElements(0, parseResult.map(function (parsedHandler) {
|
|
213
|
-
// Do some hairy string bending to generate valid typescript from json string
|
|
214
|
-
var assumedHttpMethod = parsedHandler.assumedHttpMethod, rest = __rest(parsedHandler, ["assumedHttpMethod"]);
|
|
215
|
-
var restStringified = JSON.stringify(rest);
|
|
216
|
-
// Now append handler reference the assumedHttpMethod with type (not json strings)
|
|
217
|
-
return (restStringified.substring(0, restStringified.length - 1) +
|
|
218
|
-
(",\"assumedHttpMethod\":" + assumedHttpMethod + ",\"handler\":" + parsedHandler.importName + ",\"Route\":" + parsedHandler.importName + ".Route}"));
|
|
219
|
-
}));
|
|
220
|
-
}
|
|
221
|
-
return [4 /*yield*/, generatedFile.save()];
|
|
222
|
-
case 4:
|
|
223
197
|
_a.sent();
|
|
198
|
+
return [4 /*yield*/, this.generateAndSaveJsonSchemas(handlers.schemasToGenerate)];
|
|
199
|
+
case 4:
|
|
200
|
+
jsonSchemas = _a.sent();
|
|
201
|
+
this.appendSchemasToHandlerSourceFiles(handlers.schemasToGenerate, jsonSchemas);
|
|
224
202
|
return [2 /*return*/, generatedFile];
|
|
225
203
|
}
|
|
226
204
|
});
|
|
@@ -229,14 +207,15 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
229
207
|
/**
|
|
230
208
|
* Scan `/src/handlers/*.ts` for handler files and register those.
|
|
231
209
|
*/
|
|
232
|
-
TypeScriptCompiler.prototype.parseHandlerDir = function (generatedFile) {
|
|
210
|
+
TypeScriptCompiler.prototype.parseHandlerDir = function (generatedFile, handlersArr) {
|
|
233
211
|
return __awaiter(this, void 0, void 0, function () {
|
|
234
|
-
var i,
|
|
212
|
+
var imports, i, schemasToGenerate, _i, _a, sf, isAutoRegister, namespaceImport, assumedHttpMethod, schemaTypes;
|
|
235
213
|
return __generator(this, function (_b) {
|
|
236
214
|
switch (_b.label) {
|
|
237
215
|
case 0:
|
|
216
|
+
imports = [];
|
|
238
217
|
i = 0;
|
|
239
|
-
|
|
218
|
+
schemasToGenerate = [];
|
|
240
219
|
_i = 0, _a = this.project.getSourceFiles();
|
|
241
220
|
_b.label = 1;
|
|
242
221
|
case 1:
|
|
@@ -247,39 +226,70 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
247
226
|
}
|
|
248
227
|
isAutoRegister = this.isAutoRegisterableHandler(sf);
|
|
249
228
|
console.log("Detected handler " + sf.getBaseName() + " " + (!isAutoRegister ? "(requires manual registration)" : ""));
|
|
250
|
-
|
|
229
|
+
namespaceImport = sf.getBaseNameWithoutExtension().replace(/\./g, "_") + "_" + i;
|
|
230
|
+
imports.push({
|
|
231
|
+
defaultImport: "* as " + namespaceImport,
|
|
232
|
+
moduleSpecifier: generatedFile.getRelativePathAsModuleSpecifierTo(sf),
|
|
233
|
+
});
|
|
251
234
|
assumedHttpMethod = utils_1.getHttpMethodFromHandlerName(sf.getBaseName());
|
|
252
235
|
return [4 /*yield*/, this.extractSchemasFromHandlerSourceFile(sf)];
|
|
253
236
|
case 2:
|
|
254
237
|
schemaTypes = _b.sent();
|
|
238
|
+
// Append schemas and metadata to source file that will be part of emitted dist bundle (javascript)
|
|
239
|
+
sf.addVariableStatement({
|
|
240
|
+
declarationKind: ts_morph_1.VariableDeclarationKind.Const,
|
|
241
|
+
isExported: true,
|
|
242
|
+
declarations: [
|
|
243
|
+
{
|
|
244
|
+
name: "__assumedHttpMethod",
|
|
245
|
+
initializer: "\"" + (assumedHttpMethod || "") + "\"",
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: "__file",
|
|
249
|
+
initializer: "\"" + sf.getBaseName() + "\"",
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: "__query",
|
|
253
|
+
initializer: "[" + ((schemaTypes === null || schemaTypes === void 0 ? void 0 : schemaTypes.queryMetadata) || [])
|
|
254
|
+
.map(function (_a) {
|
|
255
|
+
var description = _a.description, name = _a.name;
|
|
256
|
+
return "{description: \"" + description + "\", name: \"" + name + "\"}";
|
|
257
|
+
})
|
|
258
|
+
.join(",") + "]",
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: "__params",
|
|
262
|
+
initializer: "[" + ((schemaTypes === null || schemaTypes === void 0 ? void 0 : schemaTypes.paramsMetadata) || [])
|
|
263
|
+
.map(function (_a) {
|
|
264
|
+
var description = _a.description, name = _a.name;
|
|
265
|
+
return "{description: \"" + description + "\", name: \"" + name + "\"}";
|
|
266
|
+
})
|
|
267
|
+
.join(",") + "]",
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
});
|
|
255
271
|
if (isAutoRegister) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
reqSchemaType: schemaTypes === null || schemaTypes === void 0 ? void 0 : schemaTypes.reqSchemaType,
|
|
262
|
-
resSchemaType: schemaTypes === null || schemaTypes === void 0 ? void 0 : schemaTypes.resSchemaType,
|
|
263
|
-
}
|
|
264
|
-
: undefined,
|
|
265
|
-
assumedHttpMethod: "HttpMethod." + assumedHttpMethod,
|
|
266
|
-
__file: sf.getBaseName(),
|
|
267
|
-
__query: schemaTypes === null || schemaTypes === void 0 ? void 0 : schemaTypes.queryMetadata,
|
|
268
|
-
__params: schemaTypes === null || schemaTypes === void 0 ? void 0 : schemaTypes.paramsMetadata,
|
|
269
|
-
});
|
|
272
|
+
handlersArr.insertElement(i, "{handler: " + namespaceImport + ", assumedHttpMethod: " + (assumedHttpMethod ? "HttpMethod." + assumedHttpMethod : undefined) + "}");
|
|
273
|
+
i++;
|
|
274
|
+
}
|
|
275
|
+
if (schemaTypes) {
|
|
276
|
+
schemasToGenerate.push(__assign(__assign({}, schemaTypes), { sourceFile: sf }));
|
|
270
277
|
}
|
|
271
278
|
_b.label = 3;
|
|
272
279
|
case 3:
|
|
273
280
|
_i++;
|
|
274
281
|
return [3 /*break*/, 1];
|
|
275
|
-
case 4: return [2 /*return*/,
|
|
282
|
+
case 4: return [2 /*return*/, {
|
|
283
|
+
imports: imports,
|
|
284
|
+
schemasToGenerate: schemasToGenerate,
|
|
285
|
+
}];
|
|
276
286
|
}
|
|
277
287
|
});
|
|
278
288
|
});
|
|
279
289
|
};
|
|
280
290
|
TypeScriptCompiler.prototype.parseRepos = function () {
|
|
281
291
|
return __awaiter(this, void 0, void 0, function () {
|
|
282
|
-
var generatedFile, reposArr, imports, i,
|
|
292
|
+
var generatedFile, reposArr, imports, i, _i, _a, sf;
|
|
283
293
|
return __generator(this, function (_b) {
|
|
284
294
|
switch (_b.label) {
|
|
285
295
|
case 0:
|
|
@@ -287,7 +297,6 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
287
297
|
reposArr = generatedFile.getVariableDeclarationOrThrow("repos").getFirstDescendantByKindOrThrow(ts_morph_1.SyntaxKind.ArrayLiteralExpression);
|
|
288
298
|
imports = [];
|
|
289
299
|
i = 0;
|
|
290
|
-
reposToInsert = [];
|
|
291
300
|
for (_i = 0, _a = this.project.getSourceFiles(); _i < _a.length; _i++) {
|
|
292
301
|
sf = _a[_i];
|
|
293
302
|
if (!sf.getFilePath().includes("src/repos/")) {
|
|
@@ -298,12 +307,9 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
298
307
|
defaultImport: sf.getBaseNameWithoutExtension(),
|
|
299
308
|
moduleSpecifier: generatedFile.getRelativePathAsModuleSpecifierTo(sf),
|
|
300
309
|
});
|
|
301
|
-
|
|
310
|
+
reposArr.insertElement(i, "{collectionName: \"" + utils_1.getCollectionNameForRepo(sf.getBaseName()) + "\", repoInstanceName: \"" + utils_1.getRepoInstanceName(sf.getBaseName()) + "\", Repo: " + sf.getBaseNameWithoutExtension() + "}");
|
|
302
311
|
i++;
|
|
303
312
|
}
|
|
304
|
-
if (reposToInsert.length > 0) {
|
|
305
|
-
reposArr.insertElements(0, reposToInsert);
|
|
306
|
-
}
|
|
307
313
|
generatedFile.addImportDeclarations(imports);
|
|
308
314
|
return [4 /*yield*/, generatedFile.save()];
|
|
309
315
|
case 1:
|
|
@@ -602,34 +608,39 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
602
608
|
* @param handlers
|
|
603
609
|
* @param jsonSchemas
|
|
604
610
|
*/
|
|
605
|
-
TypeScriptCompiler.prototype.
|
|
606
|
-
var _a, _b, _c, _d;
|
|
611
|
+
TypeScriptCompiler.prototype.appendSchemasToHandlerSourceFiles = function (handlers, jsonSchemas) {
|
|
607
612
|
var jsonSchemaDefs = jsonSchemas.definitions || {};
|
|
608
|
-
for (var _i = 0,
|
|
609
|
-
var
|
|
610
|
-
if (
|
|
611
|
-
console.error("Handler " +
|
|
613
|
+
for (var _i = 0, handlers_1 = handlers; _i < handlers_1.length; _i++) {
|
|
614
|
+
var _a = handlers_1[_i], sourceFile = _a.sourceFile, reqSchemaType = _a.reqSchemaType, resSchemaType = _a.resSchemaType;
|
|
615
|
+
if (reqSchemaType && !jsonSchemaDefs[reqSchemaType]) {
|
|
616
|
+
console.error("Handler " + sourceFile.getBaseName() + " has request schema\u00A0(" + reqSchemaType + ") defined, but no JSON schema has been generated");
|
|
612
617
|
continue;
|
|
613
618
|
}
|
|
614
|
-
if (
|
|
615
|
-
console.error("Handler " +
|
|
619
|
+
if (resSchemaType && !jsonSchemaDefs[resSchemaType]) {
|
|
620
|
+
console.error("Handler " + sourceFile.getBaseName() + " has response schema\u00A0(" + resSchemaType + ") defined, but no JSON schema has been generated");
|
|
616
621
|
continue;
|
|
617
622
|
}
|
|
618
|
-
var reqJsonSchema = (
|
|
619
|
-
var resJsonSchema = (
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
623
|
+
var reqJsonSchema = JSON.stringify(reqSchemaType ? jsonSchemaDefs[reqSchemaType] : undefined);
|
|
624
|
+
var resJsonSchema = JSON.stringify(resSchemaType ? jsonSchemaDefs[resSchemaType] : undefined);
|
|
625
|
+
sourceFile.addVariableStatement({
|
|
626
|
+
declarationKind: ts_morph_1.VariableDeclarationKind.Const,
|
|
627
|
+
isExported: true,
|
|
628
|
+
declarations: [
|
|
629
|
+
{
|
|
630
|
+
name: "__schemas",
|
|
631
|
+
type: "any",
|
|
632
|
+
initializer: "{ reqSchema: " + reqJsonSchema + ", resSchema: " + resJsonSchema + " }",
|
|
633
|
+
},
|
|
634
|
+
],
|
|
635
|
+
});
|
|
624
636
|
}
|
|
625
|
-
return parseResult;
|
|
626
637
|
};
|
|
627
638
|
/**
|
|
628
639
|
* Scans project for jobs so they can be registered during start.
|
|
629
640
|
*/
|
|
630
641
|
TypeScriptCompiler.prototype.parseJobs = function () {
|
|
631
642
|
return __awaiter(this, void 0, void 0, function () {
|
|
632
|
-
var generatedFile, jobsArr, imports, i,
|
|
643
|
+
var generatedFile, jobsArr, imports, i, _i, _a, sf, namespaceImport;
|
|
633
644
|
return __generator(this, function (_b) {
|
|
634
645
|
switch (_b.label) {
|
|
635
646
|
case 0:
|
|
@@ -637,16 +648,15 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
637
648
|
jobsArr = generatedFile.getVariableDeclarationOrThrow("jobs").getFirstDescendantByKindOrThrow(ts_morph_1.SyntaxKind.ArrayLiteralExpression);
|
|
638
649
|
imports = [];
|
|
639
650
|
i = 0;
|
|
640
|
-
jobsToInsert = [];
|
|
641
651
|
for (_i = 0, _a = this.project.getSourceFiles(); _i < _a.length; _i++) {
|
|
642
652
|
sf = _a[_i];
|
|
643
653
|
if (!sf.getFilePath().includes("src/jobs/")) {
|
|
644
654
|
continue;
|
|
645
655
|
}
|
|
646
656
|
console.log("Detected job " + sf.getBaseName());
|
|
647
|
-
|
|
657
|
+
namespaceImport = sf.getBaseNameWithoutExtension().replace(/\./g, "_") + "_" + i;
|
|
648
658
|
imports.push({
|
|
649
|
-
|
|
659
|
+
defaultImport: "* as " + namespaceImport,
|
|
650
660
|
moduleSpecifier: generatedFile.getRelativePathAsModuleSpecifierTo(sf),
|
|
651
661
|
});
|
|
652
662
|
// Append metadata to source file that will be part of emitted dist bundle (javascript)
|
|
@@ -660,12 +670,9 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
660
670
|
},
|
|
661
671
|
],
|
|
662
672
|
});
|
|
663
|
-
|
|
673
|
+
jobsArr.insertElement(i, namespaceImport);
|
|
664
674
|
i++;
|
|
665
675
|
}
|
|
666
|
-
if (jobsToInsert.length > 0) {
|
|
667
|
-
jobsArr.insertElements(0, jobsToInsert);
|
|
668
|
-
}
|
|
669
676
|
generatedFile.addImportDeclarations(imports);
|
|
670
677
|
return [4 /*yield*/, generatedFile.save()];
|
|
671
678
|
case 1:
|
package/dist/src/utils.js
CHANGED
|
@@ -161,20 +161,3 @@ function getPathParams(path) {
|
|
|
161
161
|
return ((_a = path.match(pathParamsRegex)) === null || _a === void 0 ? void 0 : _a.map(function (match) { return match.slice(1); })) || [];
|
|
162
162
|
}
|
|
163
163
|
exports.getPathParams = getPathParams;
|
|
164
|
-
// export function stringifyWithoutQuotes(obj: Record<string, any>): string {
|
|
165
|
-
// let result = "{";
|
|
166
|
-
// let isFirstProp = true;
|
|
167
|
-
// for (let key in obj) {
|
|
168
|
-
// if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
169
|
-
// const value = obj[key];
|
|
170
|
-
// if (isFirstProp) {
|
|
171
|
-
// isFirstProp = false;
|
|
172
|
-
// } else {
|
|
173
|
-
// result += ",";
|
|
174
|
-
// }
|
|
175
|
-
// result += `${key}:${JSON.stringify(value)}`;
|
|
176
|
-
// }
|
|
177
|
-
// }
|
|
178
|
-
// result += "}";
|
|
179
|
-
// return result;
|
|
180
|
-
// }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flink-app/flink",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
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",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"rimraf": "^3.0.2",
|
|
68
68
|
"ts-node": "^9.1.1"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "3869def3e7e7e7105373ad31bc23a8ed68108015"
|
|
71
71
|
}
|
|
@@ -1,43 +1,46 @@
|
|
|
1
1
|
import TypeScriptCompiler from "../src/TypeScriptCompiler";
|
|
2
2
|
|
|
3
3
|
describe("TypeScriptCompiler", () => {
|
|
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
|
-
|
|
4
|
+
let compiler: TypeScriptCompiler;
|
|
5
|
+
|
|
6
|
+
beforeAll(async () => {
|
|
7
|
+
await TypeScriptCompiler.clean("spec/mock-project");
|
|
8
|
+
compiler = new TypeScriptCompiler("spec/mock-project");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("should get premit diagnostics", () => {
|
|
12
|
+
expect(compiler.getPreEmitDiagnostics()).toBeTrue();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("should parse repos and generate file", async () => {
|
|
16
|
+
const generatedFile = await compiler.parseRepos();
|
|
17
|
+
expect(generatedFile.getText()).toContain("CarRepo");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("should parse handlers and generate file", async () => {
|
|
21
|
+
const generatedFile = await compiler.parseHandlers();
|
|
22
|
+
compiler.emit();
|
|
23
|
+
|
|
24
|
+
expect(generatedFile.getText()).toContain(
|
|
25
|
+
`import { autoRegisteredHandlers, HttpMethod } from "@flink-app/flink"`
|
|
26
|
+
);
|
|
27
|
+
expect(generatedFile.getText()).toContain(
|
|
28
|
+
`import * as GetCar_0 from "../src/handlers/GetCar"`
|
|
29
|
+
);
|
|
30
|
+
expect(generatedFile.getText()).toContain(`export const handlers =`);
|
|
31
|
+
expect(generatedFile.getText()).toContain(
|
|
32
|
+
`{handler: GetCar_0, assumedHttpMethod: HttpMethod.get}`
|
|
33
|
+
);
|
|
34
|
+
// expect(generatedFile.getText()).toContain(
|
|
35
|
+
// `{routeProps: PostCar_5.Route, handlerFn: PostCar_5.default, assumedHttpMethod: HttpMethod.post}`
|
|
36
|
+
// );
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should generate start script", async () => {
|
|
40
|
+
const startScript = await compiler.generateStartScript();
|
|
41
|
+
|
|
42
|
+
expect(startScript.getText()).toContain(`import "./generatedHandlers";`);
|
|
43
|
+
expect(startScript.getText()).toContain(`import "./generatedRepos";`);
|
|
44
|
+
expect(startScript.getText()).toContain(`import "../src/index";`);
|
|
45
|
+
});
|
|
43
46
|
});
|
package/src/FlinkApp.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { v4 } from "uuid";
|
|
|
12
12
|
import { FlinkAuthPlugin } from "./auth/FlinkAuthPlugin";
|
|
13
13
|
import { FlinkContext } from "./FlinkContext";
|
|
14
14
|
import { internalServerError, notFound, unauthorized } from "./FlinkErrors";
|
|
15
|
-
import {
|
|
15
|
+
import { Handler, HandlerFile, HttpMethod, QueryParamMetadata, RouteProps } from "./FlinkHttpHandler";
|
|
16
16
|
import { FlinkJobFile } from "./FlinkJob";
|
|
17
17
|
import { log } from "./FlinkLog";
|
|
18
18
|
import { FlinkPlugin } from "./FlinkPlugin";
|
|
@@ -36,11 +36,10 @@ export type JSONSchema = JSONSchema7;
|
|
|
36
36
|
* This will be populated at compile time when the apps handlers
|
|
37
37
|
* are picked up by TypeScript compiler
|
|
38
38
|
*/
|
|
39
|
-
export const autoRegisteredHandlers:
|
|
39
|
+
export const autoRegisteredHandlers: {
|
|
40
40
|
handler: HandlerFile;
|
|
41
41
|
assumedHttpMethod: HttpMethod;
|
|
42
|
-
|
|
43
|
-
} & FlinkCompileTimeHandlerDetails)[] = [];
|
|
42
|
+
}[] = [];
|
|
44
43
|
|
|
45
44
|
/**
|
|
46
45
|
* This will be populated at compile time when the apps repos
|
|
@@ -365,7 +364,7 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
365
364
|
* Typescript compiler will scan handler function and set schemas
|
|
366
365
|
* which are derived from handler function type arguments.
|
|
367
366
|
*/
|
|
368
|
-
public addHandler(handler: HandlerFile
|
|
367
|
+
public addHandler(handler: HandlerFile, routePropsOverride?: Partial<HandlerConfig["routeProps"]>) {
|
|
369
368
|
if (this.routingConfigured) {
|
|
370
369
|
throw new Error("Cannot add handler after routes has been registered, make sure to invoke earlier");
|
|
371
370
|
}
|
|
@@ -553,29 +552,31 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
553
552
|
* Will not register any handlers added programmatically.
|
|
554
553
|
*/
|
|
555
554
|
private async registerAutoRegisterableHandlers() {
|
|
556
|
-
for (const { handler, assumedHttpMethod
|
|
555
|
+
for (const { handler, assumedHttpMethod } of autoRegisteredHandlers) {
|
|
557
556
|
if (!handler.Route) {
|
|
558
|
-
log.error(`Missing Props in handler ${__file}`);
|
|
557
|
+
log.error(`Missing Props in handler ${handler.__file}`);
|
|
559
558
|
continue;
|
|
560
559
|
}
|
|
561
560
|
|
|
562
561
|
if (!handler.default) {
|
|
563
|
-
log.error(`Missing exported handler function in handler ${__file}`);
|
|
562
|
+
log.error(`Missing exported handler function in handler ${handler.__file}`);
|
|
564
563
|
continue;
|
|
565
564
|
}
|
|
566
565
|
|
|
567
|
-
if (!!__params?.length) {
|
|
566
|
+
if (!!handler.__params?.length) {
|
|
568
567
|
const pathParams = getPathParams(handler.Route.path);
|
|
569
568
|
|
|
570
|
-
for (const param of __params) {
|
|
569
|
+
for (const param of handler.__params) {
|
|
571
570
|
if (!pathParams.includes(param.name)) {
|
|
572
|
-
log.error(`Handler ${__file} has param ${param.name} but it is not present in the path '${handler.Route.path}'`);
|
|
571
|
+
log.error(`Handler ${handler.__file} has param ${param.name} but it is not present in the path '${handler.Route.path}'`);
|
|
573
572
|
throw new Error("Invalid/missing handler path param");
|
|
574
573
|
}
|
|
575
574
|
}
|
|
576
575
|
|
|
577
|
-
if (pathParams.length !== __params.length) {
|
|
578
|
-
log.warn(
|
|
576
|
+
if (pathParams.length !== handler.__params.length) {
|
|
577
|
+
log.warn(
|
|
578
|
+
`Handler ${handler.__file} has ${handler.__params.length} typed params but the path '${handler.Route.path}' has ${pathParams.length} params`
|
|
579
|
+
);
|
|
579
580
|
}
|
|
580
581
|
}
|
|
581
582
|
|
|
@@ -587,11 +588,11 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
587
588
|
origin: this.name,
|
|
588
589
|
},
|
|
589
590
|
schema: {
|
|
590
|
-
reqSchema: __schemas?.reqSchema,
|
|
591
|
-
resSchema: __schemas?.resSchema,
|
|
591
|
+
reqSchema: handler.__schemas?.reqSchema,
|
|
592
|
+
resSchema: handler.__schemas?.resSchema,
|
|
592
593
|
},
|
|
593
|
-
queryMetadata: __query || [],
|
|
594
|
-
paramsMetadata: __params || [],
|
|
594
|
+
queryMetadata: handler.__query || [],
|
|
595
|
+
paramsMetadata: handler.__params || [],
|
|
595
596
|
},
|
|
596
597
|
handler.default
|
|
597
598
|
);
|