@flink-app/flink 0.12.1-alpha.9 → 0.13.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/CHANGELOG.md +7 -0
- package/dist/cli/build.js +2 -2
- package/dist/cli/clean.js +2 -2
- package/dist/cli/cli-utils.js +1 -2
- package/dist/cli/run.js +2 -2
- package/dist/src/FlinkApp.d.ts +6 -1
- package/dist/src/FlinkApp.js +28 -14
- package/dist/src/FlinkErrors.d.ts +69 -0
- package/dist/src/FlinkErrors.js +87 -8
- package/dist/src/FlinkHttpHandler.d.ts +14 -1
- package/dist/src/FlinkLog.d.ts +2 -2
- package/dist/src/FlinkRepo.d.ts +8 -1
- package/dist/src/FlinkRepo.js +9 -2
- package/dist/src/FlinkResponse.d.ts +0 -3
- package/dist/src/FsUtils.js +5 -6
- package/dist/src/TypeScriptCompiler.d.ts +10 -0
- package/dist/src/TypeScriptCompiler.js +169 -49
- package/dist/src/TypeScriptUtils.js +7 -8
- package/dist/src/index.d.ts +1 -0
- package/dist/src/utils.js +13 -14
- package/package.json +67 -69
- package/spec/TypeScriptCompiler.spec.ts +11 -1
- package/spec/mock-project/dist/src/handlers/GetCar.js +2 -2
- package/spec/mock-project/dist/src/handlers/GetCar2.js +2 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +2 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +2 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +2 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +2 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +2 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js +2 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +2 -2
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +3 -4
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +3 -4
- package/spec/mock-project/dist/src/handlers/PostCar.js +2 -2
- package/spec/mock-project/dist/src/handlers/PostLogin.js +2 -2
- package/spec/mock-project/dist/src/handlers/{GetCarWithOmitSchema.js → PostLogout.js} +16 -20
- package/spec/mock-project/dist/src/handlers/PutCar.js +2 -2
- package/spec/mock-project/dist/src/index.js +2 -2
- package/spec/mock-project/src/handlers/PostLogout.ts +19 -0
- package/spec/mock-project/tsconfig.json +1 -1
- package/src/FlinkApp.ts +24 -5
- package/src/FlinkErrors.ts +86 -6
- package/src/FlinkHttpHandler.ts +95 -96
- package/src/FlinkRepo.ts +8 -1
- package/src/FlinkResponse.ts +36 -39
- package/src/TypeScriptCompiler.ts +145 -39
- package/src/index.ts +12 -0
- package/tsconfig.json +1 -1
- package/dist/cli/generate-schemas.d.ts +0 -2
- package/dist/cli/generate-schemas.js +0 -140
- package/spec/mock-project/dist/src/handlers/GetCarWithTypeSchema.js +0 -60
- package/spec/mock-project/package-lock.json +0 -108
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { promises as fsPromises } from "fs";
|
|
1
|
+
import fs, { promises as fsPromises } from "fs";
|
|
2
2
|
import { JSONSchema7 } from "json-schema";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import glob from "tiny-glob";
|
|
5
|
-
import { CompletedConfig,
|
|
5
|
+
import { CompletedConfig, createFormatter, createParser, createProgram, Schema, SchemaGenerator } from "ts-json-schema-generator";
|
|
6
6
|
import {
|
|
7
7
|
ArrayLiteralExpression,
|
|
8
8
|
DiagnosticCategory,
|
|
@@ -24,6 +24,7 @@ import { getCollectionNameForRepo, getHttpMethodFromHandlerName, getRepoInstance
|
|
|
24
24
|
class TypeScriptCompiler {
|
|
25
25
|
private project: Project;
|
|
26
26
|
private schemaGenerator?: SchemaGenerator;
|
|
27
|
+
private isEsm: boolean;
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Parsed typescript schemas that will be added to intermediate
|
|
@@ -41,16 +42,72 @@ class TypeScriptCompiler {
|
|
|
41
42
|
private tsSchemasSymbolsToImports: Symbol[] = [];
|
|
42
43
|
|
|
43
44
|
constructor(private cwd: string) {
|
|
45
|
+
// Detect if project is using ESM based solely on package.json "type": "module"
|
|
46
|
+
this.isEsm = this.isEsmProject(cwd);
|
|
47
|
+
|
|
48
|
+
const compilerOptions: ts.CompilerOptions = {
|
|
49
|
+
noEmit: false, // We need to emit files
|
|
50
|
+
outDir: join(cwd, "dist"),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Set appropriate module settings based on detected module system
|
|
54
|
+
if (this.isEsm) {
|
|
55
|
+
// For ESM projects, use ESNext module with Node resolution
|
|
56
|
+
compilerOptions.module = ts.ModuleKind.ESNext;
|
|
57
|
+
compilerOptions.moduleResolution = ts.ModuleResolutionKind.NodeJs;
|
|
58
|
+
compilerOptions.esModuleInterop = true;
|
|
59
|
+
} else {
|
|
60
|
+
// For CommonJS projects, use CommonJS module with Node resolution
|
|
61
|
+
compilerOptions.module = ts.ModuleKind.CommonJS;
|
|
62
|
+
compilerOptions.moduleResolution = ts.ModuleResolutionKind.NodeJs;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const tsConfigPath = join(cwd, "tsconfig.json");
|
|
66
|
+
console.log("TypeScript config path:", require("path").resolve(tsConfigPath));
|
|
67
|
+
console.log("TypeScript version:", ts.version);
|
|
68
|
+
|
|
44
69
|
this.project = new Project({
|
|
45
|
-
tsConfigFilePath:
|
|
46
|
-
compilerOptions
|
|
47
|
-
noEmit: false,
|
|
48
|
-
outDir: join(cwd, "dist"),
|
|
49
|
-
// incremental: true,
|
|
50
|
-
},
|
|
70
|
+
tsConfigFilePath: tsConfigPath,
|
|
71
|
+
compilerOptions,
|
|
51
72
|
});
|
|
52
73
|
|
|
53
74
|
console.log("Loaded", this.project.getSourceFiles().length, "source file(s) from", cwd);
|
|
75
|
+
console.log("Module system:", this.isEsm ? "ESM" : "CommonJS");
|
|
76
|
+
console.log("Using module:", compilerOptions.module === ts.ModuleKind.ESNext ? "ESNext" : "CommonJS");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Detects if the project is using ESM (ECMAScript Modules)
|
|
81
|
+
* by checking type in package.json.
|
|
82
|
+
*/
|
|
83
|
+
private isEsmProject(cwd: string): boolean {
|
|
84
|
+
try {
|
|
85
|
+
// Check package.json for "type": "module"
|
|
86
|
+
const packageJsonPath = join(cwd, "package.json");
|
|
87
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
88
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
89
|
+
return packageJson.type === "module";
|
|
90
|
+
}
|
|
91
|
+
} catch (error) {
|
|
92
|
+
// If we can't determine, default to CommonJS
|
|
93
|
+
console.warn("Error detecting module system, defaulting to CommonJS:", error);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Gets the module specifier for imports, adding .js extension for ESM
|
|
101
|
+
*/
|
|
102
|
+
private getModuleSpecifier(fromFile: SourceFile, toFile: SourceFile): string {
|
|
103
|
+
let moduleSpecifier = fromFile.getRelativePathAsModuleSpecifierTo(toFile);
|
|
104
|
+
|
|
105
|
+
// Add .js extension for ESM imports (only for relative paths)
|
|
106
|
+
if (this.isEsm && !moduleSpecifier.startsWith("@") && !moduleSpecifier.endsWith(".js")) {
|
|
107
|
+
moduleSpecifier += ".js";
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return moduleSpecifier;
|
|
54
111
|
}
|
|
55
112
|
|
|
56
113
|
/**
|
|
@@ -139,9 +196,9 @@ autoRegisteredHandlers.push(...handlers);
|
|
|
139
196
|
|
|
140
197
|
await generatedFile.save();
|
|
141
198
|
|
|
142
|
-
await this.createIntermediateSchemaFile();
|
|
199
|
+
const schemaFilePath = await this.createIntermediateSchemaFile();
|
|
143
200
|
|
|
144
|
-
const jsonSchemas = await this.generateAndSaveJsonSchemas(handlers.schemasToGenerate);
|
|
201
|
+
const jsonSchemas = await this.generateAndSaveJsonSchemas(handlers.schemasToGenerate, schemaFilePath);
|
|
145
202
|
|
|
146
203
|
this.appendSchemasToHandlerSourceFiles(handlers.schemasToGenerate, jsonSchemas);
|
|
147
204
|
|
|
@@ -173,12 +230,20 @@ autoRegisteredHandlers.push(...handlers);
|
|
|
173
230
|
|
|
174
231
|
imports.push({
|
|
175
232
|
defaultImport: "* as " + namespaceImport,
|
|
176
|
-
moduleSpecifier:
|
|
233
|
+
moduleSpecifier: this.getModuleSpecifier(generatedFile, sf),
|
|
177
234
|
});
|
|
178
235
|
|
|
179
236
|
const assumedHttpMethod = getHttpMethodFromHandlerName(sf.getBaseName());
|
|
180
237
|
|
|
181
|
-
|
|
238
|
+
// Only extract schemas for auto-registered handlers
|
|
239
|
+
const schemaTypes = isAutoRegister ? await this.extractSchemasFromHandlerSourceFile(sf) : undefined;
|
|
240
|
+
|
|
241
|
+
// Remove existing metadata variables if they exist (to avoid redeclaration errors)
|
|
242
|
+
const existingVars = sf.getVariableStatements().filter((vs) => {
|
|
243
|
+
const varNames = vs.getDeclarations().map((d) => d.getName());
|
|
244
|
+
return varNames.some((name) => ["__assumedHttpMethod", "__file", "__query", "__params"].includes(name));
|
|
245
|
+
});
|
|
246
|
+
existingVars.forEach((v) => v.remove());
|
|
182
247
|
|
|
183
248
|
// Append schemas and metadata to source file that will be part of emitted dist bundle (javascript)
|
|
184
249
|
sf.addVariableStatement({
|
|
@@ -214,10 +279,11 @@ autoRegisteredHandlers.push(...handlers);
|
|
|
214
279
|
`{handler: ${namespaceImport}, assumedHttpMethod: ${assumedHttpMethod ? "HttpMethod." + assumedHttpMethod : undefined}}`
|
|
215
280
|
);
|
|
216
281
|
i++;
|
|
217
|
-
}
|
|
218
282
|
|
|
219
|
-
|
|
220
|
-
|
|
283
|
+
// Add schemas to generate list
|
|
284
|
+
if (schemaTypes) {
|
|
285
|
+
schemasToGenerate.push({ ...schemaTypes, sourceFile: sf });
|
|
286
|
+
}
|
|
221
287
|
}
|
|
222
288
|
}
|
|
223
289
|
|
|
@@ -252,7 +318,7 @@ autoRegisteredHandlers.push(...handlers);
|
|
|
252
318
|
|
|
253
319
|
imports.push({
|
|
254
320
|
defaultImport: sf.getBaseNameWithoutExtension(),
|
|
255
|
-
moduleSpecifier:
|
|
321
|
+
moduleSpecifier: this.getModuleSpecifier(generatedFile, sf),
|
|
256
322
|
});
|
|
257
323
|
|
|
258
324
|
reposArr.insertElement(
|
|
@@ -288,10 +354,11 @@ autoRegisteredHandlers.push(...handlers);
|
|
|
288
354
|
const sf = this.createSourceFile(
|
|
289
355
|
["start.ts"],
|
|
290
356
|
`// Generated ${new Date()}
|
|
291
|
-
import "./generatedHandlers";
|
|
292
|
-
import "./generatedRepos";
|
|
293
|
-
import "./generatedJobs";
|
|
294
|
-
import "..${appEntryScript.replace(/\.ts/g, "")}";
|
|
357
|
+
import "./generatedHandlers${this.isEsm ? ".js" : ""}";
|
|
358
|
+
import "./generatedRepos${this.isEsm ? ".js" : ""}";
|
|
359
|
+
import "./generatedJobs${this.isEsm ? ".js" : ""}";
|
|
360
|
+
import "..${appEntryScript.replace(/\.ts/g, "")}${this.isEsm ? ".js" : ""}";
|
|
361
|
+
export default {}; // Export an empty object to make it a module
|
|
295
362
|
`
|
|
296
363
|
);
|
|
297
364
|
|
|
@@ -410,15 +477,19 @@ import "..${appEntryScript.replace(/\.ts/g, "")}";
|
|
|
410
477
|
* We need extract `{car: Car}` into its own interface and make sure
|
|
411
478
|
* to import types if needed to
|
|
412
479
|
*/
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
480
|
+
const declarations = schema.getSymbolOrThrow().getDeclarations();
|
|
481
|
+
const declaration = declarations[0];
|
|
482
|
+
|
|
483
|
+
// Only extract type references if declaration exists (won't exist for empty object literals like {})
|
|
484
|
+
if (declaration) {
|
|
485
|
+
const typeRefIdentifiers = declaration
|
|
486
|
+
.getDescendantsOfKind(SyntaxKind.TypeReference)
|
|
487
|
+
.map((typeRef) => typeRef.getFirstChildByKindOrThrow(SyntaxKind.Identifier));
|
|
488
|
+
|
|
489
|
+
typeRefIdentifiers.forEach((tr) => {
|
|
490
|
+
this.tsSchemasSymbolsToImports.push(tr.getSymbolOrThrow().getDeclaredType().getSymbolOrThrow());
|
|
491
|
+
});
|
|
492
|
+
}
|
|
422
493
|
|
|
423
494
|
generatedSchemaInterfaceStr = `export interface ${schemaInterfaceName} { ${schema
|
|
424
495
|
.getProperties()
|
|
@@ -436,8 +507,10 @@ import "..${appEntryScript.replace(/\.ts/g, "")}";
|
|
|
436
507
|
return;
|
|
437
508
|
}
|
|
438
509
|
|
|
439
|
-
private initJsonSchemaGenerator() {
|
|
510
|
+
private initJsonSchemaGenerator(schemaFilePath: string) {
|
|
511
|
+
const tsconfigPath = join(this.cwd, "tsconfig.json");
|
|
440
512
|
const conf: CompletedConfig = {
|
|
513
|
+
path: schemaFilePath, // Point to the intermediate schema file
|
|
441
514
|
expose: "none", // Do not create shared $ref definitions.
|
|
442
515
|
topRef: false, // Removes the wrapper object around the schema.
|
|
443
516
|
additionalProperties: false,
|
|
@@ -451,23 +524,39 @@ import "..${appEntryScript.replace(/\.ts/g, "")}";
|
|
|
451
524
|
extraTags: [],
|
|
452
525
|
functions: "fail",
|
|
453
526
|
discriminatorType: "json-schema",
|
|
527
|
+
// tsconfig: tsconfigPath,
|
|
454
528
|
};
|
|
529
|
+
|
|
530
|
+
console.log("Creating TypeScript program for schema generation:");
|
|
531
|
+
console.log(" Schema file:", schemaFilePath);
|
|
532
|
+
console.log(" tsconfig:", tsconfigPath);
|
|
533
|
+
|
|
534
|
+
// Create a fresh TypeScript Program that includes the schema file
|
|
535
|
+
// This ensures ts-json-schema-generator can find the types we just generated
|
|
536
|
+
const program = createProgram(conf);
|
|
537
|
+
|
|
538
|
+
console.log(" TypeScript version:", ts.version);
|
|
539
|
+
console.log(" Program root files:", program.getRootFileNames().length);
|
|
540
|
+
|
|
455
541
|
const formatter = createFormatter(conf);
|
|
456
|
-
const parser = createParser(
|
|
457
|
-
const generator = new SchemaGenerator(
|
|
542
|
+
const parser = createParser(program, conf);
|
|
543
|
+
const generator = new SchemaGenerator(program, parser, formatter, conf);
|
|
458
544
|
|
|
459
545
|
return generator;
|
|
460
546
|
}
|
|
461
547
|
|
|
462
|
-
private async generateAndSaveJsonSchemas(schemas: { reqSchemaType?: string; resSchemaType?: string }[]) {
|
|
548
|
+
private async generateAndSaveJsonSchemas(schemas: { reqSchemaType?: string; resSchemaType?: string }[], schemaFilePath: string) {
|
|
549
|
+
// Reset schema generator to use the newly created intermediate schema file
|
|
550
|
+
this.schemaGenerator = undefined;
|
|
551
|
+
|
|
463
552
|
const jsonSchemas: Schema[] = [];
|
|
464
553
|
|
|
465
554
|
for (const { reqSchemaType, resSchemaType } of schemas) {
|
|
466
555
|
if (reqSchemaType) {
|
|
467
|
-
jsonSchemas.push({ definitions: { [reqSchemaType]: this.generateJsonSchema(reqSchemaType) } });
|
|
556
|
+
jsonSchemas.push({ definitions: { [reqSchemaType]: this.generateJsonSchema(reqSchemaType, schemaFilePath) } });
|
|
468
557
|
}
|
|
469
558
|
if (resSchemaType) {
|
|
470
|
-
jsonSchemas.push({ definitions: { [resSchemaType]: this.generateJsonSchema(resSchemaType) } });
|
|
559
|
+
jsonSchemas.push({ definitions: { [resSchemaType]: this.generateJsonSchema(resSchemaType, schemaFilePath) } });
|
|
471
560
|
}
|
|
472
561
|
}
|
|
473
562
|
|
|
@@ -494,9 +583,9 @@ import "..${appEntryScript.replace(/\.ts/g, "")}";
|
|
|
494
583
|
return mergedSchemas;
|
|
495
584
|
}
|
|
496
585
|
|
|
497
|
-
private generateJsonSchema(typeName: string) {
|
|
586
|
+
private generateJsonSchema(typeName: string, schemaFilePath: string) {
|
|
498
587
|
if (!this.schemaGenerator) {
|
|
499
|
-
this.schemaGenerator = this.initJsonSchemaGenerator();
|
|
588
|
+
this.schemaGenerator = this.initJsonSchemaGenerator(schemaFilePath);
|
|
500
589
|
}
|
|
501
590
|
return this.schemaGenerator.createSchema(typeName);
|
|
502
591
|
}
|
|
@@ -563,7 +652,10 @@ ${this.parsedTsSchemas.join("\n\n")}`
|
|
|
563
652
|
|
|
564
653
|
addImports(schemaSourceFile, this.tsSchemasSymbolsToImports);
|
|
565
654
|
|
|
566
|
-
|
|
655
|
+
await schemaSourceFile.save();
|
|
656
|
+
|
|
657
|
+
// Return the file path so it can be used by ts-json-schema-generator
|
|
658
|
+
return schemaSourceFile.getFilePath();
|
|
567
659
|
}
|
|
568
660
|
|
|
569
661
|
/**
|
|
@@ -617,6 +709,13 @@ ${this.parsedTsSchemas.join("\n\n")}`
|
|
|
617
709
|
const reqJsonSchema = JSON.stringify(reqSchemaType ? jsonSchemaDefs[reqSchemaType] : undefined);
|
|
618
710
|
const resJsonSchema = JSON.stringify(resSchemaType ? jsonSchemaDefs[resSchemaType] : undefined);
|
|
619
711
|
|
|
712
|
+
// Remove existing __schemas variable if it exists (to avoid redeclaration errors)
|
|
713
|
+
const existingSchemas = sourceFile.getVariableStatements().filter((vs) => {
|
|
714
|
+
const varNames = vs.getDeclarations().map((d) => d.getName());
|
|
715
|
+
return varNames.includes("__schemas");
|
|
716
|
+
});
|
|
717
|
+
existingSchemas.forEach((v) => v.remove());
|
|
718
|
+
|
|
620
719
|
sourceFile.addVariableStatement({
|
|
621
720
|
declarationKind: VariableDeclarationKind.Const,
|
|
622
721
|
isExported: true,
|
|
@@ -660,8 +759,15 @@ autoRegisteredJobs.push(...jobs);
|
|
|
660
759
|
|
|
661
760
|
imports.push({
|
|
662
761
|
defaultImport: "* as " + namespaceImport,
|
|
663
|
-
moduleSpecifier:
|
|
762
|
+
moduleSpecifier: this.getModuleSpecifier(generatedFile, sf),
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
// Remove existing __file variable if it exists (to avoid redeclaration errors)
|
|
766
|
+
const existingFile = sf.getVariableStatements().filter((vs) => {
|
|
767
|
+
const varNames = vs.getDeclarations().map((d) => d.getName());
|
|
768
|
+
return varNames.includes("__file");
|
|
664
769
|
});
|
|
770
|
+
existingFile.forEach((v) => v.remove());
|
|
665
771
|
|
|
666
772
|
// Append metadata to source file that will be part of emitted dist bundle (javascript)
|
|
667
773
|
sf.addVariableStatement({
|
package/src/index.ts
CHANGED
|
@@ -9,3 +9,15 @@ export * from "./FlinkPlugin";
|
|
|
9
9
|
export * from "./FlinkJob";
|
|
10
10
|
export * from "./auth/FlinkAuthUser";
|
|
11
11
|
export * from "./auth/FlinkAuthPlugin";
|
|
12
|
+
|
|
13
|
+
// Re-export Express types for plugins and consumer apps
|
|
14
|
+
// This ensures type consistency across the framework and plugins
|
|
15
|
+
export type {
|
|
16
|
+
Request as ExpressRequest,
|
|
17
|
+
Response as ExpressResponse,
|
|
18
|
+
NextFunction as ExpressNextFunction,
|
|
19
|
+
RequestHandler as ExpressRequestHandler,
|
|
20
|
+
ErrorRequestHandler as ExpressErrorRequestHandler,
|
|
21
|
+
Express,
|
|
22
|
+
static as expressStatic,
|
|
23
|
+
} from "express";
|
package/tsconfig.json
CHANGED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __assign = (this && this.__assign) || function () {
|
|
4
|
-
__assign = Object.assign || function(t) {
|
|
5
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
6
|
-
s = arguments[i];
|
|
7
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
8
|
-
t[p] = s[p];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
|
-
return __assign.apply(this, arguments);
|
|
13
|
-
};
|
|
14
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
15
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
16
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
17
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
18
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
19
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
20
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
24
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
25
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
26
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
27
|
-
function step(op) {
|
|
28
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
29
|
-
while (_) try {
|
|
30
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
31
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
32
|
-
switch (op[0]) {
|
|
33
|
-
case 0: case 1: t = op; break;
|
|
34
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
35
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
36
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
37
|
-
default:
|
|
38
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
39
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
40
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
41
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
42
|
-
if (t[2]) _.ops.pop();
|
|
43
|
-
_.trys.pop(); continue;
|
|
44
|
-
}
|
|
45
|
-
op = body.call(thisArg, _);
|
|
46
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
47
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
51
|
-
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
52
|
-
to[j] = from[i];
|
|
53
|
-
return to;
|
|
54
|
-
};
|
|
55
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
56
|
-
var path_1 = require("path");
|
|
57
|
-
var ts_json_schema_generator_1 = require("ts-json-schema-generator");
|
|
58
|
-
var ts_morph_1 = require("ts-morph");
|
|
59
|
-
var FsUtils_1 = require("../src/FsUtils");
|
|
60
|
-
var cli_utils_1 = require("./cli-utils");
|
|
61
|
-
module.exports = function run(args) {
|
|
62
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
63
|
-
var dir, verbose, typesDir, outFile, project, schemaDeclarations, generator, jsonSchemas, _i, _a, sf, sourceFileInterfaceDeclarations, sourceFileEnumDeclarations, sourceFileDeclarations, schema, mergedSchemas, file;
|
|
64
|
-
return __generator(this, function (_b) {
|
|
65
|
-
switch (_b.label) {
|
|
66
|
-
case 0:
|
|
67
|
-
if (args.includes("--help")) {
|
|
68
|
-
console.log("\n Description\n Generates JSON schemas for types located in schemas directory or if any other directory\n is specified with option --types-dir. \n\n Outputs generated file(s) to dir '.flink' or if any other --out-dir is specified.\n\n Usage\n $ flink generate-schemas <dir> --types-dir <types-dir> --out-file <out-file>\n\n <dir> is project root as directory where tsconfig.son resides.\n \n Options \n --types-dir Directory where typescript types are located relative to <dir>, default \"./src/schemas\"\n --out-file Path to file that will contain generated json schemas relative to <dir>, default \"./.flink/generated-schemas.json\"\n --help Displays this message\n ");
|
|
69
|
-
process.exit(0);
|
|
70
|
-
}
|
|
71
|
-
dir = "./";
|
|
72
|
-
if (args[0] && !args[0].startsWith("--")) {
|
|
73
|
-
dir = args[0];
|
|
74
|
-
}
|
|
75
|
-
verbose = cli_utils_1.getOption(args, "verbose", false, {
|
|
76
|
-
isBoolean: true,
|
|
77
|
-
});
|
|
78
|
-
typesDir = cli_utils_1.getOption(args, "types-dir", "./src/schemas");
|
|
79
|
-
outFile = cli_utils_1.getOption(args, "out-file", "./.flink/generated-schemas.json");
|
|
80
|
-
project = new ts_morph_1.Project({
|
|
81
|
-
tsConfigFilePath: path_1.join(dir, "tsconfig.json"),
|
|
82
|
-
skipAddingFilesFromTsConfig: true,
|
|
83
|
-
compilerOptions: {
|
|
84
|
-
noEmit: true,
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
project.addSourceFilesAtPaths(path_1.join(dir, typesDir, "**/*.ts"));
|
|
88
|
-
console.log("Found", project.getSourceFiles().length, "files");
|
|
89
|
-
schemaDeclarations = [];
|
|
90
|
-
generator = initJsonSchemaGenerator(project);
|
|
91
|
-
jsonSchemas = [];
|
|
92
|
-
for (_i = 0, _a = project.getSourceFiles(); _i < _a.length; _i++) {
|
|
93
|
-
sf = _a[_i];
|
|
94
|
-
if (sf.getDefaultExportSymbol()) {
|
|
95
|
-
console.warn("WARN: Schema file " + sf.getBaseName() + " has default export, but only named exports are picked up by json schemas parser");
|
|
96
|
-
}
|
|
97
|
-
sourceFileInterfaceDeclarations = sf.getChildrenOfKind(ts_morph_1.SyntaxKind.InterfaceDeclaration);
|
|
98
|
-
sourceFileEnumDeclarations = sf.getChildrenOfKind(ts_morph_1.SyntaxKind.EnumDeclaration);
|
|
99
|
-
sourceFileDeclarations = __spreadArray(__spreadArray([], sourceFileEnumDeclarations), sourceFileInterfaceDeclarations);
|
|
100
|
-
schemaDeclarations.push.apply(schemaDeclarations, sourceFileDeclarations.map(function (d) { return d.compilerNode; }));
|
|
101
|
-
verbose &&
|
|
102
|
-
console.log("Found", sourceFileDeclarations.length, "schema(s) in file", sf.getBaseName());
|
|
103
|
-
try {
|
|
104
|
-
schema = generator.createSchemaFromNodes(sourceFileInterfaceDeclarations.map(function (d) { return d.compilerNode; }));
|
|
105
|
-
jsonSchemas.push(schema);
|
|
106
|
-
// console.log("Created schemas");
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
console.error("Failed to generate schema in file", sf.getBaseName() + ":", err);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
mergedSchemas = jsonSchemas.reduce(function (out, schema) {
|
|
113
|
-
if (schema)
|
|
114
|
-
if (schema.definitions) {
|
|
115
|
-
out.definitions = __assign(__assign({}, out.definitions), schema.definitions);
|
|
116
|
-
}
|
|
117
|
-
return out;
|
|
118
|
-
}, {
|
|
119
|
-
$schema: "http://json-schema.org/draft-07/schema#",
|
|
120
|
-
$ref: "#/definitions/Schemas",
|
|
121
|
-
definitions: {},
|
|
122
|
-
});
|
|
123
|
-
file = path_1.join(dir, outFile);
|
|
124
|
-
return [4 /*yield*/, FsUtils_1.writeJsonFile(file, mergedSchemas, {
|
|
125
|
-
ensureDir: true,
|
|
126
|
-
})];
|
|
127
|
-
case 1:
|
|
128
|
-
_b.sent();
|
|
129
|
-
console.log("Wrote file", file);
|
|
130
|
-
return [2 /*return*/];
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
};
|
|
135
|
-
function initJsonSchemaGenerator(project) {
|
|
136
|
-
var formatter = ts_json_schema_generator_1.createFormatter({});
|
|
137
|
-
var parser = ts_json_schema_generator_1.createParser(project.getProgram().compilerObject, {});
|
|
138
|
-
var generator = new ts_json_schema_generator_1.SchemaGenerator(project.getProgram().compilerObject, parser, formatter, { expose: "export" });
|
|
139
|
-
return generator;
|
|
140
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.__schemas = exports.__params = exports.__query = exports.__file = exports.__assumedHttpMethod = exports.Route = void 0;
|
|
40
|
-
var flink_1 = require("@flink-app/flink");
|
|
41
|
-
exports.Route = {
|
|
42
|
-
path: "/car-with-type-schema",
|
|
43
|
-
method: flink_1.HttpMethod.get,
|
|
44
|
-
permissions: "*",
|
|
45
|
-
};
|
|
46
|
-
var GetCarWithTypeSchema = function (_a) {
|
|
47
|
-
var ctx = _a.ctx, req = _a.req;
|
|
48
|
-
return __awaiter(void 0, void 0, void 0, function () {
|
|
49
|
-
return __generator(this, function (_b) {
|
|
50
|
-
return [2 /*return*/, {
|
|
51
|
-
data: {
|
|
52
|
-
model: "Volvo",
|
|
53
|
-
},
|
|
54
|
-
}];
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
exports.default = GetCarWithTypeSchema;
|
|
59
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithTypeSchema.ts", exports.__query = [], exports.__params = [];
|
|
60
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "definitions": {} } };
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "flink-test-app",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"lockfileVersion": 2,
|
|
5
|
-
"requires": true,
|
|
6
|
-
"packages": {
|
|
7
|
-
"": {
|
|
8
|
-
"name": "flink-test-app",
|
|
9
|
-
"version": "0.1.0",
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"@flink-app/flink": "../../"
|
|
12
|
-
},
|
|
13
|
-
"devDependencies": {}
|
|
14
|
-
},
|
|
15
|
-
"../..": {
|
|
16
|
-
"name": "@flink-app/flink",
|
|
17
|
-
"version": "0.2.0-beta.3",
|
|
18
|
-
"hasInstallScript": true,
|
|
19
|
-
"license": "MIT",
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"@types/cors": "^2.8.10",
|
|
22
|
-
"@types/express": "^4.17.11",
|
|
23
|
-
"@types/fs-extra": "^9.0.12",
|
|
24
|
-
"@types/mongodb": "3.6.12",
|
|
25
|
-
"@types/uuid": "^8.3.0",
|
|
26
|
-
"ajv": "^8.2.0",
|
|
27
|
-
"ajv-formats": "^2.1.0",
|
|
28
|
-
"body-parser": "^1.19.0",
|
|
29
|
-
"cors": "^2.8.5",
|
|
30
|
-
"express": "^4.17.1",
|
|
31
|
-
"folder-hash": "^4.0.1",
|
|
32
|
-
"fs-extra": "^10.0.0",
|
|
33
|
-
"mkdirp": "^1.0.4",
|
|
34
|
-
"mock-json-schema": "^1.0.8",
|
|
35
|
-
"mongodb": "^3.6.6",
|
|
36
|
-
"node-color-log": "^5.2.0",
|
|
37
|
-
"passport": "^0.4.1",
|
|
38
|
-
"passport-jwt": "^4.0.0",
|
|
39
|
-
"reflect-metadata": "^0.1.13",
|
|
40
|
-
"tiny-glob": "^0.2.9",
|
|
41
|
-
"ts-json-schema-generator": "^0.94.1",
|
|
42
|
-
"ts-morph": "^11.0.0",
|
|
43
|
-
"typescript": "4.2.3",
|
|
44
|
-
"uuid": "^8.3.2"
|
|
45
|
-
},
|
|
46
|
-
"bin": {
|
|
47
|
-
"flink": "dist/bin/flink.js"
|
|
48
|
-
},
|
|
49
|
-
"devDependencies": {
|
|
50
|
-
"@types/folder-hash": "^4.0.0",
|
|
51
|
-
"@types/jasmine": "^3.7.1",
|
|
52
|
-
"@types/json-schema": "^7.0.7",
|
|
53
|
-
"@types/mkdirp": "^1.0.1",
|
|
54
|
-
"@types/node": "^15.0.1",
|
|
55
|
-
"jasmine": "^3.7.0",
|
|
56
|
-
"jasmine-spec-reporter": "^7.0.0",
|
|
57
|
-
"jasmine-ts": "^0.3.3",
|
|
58
|
-
"nodemon": "^2.0.7",
|
|
59
|
-
"ts-node": "^9.1.1"
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
"node_modules/@flink-app/flink": {
|
|
63
|
-
"resolved": "../..",
|
|
64
|
-
"link": true
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
"dependencies": {
|
|
68
|
-
"@flink-app/flink": {
|
|
69
|
-
"version": "file:../..",
|
|
70
|
-
"requires": {
|
|
71
|
-
"@types/cors": "^2.8.10",
|
|
72
|
-
"@types/express": "^4.17.11",
|
|
73
|
-
"@types/folder-hash": "^4.0.0",
|
|
74
|
-
"@types/fs-extra": "^9.0.12",
|
|
75
|
-
"@types/jasmine": "^3.7.1",
|
|
76
|
-
"@types/json-schema": "^7.0.7",
|
|
77
|
-
"@types/mkdirp": "^1.0.1",
|
|
78
|
-
"@types/mongodb": "3.6.12",
|
|
79
|
-
"@types/node": "^15.0.1",
|
|
80
|
-
"@types/uuid": "^8.3.0",
|
|
81
|
-
"ajv": "^8.2.0",
|
|
82
|
-
"ajv-formats": "^2.1.0",
|
|
83
|
-
"body-parser": "^1.19.0",
|
|
84
|
-
"cors": "^2.8.5",
|
|
85
|
-
"express": "^4.17.1",
|
|
86
|
-
"folder-hash": "^4.0.1",
|
|
87
|
-
"fs-extra": "^10.0.0",
|
|
88
|
-
"jasmine": "^3.7.0",
|
|
89
|
-
"jasmine-spec-reporter": "^7.0.0",
|
|
90
|
-
"jasmine-ts": "^0.3.3",
|
|
91
|
-
"mkdirp": "^1.0.4",
|
|
92
|
-
"mock-json-schema": "^1.0.8",
|
|
93
|
-
"mongodb": "^3.6.6",
|
|
94
|
-
"node-color-log": "^5.2.0",
|
|
95
|
-
"nodemon": "^2.0.7",
|
|
96
|
-
"passport": "^0.4.1",
|
|
97
|
-
"passport-jwt": "^4.0.0",
|
|
98
|
-
"reflect-metadata": "^0.1.13",
|
|
99
|
-
"tiny-glob": "^0.2.9",
|
|
100
|
-
"ts-json-schema-generator": "^0.94.1",
|
|
101
|
-
"ts-morph": "^11.0.0",
|
|
102
|
-
"ts-node": "^9.1.1",
|
|
103
|
-
"typescript": "4.2.3",
|
|
104
|
-
"uuid": "^8.3.2"
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|