@forklaunch/core 0.1.0 → 0.1.2

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.
Files changed (87) hide show
  1. package/.prettierignore +2 -0
  2. package/.prettierrc +6 -0
  3. package/dist/cache/index.d.ts +3 -0
  4. package/dist/cache/index.js +20 -0
  5. package/dist/cache/index.js.map +1 -0
  6. package/dist/cache/interfaces/ttlCache.interface.d.ts +1 -1
  7. package/dist/cache/redisTtlCache.d.ts +3 -2
  8. package/dist/cache/redisTtlCache.js +2 -2
  9. package/dist/cache/redisTtlCache.js.map +1 -1
  10. package/dist/cache/types/{ttlCacheRecord.js → ttlCacheRecord.types.js} +1 -1
  11. package/dist/cache/types/ttlCacheRecord.types.js.map +1 -0
  12. package/dist/controllers/index.d.ts +1 -0
  13. package/dist/controllers/index.js +18 -0
  14. package/dist/controllers/index.js.map +1 -0
  15. package/dist/database/index.d.ts +1 -0
  16. package/dist/database/index.js +18 -0
  17. package/dist/database/index.js.map +1 -0
  18. package/dist/database/mikro/models/entities/base.entity.js +1 -1
  19. package/dist/entityMapper/index.d.ts +2 -0
  20. package/dist/entityMapper/index.js +19 -0
  21. package/dist/entityMapper/index.js.map +1 -0
  22. package/dist/entityMapper/interfaces/entityMapper.interface.d.ts +3 -3
  23. package/dist/entityMapper/models/baseEntityMapper.model.d.ts +23 -23
  24. package/dist/entityMapper/models/baseEntityMapper.model.js +17 -17
  25. package/dist/entityMapper/models/baseEntityMapper.model.js.map +1 -1
  26. package/dist/entityMapper/models/requestEntityMapper.model.d.ts +17 -23
  27. package/dist/entityMapper/models/requestEntityMapper.model.js +13 -19
  28. package/dist/entityMapper/models/requestEntityMapper.model.js.map +1 -1
  29. package/dist/entityMapper/models/responseEntityMapper.model.d.ts +15 -16
  30. package/dist/entityMapper/models/responseEntityMapper.model.js +8 -8
  31. package/dist/entityMapper/models/responseEntityMapper.model.js.map +1 -1
  32. package/dist/entityMapper/types/entityMapper.types.d.ts +3 -22
  33. package/dist/http/index.d.ts +2 -0
  34. package/dist/http/index.js +19 -0
  35. package/dist/http/index.js.map +1 -0
  36. package/dist/http/middlewares/index.d.ts +2 -0
  37. package/dist/http/middlewares/index.js +19 -0
  38. package/dist/http/middlewares/index.js.map +1 -0
  39. package/dist/http/middlewares/request.middleware.d.ts +11 -11
  40. package/dist/http/middlewares/request.middleware.js +32 -31
  41. package/dist/http/middlewares/request.middleware.js.map +1 -1
  42. package/dist/http/middlewares/response.middleware.d.ts +3 -2
  43. package/dist/http/middlewares/response.middleware.js +9 -6
  44. package/dist/http/middlewares/response.middleware.js.map +1 -1
  45. package/dist/http/types/api.types.d.ts +16 -13
  46. package/dist/http/types/index.d.ts +2 -0
  47. package/dist/http/types/index.js +19 -0
  48. package/dist/http/types/index.js.map +1 -0
  49. package/dist/http/types/primitive.types.d.ts +14 -13
  50. package/dist/index.d.ts +6 -1
  51. package/dist/index.js +20 -5
  52. package/dist/index.js.map +1 -1
  53. package/dist/services/index.d.ts +1 -0
  54. package/dist/services/index.js +18 -0
  55. package/dist/services/index.js.map +1 -0
  56. package/dist/services/interfaces/baseService.d.ts +1 -1
  57. package/dist/tests/{dto.test.js → entityMapper.test.js} +10 -32
  58. package/dist/tests/entityMapper.test.js.map +1 -0
  59. package/dist/tests/http.middleware.test.d.ts +1 -0
  60. package/dist/tests/http.middleware.test.js +79 -0
  61. package/dist/tests/http.middleware.test.js.map +1 -0
  62. package/dist/tests/redisTtlCache.test.js +32 -15
  63. package/dist/tests/redisTtlCache.test.js.map +1 -1
  64. package/entityMapper/index.ts +2 -0
  65. package/entityMapper/interfaces/entityMapper.interface.ts +11 -11
  66. package/entityMapper/models/baseEntityMapper.model.ts +90 -73
  67. package/entityMapper/models/requestEntityMapper.model.ts +96 -76
  68. package/entityMapper/models/responseEntityMapper.model.ts +83 -62
  69. package/entityMapper/types/entityMapper.types.ts +6 -23
  70. package/http/index.ts +2 -0
  71. package/http/middlewares/index.ts +2 -0
  72. package/http/middlewares/request.middleware.ts +118 -62
  73. package/http/middlewares/response.middleware.ts +56 -30
  74. package/http/types/api.types.ts +43 -25
  75. package/http/types/index.ts +2 -0
  76. package/http/types/primitive.types.ts +65 -44
  77. package/index.ts +6 -5
  78. package/jest.config.ts +2 -2
  79. package/package.json +13 -4
  80. package/tests/entityMapper.test.ts +219 -0
  81. package/tests/http.middleware.test.ts +99 -0
  82. package/tests/redisTtlCache.test.ts +49 -29
  83. package/dist/cache/types/ttlCacheRecord.js.map +0 -1
  84. package/dist/tests/dto.test.js.map +0 -1
  85. package/tests/dto.test.ts +0 -235
  86. /package/dist/cache/types/{ttlCacheRecord.d.ts → ttlCacheRecord.types.d.ts} +0 -0
  87. /package/dist/tests/{dto.test.d.ts → entityMapper.test.d.ts} +0 -0
