@aeriajs/http 0.0.8 → 0.0.9

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.
@@ -1,13 +1,2 @@
1
- import type { Property } from '@aeriajs/types';
2
- export type Contract = {
3
- response: Property | Property[];
4
- } | {
5
- payload: Property;
6
- } | {
7
- query: Property;
8
- } | {
9
- response?: Property | Property[];
10
- payload?: Property;
11
- query?: Property;
12
- };
13
- export declare const defineContract: <const TContract extends Contract>(contract: TContract) => TContract;
1
+ import type { ContractWithRoles } from '@aeriajs/types';
2
+ export declare const defineContract: <const TContractWithRoles extends ContractWithRoles>(contract: TContractWithRoles) => TContractWithRoles;
package/dist/routing.d.ts CHANGED
@@ -1,41 +1,41 @@
1
- import type { Context, GenericRequest, GenericResponse, RequestMethod, InferProperty, InferResponse, PackReferences } from '@aeriajs/types';
2
- import type { Contract } from './contract.js';
1
+ import type { Context, GenericRequest, GenericResponse, RequestMethod, InferProperty, InferResponse, PackReferences, ContractWithRoles } from '@aeriajs/types';
3
2
  export type RouteUri = `/${string}`;
4
3
  export type RouterOptions = {
5
4
  exhaust?: boolean;
6
5
  base?: RouteUri;
7
6
  };
7
+ export type RoutesMeta = Record<RouteUri, Partial<Record<RequestMethod, ContractWithRoles | null> | undefined>>;
8
8
  export type Middleware = (context: Context) => any;
9
9
  export type RouteGroupOptions = {
10
10
  base?: RouteUri;
11
11
  };
