@flink-app/flink 0.12.1-alpha.45 → 0.12.1-alpha.47
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/dist/bin/flink.js +0 -0
- package/dist/src/FlinkErrors.d.ts +69 -0
- package/dist/src/FlinkErrors.js +83 -3
- package/dist/src/TypeScriptCompiler.js +18 -2
- package/package.json +2 -2
- package/spec/mock-project/dist/src/handlers/GetCar.js +0 -2
- package/spec/mock-project/dist/src/handlers/GetCar2.js +0 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +0 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +0 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +0 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +0 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +0 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js +0 -2
- package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +0 -2
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +0 -2
- package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +0 -2
- package/spec/mock-project/dist/src/handlers/PostCar.js +0 -2
- package/spec/mock-project/dist/src/handlers/PostLogin.js +0 -2
- package/spec/mock-project/dist/src/handlers/PostLogout.js +0 -2
- package/spec/mock-project/dist/src/handlers/PutCar.js +0 -2
- package/src/FlinkErrors.ts +86 -6
- package/src/TypeScriptCompiler.ts +21 -0
package/dist/bin/flink.js
CHANGED
|
File without changes
|
|
@@ -1,7 +1,76 @@
|
|
|
1
1
|
import { FlinkResponse } from "./FlinkResponse";
|
|
2
2
|
export type FlinkError = undefined;
|
|
3
|
+
/**
|
|
4
|
+
* Returns a 404 Not Found error response.
|
|
5
|
+
* Use when a requested resource doesn't exist (e.g., invalid ID, missing entity).
|
|
6
|
+
*
|
|
7
|
+
* @param detail - Optional custom error message
|
|
8
|
+
* @param code - Optional custom error code
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* if (!user) return notFound("User not found");
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
3
14
|
export declare function notFound(detail?: string, code?: string): FlinkResponse<FlinkError>;
|
|
15
|
+
/**
|
|
16
|
+
* Returns a 409 Conflict error response.
|
|
17
|
+
* Use when a request conflicts with existing data (e.g., duplicate username/email).
|
|
18
|
+
*
|
|
19
|
+
* @param detail - Optional custom error message
|
|
20
|
+
* @param code - Optional custom error code
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* if (existingUser) return conflict("Email already registered");
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
4
26
|
export declare function conflict(detail?: string, code?: string): FlinkResponse<FlinkError>;
|
|
27
|
+
/**
|
|
28
|
+
* Returns a 400 Bad Request error response.
|
|
29
|
+
* Use when the request is malformed or contains invalid data (e.g., validation errors).
|
|
30
|
+
*
|
|
31
|
+
* @param detail - Optional custom error message
|
|
32
|
+
* @param code - Optional custom error code
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* if (!email || !password) return badRequest("Email and password are required");
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
5
38
|
export declare function badRequest(detail?: string, code?: string): FlinkResponse<FlinkError>;
|
|
39
|
+
/**
|
|
40
|
+
* Returns a 401 Unauthorized error response.
|
|
41
|
+
* Use when authentication is required but missing or invalid (e.g., no token, expired token).
|
|
42
|
+
* This means "who are you?" - the user needs to identify themselves first.
|
|
43
|
+
*
|
|
44
|
+
* @param detail - Optional custom error message
|
|
45
|
+
* @param code - Optional custom error code
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* if (!ctx.auth?.user) return unauthorized("Authentication required");
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
6
51
|
export declare function unauthorized(detail?: string, code?: string): FlinkResponse<FlinkError>;
|
|
52
|
+
/**
|
|
53
|
+
* Returns a 403 Forbidden error response.
|
|
54
|
+
* Use when the user is authenticated but lacks permission to access the resource.
|
|
55
|
+
* This means "I know who you are, but you're not allowed to do this."
|
|
56
|
+
*
|
|
57
|
+
* @param detail - Optional custom error message
|
|
58
|
+
* @param code - Optional custom error code
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* if (ctx.auth?.user?.role !== "admin") return forbidden("Admin access required");
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function forbidden(detail?: string, code?: string): FlinkResponse<FlinkError>;
|
|
65
|
+
/**
|
|
66
|
+
* Returns a 500 Internal Server Error response.
|
|
67
|
+
* Use when an unexpected error occurs on the server side.
|
|
68
|
+
*
|
|
69
|
+
* @param detail - Optional custom error message
|
|
70
|
+
* @param code - Optional custom error code
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* try { ... } catch (error) { return internalServerError("Failed to process request"); }
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
7
76
|
export declare function internalServerError(detail?: string, code?: string): FlinkResponse<FlinkError>;
|
package/dist/src/FlinkErrors.js
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.internalServerError = exports.unauthorized = exports.badRequest = exports.conflict = exports.notFound = void 0;
|
|
3
|
+
exports.internalServerError = exports.forbidden = exports.unauthorized = exports.badRequest = exports.conflict = exports.notFound = void 0;
|
|
4
4
|
var uuid_1 = require("uuid");
|
|
5
|
+
/**
|
|
6
|
+
* Returns a 404 Not Found error response.
|
|
7
|
+
* Use when a requested resource doesn't exist (e.g., invalid ID, missing entity).
|
|
8
|
+
*
|
|
9
|
+
* @param detail - Optional custom error message
|
|
10
|
+
* @param code - Optional custom error code
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* if (!user) return notFound("User not found");
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
5
16
|
function notFound(detail, code) {
|
|
6
17
|
return {
|
|
7
18
|
status: 404,
|
|
@@ -14,6 +25,17 @@ function notFound(detail, code) {
|
|
|
14
25
|
};
|
|
15
26
|
}
|
|
16
27
|
exports.notFound = notFound;
|
|
28
|
+
/**
|
|
29
|
+
* Returns a 409 Conflict error response.
|
|
30
|
+
* Use when a request conflicts with existing data (e.g., duplicate username/email).
|
|
31
|
+
*
|
|
32
|
+
* @param detail - Optional custom error message
|
|
33
|
+
* @param code - Optional custom error code
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* if (existingUser) return conflict("Email already registered");
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
17
39
|
function conflict(detail, code) {
|
|
18
40
|
return {
|
|
19
41
|
status: 409,
|
|
@@ -26,6 +48,17 @@ function conflict(detail, code) {
|
|
|
26
48
|
};
|
|
27
49
|
}
|
|
28
50
|
exports.conflict = conflict;
|
|
51
|
+
/**
|
|
52
|
+
* Returns a 400 Bad Request error response.
|
|
53
|
+
* Use when the request is malformed or contains invalid data (e.g., validation errors).
|
|
54
|
+
*
|
|
55
|
+
* @param detail - Optional custom error message
|
|
56
|
+
* @param code - Optional custom error code
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* if (!email || !password) return badRequest("Email and password are required");
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
29
62
|
function badRequest(detail, code) {
|
|
30
63
|
return {
|
|
31
64
|
status: 400,
|
|
@@ -38,18 +71,65 @@ function badRequest(detail, code) {
|
|
|
38
71
|
};
|
|
39
72
|
}
|
|
40
73
|
exports.badRequest = badRequest;
|
|
74
|
+
/**
|
|
75
|
+
* Returns a 401 Unauthorized error response.
|
|
76
|
+
* Use when authentication is required but missing or invalid (e.g., no token, expired token).
|
|
77
|
+
* This means "who are you?" - the user needs to identify themselves first.
|
|
78
|
+
*
|
|
79
|
+
* @param detail - Optional custom error message
|
|
80
|
+
* @param code - Optional custom error code
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* if (!ctx.auth?.user) return unauthorized("Authentication required");
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
41
86
|
function unauthorized(detail, code) {
|
|
42
87
|
return {
|
|
43
88
|
status: 401,
|
|
44
89
|
error: {
|
|
45
90
|
id: (0, uuid_1.v4)(),
|
|
46
91
|
title: "Unauthorized",
|
|
47
|
-
detail: detail || "
|
|
48
|
-
code: code || "
|
|
92
|
+
detail: detail || "Authentication required",
|
|
93
|
+
code: code || "unauthorized"
|
|
49
94
|
},
|
|
50
95
|
};
|
|
51
96
|
}
|
|
52
97
|
exports.unauthorized = unauthorized;
|
|
98
|
+
/**
|
|
99
|
+
* Returns a 403 Forbidden error response.
|
|
100
|
+
* Use when the user is authenticated but lacks permission to access the resource.
|
|
101
|
+
* This means "I know who you are, but you're not allowed to do this."
|
|
102
|
+
*
|
|
103
|
+
* @param detail - Optional custom error message
|
|
104
|
+
* @param code - Optional custom error code
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* if (ctx.auth?.user?.role !== "admin") return forbidden("Admin access required");
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
function forbidden(detail, code) {
|
|
111
|
+
return {
|
|
112
|
+
status: 403,
|
|
113
|
+
error: {
|
|
114
|
+
id: (0, uuid_1.v4)(),
|
|
115
|
+
title: "Forbidden",
|
|
116
|
+
detail: detail || "You do not have permission to access this resource",
|
|
117
|
+
code: code || "forbidden"
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
exports.forbidden = forbidden;
|
|
122
|
+
/**
|
|
123
|
+
* Returns a 500 Internal Server Error response.
|
|
124
|
+
* Use when an unexpected error occurs on the server side.
|
|
125
|
+
*
|
|
126
|
+
* @param detail - Optional custom error message
|
|
127
|
+
* @param code - Optional custom error code
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* try { ... } catch (error) { return internalServerError("Failed to process request"); }
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
53
133
|
function internalServerError(detail, code) {
|
|
54
134
|
return {
|
|
55
135
|
status: 500,
|
|
@@ -282,7 +282,7 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
282
282
|
*/
|
|
283
283
|
TypeScriptCompiler.prototype.parseHandlerDir = function (generatedFile, handlersArr) {
|
|
284
284
|
return __awaiter(this, void 0, void 0, function () {
|
|
285
|
-
var imports, i, schemasToGenerate, _i, _a, sf, isAutoRegister, namespaceImport, assumedHttpMethod, schemaTypes;
|
|
285
|
+
var imports, i, schemasToGenerate, _i, _a, sf, isAutoRegister, namespaceImport, assumedHttpMethod, schemaTypes, existingVars;
|
|
286
286
|
return __generator(this, function (_b) {
|
|
287
287
|
switch (_b.label) {
|
|
288
288
|
case 0:
|
|
@@ -308,6 +308,11 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
308
308
|
return [4 /*yield*/, this.extractSchemasFromHandlerSourceFile(sf)];
|
|
309
309
|
case 2:
|
|
310
310
|
schemaTypes = _b.sent();
|
|
311
|
+
existingVars = sf.getVariableStatements().filter(function (vs) {
|
|
312
|
+
var varNames = vs.getDeclarations().map(function (d) { return d.getName(); });
|
|
313
|
+
return varNames.some(function (name) { return ['__assumedHttpMethod', '__file', '__query', '__params'].includes(name); });
|
|
314
|
+
});
|
|
315
|
+
existingVars.forEach(function (v) { return v.remove(); });
|
|
311
316
|
// Append schemas and metadata to source file that will be part of emitted dist bundle (javascript)
|
|
312
317
|
sf.addVariableStatement({
|
|
313
318
|
declarationKind: ts_morph_1.VariableDeclarationKind.Const,
|
|
@@ -710,6 +715,12 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
710
715
|
}
|
|
711
716
|
var reqJsonSchema = JSON.stringify(reqSchemaType ? jsonSchemaDefs[reqSchemaType] : undefined);
|
|
712
717
|
var resJsonSchema = JSON.stringify(resSchemaType ? jsonSchemaDefs[resSchemaType] : undefined);
|
|
718
|
+
// Remove existing __schemas variable if it exists (to avoid redeclaration errors)
|
|
719
|
+
var existingSchemas = sourceFile.getVariableStatements().filter(function (vs) {
|
|
720
|
+
var varNames = vs.getDeclarations().map(function (d) { return d.getName(); });
|
|
721
|
+
return varNames.includes('__schemas');
|
|
722
|
+
});
|
|
723
|
+
existingSchemas.forEach(function (v) { return v.remove(); });
|
|
713
724
|
sourceFile.addVariableStatement({
|
|
714
725
|
declarationKind: ts_morph_1.VariableDeclarationKind.Const,
|
|
715
726
|
isExported: true,
|
|
@@ -728,7 +739,7 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
728
739
|
*/
|
|
729
740
|
TypeScriptCompiler.prototype.parseJobs = function () {
|
|
730
741
|
return __awaiter(this, void 0, void 0, function () {
|
|
731
|
-
var generatedFile, jobsArr, imports, i, _i, _a, sf, namespaceImport;
|
|
742
|
+
var generatedFile, jobsArr, imports, i, _i, _a, sf, namespaceImport, existingFile;
|
|
732
743
|
return __generator(this, function (_b) {
|
|
733
744
|
switch (_b.label) {
|
|
734
745
|
case 0:
|
|
@@ -747,6 +758,11 @@ var TypeScriptCompiler = /** @class */ (function () {
|
|
|
747
758
|
defaultImport: "* as " + namespaceImport,
|
|
748
759
|
moduleSpecifier: this.getModuleSpecifier(generatedFile, sf),
|
|
749
760
|
});
|
|
761
|
+
existingFile = sf.getVariableStatements().filter(function (vs) {
|
|
762
|
+
var varNames = vs.getDeclarations().map(function (d) { return d.getName(); });
|
|
763
|
+
return varNames.includes('__file');
|
|
764
|
+
});
|
|
765
|
+
existingFile.forEach(function (v) { return v.remove(); });
|
|
750
766
|
// Append metadata to source file that will be part of emitted dist bundle (javascript)
|
|
751
767
|
sf.addVariableStatement({
|
|
752
768
|
declarationKind: ts_morph_1.VariableDeclarationKind.Const,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flink-app/flink",
|
|
3
|
-
"version": "0.12.1-alpha.
|
|
3
|
+
"version": "0.12.1-alpha.47",
|
|
4
4
|
"description": "Typescript only framework for creating REST-like APIs on top of Express and mongodb",
|
|
5
5
|
"types": "dist/src/index.d.ts",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -69,5 +69,5 @@
|
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"mongodb": ">=3.7.0 <7.0.0"
|
|
71
71
|
},
|
|
72
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "a98a0af7f11e4a97f68da4d0d67677df7d2a2749"
|
|
73
73
|
}
|
|
@@ -55,5 +55,3 @@ var GetCar = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b
|
|
|
55
55
|
exports.default = GetCar;
|
|
56
56
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCar.ts", exports.__query = [{ description: "For pagination", name: "page" }], exports.__params = [{ description: "", name: "id" }];
|
|
57
57
|
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": {} } };
|
|
58
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCar.ts", exports.__query = [{ description: "For pagination", name: "page" }], exports.__params = [{ description: "", name: "id" }];
|
|
59
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$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": {} } };
|
|
@@ -57,5 +57,3 @@ var GetCar2 = function (_a) { return __awaiter(void 0, [_a], void 0, function (_
|
|
|
57
57
|
exports.default = GetCar2;
|
|
58
58
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCar2.ts", exports.__query = [], exports.__params = [];
|
|
59
59
|
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "model": { "type": "object", "properties": { "name": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["name"], "additionalProperties": false }, "engine": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"], "additionalProperties": false } }, "required": ["model", "engine"], "additionalProperties": false, "definitions": {} } };
|
|
60
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCar2.ts", exports.__query = [], exports.__params = [];
|
|
61
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "model": { "type": "object", "properties": { "name": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["name"], "additionalProperties": false }, "engine": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"], "additionalProperties": false } }, "required": ["model", "engine"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -51,5 +51,3 @@ var GetCarWithArraySchema = function (_a) { return __awaiter(void 0, [_a], void
|
|
|
51
51
|
exports.default = GetCarWithArraySchema;
|
|
52
52
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithArraySchema.ts", exports.__query = [], exports.__params = [];
|
|
53
53
|
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false }, "definitions": {} } };
|
|
54
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithArraySchema.ts", exports.__query = [], exports.__params = [];
|
|
55
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false }, "definitions": {} } };
|
|
@@ -51,5 +51,3 @@ var GetCarWithArraySchema2 = function (_a) { return __awaiter(void 0, [_a], void
|
|
|
51
51
|
exports.default = GetCarWithArraySchema2;
|
|
52
52
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithArraySchema2.ts", exports.__query = [], exports.__params = [];
|
|
53
53
|
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false }, "definitions": {} } };
|
|
54
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithArraySchema2.ts", exports.__query = [], exports.__params = [];
|
|
55
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false }, "definitions": {} } };
|
|
@@ -51,5 +51,3 @@ var GetCarWithArraySchema3 = function (_a) { return __awaiter(void 0, [_a], void
|
|
|
51
51
|
exports.default = GetCarWithArraySchema3;
|
|
52
52
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithArraySchema3.ts", exports.__query = [], exports.__params = [];
|
|
53
53
|
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false }, "year": { "type": "number" } }, "required": ["car", "year"], "additionalProperties": false }, "definitions": {} } };
|
|
54
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithArraySchema3.ts", exports.__query = [], exports.__params = [];
|
|
55
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false }, "year": { "type": "number" } }, "required": ["car", "year"], "additionalProperties": false }, "definitions": {} } };
|
|
@@ -53,5 +53,3 @@ var GetCarWithLiteralSchema = function (_a) { return __awaiter(void 0, [_a], voi
|
|
|
53
53
|
exports.default = GetCarWithLiteralSchema;
|
|
54
54
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithLiteralSchema.ts", exports.__query = [], exports.__params = [];
|
|
55
55
|
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false, "definitions": {} } };
|
|
56
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithLiteralSchema.ts", exports.__query = [], exports.__params = [];
|
|
57
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -53,5 +53,3 @@ var GetCarWithLiteralSchema2 = function (_a) { return __awaiter(void 0, [_a], vo
|
|
|
53
53
|
exports.default = GetCarWithLiteralSchema2;
|
|
54
54
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithLiteralSchema2.ts", exports.__query = [], exports.__params = [];
|
|
55
55
|
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "car": { "type": "object", "properties": { "nestedCar": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["nestedCar"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false, "definitions": {} } };
|
|
56
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithLiteralSchema2.ts", exports.__query = [], exports.__params = [];
|
|
57
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "car": { "type": "object", "properties": { "nestedCar": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["nestedCar"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -56,5 +56,3 @@ var GetCarWithSchemaInFile = function (_a) { return __awaiter(void 0, [_a], void
|
|
|
56
56
|
exports.default = GetCarWithSchemaInFile;
|
|
57
57
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithSchemaInFile.ts", exports.__query = [], exports.__params = [];
|
|
58
58
|
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "model": { "type": "string" } }, "required": ["model"], "additionalProperties": false, "definitions": {} } };
|
|
59
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithSchemaInFile.ts", exports.__query = [], exports.__params = [];
|
|
60
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "model": { "type": "string" } }, "required": ["model"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -56,5 +56,3 @@ var GetCarWithSchemaInFile2 = function (_a) { return __awaiter(void 0, [_a], voi
|
|
|
56
56
|
exports.default = GetCarWithSchemaInFile2;
|
|
57
57
|
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithSchemaInFile2.ts", exports.__query = [], exports.__params = [];
|
|
58
58
|
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false, "definitions": {} } };
|
|
59
|
-
exports.__assumedHttpMethod = "get", exports.__file = "GetCarWithSchemaInFile2.ts", exports.__query = [], exports.__params = [];
|
|
60
|
-
exports.__schemas = { reqSchema: undefined, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "car": { "type": "object", "properties": { "model": { "type": "string" }, "metadata": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" } }, "additionalProperties": false } }, "required": ["model"], "additionalProperties": false } }, "required": ["car"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -52,5 +52,3 @@ var manuallyAddedHandler = function (_a) { return __awaiter(void 0, [_a], void 0
|
|
|
52
52
|
exports.default = manuallyAddedHandler;
|
|
53
53
|
exports.__assumedHttpMethod = "", exports.__file = "ManuallyAddedHandler.ts", exports.__query = [], exports.__params = [];
|
|
54
54
|
exports.__schemas = { reqSchema: { "$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": {} }, resSchema: undefined };
|
|
55
|
-
exports.__assumedHttpMethod = "", exports.__file = "ManuallyAddedHandler.ts", exports.__query = [], exports.__params = [];
|
|
56
|
-
exports.__schemas = { reqSchema: { "$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": {} }, resSchema: undefined };
|
|
@@ -54,5 +54,3 @@ var manuallyAddedHandler = function (_a) { return __awaiter(void 0, [_a], void 0
|
|
|
54
54
|
exports.default = manuallyAddedHandler;
|
|
55
55
|
exports.__assumedHttpMethod = "", exports.__file = "ManuallyAddedHandler2.ts", exports.__query = [], exports.__params = [];
|
|
56
56
|
exports.__schemas = { reqSchema: { "$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": {} }, resSchema: undefined };
|
|
57
|
-
exports.__assumedHttpMethod = "", exports.__file = "ManuallyAddedHandler2.ts", exports.__query = [], exports.__params = [];
|
|
58
|
-
exports.__schemas = { reqSchema: { "$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": {} }, resSchema: undefined };
|
|
@@ -53,5 +53,3 @@ var PostCar = function (_a) { return __awaiter(void 0, [_a], void 0, function (_
|
|
|
53
53
|
exports.default = PostCar;
|
|
54
54
|
exports.__assumedHttpMethod = "post", exports.__file = "PostCar.ts", exports.__query = [], exports.__params = [];
|
|
55
55
|
exports.__schemas = { reqSchema: { "$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": {} }, 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": {} } };
|
|
56
|
-
exports.__assumedHttpMethod = "post", exports.__file = "PostCar.ts", exports.__query = [], exports.__params = [];
|
|
57
|
-
exports.__schemas = { reqSchema: { "$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": {} }, 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": {} } };
|
|
@@ -54,5 +54,3 @@ var PostLogin = function (_a) { return __awaiter(void 0, [_a], void 0, function
|
|
|
54
54
|
exports.default = PostLogin;
|
|
55
55
|
exports.__assumedHttpMethod = "post", exports.__file = "PostLogin.ts", exports.__query = [], exports.__params = [];
|
|
56
56
|
exports.__schemas = { reqSchema: undefined, resSchema: undefined };
|
|
57
|
-
exports.__assumedHttpMethod = "post", exports.__file = "PostLogin.ts", exports.__query = [], exports.__params = [];
|
|
58
|
-
exports.__schemas = { reqSchema: undefined, resSchema: undefined };
|
|
@@ -53,5 +53,3 @@ var PostLogout = function (_a) { return __awaiter(void 0, [_a], void 0, function
|
|
|
53
53
|
exports.default = PostLogout;
|
|
54
54
|
exports.__assumedHttpMethod = "post", exports.__file = "PostLogout.ts", exports.__query = [], exports.__params = [];
|
|
55
55
|
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "definitions": {} }, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "success": { "type": "boolean" } }, "required": ["success"], "additionalProperties": false, "definitions": {} } };
|
|
56
|
-
exports.__assumedHttpMethod = "post", exports.__file = "PostLogout.ts", exports.__query = [], exports.__params = [];
|
|
57
|
-
exports.__schemas = { reqSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "definitions": {} }, resSchema: { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "success": { "type": "boolean" } }, "required": ["success"], "additionalProperties": false, "definitions": {} } };
|
|
@@ -53,5 +53,3 @@ var PutCar = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b
|
|
|
53
53
|
exports.default = PutCar;
|
|
54
54
|
exports.__assumedHttpMethod = "put", exports.__file = "PutCar.ts", exports.__query = [], exports.__params = [];
|
|
55
55
|
exports.__schemas = { reqSchema: { "$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": {} }, resSchema: undefined };
|
|
56
|
-
exports.__assumedHttpMethod = "put", exports.__file = "PutCar.ts", exports.__query = [], exports.__params = [];
|
|
57
|
-
exports.__schemas = { reqSchema: { "$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": {} }, resSchema: undefined };
|
package/src/FlinkErrors.ts
CHANGED
|
@@ -4,6 +4,17 @@ import { FlinkResponse } from "./FlinkResponse";
|
|
|
4
4
|
// A marker for FlinkError, but all it means is that data is undefined
|
|
5
5
|
export type FlinkError = undefined;
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Returns a 404 Not Found error response.
|
|
9
|
+
* Use when a requested resource doesn't exist (e.g., invalid ID, missing entity).
|
|
10
|
+
*
|
|
11
|
+
* @param detail - Optional custom error message
|
|
12
|
+
* @param code - Optional custom error code
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* if (!user) return notFound("User not found");
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
7
18
|
export function notFound(detail?: string, code?: string ): FlinkResponse<FlinkError> {
|
|
8
19
|
return {
|
|
9
20
|
status: 404,
|
|
@@ -11,11 +22,22 @@ export function notFound(detail?: string, code?: string ): FlinkResponse<FlinkEr
|
|
|
11
22
|
id: v4(),
|
|
12
23
|
title: "Not Found",
|
|
13
24
|
detail: detail || "The requested resource does not exist",
|
|
14
|
-
code : code ||
|
|
25
|
+
code : code || "notFound"
|
|
15
26
|
},
|
|
16
27
|
};
|
|
17
28
|
}
|
|
18
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Returns a 409 Conflict error response.
|
|
32
|
+
* Use when a request conflicts with existing data (e.g., duplicate username/email).
|
|
33
|
+
*
|
|
34
|
+
* @param detail - Optional custom error message
|
|
35
|
+
* @param code - Optional custom error code
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* if (existingUser) return conflict("Email already registered");
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
19
41
|
export function conflict(detail?: string, code?: string ): FlinkResponse<FlinkError> {
|
|
20
42
|
return {
|
|
21
43
|
status: 409,
|
|
@@ -23,13 +45,24 @@ export function conflict(detail?: string, code?: string ): FlinkResponse<FlinkEr
|
|
|
23
45
|
id: v4(),
|
|
24
46
|
title: "Conflict",
|
|
25
47
|
detail: detail || "An identical entity exits",
|
|
26
|
-
code : code ||
|
|
48
|
+
code : code || "conflict"
|
|
27
49
|
},
|
|
28
50
|
};
|
|
29
51
|
}
|
|
30
52
|
|
|
31
53
|
|
|
32
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Returns a 400 Bad Request error response.
|
|
57
|
+
* Use when the request is malformed or contains invalid data (e.g., validation errors).
|
|
58
|
+
*
|
|
59
|
+
* @param detail - Optional custom error message
|
|
60
|
+
* @param code - Optional custom error code
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* if (!email || !password) return badRequest("Email and password are required");
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
33
66
|
export function badRequest(detail?: string, code?: string): FlinkResponse<FlinkError> {
|
|
34
67
|
return {
|
|
35
68
|
status: 400,
|
|
@@ -37,11 +70,23 @@ export function badRequest(detail?: string, code?: string): FlinkResponse<FlinkE
|
|
|
37
70
|
id: v4(),
|
|
38
71
|
title: "Bad Request",
|
|
39
72
|
detail: detail || "Invalid request",
|
|
40
|
-
code : code ||
|
|
73
|
+
code : code || "badRequest"
|
|
41
74
|
},
|
|
42
75
|
};
|
|
43
76
|
}
|
|
44
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Returns a 401 Unauthorized error response.
|
|
80
|
+
* Use when authentication is required but missing or invalid (e.g., no token, expired token).
|
|
81
|
+
* This means "who are you?" - the user needs to identify themselves first.
|
|
82
|
+
*
|
|
83
|
+
* @param detail - Optional custom error message
|
|
84
|
+
* @param code - Optional custom error code
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* if (!ctx.auth?.user) return unauthorized("Authentication required");
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
45
90
|
export function unauthorized(detail?: string, code?: string): FlinkResponse<FlinkError> {
|
|
46
91
|
return {
|
|
47
92
|
status: 401,
|
|
@@ -49,12 +94,47 @@ export function unauthorized(detail?: string, code?: string): FlinkResponse<Flin
|
|
|
49
94
|
id: v4(),
|
|
50
95
|
title: "Unauthorized",
|
|
51
96
|
detail:
|
|
52
|
-
detail || "
|
|
53
|
-
code : code ||
|
|
97
|
+
detail || "Authentication required",
|
|
98
|
+
code : code || "unauthorized"
|
|
54
99
|
},
|
|
55
100
|
};
|
|
56
101
|
}
|
|
57
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Returns a 403 Forbidden error response.
|
|
105
|
+
* Use when the user is authenticated but lacks permission to access the resource.
|
|
106
|
+
* This means "I know who you are, but you're not allowed to do this."
|
|
107
|
+
*
|
|
108
|
+
* @param detail - Optional custom error message
|
|
109
|
+
* @param code - Optional custom error code
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* if (ctx.auth?.user?.role !== "admin") return forbidden("Admin access required");
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export function forbidden(detail?: string, code?: string): FlinkResponse<FlinkError> {
|
|
116
|
+
return {
|
|
117
|
+
status: 403,
|
|
118
|
+
error: {
|
|
119
|
+
id: v4(),
|
|
120
|
+
title: "Forbidden",
|
|
121
|
+
detail: detail || "You do not have permission to access this resource",
|
|
122
|
+
code : code || "forbidden"
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Returns a 500 Internal Server Error response.
|
|
129
|
+
* Use when an unexpected error occurs on the server side.
|
|
130
|
+
*
|
|
131
|
+
* @param detail - Optional custom error message
|
|
132
|
+
* @param code - Optional custom error code
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* try { ... } catch (error) { return internalServerError("Failed to process request"); }
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
58
138
|
export function internalServerError(
|
|
59
139
|
detail?: string,
|
|
60
140
|
code?: string
|
|
@@ -65,7 +145,7 @@ export function internalServerError(
|
|
|
65
145
|
id: v4(),
|
|
66
146
|
title: "Internal Server Error",
|
|
67
147
|
detail: detail || "Something unexpected went wrong",
|
|
68
|
-
code : code ||
|
|
148
|
+
code : code || "internalServerError"
|
|
69
149
|
},
|
|
70
150
|
};
|
|
71
151
|
}
|
|
@@ -233,6 +233,13 @@ autoRegisteredHandlers.push(...handlers);
|
|
|
233
233
|
|
|
234
234
|
const schemaTypes = await this.extractSchemasFromHandlerSourceFile(sf);
|
|
235
235
|
|
|
236
|
+
// Remove existing metadata variables if they exist (to avoid redeclaration errors)
|
|
237
|
+
const existingVars = sf.getVariableStatements().filter(vs => {
|
|
238
|
+
const varNames = vs.getDeclarations().map(d => d.getName());
|
|
239
|
+
return varNames.some(name => ['__assumedHttpMethod', '__file', '__query', '__params'].includes(name));
|
|
240
|
+
});
|
|
241
|
+
existingVars.forEach(v => v.remove());
|
|
242
|
+
|
|
236
243
|
// Append schemas and metadata to source file that will be part of emitted dist bundle (javascript)
|
|
237
244
|
sf.addVariableStatement({
|
|
238
245
|
declarationKind: VariableDeclarationKind.Const,
|
|
@@ -675,6 +682,13 @@ ${this.parsedTsSchemas.join("\n\n")}`
|
|
|
675
682
|
const reqJsonSchema = JSON.stringify(reqSchemaType ? jsonSchemaDefs[reqSchemaType] : undefined);
|
|
676
683
|
const resJsonSchema = JSON.stringify(resSchemaType ? jsonSchemaDefs[resSchemaType] : undefined);
|
|
677
684
|
|
|
685
|
+
// Remove existing __schemas variable if it exists (to avoid redeclaration errors)
|
|
686
|
+
const existingSchemas = sourceFile.getVariableStatements().filter(vs => {
|
|
687
|
+
const varNames = vs.getDeclarations().map(d => d.getName());
|
|
688
|
+
return varNames.includes('__schemas');
|
|
689
|
+
});
|
|
690
|
+
existingSchemas.forEach(v => v.remove());
|
|
691
|
+
|
|
678
692
|
sourceFile.addVariableStatement({
|
|
679
693
|
declarationKind: VariableDeclarationKind.Const,
|
|
680
694
|
isExported: true,
|
|
@@ -721,6 +735,13 @@ autoRegisteredJobs.push(...jobs);
|
|
|
721
735
|
moduleSpecifier: this.getModuleSpecifier(generatedFile, sf),
|
|
722
736
|
});
|
|
723
737
|
|
|
738
|
+
// Remove existing __file variable if it exists (to avoid redeclaration errors)
|
|
739
|
+
const existingFile = sf.getVariableStatements().filter(vs => {
|
|
740
|
+
const varNames = vs.getDeclarations().map(d => d.getName());
|
|
741
|
+
return varNames.includes('__file');
|
|
742
|
+
});
|
|
743
|
+
existingFile.forEach(v => v.remove());
|
|
744
|
+
|
|
724
745
|
// Append metadata to source file that will be part of emitted dist bundle (javascript)
|
|
725
746
|
sf.addVariableStatement({
|
|
726
747
|
declarationKind: VariableDeclarationKind.Const,
|