bootpress 10.0.4 → 11.0.0-rc.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 (3) hide show
  1. package/index.d.ts +37 -33
  2. package/index.js +87 -241
  3. package/package.json +39 -38
package/index.d.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { Request, Response } from "express";
2
- import { ArraySchema, ErrorTemplateConfiguration, ExtValOf, ExtendedTypeKeys, JsSchema, TypedArraySchema, TypedSchema } from "./helpers";
3
-
4
- type RequestHandler = (req: Request, res: Response) => void
5
- type ArrayWithLastElement<L> = [...rest: any[], lastArg: L];
6
- type RequsetHandlerWithLastArg<T, F extends (...args: any) => RequestHandler = (...args: any[]) => RequestHandler, P extends ArrayWithLastElement<T> = Parameters<F>> = (...args: P) => RequestHandler;
7
- type NonEmptyArray = readonly [any, ...any[]];
8
- type ShiftRequestHandler<F extends RequsetHandlerWithLastArg<any> | RequestHandler> =
9
- F extends (arg1: infer T, ...rest: infer U) => RequestHandler ?
10
- U extends NonEmptyArray ? (...rest: U) => RequestHandler : RequestHandler
11
- : RequestHandler
1
+ import { Request, Response, NextFunction } from "express";
2
+ import { ArraySchema, ErrorTemplateConfiguration, ExtendedTypeKeys, JsSchema, TypedSchema } from "./helpers";
3
+
4
+ type RequestHandler = {
5
+ (req: Request, res: Response): void
6
+ (req: Request, res: Response, next: NextFunction): void
7
+ }
8
+
9
+ type FunctionWithArgs<T = any> = (...args: any[]) => T;
10
+ type FunctionWithoutArgs<T = any> = () => T;
11
+
12
12
 