12
- type TypedContext<TContract extends Contract> = Omit<Context, 'request'> & {
12
+ type TypedContext<TContractWithRoles extends ContractWithRoles> = Omit<Context, 'request'> & {
13
13
  request: Omit<Context['request'], 'payload' | 'query'> & {
14
- payload: TContract extends {
14
+ payload: TContractWithRoles extends {
15
15
  payload: infer Payload;
16
16
  } ? PackReferences<InferProperty<Payload>> : never;
17
- query: TContract extends {
17
+ query: TContractWithRoles extends {
18
18
  query: infer Query;
19
19
  } ? InferProperty<Query> : any;
20
20
  };
21
21
  };
22
- export type ProxiedRouter<TRouter> = TRouter & Record<RequestMethod, <TCallback extends (context: TypedContext<TContract>) => TContract extends {
22
+ export type ProxiedRouter<TRouter> = TRouter & Record<RequestMethod, <TCallback extends (context: TypedContext<TContractWithRoles>) => TContractWithRoles extends {
23
23
  response: infer Response;
24
- } ? InferResponse<Response> : any, const TContract extends Contract>(exp: RouteUri, cb: TCallback, contract?: TContract) => ReturnType<typeof registerRoute>>;
24
+ } ? InferResponse<Response> : any, const TContractWithRoles extends ContractWithRoles>(exp: RouteUri, cb: TCallback, contract?: TContractWithRoles) => ReturnType<typeof registerRoute>>;
25
25
  export declare const matches: <TRequest extends GenericRequest>(req: TRequest, method: RequestMethod | RequestMethod[] | null, exp: string | RegExp, options: RouterOptions) => {
26
26
  fragments: string[];
27
27
  } | undefined;
28
- export declare const registerRoute: <TCallback extends (context: Context) => any>(context: Context, method: RequestMethod | RequestMethod[], exp: RouteUri, cb: TCallback, contract?: Contract, options?: RouterOptions) => Promise<any>;
28
+ export declare const registerRoute: <TCallback extends (context: Context) => any>(context: Context, method: RequestMethod | RequestMethod[], exp: RouteUri, cb: TCallback, contract?: ContractWithRoles, options?: RouterOptions) => Promise<any>;
29
29
  export declare const wrapRouteExecution: (res: GenericResponse, cb: () => any | Promise<any>) => Promise<any>;
30
30
  export declare const createRouter: (options?: Partial<RouterOptions>) => ProxiedRouter<{
31
- route: <TCallback extends (context: TypedContext<TContract>) => TContract extends {
31
+ route: <TCallback extends (context: TypedContext<TContractWithRoles>) => TContractWithRoles extends {
32
32
  response: infer Response;
33
- } ? InferResponse<Response> : TContract, const TContract extends Contract>(method: RequestMethod | RequestMethod[], exp: RouteUri, cb: TCallback, contract?: TContract) => void;
33
+ } ? InferResponse<Response> : TContractWithRoles, const TContractWithRoles extends ContractWithRoles>(method: RequestMethod | RequestMethod[], exp: RouteUri, cb: TCallback, contract?: TContractWithRoles) => void;
34
34
  routes: ((_: unknown, context: Context, groupOptions?: RouteGroupOptions) => ReturnType<typeof registerRoute>)[];
35
- routesMeta: Record<`/${string}`, Partial<Record<"GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "OPTIONS" | "PATCH" | "TRACE" | "SEARCH", Contract | null> | undefined>>;
35
+ routesMeta: RoutesMeta;
36
36
  group: <TRouter extends {
37
37
  install: (context: Context, options?: RouterOptions) => any;
38
- routesMeta: Record<`/${string}`, Partial<Record<"GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "OPTIONS" | "PATCH" | "TRACE" | "SEARCH", Contract | null> | undefined>>;
38
+ routesMeta: RoutesMeta;
39
39
  }>(exp: RouteUri, router: TRouter, middleware?: Middleware) => void;
40
40
  install: (_context: Context, _options?: RouterOptions) => Promise<true | Promise<any>>;
41
41
  }>;
package/dist/routing.js CHANGED
@@ -7,6 +7,22 @@ const common_1 = require("@aeriajs/common");
7
7
  const validation_1 = require("@aeriajs/validation");
8
8
  const payload_js_1 = require("./payload.js");
9
9
  const constants_js_1 = require("./constants.js");
10
+ const checkUnprocessable = (validationEither, context) => {
11
+ if ((0, common_1.isLeft)(validationEither)) {
12
+ context.response.writeHead(422, {
13
+ 'content-type': 'application/json',
14
+ });
15
+ return validationEither;
16
+ }
17
+ };
18
+ const unsufficientRoles = (context) => {
19
+ context.response.writeHead(403, {
20
+ 'content-type': 'application/json',
21
+ });
22
+ return {
23
+ error: types_1.ACErrors.AuthorizationError,
24
+ };
25
+ };
10
26
  const matches = (req, method, exp, options) => {
11
27
  const { url } = req;
12
28
  const { base = constants_js_1.DEFAULT_BASE_URI } = options;
@@ -47,17 +63,19 @@ const registerRoute = async (context, method, exp, cb, contract, options = {}) =
47
63
  }
48
64
  Object.assign(context.request, match);
49
65
  if (contract) {
50
- const checkUnprocessable = (validationEither) => {
51
- if ((0, common_1.isLeft)(validationEither)) {
52
- context.response.writeHead(422, {
53
- 'content-type': 'application/json',
54
- });
55
- return validationEither;
66
+ if (contract.roles) {
67
+ if (!context.token.authenticated) {
68
+ if (!contract.roles.includes('guest')) {
69
+ return unsufficientRoles(context);
70
+ }
56
71
  }
57
- };
72
+ else if (!(0, common_1.arraysIntersects)(context.token.roles, contract.roles)) {
73
+ return unsufficientRoles(context);
74
+ }
75
+ }
58
76
  if ('payload' in contract && contract.payload) {
59
77
  const validationEither = (0, validation_1.validate)(context.request.payload, contract.payload);
60
- const error = checkUnprocessable(validationEither);
78
+ const error = checkUnprocessable(validationEither, context);
61
79
  if (error) {
62
80
  return error;
63
81
  }
@@ -66,7 +84,7 @@ const registerRoute = async (context, method, exp, cb, contract, options = {}) =
66
84
  const validationEither = (0, validation_1.validate)(context.request.query, contract.query, {
67
85
  coerce: true,
68
86
  });
69
- const error = checkUnprocessable(validationEither);
87
+ const error = checkUnprocessable(validationEither, context);
70
88
  if (error) {
71
89
  return error;
72
90
  }
package/dist/routing.mjs CHANGED
@@ -154,12 +154,28 @@ function _ts_generator(thisArg, body) {
154
154
  };
155
155
  }
156
156
  }
157
- import { REQUEST_METHODS } from "@aeriajs/types";
157
+ import { ACErrors, REQUEST_METHODS } from "@aeriajs/types";
158
158
  import { Stream } from "stream";
159
- import { pipe, left, isLeft, unwrapEither, deepMerge } from "@aeriajs/common";
159
+ import { pipe, arraysIntersects, left, isLeft, unwrapEither, deepMerge } from "@aeriajs/common";
160
160
  import { validate } from "@aeriajs/validation";
161
161
  import { safeJson } from "./payload.mjs";
162
162
  import { DEFAULT_BASE_URI } from "./constants.mjs";
163
+ var checkUnprocessable = function(validationEither, context) {
164
+ if (isLeft(validationEither)) {
165
+ context.response.writeHead(422, {
166
+ "content-type": "application/json"
167
+ });
168
+ return validationEither;
169
+ }
170
+ };
171
+ var unsufficientRoles = function(context) {
172
+ context.response.writeHead(403, {
173
+ "content-type": "application/json"
174
+ });
175
+ return {
176
+ error: ACErrors.AuthorizationError
177
+ };
178
+ };
163
179
  export var matches = function(req, method, exp, options) {
164
180
  var url = req.url;
165
181
  var _options_base = options.base, base = _options_base === void 0 ? DEFAULT_BASE_URI : _options_base;
@@ -179,7 +195,7 @@ export var matches = function(req, method, exp, options) {
179
195
  };
180
196
  export var registerRoute = function() {
181
197
  var _ref = _async_to_generator(function(context, method, exp, cb, contract) {
182
- var options, match, checkUnprocessable, validationEither, error, validationEither1, error1, result;
198
+ var options, match, validationEither, error, validationEither1, error1, result;
183
199
  var _arguments = arguments;
184
200
  return _ts_generator(this, function(_state) {
185
201
  switch(_state.label){
@@ -209,17 +225,24 @@ export var registerRoute = function() {
209
225
  }
210
226
  Object.assign(context.request, match);
211
227
  if (contract) {
212
- checkUnprocessable = function(validationEither) {
213
- if (isLeft(validationEither)) {
214
- context.response.writeHead(422, {
215
- "content-type": "application/json"
216
- });
217
- return validationEither;
228
+ if (contract.roles) {
229
+ if (!context.token.authenticated) {
230
+ if (!contract.roles.includes("guest")) {
231
+ return [
232
+ 2,
233
+ unsufficientRoles(context)
234
+ ];
235
+ }
236
+ } else if (!arraysIntersects(context.token.roles, contract.roles)) {
237
+ return [
238
+ 2,
239
+ unsufficientRoles(context)
240
+ ];
218
241
  }
219
- };
242
+ }
220
243
  if ("payload" in contract && contract.payload) {
221
244
  validationEither = validate(context.request.payload, contract.payload);
222
- error = checkUnprocessable(validationEither);
245
+ error = checkUnprocessable(validationEither, context);
223
246
  if (error) {
224
247
  return [
225
248
  2,
@@ -231,7 +254,7 @@ export var registerRoute = function() {
231
254
  validationEither1 = validate(context.request.query, contract.query, {
232
255
  coerce: true
233
256
  });
234
- error1 = checkUnprocessable(validationEither1);
257
+ error1 = checkUnprocessable(validationEither1, context);
235
258
  if (error1) {
236
259
  return [
237
260
  2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aeriajs/http",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "## Installation",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -22,10 +22,10 @@
22
22
  "dist"
23
23
  ],
24
24
  "peerDependencies": {
25
- "@aeriajs/access-control": "^0.0.5",
26
- "@aeriajs/common": "^0.0.5",
27
- "@aeriajs/types": "^0.0.4",
28
- "@aeriajs/validation": "^0.0.8"
25
+ "@aeriajs/access-control": "^0.0.6",
26
+ "@aeriajs/common": "^0.0.6",
27
+ "@aeriajs/types": "^0.0.5",
28
+ "@aeriajs/validation": "^0.0.9"
29
29
  },
30
30
  "scripts": {
31
31
  "test": "echo skipping",