@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 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>;
@@ -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 || "User not logged in or or not allowed to access resource",
48
- code: code || "badRequest"
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.45",
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": "af426a157217c110ac9c7beb48e2e746968bec33"
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 };
@@ -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 || "notFound"
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 || "conflict"
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 || "badRequest"
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 || "User not logged in or or not allowed to access resource",
53
- code : code || "badRequest"
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 || "internalServerError"
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,