13
13
  type RestedService<T extends Record<PropertyKey, any>> = {
14
14
  [K in keyof T]:
@@ -19,31 +19,35 @@ type RestedService<T extends Record<PropertyKey, any>> = {
19
19
 
20
20
  type InstanceOrClass<T extends Record<PropertyKey, any>> = T | (new () => T);
21
21
 
22
- type TypeValueOf<S extends ExtendedTypeKeys | JsSchema | TypedSchema<JsSchema> | ArraySchema> =
23
- S extends TypedSchema<JsSchema> ? S
24
- : S extends ExtendedTypeKeys ? ExtValOf<S>
25
- : S extends JsSchema ? TypedSchema<S>
26
- : S extends ArraySchema ? TypedArraySchema<S>
27
- : never;
28
-
29
22
  declare function RestService<T extends Record<PropertyKey, any>>(service: InstanceOrClass<T>): RestedService<T>;
30
- declare function RestMethod<T extends Function>(callback: T): (args: Parameters<T>) => RequestHandler;
23
+ declare function RestMethod<T extends FunctionWithoutArgs>(callback: T): RequestHandler;
24
+ declare function RestMethod<T extends FunctionWithArgs>(callback: T): (...args: Parameters<T>) => RequestHandler;
31
25
  declare function Restify(target: any, key: PropertyKey, desc: PropertyDescriptor): PropertyDescriptor;
32
26
 
33
- declare function PassBody<F extends RequsetHandlerWithLastArg<any>>(serviceFunction: F): ShiftRequestHandler<F>
34
- declare function ParseBodyAs<S extends ExtendedTypeKeys | JsSchema | TypedSchema<JsSchema> | ArraySchema, T = TypeValueOf<S>>(type: S, config?: ErrorTemplateConfiguration): <F extends RequsetHandlerWithLastArg<T>>(serviceFunction: F) => ShiftRequestHandler<F>
35
- declare function PassBodyAs<S extends ExtendedTypeKeys | JsSchema | TypedSchema<JsSchema> | ArraySchema, T = TypeValueOf<S>>(type: S, config?: ErrorTemplateConfiguration): <F extends RequsetHandlerWithLastArg<T>>(serviceFunction: F) => ShiftRequestHandler<F>
36
- declare function PassAllParams<F extends RequsetHandlerWithLastArg<string[]>>(serviceFunction: F): ShiftRequestHandler<F>
37
- declare function PassAllQueries<F extends RequsetHandlerWithLastArg<string[]>>(serviceFunction: F): ShiftRequestHandler<F>
38
- declare function PassAllCookies<F extends RequsetHandlerWithLastArg<string[]>>(serviceFunction: F): ShiftRequestHandler<F>
39
- declare function PassParam(paramName: string): <F extends RequsetHandlerWithLastArg<string | undefined>>(serviceFunction: F) => ShiftRequestHandler<F>
40
- declare function PassQuery(queryName: string): <F extends RequsetHandlerWithLastArg<string | undefined>>(serviceFunction: F) => ShiftRequestHandler<F>
41
- declare function PassCookie(cookieName: string): <F extends RequsetHandlerWithLastArg<string | undefined>>(serviceFunction: F) => ShiftRequestHandler<F>
42
- declare function PassRequest<F extends RequsetHandlerWithLastArg<Request>>(serviceFunction: F): ShiftRequestHandler<F>
43
- declare function PassResponse<F extends RequsetHandlerWithLastArg<Response>>(serviceFunction: F): ShiftRequestHandler<F>
27
+ type BodyArgGetter = {
28
+ (type: ExtendedTypeKeys | JsSchema | TypedSchema<JsSchema> | ArraySchema): NeedsBuilder;
29
+ (type: ExtendedTypeKeys | JsSchema | TypedSchema<JsSchema> | ArraySchema, config: ErrorTemplateConfiguration): NeedsBuilder;
30
+ }
31
+
32
+ type NeedsBuilder = {
33
+ param: (name: string) => NeedsBuilder;
34
+ params: () => NeedsBuilder;
35
+ query: (name: string) => NeedsBuilder;
36
+ queries: () => NeedsBuilder;
37
+ body: (() => NeedsBuilder) | BodyArgGetter;
38
+ parseBody: BodyArgGetter;
39
+ cookie: (name: string) => NeedsBuilder;
40
+ cookies: () => NeedsBuilder;
41
+ header: (name: string) => NeedsBuilder;
42
+ headers: () => NeedsBuilder;
43
+ to: (handler: FunctionWithArgs) => RequestHandler;
44
+ }
45
+ declare function Needs(): NeedsBuilder;
44
46
 
45
47
  export {
46
- ParseBodyAs, PassAllCookies, PassAllParams, PassAllQueries, PassBody,
47
- PassBodyAs, PassCookie, PassParam, PassQuery, PassRequest,
48
- PassResponse, RestMethod, RestService, Restify
48
+ RestMethod,
49
+ RestService,
50
+ Restify,
51
+ Needs
49
52
  };
53
+
package/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  const { as, asStrict, log } = require("./helpers");
2
- const { HttpError } = require("./types");
3
2
 
4
3
  const protectedProperties = [
5
4
  "toString",
@@ -36,7 +35,7 @@ function RestService(service) {
36
35
  const value = keyvalue[1].value;
37
36
  if (typeof value == "function" && !propertyName.startsWith("#")) {
38
37
  newService[propertyName] = ((...args) =>
39
- (req, res) => {
38
+ (_req, res) => {
40
39
  try {
41
40
  const result = service[propertyName](...args);
42
41
  if (result == undefined) {
@@ -72,34 +71,35 @@ function RestService(service) {
72
71
  }
73
72
 
74
73
  function RestMethod(callback) {
75
- if (callback.length < 1) {
76
- return handle(callback());
77
- }
78
- return (...args) => handle(callback(...args));
74
+ return callback.length == 0
75
+ ? handle(callback())
76
+ : (...args) => handle(callback(...args));
79
77
  function handle(result) {
80
- try {
81
- if (result == undefined) {
82
- reply(res, 204, null);
83
- } else if (result instanceof Promise) {
84
- result.then((r) => {
85
- if (r == undefined) {
86
- reply(res, 204, undefined);
87
- } else {
88
- reply(res, r.status ?? 200, r.data ?? r);
89
- }
90
- })
91
- .catch((e) => {
92
- const status = e.status ?? 500;
93
- status === 500 && log.error(e.stack);
94
- reply(res, status, e.message ?? e);
95
- });
96
- } else {
97
- reply(res, result.status ?? 200, result.data ?? result);
78
+ return (_req, res) => {
79
+ try {
80
+ if (result == undefined) {
81
+ reply(res, 204, null);
82
+ } else if (result instanceof Promise) {
83
+ result.then((r) => {
84
+ if (r == undefined) {
85
+ reply(res, 204, undefined);
86
+ } else {
87
+ reply(res, r.status ?? 200, r.data ?? r);
88
+ }
89
+ })
90
+ .catch((e) => {
91
+ const status = e.status ?? 500;
92
+ status === 500 && log.error(e.stack);
93
+ reply(res, status, e.message ?? e);
94
+ });
95
+ } else {
96
+ reply(res, result.status ?? 200, result.data ?? result);
97
+ }
98
+ } catch (e) {
99
+ const status = e.status ?? 500;
100
+ status === 500 && log.error(e.stack);
101
+ reply(res, status, e.message ?? e);
98
102
  }
99
- } catch (e) {
100
- const status = e.status ?? 500;
101
- status === 500 && log.error(e.stack);
102
- reply(res, status, e.message ?? e);
103
103
  }
104
104
  }
105
105
  }
@@ -140,230 +140,76 @@ function Restify(target, key, desc) {
140
140
  }
141
141
  }
142
142
 
143
-
144
- function isResponse(o) {
145
- return o instanceof Object && "socket" in o && "parser" in o.socket && "_httpMessage" in o.socket && o.socket._httpMessage.writable == true;
146
- }
147
- function isRequest(o) {
148
- return o instanceof Object && "socket" in o && "url" in o && "body" in o && "params" in o && "query" in o && "res" in o;
149
- }
150
-
151
- function isRequstHandlerArgs(args) {
152
- const [_last1, last2, last3, ..._others] = [...args].reverse();
153
- return isResponse(last2) && isRequest(last3);
154
- }
155
-
156
- function PassParam(paramName) {
157
- return (actualHandler) => {
158
- return (...args) => {
159
- if (isRequstHandlerArgs(args)) {
160
- const req = args.at(-3);
161
- const res = args.at(-2);
162
- const paramToPass = req.params[paramName];
163
- return actualHandler(paramToPass)(req, res);
164
- } else {
165
- return (req, res) => {
166
- const paramToPass = req.params[paramName];
167
- actualHandler(...args, paramToPass)(req, res);
168
- };
169
- }
170
- };
171
- };
172
- }
173
-
174
- function PassQuery(searchQuery) {
175
- return (actualHandler) => {
176
- return (...args) => {
177
- if (isRequstHandlerArgs(args)) {
178
- const req = args.at(-3);
179
- const res = args.at(-2);
180
- const paramToPass = req.query[searchQuery];
181
- return actualHandler(paramToPass)(req, res);
182
- } else {
183
- return (req, res) => {
184
- const paramToPass = req.query[searchQuery];
185
- actualHandler(...args, paramToPass)(req, res);
186
- };
187
- }
188
- };
189
- };
190
- }
191
-
192
- function PassAllParams(actualHandler) {
193
- return (...args) => {
194
- if (isRequstHandlerArgs(args)) {
195
- const req = args.at(-3);
196
- const res = args.at(-2);
197
- return actualHandler(req.params)(req, res);
198
- } else {
199
- return (req, res) => actualHandler(...args, req.params)(req, res);
200
- }
201
- };
202
- }
203
-
204
- function PassAllQueries(actualHandler) {
205
- return (...args) => {
206
- if (isRequstHandlerArgs(args)) {
207
- const req = args.at(-3);
208
- const res = args.at(-2);
209
- return actualHandler(req.query)(req, res);
210
- } else {
211
- return (req, res) => actualHandler(...args, req.query)(req, res);
212
- }
213
- };
214
- }
215
-
216
- function ParseBodyAs(type, config = { messageTemplate: "Malformed Request Body\n{0}" }) {
217
- return (actualHandler) => {
218
- return (...args) => {
219
- if (isRequstHandlerArgs(args)) {
220
- const req = args.at(-3);
221
- const res = args.at(-2);
222
- try {
223
- return actualHandler(as(req.body, type, config))(req, res);
224
- } catch (e) {
225
- const status = e.status ?? 500;
226
- status === 500 && log.error(e.stack);
227
- reply(res, status, e.message || e);
228
- }
229
- } else {
230
- return (req, res) => {
231
- try {
232
- return actualHandler(...args, as(req.body, type, config))(req, res);
233
- } catch (e) {
234
- const status = e.status ?? 500;
235
- status === 500 && log.error(e.stack);
236
- reply(res, status, e.message || e);
237
- }
238
- };
239
- }
240
- };
241
- };
242
- }
243
-
244
- function PassBodyAs(type, config = { messageTemplate: "Malformed Request Body\n{0}" }) {
245
- return (actualHandler) => {
246
- return (...args) => {
247
- if (isRequstHandlerArgs(args)) {
248
- const req = args.at(-3);
249
- const res = args.at(-2);
250
- try {
251
- if (req.body === null || req.body === undefined) throw new HttpError(400, "Request body is mandatory");
252
- return actualHandler(asStrict(req.body, type, config))(req, res);
253
- } catch (e) {
254
- const status = e.status ?? 500;
255
- status === 500 && log.error(e.stack);
256
- reply(res, status, e.message || e);
257
- }
143
+ function Needs() {
144
+ const argGetters = [];
145
+
146
+ const needs = {
147
+ param(name) {
148
+ argGetters.push((req) => req.params[name]);
149
+ return needs; // Return the object itself
150
+ },
151
+ params() {
152
+ argGetters.push((req) => req.params);
153
+ return needs;
154
+ },
155
+ query(name) {
156
+ argGetters.push((req) => req.query[name]);
157
+ return needs;
158
+ },
159
+ queries() {
160
+ argGetters.push((req) => req.query);
161
+ return needs;
162
+ },
163
+ body(type, config) {
164
+ if (type) {
165
+ argGetters.push((req) => asStrict(req.body || {}, type, config || { messageTemplate: "Malformed Request Body\n{0}" }));
258
166
  } else {
259
- return (req, res) => {
260
- try {
261
- if (req.body === null || req.body === undefined) throw new HttpError(400, "Request body is mandatory");
262
- return actualHandler(...args, asStrict(req.body, type, config))(req, res);
263
- } catch (e) {
264
- const status = e.status ?? 500;
265
- status === 500 && log.error(e.stack);
266
- reply(res, status, e.message || e);
267
- }
268
- };
269
- }
270
- };
271
- };
272
- }
273
-
274
- function PassBody(actualHandler) {
275
- return (...args) => {
276
- if (isRequstHandlerArgs(args)) {
277
- const req = args.at(-3);
278
- const res = args.at(-2);
279
- try {
280
- return actualHandler(req.body)(req, res);
281
- } catch (e) {
282
- const status = e.status ?? 500;
283
- status === 500 && log.error(e.stack);
284
- reply(res, status, e.message || e);
167
+ argGetters.push((req) => req.body || {});
285
168
  }
286
- } else {
169
+ return needs;
170
+ },
171
+ parseBody(type, config) {
172
+ argGetters.push((req) => as(req.body || {}, type, config || { messageTemplate: "Malformed Request Body\n{0}" }));
173
+ return needs;
174
+ },
175
+ cookie(name) {
176
+ argGetters.push((req) => req.cookies[name]);
177
+ return needs;
178
+ },
179
+ cookies() {
180
+ argGetters.push((req) => req.cookies);
181
+ return needs;
182
+ },
183
+ header(name) {
184
+ argGetters.push((req) => req.headers[name]);
185
+ return needs;
186
+ },
187
+ headers() {
188
+ argGetters.push((req) => req.headers);
189
+ return needs;
190
+ },
191
+ request() {
192
+ argGetters.push((req) => req)
193
+ return needs;
194
+ },
195
+ response() {
196
+ argGetters.push((_, res) => res)
197
+ return needs;
198
+ },
199
+ to(callback) {
287
200
  return (req, res) => {
288
- try {
289
- return actualHandler(...args, req.body)(req, res);
290
- } catch (e) {
291
- const status = e.status ?? 500;
292
- status === 500 && log.error(e.stack);
293
- reply(res, status, e.message || e);
294
- }
201
+ const args = argGetters.map((getter) => getter(req, res));
202
+ return RestMethod(callback)(...args)(req, res);
295
203
  };
296
204
  }
297
205
  };
298
- }
299
206
 
300
- function PassRequest(actualHandler) {
301
- return (...args) => {
302
- if (isRequstHandlerArgs(args)) {
303
- const req = args.at(-3);
304
- const res = args.at(-2);
305
- return actualHandler(req)(req, res);
306
- } else {
307
- return (req, res) => actualHandler(...args, req)(req, res);
308
- }
309
- };
310
- }
311
-
312
- function PassResponse(actualHandler) {
313
- return (...args) => {
314
- if (isRequstHandlerArgs(args)) {
315
- const req = args.at(-3);
316
- const res = args.at(-2);
317
- return actualHandler(res)(req, res);
318
- } else {
319
- return (req, res) => actualHandler(...args, res)(req, res);
320
- }
321
- };
322
- }
323
-
324
- function PassAllCookies(actualHandler) {
325
- return (...args) => {
326
- if (isRequstHandlerArgs(args)) {
327
- const req = args.at(-3);
328
- const res = args.at(-2);
329
- return actualHandler(req.cookies)(req, res);
330
- } else {
331
- return (req, res) => actualHandler(...args, req.cookies)(req, res);
332
- }
333
- };
334
- }
335
-
336
- function PassCookie(cookieName) {
337
- return (actualHandler) => {
338
- return (...args) => {
339
- if (isRequstHandlerArgs(args)) {
340
- const req = args.at(-3);
341
- const res = args.at(-2);
342
- const cookie = req.cookies[cookieName];
343
- return actualHandler(cookie)(req, res);
344
- } else {
345
- return (req, res) => {
346
- const cookie = req.cookies[cookieName];
347
- actualHandler(...args, cookie)(req, res);
348
- };
349
- }
350
- };
351
- };
207
+ return needs;
352
208
  }
353
209
 
354
210
  module.exports = {
355
211
  RestService,
356
212
  RestMethod,
357
213
  Restify,
358
- PassParam,
359
- PassAllParams,
360
- PassQuery,
361
- PassAllQueries,
362
- PassAllCookies,
363
- PassCookie,
364
- PassBody,
365
- PassBodyAs,
366
- ParseBodyAs,
367
- PassRequest,
368
- PassResponse,
214
+ Needs,
369
215
  };
package/package.json CHANGED
@@ -1,38 +1,39 @@
1
- {
2
- "name": "bootpress",
3
- "version": "10.0.4",
4
- "description": "REST service methods for express",
5
- "main": "index.js",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/ufukbakan/bootpress.git"
9
- },
10
- "keywords": [
11
- "bootpress",
12
- "express",
13
- "js",
14
- "javascript",
15
- "backend framework",
16
- "backend",
17
- "rest",
18
- "service",
19
- "methods",
20
- "spring",
21
- "boot",
22
- "like"
23
- ],
24
- "author": "Ufuk Bakan",
25
- "license": "MIT",
26
- "bugs": {
27
- "url": "https://github.com/ufukbakan/bootpress/issues"
28
- },
29
- "homepage": "https://github.com/ufukbakan/bootpress#readme",
30
- "dependencies": {
31
- "express": "^4.18.2"
32
- },
33
- "devDependencies": {
34
- "@types/express": "^4.17.17",
35
- "eslint": "^8.55.0",
36
- "typescript": "^4.9.5"
37
- }
38
- }
1
+ {
2
+ "name": "bootpress",
3
+ "version": "11.0.0-rc.2",
4
+ "description": "REST service methods for express",
5
+ "main": "index.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ufukbakan/bootpress.git"
9
+ },
10
+ "keywords": [
11
+ "bootpress",
12
+ "express",
13
+ "js",
14
+ "javascript",
15
+ "backend framework",
16
+ "backend",
17
+ "rest",
18
+ "service",
19
+ "methods",
20
+ "spring",
21
+ "boot",
22
+ "like"
23
+ ],
24
+ "author": "Ufuk Bakan",
25
+ "license": "MIT",
26
+ "bugs": {
27
+ "url": "https://github.com/ufukbakan/bootpress/issues"
28
+ },
29
+ "homepage": "https://github.com/ufukbakan/bootpress#readme",
30
+ "dependencies": {
31
+ "express": "^4.18.2"
32
+ },
33
+ "devDependencies": {
34
+ "@types/express": "^4.17.17",
35
+ "eslint": "^8.55.0",
36
+ "typescript": "^4.9.5",
37
+ "vitest": "^4.0.18"
38
+ }
39
+ }