@@ -1,15 +1,26 @@
1
- import { SchemaValidator } from "@forklaunch/validator/interfaces";
2
- import * as jose from "jose";
3
- import { v4 } from "uuid";
4
- import { ForklaunchNextFunction, ForklaunchRequest, ForklaunchResponse } from "../types/api.types";
5
- import { AuthMethod, HttpContractDetails, PathParamHttpContractDetails, StringOnlyObject } from "../types/primitive.types";
1
+ import { AnySchemaValidator, SchemaValidator } from '@forklaunch/validator';
2
+ import * as jose from 'jose';
3
+ import { v4 } from 'uuid';
4
+ import {
5
+ ForklaunchNextFunction,
6
+ ForklaunchRequest,
7
+ ForklaunchResponse
8
+ } from '../types/api.types';
9
+ import {
10
+ AuthMethod,
11
+ HttpContractDetails,
12
+ PathParamHttpContractDetails,
13
+ StringOnlyObject
14
+ } from '../types/primitive.types';
6
15
 
7
16
  export function createRequestContext<
8
- Request extends ForklaunchRequest<any, any, any, any>,
9
- Response extends ForklaunchResponse<any, any>
10
- >(schemaValidator: SchemaValidator) {
11
- return (req: Request, res: Response, next?: Function) => {
12
- req.schemaValidator = schemaValidator;
17
+ SV extends AnySchemaValidator,
18
+ Request extends ForklaunchRequest<SV>,
19
+ Response extends ForklaunchResponse,
20
+ NextFunction extends ForklaunchNextFunction
21
+ >(schemaValidator: SV) {
22
+ return (req: Request, res: Response, next?: NextFunction) => {
23
+ req.schemaValidator = schemaValidator as SchemaValidator;
13
24
 
14
25
  let correlationId = v4();
15
26
 
@@ -21,29 +32,34 @@ export function createRequestContext<
21
32
 
22
33
  req.context = {
23
34
  correlationId: correlationId
24
- }
35
+ };
25
36
 
26
37
  if (next) {
27
38
  next();
28
39
  }
29
- }
40
+ };
30
41
  }
31
42
 
32
43
  export function enrichRequestDetails<
33
- SV extends SchemaValidator,
34
- Request extends ForklaunchRequest<any, any, any, any>,
35
- Response extends ForklaunchResponse<any, any>
44
+ SV extends AnySchemaValidator,
45
+ Request extends ForklaunchRequest<SV>,
46
+ Response extends ForklaunchResponse,
47
+ NextFunction extends ForklaunchNextFunction
36
48
  >(contractDetails: PathParamHttpContractDetails<SV> | HttpContractDetails<SV>) {
37
- return (req: Request, _res: Response, next?: Function) => {
49
+ return (req: Request, _res: Response, next?: NextFunction) => {
38
50
  req.contractDetails = contractDetails;
39
51
 
40
52
  if (next) {
41
53
  next();
42
54
  }
43
- }
55
+ };
44
56
  }
45
57
 
