@flink-app/flink 0.13.3 → 0.13.4
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/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/CHANGELOG.md +12 -0
- package/dist/src/FlinkHttpHandler.d.ts +2 -1
- package/dist/src/FlinkHttpHandler.js +1 -0
- package/dist/src/TypeScriptCompiler.d.ts +4 -0
- package/dist/src/TypeScriptCompiler.js +123 -11
- package/dist/src/utils.js +2 -0
- package/package.json +1 -1
- package/spec/mock-project/dist/src/handlers/PatchCar.js +58 -0
- package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js +76 -0
- package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js +58 -0
- package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js +59 -0
- package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js +59 -0
- package/spec/mock-project/src/handlers/PatchCar.ts +25 -0
- package/spec/mock-project/src/handlers/PatchOnboardingSession.ts +66 -0
- package/spec/mock-project/src/handlers/PatchOrderWithComplexTypes.ts +79 -0
- package/spec/mock-project/src/handlers/PatchProductWithIntersection.ts +49 -0
- package/spec/mock-project/src/handlers/PatchUserWithUnion.ts +46 -0
- package/src/FlinkHttpHandler.ts +1 -0
- package/src/TypeScriptCompiler.ts +128 -5
- package/src/utils.ts +1 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
+
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
+
|
|
7
|
+
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": false,
|
|
5
|
+
"fixed": [],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "restricted",
|
|
8
|
+
"baseBranch": "main",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": []
|
|
11
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @flink-app/flink
|
|
2
2
|
|
|
3
|
+
## 0.13.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Add PATCH HTTP method support and fix schema generation for utility types
|
|
8
|
+
|
|
9
|
+
- Add PATCH HTTP method to HttpMethod enum and auto-detection from handler filenames
|
|
10
|
+
- Fix schema generation to support nested Partial types with indexed access (e.g., `Partial<Interface["property"]>`)
|
|
11
|
+
- Add recursive dependency resolution for interface copying in TypeScript compiler
|
|
12
|
+
- Add support for union and intersection types with utility type patterns
|
|
13
|
+
- Add test coverage for complex type scenarios (union, intersection, nested utility types)
|
|
14
|
+
|
|
3
15
|
## 0.13.3
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -89,6 +89,10 @@ declare class TypeScriptCompiler {
|
|
|
89
89
|
* Return names of req and/or res schema types.
|
|
90
90
|
*/
|
|
91
91
|
private extractSchemasFromHandlerSourceFile;
|
|
92
|
+
/**
|
|
93
|
+
* Recursively copies an interface and all its dependencies from the same file
|
|
94
|
+
*/
|
|
95
|
+
private copyInterfaceWithDependencies;
|
|
92
96
|
private saveIntermediateTsSchema;
|
|
93
97
|
private initJsonSchemaGenerator;
|
|
94
98
|
private generateAndSaveJsonSchemas;
|
|
@@ -480,10 +480,50 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
480
480
|
});
|
|
481
481
|
});
|
|
482
482
|
};
|
|
483
|
+
/**
|
|
484
|
+
* Recursively copies an interface and all its dependencies from the same file
|
|
485
|
+
*/
|
|
486
|
+
TypeScriptCompiler.prototype.copyInterfaceWithDependencies = function (interfaceDecl, handlerFile) {
|
|
487
|
+
var _a, _b, _c;
|
|
488
|
+
var interfaceName = ((_a = interfaceDecl.getName) === null || _a === void 0 ? void 0 : _a.call(interfaceDecl)) || ((_b = interfaceDecl.getFirstChildByKind(ts_morph_1.SyntaxKind.Identifier)) === null || _b === void 0 ? void 0 : _b.getText());
|
|
489
|
+
if (!interfaceName)
|
|
490
|
+
return;
|
|
491
|
+
// Check if already copied
|
|
492
|
+
var existingInterface = this.parsedTsSchemas.find(function (s) { return s.includes("interface ".concat(interfaceName, " ")) || s.includes("type ".concat(interfaceName, " =")); });
|
|
493
|
+
if (existingInterface)
|
|
494
|
+
return;
|
|
495
|
+
// Copy the interface
|
|
496
|
+
this.parsedTsSchemas.push(interfaceDecl.getText());
|
|
497
|
+
// Find and recursively copy dependencies from the same file
|
|
498
|
+
// First, find direct type references in this interface
|
|
499
|
+
var typeRefIdentifiers = interfaceDecl
|
|
500
|
+
.getDescendantsOfKind(ts_morph_1.SyntaxKind.TypeReference)
|
|
501
|
+
.filter(function (typeRefNode) { return !!typeRefNode.getFirstChildIfKind(ts_morph_1.SyntaxKind.Identifier); })
|
|
502
|
+
.map(function (typeRefNode) { return typeRefNode.getFirstChildIfKindOrThrow(ts_morph_1.SyntaxKind.Identifier); });
|
|
503
|
+
for (var _i = 0, typeRefIdentifiers_1 = typeRefIdentifiers; _i < typeRefIdentifiers_1.length; _i++) {
|
|
504
|
+
var typeRefIdentifier = typeRefIdentifiers_1[_i];
|
|
505
|
+
var typeSymbol = typeRefIdentifier.getSymbol();
|
|
506
|
+
if (typeSymbol) {
|
|
507
|
+
var declaredType = typeSymbol.getDeclaredType();
|
|
508
|
+
var declaration = (_c = declaredType.getSymbol()) === null || _c === void 0 ? void 0 : _c.getDeclarations()[0];
|
|
509
|
+
if (declaration && declaration.getSourceFile() === handlerFile) {
|
|
510
|
+
// Same file - recursively copy this dependency
|
|
511
|
+
this.copyInterfaceWithDependencies(declaration, handlerFile);
|
|
512
|
+
}
|
|
513
|
+
else if (declaration && declaration.getSourceFile() !== handlerFile) {
|
|
514
|
+
// Different file - add to imports
|
|
515
|
+
var declaredTypeSymbol = declaredType.getSymbol();
|
|
516
|
+
if (declaredTypeSymbol) {
|
|
517
|
+
this.tsSchemasSymbolsToImports.push(declaredTypeSymbol);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
};
|
|
483
523
|
TypeScriptCompiler.prototype.saveIntermediateTsSchema = function (schema, handlerFile, suffix) {
|
|
484
524
|
return __awaiter(this, void 0, void 0, function () {
|
|
485
|
-
var handlerFileName, generatedSchemaInterfaceStr, schemaInterfaceName, schemaSymbol, interfaceName, declaration, _i, _a, typeToImport, arrayTypeArg, schemaSymbol, interfaceName, declaration, props,
|
|
486
|
-
return __generator(this, function (
|
|
525
|
+
var handlerFileName, generatedSchemaInterfaceStr, schemaInterfaceName, schemaSymbol, interfaceName, declaration, _i, _a, typeToImport, typeSymbol, declaredTypeSymbol, _b, _c, prop, propDecl, propText, interfaceNameMatches, _d, interfaceNameMatches_1, match, referencedInterfaceName, referencedInterfaceDecl, arrayTypeArg, schemaSymbol, interfaceName, declaration, props, _e, _f, typeToImport, typeSymbol, declaredTypeSymbol, schemaSymbol, declarations, declaration, propertySignatures, _g, _h, prop, propType, typeSymbol, typeDeclaration, elementType, elementSymbol, elementDeclaration, currentPropTypeText, interfaceNameMatches, _j, interfaceNameMatches_2, match, interfaceName, interfaceDecl, typeArgs, _k, typeArgs_1, typeArg, argSymbol, argDeclaration, _l, _m, typeToImport, typeSymbol, declaredTypeSymbol;
|
|
526
|
+
return __generator(this, function (_o) {
|
|
487
527
|
if (schema.isAny()) {
|
|
488
528
|
return [2 /*return*/]; // 'any' indicates that no schema is used
|
|
489
529
|
}
|
|
@@ -496,13 +536,39 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
496
536
|
declaration = schemaSymbol.getDeclarations()[0];
|
|
497
537
|
if (declaration.getSourceFile() === handlerFile) {
|
|
498
538
|
// Interface is declared within handler file
|
|
499
|
-
generatedSchemaInterfaceStr = "export interface ".concat(schemaInterfaceName, " {
|
|
539
|
+
generatedSchemaInterfaceStr = "export interface ".concat(schemaInterfaceName, " {\n ").concat(schema
|
|
500
540
|
.getProperties()
|
|
501
541
|
.map(function (p) { return p.getValueDeclarationOrThrow().getText(); })
|
|
502
542
|
.join("\n"), "\n }");
|
|
503
543
|
for (_i = 0, _a = (0, TypeScriptUtils_1.getTypesToImport)(declaration); _i < _a.length; _i++) {
|
|
504
544
|
typeToImport = _a[_i];
|
|
505
|
-
|
|
545
|
+
typeSymbol = typeToImport.getSymbol();
|
|
546
|
+
if (typeSymbol) {
|
|
547
|
+
declaredTypeSymbol = typeSymbol.getDeclaredType().getSymbol();
|
|
548
|
+
if (declaredTypeSymbol) {
|
|
549
|
+
this.tsSchemasSymbolsToImports.push(declaredTypeSymbol);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
// Also check for utility types with indexed access patterns like Partial<Foo["bar"]>
|
|
554
|
+
for (_b = 0, _c = schema.getProperties(); _b < _c.length; _b++) {
|
|
555
|
+
prop = _c[_b];
|
|
556
|
+
propDecl = prop.getValueDeclaration();
|
|
557
|
+
if (propDecl) {
|
|
558
|
+
propText = propDecl.getText();
|
|
559
|
+
interfaceNameMatches = propText.match(/\b([A-Z][a-zA-Z0-9]*)\s*\[/g);
|
|
560
|
+
if (interfaceNameMatches) {
|
|
561
|
+
for (_d = 0, interfaceNameMatches_1 = interfaceNameMatches; _d < interfaceNameMatches_1.length; _d++) {
|
|
562
|
+
match = interfaceNameMatches_1[_d];
|
|
563
|
+
referencedInterfaceName = match.replace(/\s*\[$/, '').trim();
|
|
564
|
+
referencedInterfaceDecl = handlerFile.getInterface(referencedInterfaceName) || handlerFile.getTypeAlias(referencedInterfaceName);
|
|
565
|
+
if (referencedInterfaceDecl) {
|
|
566
|
+
// Interface is in same file - copy it and all its dependencies recursively
|
|
567
|
+
this.copyInterfaceWithDependencies(referencedInterfaceDecl, handlerFile);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
506
572
|
}
|
|
507
573
|
}
|
|
508
574
|
else {
|
|
@@ -531,15 +597,22 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
531
597
|
else {
|
|
532
598
|
generatedSchemaInterfaceStr = "export interface ".concat(schemaInterfaceName, " extends Array<").concat(declaration.getText(), "> {}");
|
|
533
599
|
}
|
|
534
|
-
for (
|
|
535
|
-
typeToImport =
|
|
536
|
-
|
|
600
|
+
for (_e = 0, _f = (0, TypeScriptUtils_1.getTypesToImport)(declaration); _e < _f.length; _e++) {
|
|
601
|
+
typeToImport = _f[_e];
|
|
602
|
+
typeSymbol = typeToImport.getSymbol();
|
|
603
|
+
if (typeSymbol) {
|
|
604
|
+
declaredTypeSymbol = typeSymbol.getDeclaredType().getSymbol();
|
|
605
|
+
if (declaredTypeSymbol) {
|
|
606
|
+
this.tsSchemasSymbolsToImports.push(declaredTypeSymbol);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
537
609
|
}
|
|
538
610
|
}
|
|
539
611
|
}
|
|
540
612
|
else if (schema.isObject()) {
|
|
541
|
-
|
|
542
|
-
|
|
613
|
+
schemaSymbol = schema.getSymbol();
|
|
614
|
+
declarations = schemaSymbol === null || schemaSymbol === void 0 ? void 0 : schemaSymbol.getDeclarations();
|
|
615
|
+
declaration = declarations === null || declarations === void 0 ? void 0 : declarations[0];
|
|
543
616
|
propertySignatures = schema.getProperties().map(function (prop) {
|
|
544
617
|
var propName = prop.getName();
|
|
545
618
|
var propType = prop.getTypeAtLocation(handlerFile);
|
|
@@ -560,8 +633,8 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
560
633
|
return "".concat(propName).concat(isOptional ? "?" : "", ": ").concat(propTypeText);
|
|
561
634
|
});
|
|
562
635
|
// Extract type references for imports from resolved types
|
|
563
|
-
for (
|
|
564
|
-
prop =
|
|
636
|
+
for (_g = 0, _h = schema.getProperties(); _g < _h.length; _g++) {
|
|
637
|
+
prop = _h[_g];
|
|
565
638
|
propType = prop.getTypeAtLocation(handlerFile);
|
|
566
639
|
typeSymbol = propType.getSymbol();
|
|
567
640
|
if (typeSymbol) {
|
|
@@ -581,6 +654,45 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
581
654
|
}
|
|
582
655
|
}
|
|
583
656
|
}
|
|
657
|
+
currentPropTypeText = propType.getText(undefined, ts_morph_1.ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope);
|
|
658
|
+
interfaceNameMatches = currentPropTypeText.match(/\b([A-Z][a-zA-Z0-9]*)\s*\[/g);
|
|
659
|
+
if (interfaceNameMatches) {
|
|
660
|
+
for (_j = 0, interfaceNameMatches_2 = interfaceNameMatches; _j < interfaceNameMatches_2.length; _j++) {
|
|
661
|
+
match = interfaceNameMatches_2[_j];
|
|
662
|
+
interfaceName = match.replace(/\s*\[$/, '').trim();
|
|
663
|
+
interfaceDecl = handlerFile.getInterface(interfaceName) || handlerFile.getTypeAlias(interfaceName);
|
|
664
|
+
if (interfaceDecl) {
|
|
665
|
+
// Interface is in same file - copy it and all its dependencies recursively
|
|
666
|
+
this.copyInterfaceWithDependencies(interfaceDecl, handlerFile);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
typeArgs = propType.getTypeArguments();
|
|
671
|
+
if (typeArgs && typeArgs.length > 0) {
|
|
672
|
+
for (_k = 0, typeArgs_1 = typeArgs; _k < typeArgs_1.length; _k++) {
|
|
673
|
+
typeArg = typeArgs_1[_k];
|
|
674
|
+
argSymbol = typeArg.getSymbol();
|
|
675
|
+
if (argSymbol) {
|
|
676
|
+
argDeclaration = argSymbol.getDeclarations()[0];
|
|
677
|
+
if (argDeclaration && argDeclaration.getSourceFile() !== handlerFile) {
|
|
678
|
+
this.tsSchemasSymbolsToImports.push(argSymbol);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
// If we have a declaration, check if we need to import any types
|
|
685
|
+
if (declaration) {
|
|
686
|
+
for (_l = 0, _m = (0, TypeScriptUtils_1.getTypesToImport)(declaration); _l < _m.length; _l++) {
|
|
687
|
+
typeToImport = _m[_l];
|
|
688
|
+
typeSymbol = typeToImport.getSymbol();
|
|
689
|
+
if (typeSymbol) {
|
|
690
|
+
declaredTypeSymbol = typeSymbol.getDeclaredType().getSymbol();
|
|
691
|
+
if (declaredTypeSymbol) {
|
|
692
|
+
this.tsSchemasSymbolsToImports.push(declaredTypeSymbol);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
584
696
|
}
|
|
585
697
|
generatedSchemaInterfaceStr = "export interface ".concat(schemaInterfaceName, " { ").concat(propertySignatures.join(";\n"), " }");
|
|
586
698
|
}
|
package/dist/src/utils.js
CHANGED
|
@@ -138,6 +138,8 @@ function getHttpMethodFromHandlerName(handlerFilename) {
|
|
|
138
138
|
return FlinkHttpHandler_1.HttpMethod.put;
|
|
139
139
|
if (handlerFilename.startsWith(FlinkHttpHandler_1.HttpMethod.delete))
|
|
140
140
|
return FlinkHttpHandler_1.HttpMethod.delete;
|
|
141
|
+
if (handlerFilename.startsWith(FlinkHttpHandler_1.HttpMethod.patch))
|
|
142
|
+
return FlinkHttpHandler_1.HttpMethod.patch;
|
|
141
143
|
}
|
|
142
144
|
function getJsDocComment(comment) {
|
|
143
145
|
var rows = comment.split("\n").map(function (line) {
|
package/package.json
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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/:id",
|
|
43
|
+
method: flink_1.HttpMethod.patch,
|
|
44
|
+
};
|
|
45
|
+
var PatchCar = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
46
|
+
var req = _b.req;
|
|
47
|
+
return __generator(this, function (_c) {
|
|
48
|
+
return [2 /*return*/, {
|
|
49
|
+
data: {
|
|
50
|
+
model: req.body.model || "Updated Model",
|
|
51
|
+
year: req.body.year || 2024,
|
|
52
|
+
},
|
|
53
|
+
}];
|
|
54
|
+
});
|
|
55
|
+
}); };
|
|
56
|
+
exports.default = PatchCar;
|
|
57
|
+
exports.__assumedHttpMethod = "patch", exports.__file = "PatchCar.ts", exports.__query = [], exports.__params = [{ description: "", name: "id" }];
|
|
58
|
+
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "model": { "type": "string" }, "year": { "type": "number" } }, "additionalProperties": false, "definitions": {} }, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "model": { "type": "string" }, "year": { "type": "number" } }, "required": ["model", "year"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -0,0 +1,76 @@
|
|
|
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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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: "/onboarding/:sessionId",
|
|
43
|
+
method: flink_1.HttpMethod.patch,
|
|
44
|
+
};
|
|
45
|
+
var PatchOnboardingSession = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
46
|
+
var _c, _d;
|
|
47
|
+
var req = _b.req;
|
|
48
|
+
return __generator(this, function (_e) {
|
|
49
|
+
return [2 /*return*/, {
|
|
50
|
+
data: {
|
|
51
|
+
sessionId: req.params.sessionId,
|
|
52
|
+
status: req.body.status || "pending",
|
|
53
|
+
extractedData: {
|
|
54
|
+
companyName: ((_c = req.body.extractedData) === null || _c === void 0 ? void 0 : _c.companyName) || "Test Company",
|
|
55
|
+
orgNumber: ((_d = req.body.extractedData) === null || _d === void 0 ? void 0 : _d.orgNumber) || "123456",
|
|
56
|
+
address: {
|
|
57
|
+
street: "Main St",
|
|
58
|
+
city: "Stockholm",
|
|
59
|
+
postalCode: "12345",
|
|
60
|
+
},
|
|
61
|
+
contactInfo: {
|
|
62
|
+
email: "test@example.com",
|
|
63
|
+
phone: "+46701234567",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
metadata: {
|
|
67
|
+
createdAt: new Date(),
|
|
68
|
+
updatedAt: new Date(),
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
}];
|
|
72
|
+
});
|
|
73
|
+
}); };
|
|
74
|
+
exports.default = PatchOnboardingSession;
|
|
75
|
+
exports.__assumedHttpMethod = "patch", exports.__file = "PatchOnboardingSession.ts", exports.__query = [], exports.__params = [{ description: "", name: "sessionId" }];
|
|
76
|
+
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "status": { "type": "string" }, "extractedData": { "type": "object", "properties": { "companyName": { "type": "string" }, "orgNumber": { "type": "string" }, "address": { "type": "object", "properties": { "street": { "type": "string" }, "city": { "type": "string" }, "postalCode": { "type": "string" } }, "required": ["street", "city", "postalCode"], "additionalProperties": false }, "contactInfo": { "type": "object", "properties": { "email": { "type": "string" }, "phone": { "type": "string" } }, "required": ["email", "phone"], "additionalProperties": false } }, "additionalProperties": false }, "metadata": { "type": "object", "properties": { "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "additionalProperties": false, "definitions": {} }, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "sessionId": { "type": "string" }, "status": { "type": "string" }, "extractedData": { "type": "object", "properties": { "companyName": { "type": "string" }, "orgNumber": { "type": "string" }, "address": { "type": "object", "properties": { "street": { "type": "string" }, "city": { "type": "string" }, "postalCode": { "type": "string" } }, "required": ["street", "city", "postalCode"], "additionalProperties": false }, "contactInfo": { "type": "object", "properties": { "email": { "type": "string" }, "phone": { "type": "string" } }, "required": ["email", "phone"], "additionalProperties": false } }, "required": ["companyName", "orgNumber", "address", "contactInfo"], "additionalProperties": false }, "metadata": { "type": "object", "properties": { "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } }, "required": ["createdAt", "updatedAt"], "additionalProperties": false } }, "required": ["sessionId", "status", "extractedData", "metadata"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -0,0 +1,58 @@
|
|
|
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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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: "/order/:orderId",
|
|
43
|
+
method: flink_1.HttpMethod.patch,
|
|
44
|
+
};
|
|
45
|
+
var PatchOrderWithComplexTypes = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
46
|
+
var req = _b.req;
|
|
47
|
+
return __generator(this, function (_c) {
|
|
48
|
+
return [2 /*return*/, {
|
|
49
|
+
data: {
|
|
50
|
+
orderId: req.params.orderId,
|
|
51
|
+
status: "updated",
|
|
52
|
+
},
|
|
53
|
+
}];
|
|
54
|
+
});
|
|
55
|
+
}); };
|
|
56
|
+
exports.default = PatchOrderWithComplexTypes;
|
|
57
|
+
exports.__assumedHttpMethod = "patch", exports.__file = "PatchOrderWithComplexTypes.ts", exports.__query = [], exports.__params = [{ description: "", name: "orderId" }];
|
|
58
|
+
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "customerCity": { "type": "object", "properties": { "street": { "type": "string" }, "city": { "type": "string" }, "country": { "type": "string" } }, "additionalProperties": false }, "items": { "type": "object", "additionalProperties": false, "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "productId": { "type": "string" }, "quantity": { "type": "number" }, "price": { "type": "number" } }, "required": ["productId", "quantity", "price"], "additionalProperties": false } }, "subtotal": { "type": "number" } }, "required": ["items", "subtotal"] }, "shipping": { "type": "object", "additionalProperties": false, "properties": { "method": { "type": "string" } }, "required": ["method"] }, "paymentOrShipping": { "type": "object", "additionalProperties": false }, "itemUpdates": { "type": "array", "items": { "type": "object", "properties": { "productId": { "type": "string" }, "quantity": { "type": "number" }, "price": { "type": "number" } }, "additionalProperties": false } } }, "additionalProperties": false, "definitions": {} }, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "orderId": { "type": "string" }, "status": { "type": "string" } }, "required": ["orderId", "status"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -0,0 +1,59 @@
|
|
|
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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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: "/product/:productId",
|
|
43
|
+
method: flink_1.HttpMethod.patch,
|
|
44
|
+
};
|
|
45
|
+
var PatchProductWithIntersection = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
46
|
+
var req = _b.req;
|
|
47
|
+
return __generator(this, function (_c) {
|
|
48
|
+
return [2 /*return*/, {
|
|
49
|
+
data: {
|
|
50
|
+
name: "Test Product",
|
|
51
|
+
description: "Test Description",
|
|
52
|
+
price: req.body.update || 99.99,
|
|
53
|
+
},
|
|
54
|
+
}];
|
|
55
|
+
});
|
|
56
|
+
}); };
|
|
57
|
+
exports.default = PatchProductWithIntersection;
|
|
58
|
+
exports.__assumedHttpMethod = "patch", exports.__file = "PatchProductWithIntersection.ts", exports.__query = [], exports.__params = [{ description: "", name: "productId" }];
|
|
59
|
+
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "update": { "type": "object", "additionalProperties": false }, "fullUpdate": { "type": "object", "additionalProperties": false, "properties": { "notes": { "type": "string" }, "stock": { "type": "number" }, "warehouse": { "type": "string" }, "sku": { "type": "string" }, "name": { "type": "string" }, "description": { "type": "string" }, "price": { "type": "number" } }, "required": ["notes"] }, "metadataUpdate": { "type": "object", "additionalProperties": false, "properties": { "updatedBy": { "type": "string" } }, "required": ["updatedBy"] } }, "additionalProperties": false, "definitions": {} }, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "price": { "type": "number" } }, "required": ["name", "description", "price"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -0,0 +1,59 @@
|
|
|
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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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: "/user/:userId",
|
|
43
|
+
method: flink_1.HttpMethod.patch,
|
|
44
|
+
};
|
|
45
|
+
var PatchUserWithUnion = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
46
|
+
var req = _b.req;
|
|
47
|
+
return __generator(this, function (_c) {
|
|
48
|
+
return [2 /*return*/, {
|
|
49
|
+
data: {
|
|
50
|
+
firstName: "Test",
|
|
51
|
+
lastName: "User",
|
|
52
|
+
bio: req.body.data || "Default bio",
|
|
53
|
+
},
|
|
54
|
+
}];
|
|
55
|
+
});
|
|
56
|
+
}); };
|
|
57
|
+
exports.default = PatchUserWithUnion;
|
|
58
|
+
exports.__assumedHttpMethod = "patch", exports.__file = "PatchUserWithUnion.ts", exports.__query = [], exports.__params = [{ description: "", name: "userId" }];
|
|
59
|
+
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "data": { "type": "object", "additionalProperties": false }, "profileUpdate": { "anyOf": [{ "type": "object", "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" }, "bio": { "type": "string" } }, "additionalProperties": false }, { "type": "object", "properties": { "theme": { "type": "string" }, "notifications": { "type": "boolean" }, "language": { "type": "string" } }, "additionalProperties": false }] } }, "additionalProperties": false, "definitions": {} }, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" }, "bio": { "type": "string" } }, "required": ["firstName", "lastName", "bio"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Handler, HttpMethod, RouteProps } from "@flink-app/flink";
|
|
2
|
+
|
|
3
|
+
export const Route: RouteProps = {
|
|
4
|
+
path: "/car/:id",
|
|
5
|
+
method: HttpMethod.patch,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
interface Car {
|
|
9
|
+
model: string;
|
|
10
|
+
year: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type Params = { id: string };
|
|
14
|
+
type PatchCarReq = Partial<Car>;
|
|
15
|
+
|
|
16
|
+
const PatchCar: Handler<any, PatchCarReq, Car, Params> = async ({ req }) => {
|
|
17
|
+
return {
|
|
18
|
+
data: {
|
|
19
|
+
model: req.body.model || "Updated Model",
|
|
20
|
+
year: req.body.year || 2024,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default PatchCar;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Handler, HttpMethod, RouteProps } from "@flink-app/flink";
|
|
2
|
+
|
|
3
|
+
export const Route: RouteProps = {
|
|
4
|
+
path: "/onboarding/:sessionId",
|
|
5
|
+
method: HttpMethod.patch,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// Simulating a complex nested structure like in your example
|
|
9
|
+
interface OnboardingSession {
|
|
10
|
+
sessionId: string;
|
|
11
|
+
status: string;
|
|
12
|
+
extractedData: {
|
|
13
|
+
companyName: string;
|
|
14
|
+
orgNumber: string;
|
|
15
|
+
address: {
|
|
16
|
+
street: string;
|
|
17
|
+
city: string;
|
|
18
|
+
postalCode: string;
|
|
19
|
+
};
|
|
20
|
+
contactInfo: {
|
|
21
|
+
email: string;
|
|
22
|
+
phone: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
metadata: {
|
|
26
|
+
createdAt: Date;
|
|
27
|
+
updatedAt: Date;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Test case: Partial of a nested property using bracket notation
|
|
32
|
+
interface PatchOnboardingSessionReq {
|
|
33
|
+
status?: string;
|
|
34
|
+
extractedData?: Partial<OnboardingSession["extractedData"]>;
|
|
35
|
+
metadata?: Partial<OnboardingSession["metadata"]>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type Params = { sessionId: string };
|
|
39
|
+
|
|
40
|
+
const PatchOnboardingSession: Handler<any, PatchOnboardingSessionReq, OnboardingSession, Params> = async ({ req }) => {
|
|
41
|
+
return {
|
|
42
|
+
data: {
|
|
43
|
+
sessionId: req.params.sessionId,
|
|
44
|
+
status: req.body.status || "pending",
|
|
45
|
+
extractedData: {
|
|
46
|
+
companyName: req.body.extractedData?.companyName || "Test Company",
|
|
47
|
+
orgNumber: req.body.extractedData?.orgNumber || "123456",
|
|
48
|
+
address: {
|
|
49
|
+
street: "Main St",
|
|
50
|
+
city: "Stockholm",
|
|
51
|
+
postalCode: "12345",
|
|
52
|
+
},
|
|
53
|
+
contactInfo: {
|
|
54
|
+
email: "test@example.com",
|
|
55
|
+
phone: "+46701234567",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
metadata: {
|
|
59
|
+
createdAt: new Date(),
|
|
60
|
+
updatedAt: new Date(),
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export default PatchOnboardingSession;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Handler, HttpMethod, RouteProps } from "@flink-app/flink";
|
|
2
|
+
|
|
3
|
+
export const Route: RouteProps = {
|
|
4
|
+
path: "/order/:orderId",
|
|
5
|
+
method: HttpMethod.patch,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// Complex nested structures for testing edge cases
|
|
9
|
+
interface OrderCustomer {
|
|
10
|
+
customerId: string;
|
|
11
|
+
name: string;
|
|
12
|
+
email: string;
|
|
13
|
+
address: {
|
|
14
|
+
street: string;
|
|
15
|
+
city: string;
|
|
16
|
+
country: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface OrderItem {
|
|
21
|
+
productId: string;
|
|
22
|
+
quantity: number;
|
|
23
|
+
price: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface OrderItems {
|
|
27
|
+
items: Array<OrderItem>;
|
|
28
|
+
subtotal: number;
|
|
29
|
+
tax: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface OrderShipping {
|
|
33
|
+
method: string;
|
|
34
|
+
trackingNumber: string;
|
|
35
|
+
estimatedDelivery: Date;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface OrderPayment {
|
|
39
|
+
method: string;
|
|
40
|
+
status: string;
|
|
41
|
+
transactionId: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Test case: Complex combinations of utility types
|
|
45
|
+
interface PatchOrderWithComplexTypesReq {
|
|
46
|
+
// Nested indexed access - should extract OrderCustomer
|
|
47
|
+
customerCity?: Partial<OrderCustomer["address"]>;
|
|
48
|
+
|
|
49
|
+
// Omit with indexed access - should extract OrderItems
|
|
50
|
+
items?: Omit<OrderItems, "tax"> & Partial<OrderItems["subtotal"]>;
|
|
51
|
+
|
|
52
|
+
// Pick with indexed access - should extract OrderShipping
|
|
53
|
+
shipping?: Pick<OrderShipping, "method"> & Partial<OrderShipping["trackingNumber"]>;
|
|
54
|
+
|
|
55
|
+
// Union of Partial with indexed access
|
|
56
|
+
paymentOrShipping?:
|
|
57
|
+
Partial<OrderPayment["status"]> | Partial<OrderShipping["method"]>;
|
|
58
|
+
|
|
59
|
+
// Array of Partial types
|
|
60
|
+
itemUpdates?: Array<Partial<OrderItem>>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
type Params = { orderId: string };
|
|
64
|
+
|
|
65
|
+
interface OrderResponse {
|
|
66
|
+
orderId: string;
|
|
67
|
+
status: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const PatchOrderWithComplexTypes: Handler<any, PatchOrderWithComplexTypesReq, OrderResponse, Params> = async ({ req }) => {
|
|
71
|
+
return {
|
|
72
|
+
data: {
|
|
73
|
+
orderId: req.params.orderId,
|
|
74
|
+
status: "updated",
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export default PatchOrderWithComplexTypes;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Handler, HttpMethod, RouteProps } from "@flink-app/flink";
|
|
2
|
+
|
|
3
|
+
export const Route: RouteProps = {
|
|
4
|
+
path: "/product/:productId",
|
|
5
|
+
method: HttpMethod.patch,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// Base interfaces for testing intersection types
|
|
9
|
+
interface ProductDetails {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
price: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface ProductInventory {
|
|
16
|
+
stock: number;
|
|
17
|
+
warehouse: string;
|
|
18
|
+
sku: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ProductMetadata {
|
|
22
|
+
createdAt: Date;
|
|
23
|
+
updatedAt: Date;
|
|
24
|
+
createdBy: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Test case: Intersection type with Partial indexed access patterns
|
|
28
|
+
interface PatchProductWithIntersectionReq {
|
|
29
|
+
// Intersection of Partial types - should extract ProductDetails and ProductInventory
|
|
30
|
+
update?: Partial<ProductDetails["price"]> & Partial<ProductInventory["stock"]>;
|
|
31
|
+
// More realistic intersection pattern
|
|
32
|
+
fullUpdate?: Partial<ProductDetails> & Partial<ProductInventory> & { notes: string };
|
|
33
|
+
// Intersection with indexed access
|
|
34
|
+
metadataUpdate?: Partial<ProductMetadata["updatedAt"]> & { updatedBy: string };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type Params = { productId: string };
|
|
38
|
+
|
|
39
|
+
const PatchProductWithIntersection: Handler<any, PatchProductWithIntersectionReq, ProductDetails, Params> = async ({ req }) => {
|
|
40
|
+
return {
|
|
41
|
+
data: {
|
|
42
|
+
name: "Test Product",
|
|
43
|
+
description: "Test Description",
|
|
44
|
+
price: (req.body.update as any) || 99.99,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default PatchProductWithIntersection;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Handler, HttpMethod, RouteProps } from "@flink-app/flink";
|
|
2
|
+
|
|
3
|
+
export const Route: RouteProps = {
|
|
4
|
+
path: "/user/:userId",
|
|
5
|
+
method: HttpMethod.patch,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// Base interfaces for testing union types
|
|
9
|
+
interface UserProfile {
|
|
10
|
+
firstName: string;
|
|
11
|
+
lastName: string;
|
|
12
|
+
bio: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface UserSettings {
|
|
16
|
+
theme: string;
|
|
17
|
+
notifications: boolean;
|
|
18
|
+
language: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface UserPreferences {
|
|
22
|
+
emailFrequency: string;
|
|
23
|
+
newsletter: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Test case: Union type with multiple Partial indexed access patterns
|
|
27
|
+
interface PatchUserWithUnionReq {
|
|
28
|
+
// Union of Partial types - should extract UserProfile, UserSettings, UserPreferences
|
|
29
|
+
data?: Partial<UserProfile["firstName"]> | Partial<UserSettings["theme"]> | Partial<UserPreferences["emailFrequency"]>;
|
|
30
|
+
// More realistic union pattern
|
|
31
|
+
profileUpdate?: Partial<UserProfile> | Partial<UserSettings>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type Params = { userId: string };
|
|
35
|
+
|
|
36
|
+
const PatchUserWithUnion: Handler<any, PatchUserWithUnionReq, UserProfile, Params> = async ({ req }) => {
|
|
37
|
+
return {
|
|
38
|
+
data: {
|
|
39
|
+
firstName: "Test",
|
|
40
|
+
lastName: "User",
|
|
41
|
+
bio: req.body.data as string || "Default bio",
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default PatchUserWithUnion;
|
package/src/FlinkHttpHandler.ts
CHANGED
|
@@ -409,6 +409,48 @@ export default {}; // Export an empty object to make it a module
|
|
|
409
409
|
}
|
|
410
410
|
}
|
|
411
411
|
|
|
412
|
+
/**
|
|
413
|
+
* Recursively copies an interface and all its dependencies from the same file
|
|
414
|
+
*/
|
|
415
|
+
private copyInterfaceWithDependencies(interfaceDecl: any, handlerFile: SourceFile): void {
|
|
416
|
+
const interfaceName = interfaceDecl.getName?.() || interfaceDecl.getFirstChildByKind(SyntaxKind.Identifier)?.getText();
|
|
417
|
+
if (!interfaceName) return;
|
|
418
|
+
|
|
419
|
+
// Check if already copied
|
|
420
|
+
const existingInterface = this.parsedTsSchemas.find(
|
|
421
|
+
s => s.includes(`interface ${interfaceName} `) || s.includes(`type ${interfaceName} =`)
|
|
422
|
+
);
|
|
423
|
+
if (existingInterface) return;
|
|
424
|
+
|
|
425
|
+
// Copy the interface
|
|
426
|
+
this.parsedTsSchemas.push(interfaceDecl.getText());
|
|
427
|
+
|
|
428
|
+
// Find and recursively copy dependencies from the same file
|
|
429
|
+
// First, find direct type references in this interface
|
|
430
|
+
const typeRefIdentifiers = interfaceDecl
|
|
431
|
+
.getDescendantsOfKind(SyntaxKind.TypeReference)
|
|
432
|
+
.filter((typeRefNode: any) => !!typeRefNode.getFirstChildIfKind(SyntaxKind.Identifier))
|
|
433
|
+
.map((typeRefNode: any) => typeRefNode.getFirstChildIfKindOrThrow(SyntaxKind.Identifier));
|
|
434
|
+
|
|
435
|
+
for (const typeRefIdentifier of typeRefIdentifiers) {
|
|
436
|
+
const typeSymbol = typeRefIdentifier.getSymbol();
|
|
437
|
+
if (typeSymbol) {
|
|
438
|
+
const declaredType = typeSymbol.getDeclaredType();
|
|
439
|
+
const declaration = declaredType.getSymbol()?.getDeclarations()[0];
|
|
440
|
+
if (declaration && declaration.getSourceFile() === handlerFile) {
|
|
441
|
+
// Same file - recursively copy this dependency
|
|
442
|
+
this.copyInterfaceWithDependencies(declaration, handlerFile);
|
|
443
|
+
} else if (declaration && declaration.getSourceFile() !== handlerFile) {
|
|
444
|
+
// Different file - add to imports
|
|
445
|
+
const declaredTypeSymbol = declaredType.getSymbol();
|
|
446
|
+
if (declaredTypeSymbol) {
|
|
447
|
+
this.tsSchemasSymbolsToImports.push(declaredTypeSymbol);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
412
454
|
private async saveIntermediateTsSchema(schema: Type<ts.Type>, handlerFile: SourceFile, suffix: string) {
|
|
413
455
|
if (schema.isAny()) {
|
|
414
456
|
return; // 'any' indicates that no schema is used
|
|
@@ -431,7 +473,7 @@ export default {}; // Export an empty object to make it a module
|
|
|
431
473
|
|
|
432
474
|
if (declaration.getSourceFile() === handlerFile) {
|
|
433
475
|
// Interface is declared within handler file
|
|
434
|
-
generatedSchemaInterfaceStr = `export interface ${schemaInterfaceName} {
|
|
476
|
+
generatedSchemaInterfaceStr = `export interface ${schemaInterfaceName} {
|
|
435
477
|
${schema
|
|
436
478
|
.getProperties()
|
|
437
479
|
.map((p) => p.getValueDeclarationOrThrow().getText())
|
|
@@ -439,7 +481,34 @@ export default {}; // Export an empty object to make it a module
|
|
|
439
481
|
}`;
|
|
440
482
|
|
|
441
483
|
for (const typeToImport of getTypesToImport(declaration)) {
|
|
442
|
-
|
|
484
|
+
const typeSymbol = typeToImport.getSymbol();
|
|
485
|
+
if (typeSymbol) {
|
|
486
|
+
const declaredTypeSymbol = typeSymbol.getDeclaredType().getSymbol();
|
|
487
|
+
if (declaredTypeSymbol) {
|
|
488
|
+
this.tsSchemasSymbolsToImports.push(declaredTypeSymbol);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Also check for utility types with indexed access patterns like Partial<Foo["bar"]>
|
|
494
|
+
for (const prop of schema.getProperties()) {
|
|
495
|
+
const propDecl = prop.getValueDeclaration();
|
|
496
|
+
if (propDecl) {
|
|
497
|
+
const propText = propDecl.getText();
|
|
498
|
+
// Match interface names in patterns like: Partial<InterfaceName["prop"]>
|
|
499
|
+
const interfaceNameMatches = propText.match(/\b([A-Z][a-zA-Z0-9]*)\s*\[/g);
|
|
500
|
+
if (interfaceNameMatches) {
|
|
501
|
+
for (const match of interfaceNameMatches) {
|
|
502
|
+
const referencedInterfaceName = match.replace(/\s*\[$/, '').trim();
|
|
503
|
+
// Try to find this interface in the handler file
|
|
504
|
+
const referencedInterfaceDecl = handlerFile.getInterface(referencedInterfaceName) || handlerFile.getTypeAlias(referencedInterfaceName);
|
|
505
|
+
if (referencedInterfaceDecl) {
|
|
506
|
+
// Interface is in same file - copy it and all its dependencies recursively
|
|
507
|
+
this.copyInterfaceWithDependencies(referencedInterfaceDecl, handlerFile);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
443
512
|
}
|
|
444
513
|
} else {
|
|
445
514
|
// Interface is imported from other file
|
|
@@ -468,7 +537,13 @@ export default {}; // Export an empty object to make it a module
|
|
|
468
537
|
}
|
|
469
538
|
|
|
470
539
|
for (const typeToImport of getTypesToImport(declaration)) {
|
|
471
|
-
|
|
540
|
+
const typeSymbol = typeToImport.getSymbol();
|
|
541
|
+
if (typeSymbol) {
|
|
542
|
+
const declaredTypeSymbol = typeSymbol.getDeclaredType().getSymbol();
|
|
543
|
+
if (declaredTypeSymbol) {
|
|
544
|
+
this.tsSchemasSymbolsToImports.push(declaredTypeSymbol);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
472
547
|
}
|
|
473
548
|
}
|
|
474
549
|
} else if (schema.isObject()) {
|
|
@@ -477,8 +552,11 @@ export default {}; // Export an empty object to make it a module
|
|
|
477
552
|
* We need extract `{car: Car}` into its own interface and make sure
|
|
478
553
|
* to import types if needed to
|
|
479
554
|
*/
|
|
480
|
-
|
|
481
|
-
|
|
555
|
+
|
|
556
|
+
// Try to get symbol - it may not exist for utility types (Partial, Omit, Pick, etc.)
|
|
557
|
+
const schemaSymbol = schema.getSymbol();
|
|
558
|
+
const declarations = schemaSymbol?.getDeclarations();
|
|
559
|
+
const declaration = declarations?.[0];
|
|
482
560
|
|
|
483
561
|
// Build property signatures using resolved types instead of source text
|
|
484
562
|
// This ensures generic type parameters are properly expanded
|
|
@@ -528,6 +606,51 @@ export default {}; // Export an empty object to make it a module
|
|
|
528
606
|
}
|
|
529
607
|
}
|
|
530
608
|
}
|
|
609
|
+
|
|
610
|
+
// Check for utility types (Partial, Omit, Pick, etc.) and extract their type arguments
|
|
611
|
+
// For example: Partial<Foo["bar"]> should extract Foo
|
|
612
|
+
// Use a pragmatic text-based approach to find interface references in type expressions
|
|
613
|
+
// Match interface names in patterns like: Partial<InterfaceName["prop"]>, Omit<InterfaceName, "key">, etc.
|
|
614
|
+
const currentPropTypeText = propType.getText(undefined, ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope);
|
|
615
|
+
const interfaceNameMatches = currentPropTypeText.match(/\b([A-Z][a-zA-Z0-9]*)\s*\[/g);
|
|
616
|
+
if (interfaceNameMatches) {
|
|
617
|
+
for (const match of interfaceNameMatches) {
|
|
618
|
+
const interfaceName = match.replace(/\s*\[$/, '').trim();
|
|
619
|
+
// Try to find this interface in the handler file
|
|
620
|
+
const interfaceDecl = handlerFile.getInterface(interfaceName) || handlerFile.getTypeAlias(interfaceName);
|
|
621
|
+
if (interfaceDecl) {
|
|
622
|
+
// Interface is in same file - copy it and all its dependencies recursively
|
|
623
|
+
this.copyInterfaceWithDependencies(interfaceDecl, handlerFile);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Also check regular type arguments (for types like Array<Foo>, Promise<Bar>)
|
|
629
|
+
const typeArgs = propType.getTypeArguments();
|
|
630
|
+
if (typeArgs && typeArgs.length > 0) {
|
|
631
|
+
for (const typeArg of typeArgs) {
|
|
632
|
+
const argSymbol = typeArg.getSymbol();
|
|
633
|
+
if (argSymbol) {
|
|
634
|
+
const argDeclaration = argSymbol.getDeclarations()[0];
|
|
635
|
+
if (argDeclaration && argDeclaration.getSourceFile() !== handlerFile) {
|
|
636
|
+
this.tsSchemasSymbolsToImports.push(argSymbol);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// If we have a declaration, check if we need to import any types
|
|
644
|
+
if (declaration) {
|
|
645
|
+
for (const typeToImport of getTypesToImport(declaration)) {
|
|
646
|
+
const typeSymbol = typeToImport.getSymbol();
|
|
647
|
+
if (typeSymbol) {
|
|
648
|
+
const declaredTypeSymbol = typeSymbol.getDeclaredType().getSymbol();
|
|
649
|
+
if (declaredTypeSymbol) {
|
|
650
|
+
this.tsSchemasSymbolsToImports.push(declaredTypeSymbol);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
531
654
|
}
|
|
532
655
|
|
|
533
656
|
generatedSchemaInterfaceStr = `export interface ${schemaInterfaceName} { ${propertySignatures.join(";\n")} }`;
|
package/src/utils.ts
CHANGED
|
@@ -75,6 +75,7 @@ export function getHttpMethodFromHandlerName(handlerFilename: string) {
|
|
|
75
75
|
if (handlerFilename.startsWith(HttpMethod.post)) return HttpMethod.post;
|
|
76
76
|
if (handlerFilename.startsWith(HttpMethod.put)) return HttpMethod.put;
|
|
77
77
|
if (handlerFilename.startsWith(HttpMethod.delete)) return HttpMethod.delete;
|
|
78
|
+
if (handlerFilename.startsWith(HttpMethod.patch)) return HttpMethod.patch;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
export function getJsDocComment(comment: string) {
|