46
- export function preHandlerParse<SV extends SchemaValidator>(schemaValidator: SV, object: unknown, schemaInput?: StringOnlyObject<SV>) {
58
+ export function preHandlerParse<SV extends AnySchemaValidator>(
59
+ schemaValidator: SchemaValidator,
60
+ object: unknown,
61
+ schemaInput?: StringOnlyObject<SV>
62
+ ) {
47
63
  if (!schemaInput) {
48
64
  return;
49
65
  }
@@ -55,33 +71,42 @@ export function preHandlerParse<SV extends SchemaValidator>(schemaValidator: SV,
55
71
  }
56
72
 
57
73
  export function parseRequestParams<
58
- Request extends ForklaunchRequest<any, any, any, any>,
59
- Response extends ForklaunchResponse<any, any>,
74
+ SV extends AnySchemaValidator,
75
+ Request extends ForklaunchRequest<SV>,
76
+ Response extends ForklaunchResponse,
60
77
  NextFunction extends ForklaunchNextFunction
61
78
  >(req: Request, res: Response, next?: NextFunction) {
62
79
  const params = req.contractDetails.params;
63
80
  if (preHandlerParse(req.schemaValidator, req.params, params) === 400) {
64
- res.status(400).send("Invalid request parameters.");
81
+ res.status(400).send('Invalid request parameters.');
65
82
  if (next) {
66
- next(new Error("Invalid request parameters."));
83
+ next(new Error('Invalid request parameters.'));
67
84
  }
68
- };
85
+ }
69
86
  if (next) {
70
87
  next();
71
88
  }
72
89
  }
73
90
 
74
91
  export function parseRequestBody<
75
- Request extends ForklaunchRequest<any, any, any, any>,
76
- Response extends ForklaunchResponse<any, any>,
92
+ SV extends AnySchemaValidator,
93
+ Request extends ForklaunchRequest<SV>,
94
+ Response extends ForklaunchResponse,
77
95
  NextFunction extends ForklaunchNextFunction
78
96
  >(req: Request, res: Response, next?: NextFunction) {
79
97
  if (req.headers['content-type'] === 'application/json') {
80
- const body = (req.schemaValidator, req.contractDetails as HttpContractDetails<typeof req.schemaValidator>).body;
81
- if (preHandlerParse(req.body, body as StringOnlyObject<typeof req.schemaValidator>) === 400) {
82
- res.status(400).send("Invalid request body.");
98
+ const body = (req.schemaValidator,
99
+ req.contractDetails as HttpContractDetails<SV>).body;
100
+ if (
101
+ preHandlerParse(
102
+ req.schemaValidator,
103
+ req.body,
104
+ body as StringOnlyObject<SV>
105
+ ) === 400
106
+ ) {
107
+ res.status(400).send('Invalid request body.');
83
108
  if (next) {
84
- next(new Error("Invalid request body."));
109
+ next(new Error('Invalid request body.'));
85
110
  }
86
111
  }
87
112
  }
@@ -91,15 +116,16 @@ export function parseRequestBody<
91
116
  }
92
117
 
93
118
  export function parseRequestHeaders<
94
- Request extends ForklaunchRequest<any, any, any, any>,
95
- Response extends ForklaunchResponse<any, any>,
119
+ SV extends AnySchemaValidator,
120
+ Request extends ForklaunchRequest<SV>,
121
+ Response extends ForklaunchResponse,
96
122
  NextFunction extends ForklaunchNextFunction
97
- > (req: Request, res: Response, next?: NextFunction) {
123
+ >(req: Request, res: Response, next?: NextFunction) {
98
124
  const headers = req.contractDetails.requestHeaders;
99
125
  if (preHandlerParse(req.schemaValidator, req.headers, headers) === 400) {
100
- res.status(400).send("Invalid request headers.");
126
+ res.status(400).send('Invalid request headers.');
101
127
  if (next) {
102
- next(new Error("Invalid request headers."));
128
+ next(new Error('Invalid request headers.'));
103
129
  }
104
130
  }
105
131
  if (next) {
@@ -108,15 +134,16 @@ export function parseRequestHeaders<
108
134
  }
109
135
 
110
136
  export function parseRequestQuery<
111
- Request extends ForklaunchRequest<any, any, any, any>,
112
- Response extends ForklaunchResponse<any, any>,
137
+ SV extends AnySchemaValidator,
138
+ Request extends ForklaunchRequest<SV>,
139
+ Response extends ForklaunchResponse,
113
140
  NextFunction extends ForklaunchNextFunction
114
141
  >(req: Request, res: Response, next?: NextFunction) {
115
142
  const query = req.contractDetails.query;
116
- if (preHandlerParse(req.query, query) === 400) {
117
- res.status(400).send("Invalid request query.");
143
+ if (preHandlerParse(req.schemaValidator, req.query, query) === 400) {
144
+ res.status(400).send('Invalid request query.');
118
145
  if (next) {
119
- next(new Error("Invalid request query."));
146
+ next(new Error('Invalid request query.'));
120
147
  }
121
148
  }
122
149
  if (next) {
@@ -124,43 +151,61 @@ export function parseRequestQuery<
124
151
  }
125
152
  }
126
153
 
127
- async function checkAuthorizationToken(authorizationMethod?: AuthMethod, authorizationString?: string): Promise<[number, string] | string | undefined> {
154
+ async function checkAuthorizationToken(
155
+ authorizationMethod?: AuthMethod,
156
+ authorizationString?: string
157
+ ): Promise<[401 | 403, string] | string | undefined> {
128
158
  if (!authorizationString) {
129
- return [401, "No Authorization token provided."];
159
+ return [401, 'No Authorization token provided.'];
130
160
  }
131
161
  switch (authorizationMethod) {
132
162
  case 'jwt': {
133
163
  if (!authorizationString.startsWith('Bearer ')) {
134
- return [401, "Invalid Authorization token format."];
164
+ return [401, 'Invalid Authorization token format.'];
135
165
  }
136
166
  try {
137
- const decodedJwt = await jose.jwtVerify(authorizationString.split(' ')[1], new TextEncoder().encode(process.env.JWT_SECRET || 'your-256-bit-secret'));
167
+ const decodedJwt = await jose.jwtVerify(
168
+ authorizationString.split(' ')[1],
169
+ new TextEncoder().encode(
170
+ process.env.JWT_SECRET || 'your-256-bit-secret'
171
+ )
172
+ );
138
173
  return decodedJwt.payload.iss;
139
- } catch(error) {
174
+ } catch (error) {
140
175
  console.error(error);
141
- return [403, "Invalid Authorization token."];
176
+ return [403, 'Invalid Authorization token.'];
142
177
  }
143
178
  }
144
179
  default:
145
- return [401, "Invalid Authorization method."];
180
+ return [401, 'Invalid Authorization method.'];
146
181
  }
147
182
  }
148
183
 
149
- function mapRoles(authorizationType?: AuthMethod, authorizationToken?: string): string[] {
184
+ function mapRoles(
185
+ authorizationType?: AuthMethod,
186
+ authorizationToken?: string
187
+ ): string[] {
150
188
  return [];
151
189
  }
152
- function mapPermissions(authorizationType?: AuthMethod, authorizationToken?: string): string[] {
190
+ function mapPermissions(
191
+ authorizationType?: AuthMethod,
192
+ authorizationToken?: string
193
+ ): string[] {
153
194
  return [];
154
195
  }
155
196
 
156
197
  export async function parseRequestAuth<
157
- Request extends ForklaunchRequest<any, any, any, any>,
158
- Response extends ForklaunchResponse<any, any>,
198
+ SV extends AnySchemaValidator,
199
+ Request extends ForklaunchRequest<SV>,
200
+ Response extends ForklaunchResponse,
159
201
  NextFunction extends ForklaunchNextFunction
160
202
  >(req: Request, res: Response, next?: NextFunction) {
161
203
  const auth = req.contractDetails.auth;
162
204
  if (auth) {
163
- const errorAndMessage = await checkAuthorizationToken(auth.method, req.headers.authorization);
205
+ const errorAndMessage = await checkAuthorizationToken(
206
+ auth.method,
207
+ req.headers.authorization
208
+ );
164
209
  if (Array.isArray(errorAndMessage)) {
165
210
  res.status(errorAndMessage[0]).send(errorAndMessage[1]);
166
211
  if (next) {
@@ -169,33 +214,44 @@ export async function parseRequestAuth<
169
214
  }
170
215
 
171
216
  // TODO: Implement role and permission checking
172
- const permissionSlugs = mapPermissions(auth.method, req.headers.authorization);
217
+ const permissionSlugs = mapPermissions(
218
+ auth.method,
219
+ req.headers.authorization
220
+ );
173
221
  const roles = mapRoles(auth.method, req.headers.authorization);
174
222
 
175
- const permissionErrorMessage = "User does not have sufficient permissions to perform action.";
176
- const roleErrorMessage = "User does not have correct role to perform action.";
223
+ const permissionErrorMessage =
224
+ 'User does not have sufficient permissions to perform action.';
225
+ const roleErrorMessage =
226
+ 'User does not have correct role to perform action.';
177
227
 
178
228
  // this is wrong, we need to check if any of the user's permissions are in the allowed permissions, while checking that any of the permissions is not in the forbidden slugs
179
229
  // currently this is checking if any of the user's permissions are NOT in the allowed permissions
180
- permissionSlugs.forEach(permissionSlug => {
181
- if (!req.contractDetails.auth?.allowedSlugs?.has(permissionSlug) || req.contractDetails.auth?.forbiddenSlugs?.has(permissionSlug)) {
230
+ permissionSlugs.forEach((permissionSlug) => {
231
+ if (
232
+ !req.contractDetails.auth?.allowedSlugs?.has(permissionSlug) ||
233
+ req.contractDetails.auth?.forbiddenSlugs?.has(permissionSlug)
234
+ ) {
182
235
  res.status(403).send(permissionErrorMessage);
183
236
  if (next) {
184
237
  next(new Error(permissionErrorMessage));
185
238
  }
186
- }
239
+ }
187
240
  });
188
- roles.forEach(role => {
189
- if (!req.contractDetails.auth?.allowedRoles?.has(role) || req.contractDetails.auth?.forbiddenRoles?.has(role)) {
241
+ roles.forEach((role) => {
242
+ if (
243
+ !req.contractDetails.auth?.allowedRoles?.has(role) ||
244
+ req.contractDetails.auth?.forbiddenRoles?.has(role)
245
+ ) {
190
246
  res.status(403).send(roleErrorMessage);
191
247
  if (next) {
192
248
  next(new Error(roleErrorMessage));
193
249
  }
194
- }
250
+ }
195
251
  });
196
252
  }
197
-
253
+
198
254
  // if (next) {
199
255
  // next();
200
256
  // }
201
- }
257
+ }
@@ -1,37 +1,63 @@
1
- import { SchemaValidator } from "@forklaunch/validator/interfaces";
2
- import { ForklaunchNextFunction, ForklaunchRequest, ForklaunchResponse } from "../types/api.types";
3
- import { HttpContractDetails } from "../types/primitive.types";
1
+ import { AnySchemaValidator } from '@forklaunch/validator';
2
+ import {
3
+ ForklaunchNextFunction,
4
+ ForklaunchRequest,
5
+ ForklaunchResponse
6
+ } from '../types/api.types';
7
+ import { HttpContractDetails } from '../types/primitive.types';
4
8
 
5
- function checkAnyValidation<SV extends SchemaValidator>(contractDetails: HttpContractDetails<SV>) {
6
- return contractDetails.body || contractDetails.params || contractDetails.requestHeaders || contractDetails.query;
9
+ function checkAnyValidation<SV extends AnySchemaValidator>(
10
+ contractDetails: HttpContractDetails<SV>
11
+ ) {
12
+ return (
13
+ contractDetails.body ||
14
+ contractDetails.params ||
15
+ contractDetails.requestHeaders ||
16
+ contractDetails.query
17
+ );
7
18
  }
8
19
 
9
20
  export function parseResponse<
10
- Request extends ForklaunchRequest<any, any, any, any>,
11
- Response extends ForklaunchResponse<any, any>,
12
- NextFunction extends ForklaunchNextFunction
13
- > (req: Request, res: Response, next?: NextFunction) {
14
- if (req.contractDetails.responseHeaders) {
15
- const schema = req.schemaValidator.schemify(req.contractDetails.responseHeaders);
16
- req.schemaValidator.validate(schema, res.getHeaders());
17
- }
18
-
19
- if (res.statusCode === 500 ||
20
- (checkAnyValidation(req.contractDetails) && res.statusCode === 400) ||
21
- (req.contractDetails.auth && (res.statusCode === 401 || res.statusCode === 403))
22
- ) {
23
- return;
24
- }
25
- if (!req.contractDetails.responses.hasOwnProperty(res.statusCode)) {
26
- if (next) {
27
- next(new Error(`Response code ${res.statusCode} not defined in contract.`));
28
- };
29
- }
30
-
31
- const schema = req.schemaValidator.schemify(req.contractDetails.responses[res.statusCode]);
32
- req.schemaValidator.validate(schema, res.bodyData);
21
+ SV extends AnySchemaValidator,
22
+ Request extends ForklaunchRequest<SV>,
23
+ Response extends ForklaunchResponse,
24
+ NextFunction extends ForklaunchNextFunction
25
+ >(req: Request, res: Response, next?: NextFunction) {
26
+ if (req.contractDetails.responseHeaders) {
27
+ const schema = req.schemaValidator.schemify(
28
+ req.contractDetails.responseHeaders
29
+ );
30
+ req.schemaValidator.validate(schema, res.getHeaders());
31
+ }
33
32
 
33
+ if (
34
+ res.statusCode === 500 ||
35
+ (checkAnyValidation(req.contractDetails) && res.statusCode === 400) ||
36
+ (req.contractDetails.auth &&
37
+ (res.statusCode === 401 || res.statusCode === 403))
38
+ ) {
39
+ req.schemaValidator.validate(req.schemaValidator.string, res.bodyData);
40
+ return;
41
+ }
42
+ if (
43
+ Object.prototype.hasOwnProperty.call(
44
+ !req.contractDetails.responses,
45
+ res.statusCode
46
+ )
47
+ ) {
34
48
  if (next) {
35
- next();
49
+ next(
50
+ new Error(`Response code ${res.statusCode} not defined in contract.`)
51
+ );
36
52
  }
37
- }
53
+ }
54
+
55
+ const schema = req.schemaValidator.schemify(
56
+ req.contractDetails.responses[res.statusCode]
57
+ );
58
+ req.schemaValidator.validate(schema, res.bodyData);
59
+
60
+ if (next) {
61
+ next();
62
+ }
63
+ }
@@ -1,10 +1,16 @@
1
- import { Prettify } from "@forklaunch/common";
2
- import { Schema, SchemaCatchall, ValidSchemaObject } from "@forklaunch/validator";
3
- import { SchemaValidator } from "@forklaunch/validator/interfaces";
4
- import { IdiomaticSchema } from "@forklaunch/validator/types";
5
- import { IncomingHttpHeaders, OutgoingHttpHeader } from "http";
6
- import { ParsedQs } from "qs";
7
- import { HttpContractDetails, ParamsDictionary, PathParamHttpContractDetails } from "./primitive.types";
1
+ import { Prettify } from '@forklaunch/common';
2
+ import {
3
+ AnySchemaValidator,
4
+ Schema
5
+ } from '@forklaunch/validator';
6
+ import { IdiomaticSchema, SchemaValidator } from '@forklaunch/validator/types';
7
+ import { IncomingHttpHeaders, OutgoingHttpHeader } from 'http';
8
+ import { ParsedQs } from 'qs';
9
+ import {
10
+ HttpContractDetails,
11
+ ParamsDictionary,
12
+ PathParamHttpContractDetails
13
+ } from './primitive.types';
8
14
 
9
15
  export interface RequestContext {
10
16
  correlationId: string;
@@ -12,15 +18,15 @@ export interface RequestContext {
12
18
  }
13
19
 
14
20
  export interface ForklaunchRequest<
15
- SV extends SchemaValidator,
21
+ SV extends AnySchemaValidator,
16
22
  P = ParamsDictionary,
17
- ReqBody = any,
23
+ ReqBody = unknown,
18
24
  ReqQuery = ParsedQs,
19
- Headers = IncomingHttpHeaders,
25
+ Headers = IncomingHttpHeaders
20
26
  > {
21
27
  context: Prettify<RequestContext>;
22
28
  contractDetails: HttpContractDetails<SV> | PathParamHttpContractDetails<SV>;
23
- schemaValidator: SV;
29
+ schemaValidator: SchemaValidator;
24
30
 
25
31
  params: P;
26
32
  headers: Headers;
@@ -29,37 +35,49 @@ export interface ForklaunchRequest<
29
35
  }
30
36
 
31
37
  export interface ForklaunchResponse<
32
- ResBody = any,
33
- StatusCode = number,
38
+ ResBody = {
39
+ 400: unknown;
40
+ 401: unknown;
41
+ 403: unknown;
42
+ 500: unknown;
43
+ },
44
+ StatusCode = number
34
45
  > {
35
46
  bodyData: unknown;
36
47
  statusCode: StatusCode;
37
48
  corked: boolean;
38
-
49
+
39
50
  getHeaders: () => OutgoingHttpHeader;
40
51
  setHeader: (key: string, value: string) => void;
41
52
  status: {
42
53
  <U extends keyof ResBody>(code: U): ForklaunchResponse<ResBody[U], U>;
43
- <U extends keyof ResBody>(code: U, message?: string): ForklaunchResponse<ResBody[U], U>;
54
+ <U extends keyof ResBody>(
55
+ code: U,
56
+ message?: string
57
+ ): ForklaunchResponse<ResBody[U], U>;
44
58
  <U extends 500>(code: U): ForklaunchResponse<string, U>;
45
59
  <U extends 500>(code: U, message?: string): ForklaunchResponse<string, U>;
46
- }
60
+ };
47
61
  send: {
48
62
  <T>(body?: ResBody, close_connection?: boolean): T;
49
63
  <T>(body?: ResBody): T;
50
- }
64
+ };
51
65
  json: {
52
66
  (body?: ResBody): boolean;
53
67
  <T>(body?: ResBody): T;
54
- }
68
+ };
55
69
  jsonp: {
56
70
  (body?: ResBody): boolean;
57
71
  <T>(body?: ResBody): T;
58
- }
72
+ };
59
73
  }
60
- export type MapSchema<SV extends SchemaValidator, T extends IdiomaticSchema<SchemaCatchall<SV>> | ValidSchemaObject<SV>> = Schema<T, SV> extends infer U ?
61
- { [key: string]: unknown } extends U ?
62
- never :
63
- U :
64
- never;
65
- export type ForklaunchNextFunction = (err?: any) => void;
74
+ export type MapSchema<
75
+ SV extends AnySchemaValidator,
76
+ T extends IdiomaticSchema<SV> | SV['_ValidSchemaObject']
77
+ > =
78
+ Schema<T, SV> extends infer U
79
+ ? { [key: string]: unknown } extends U
80
+ ? never
81
+ : U
82
+ : never;
83
+ export type ForklaunchNextFunction = (err?: unknown) => void;
@@ -0,0 +1,2 @@
1
+ export * from './api.types';
2
+ export * from './primitive.types';
@@ -1,55 +1,76 @@
1
- import { SchemaCatchall, ValidSchemaObject } from "@forklaunch/validator";
2
- import { SchemaValidator } from "@forklaunch/validator/interfaces";
3
- import { UnboxedObjectSchema } from "@forklaunch/validator/types";
1
+ import { AnySchemaValidator } from '@forklaunch/validator';
2
+ import { UnboxedObjectSchema } from '@forklaunch/validator/types';
4
3
 
5
- export type ParamsDictionary = { [key: string]: string; };
4
+ export type ParamsDictionary = { [key: string]: string };
6
5
 
7
- export type StringOnlyObject<SV extends SchemaValidator> = Omit<UnboxedObjectSchema<SchemaCatchall<SV>>, number | symbol>;
8
- export type NumberOnlyObject<SV extends SchemaValidator> = Omit<UnboxedObjectSchema<SchemaCatchall<SV>>, string | symbol>;
6
+ export type StringOnlyObject<SV extends AnySchemaValidator> = Omit<
7
+ UnboxedObjectSchema<SV>,
8
+ number | symbol
9
+ >;
10
+ export type NumberOnlyObject<SV extends AnySchemaValidator> = Omit<
11
+ UnboxedObjectSchema<SV>,
12
+ string | symbol
13
+ >;
9
14
 
10
- export type BodyObject<SV extends SchemaValidator> = StringOnlyObject<SV> & unknown;
11
- export type ParamsObject<SV extends SchemaValidator> = StringOnlyObject<SV> & unknown;
12
- export type QueryObject<SV extends SchemaValidator> = StringOnlyObject<SV> & unknown;
13
- export type HeadersObject<SV extends SchemaValidator> = StringOnlyObject<SV> & unknown;
14
- export type ResponsesObject<SV extends SchemaValidator> = NumberOnlyObject<SV> & unknown;
15
+ export type BodyObject<SV extends AnySchemaValidator> = StringOnlyObject<SV> &
16
+ unknown;
17
+ export type ParamsObject<SV extends AnySchemaValidator> = StringOnlyObject<SV> &
18
+ unknown;
19
+ export type QueryObject<SV extends AnySchemaValidator> = StringOnlyObject<SV> &
20
+ unknown;
21
+ export type HeadersObject<SV extends AnySchemaValidator> =
22
+ StringOnlyObject<SV> & unknown;
23
+ export type ResponsesObject<SV extends AnySchemaValidator> = {
24
+ [key: number]:
25
+ | SV['_ValidSchemaObject']
26
+ | UnboxedObjectSchema<SV>
27
+ | string
28
+ | SV['string'];
29
+ } & unknown;
15
30
 
16
- export type Body<SV extends SchemaValidator> = BodyObject<SV>
17
- | ValidSchemaObject<SV>
18
- | SchemaCatchall<SV>;
31
+ export type Body<SV extends AnySchemaValidator> =
32
+ | BodyObject<SV>
33
+ | SV['_ValidSchemaObject']
34
+ | SV['_SchemaCatchall'];
19
35
 
20
36
  export type AuthMethod = 'jwt' | 'session';
21
37
  export interface PathParamHttpContractDetails<
22
- SV extends SchemaValidator,
23
- ParamSchemas extends ParamsObject<SV> = ParamsObject<SV>,
24
- ResponseSchemas extends ResponsesObject<SV> = ResponsesObject<SV>,
25
- QuerySchemas extends QueryObject<SV> = QueryObject<SV>
26
- > {
27
- name: string,
28
- summary: string,
29
- responses: ResponseSchemas,
30
- requestHeaders?: HeadersObject<SV>,
31
- responseHeaders?: HeadersObject<SV>,
32
- params?: ParamSchemas,
33
- query?: QuerySchemas,
34
- auth?: {
35
- method: AuthMethod,
36
- allowedSlugs?: Set<string>,
37
- forbiddenSlugs?: Set<string>,
38
- allowedRoles?: Set<string>,
39
- forbiddenRoles?: Set<string>
40
- }
38
+ SV extends AnySchemaValidator,
39
+ ParamSchemas extends ParamsObject<SV> = ParamsObject<SV>,
40
+ ResponseSchemas extends ResponsesObject<SV> = ResponsesObject<SV>,
41
+ QuerySchemas extends QueryObject<SV> = QueryObject<SV>
42
+ > {
43
+ name: string;
44
+ summary: string;
45
+ responses: ResponseSchemas;
46
+ requestHeaders?: HeadersObject<SV>;
47
+ responseHeaders?: HeadersObject<SV>;
48
+ params?: ParamSchemas;
49
+ query?: QuerySchemas;
50
+ auth?: {
51
+ method: AuthMethod;
52
+ allowedSlugs?: Set<string>;
53
+ forbiddenSlugs?: Set<string>;
54
+ allowedRoles?: Set<string>;
55
+ forbiddenRoles?: Set<string>;
56
+ };
41
57
  }
42
58
 
43
59
  export interface HttpContractDetails<
44
- SV extends SchemaValidator,
45
- ParamSchemas extends ParamsObject<SV> = ParamsObject<SV>,
46
- ResponseSchemas extends ResponsesObject<SV> = ResponsesObject<SV>,
47
- BodySchema extends Body<SV> = Body<SV>,
48
- QuerySchemas extends QueryObject<SV> = QueryObject<SV>
49
- > extends PathParamHttpContractDetails<SV, ParamSchemas, ResponseSchemas, QuerySchemas> {
50
- body?: BodySchema,
51
- contentType?:
52
- | 'application/json'
53
- | 'multipart/form-data'
54
- | 'application/x-www-form-urlencoded';
60
+ SV extends AnySchemaValidator,
61
+ ParamSchemas extends ParamsObject<SV> = ParamsObject<SV>,
62
+ ResponseSchemas extends ResponsesObject<SV> = ResponsesObject<SV>,
63
+ BodySchema extends Body<SV> = Body<SV>,
64
+ QuerySchemas extends QueryObject<SV> = QueryObject<SV>
65
+ > extends PathParamHttpContractDetails<
66
+ SV,
67
+ ParamSchemas,
68
+ ResponseSchemas,
69
+ QuerySchemas
70
+ > {
71
+ body?: BodySchema;
72
+ contentType?:
73
+ | 'application/json'
74
+ | 'multipart/form-data'
75
+ | 'application/x-www-form-urlencoded';
55
76
  }
package/index.ts CHANGED
@@ -1,5 +1,6 @@
1
- // export * from './cache';
2
- // export * from './controllers';
3
- // export * from './database';
4
- // export * from './entityMapper';
5
- // export * from './services';
1
+ export * from './cache';
2
+ export * from './controllers';
3
+ export * from './database';
4
+ export * from './entityMapper';
5
+ export * from './http';
6
+ export * from './services';
package/jest.config.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type {Config} from 'jest';
1
+ import type { Config } from 'jest';
2
2
 
3
3
  const config: Config = {
4
4
  verbose: true,
@@ -7,4 +7,4 @@ const config: Config = {
7
7
  testPathIgnorePatterns: ['dist/', 'node_modules/']
8
8
  };
9
9
 
10
- export default config;
10
+ export default config;