express-ext 0.2.6 → 0.3.0

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/src/edit.ts CHANGED
@@ -1,6 +1,6 @@
1
- import {Response} from 'express';
2
- import {handleError} from './http';
3
- import {Attribute, ErrorMessage} from './metadata';
1
+ import { Response } from 'express';
2
+ import { handleError } from './http';
3
+ import { Attribute, ErrorMessage } from './metadata';
4
4
  /*
5
5
  export interface StatusConfig {
6
6
  duplicate_key: number|string;
@@ -32,7 +32,7 @@ export function initializeStatus(s?: StatusConfig): StatusConfig {
32
32
  }
33
33
  */
34
34
  export function checkId<T, ID>(obj: T, id: ID, keys?: Attribute[]): boolean {
35
- const n: string = (keys && keys.length === 1 && keys[0].name ? keys[0].name : 'id');
35
+ const n: string = keys && keys.length === 1 && keys[0].name ? keys[0].name : 'id';
36
36
  const o: any = obj;
37
37
  const i: any = id;
38
38
  if (!keys || keys.length === 1) {
@@ -62,37 +62,59 @@ export function checkId<T, ID>(obj: T, id: ID, keys?: Attribute[]): boolean {
62
62
  }
63
63
  return true;
64
64
  }
65
- export function create<T>(res: Response, obj: T, insert: (obj: T, ctx?: any) => Promise<number|T|ErrorMessage[]>, log: (msg: string, ctx?: any) => void, returnNumber?: boolean): void {
66
- insert(obj).then(result => {
67
- if (typeof result === 'number') {
68
- if (result >= 1) {
69
- res.status(201).json(returnNumber ? result : obj).end();
65
+ export function create<T>(
66
+ res: Response,
67
+ obj: T,
68
+ insert: (obj: T, ctx?: any) => Promise<number | T | ErrorMessage[]>,
69
+ log: (msg: string, ctx?: any) => void,
70
+ returnNumber?: boolean,
71
+ ): void {
72
+ insert(obj)
73
+ .then((result) => {
74
+ if (typeof result === 'number') {
75
+ if (result >= 1) {
76
+ res
77
+ .status(201)
78
+ .json(returnNumber ? result : obj)
79
+ .end();
80
+ } else {
81
+ res.status(409).json(result).end();
82
+ }
83
+ } else if (Array.isArray(result)) {
84
+ res.status(422).json(result).end();
70
85
  } else {
71
- res.status(409).json(result).end();
86
+ res.status(201).json(result).end();
72
87
  }
73
- } else if (Array.isArray(result)) {
74
- res.status(422).json(result).end();
75
- } else {
76
- res.status(201).json(result).end();
77
- }
78
- }).catch(err => handleError(err, res, log));
88
+ })
89
+ .catch((err) => handleError(err, res, log));
79
90
  }
80
- export function update<T>(res: Response, obj: T, save: (obj: T, ctx?: any) => Promise<number|T|ErrorMessage[]>, log: (msg: string, ctx?: any) => void, returnNumber?: boolean): void {
81
- save(obj).then(result => {
82
- if (typeof result === 'number') {
83
- if (result >= 1) {
84
- res.status(200).json(returnNumber ? result : obj).end();
85
- } else if (result === 0) {
86
- res.status(404).json(result).end();
91
+ export function update<T>(
92
+ res: Response,
93
+ obj: T,
94
+ save: (obj: T, ctx?: any) => Promise<number | T | ErrorMessage[]>,
95
+ log: (msg: string, ctx?: any) => void,
96
+ returnNumber?: boolean,
97
+ ): void {
98
+ save(obj)
99
+ .then((result) => {
100
+ if (typeof result === 'number') {
101
+ if (result >= 1) {
102
+ res
103
+ .status(200)
104
+ .json(returnNumber ? result : obj)
105
+ .end();
106
+ } else if (result === 0) {
107
+ res.status(404).json(result).end();
108
+ } else {
109
+ res.status(409).json(result).end();
110
+ }
111
+ } else if (Array.isArray(result)) {
112
+ res.status(422).json(result).end();
87
113
  } else {
88
- res.status(409).json(result).end();
114
+ res.status(200).json(result).end();
89
115
  }
90
- } else if (Array.isArray(result)) {
91
- res.status(422).json(result).end();
92
- } else {
93
- res.status(200).json(result).end();
94
- }
95
- }).catch(err => handleError(err, res, log));
116
+ })
117
+ .catch((err) => handleError(err, res, log));
96
118
  }
97
119
  export function isTypeError(errs: ErrorMessage[]): boolean {
98
120
  if (!errs) {
@@ -100,7 +122,19 @@ export function isTypeError(errs: ErrorMessage[]): boolean {
100
122
  }
101
123
  for (const err of errs) {
102
124
  const c = err.code;
103
- if (c === 'string' || c === 'number' || c === 'date' || c === 'boolean') {
125
+ if (
126
+ c === 'type' ||
127
+ c === 'string' ||
128
+ c === 'number' ||
129
+ c === 'date' ||
130
+ c === 'boolean' ||
131
+ c === 'strings' ||
132
+ c === 'numbers' ||
133
+ c === 'integers' ||
134
+ c === 'dates' ||
135
+ c === 'datetimes' ||
136
+ c === 'booleans'
137
+ ) {
104
138
  return true;
105
139
  }
106
140
  }
package/src/index.ts CHANGED
@@ -36,7 +36,6 @@ export * from './LowCodeController';
36
36
  export * from './metadata';
37
37
  export * from './resources';
38
38
  export * from './search';
39
- export * from './search_func';
40
39
  export * from './SearchController';
41
40
  export * from './view';
42
41
 
@@ -291,3 +290,8 @@ export class UserReactionController {
291
290
  }
292
291
  export const ReactController = UserReactionController;
293
292
  export const ReactionController = UserReactionController;
293
+ export function addDays(d: Date, n: number): Date {
294
+ const newDate = new Date(d);
295
+ newDate.setDate(newDate.getDate() + n);
296
+ return newDate;
297
+ }
package/src/resources.ts CHANGED
@@ -4,18 +4,29 @@ import * as http from 'http';
4
4
  import * as https from 'https';
5
5
  import { Attributes, ErrorMessage } from './metadata';
6
6
 
7
+ export interface StringMap {
8
+ [key: string]: string;
9
+ }
7
10
  // tslint:disable-next-line:class-name
8
11
  export class resources {
12
+ static limits = [12, 24, 60, 100, 120, 180, 300, 600];
13
+ static component = 'page';
9
14
  static page = 'page';
15
+ static limit = 'limit';
16
+ static defaultLimit = 12;
10
17
  static sort = 'sort';
11
18
  static partial = 'partial';
12
19
  static createValidator?: <T>(attributes: Attributes, allowUndefined?: boolean, max?: number) => Validator<T>;
13
20
  static check: (obj: any, attributes: Attributes, allowUndefined?: boolean, patch?: boolean) => ErrorMessage[];
14
21
  static encoding?: BufferEncoding = 'utf-8';
15
22
  }
23
+ export function getView(req: Request, view: string): string {
24
+ const partial = req.query[resources.partial];
25
+ return partial == 'true' ? resources.component + '/' + view : view;
26
+ }
16
27
 
17
28
  export interface Validator<T> {
18
- validate(obj: T, patch?: boolean): Promise<ErrorMessage[]>;
29
+ validate(obj: T, resource?: StringMap, patch?: boolean): Promise<ErrorMessage[]>;
19
30
  }
20
31
 
21
32
  // tslint:disable-next-line:max-classes-per-file
package/src/search.ts CHANGED
@@ -1,11 +1,15 @@
1
1
  import { Request, Response } from 'express';
2
2
  import { minimizeArray, query } from './http';
3
+ import { ViewService } from './LoadController';
3
4
  import { Attribute, Attributes } from './metadata';
4
5
  import { resources } from './resources';
5
6
 
6
7
  const et = '';
7
8
 
8
9
  export interface Filter {
10
+ page?: number;
11
+ limit?: number;
12
+
9
13
  fields?: string[];
10
14
  sort?: string;
11
15
 
@@ -170,6 +174,53 @@ export function buildSortSearch(search: string, fields: string[], sort: Sort): S
170
174
  }
171
175
  return sorts;
172
176
  }
177
+ export function clone(obj: any): any {
178
+ if (!obj) {
179
+ return obj;
180
+ }
181
+ if (obj instanceof Date) {
182
+ return new Date(obj.getTime());
183
+ }
184
+ if (typeof obj !== 'object') {
185
+ return obj;
186
+ }
187
+ if (Array.isArray(obj)) {
188
+ const arr = [];
189
+ for (const sub of obj) {
190
+ const c = clone(sub);
191
+ arr.push(c);
192
+ }
193
+ return arr;
194
+ }
195
+ const x: any = {};
196
+ const keys = Object.keys(obj);
197
+ for (const k of keys) {
198
+ const v = obj[k];
199
+ if (v instanceof Date) {
200
+ x[k] = new Date(v.getTime());
201
+ } else {
202
+ switch (typeof v) {
203
+ case 'object':
204
+ x[k] = clone(v);
205
+ break;
206
+ default:
207
+ x[k] = v;
208
+ break;
209
+ }
210
+ }
211
+ }
212
+ return x;
213
+ }
214
+ export function cloneFilter<F extends Filter>(obj: F, page: number, limit: number): F {
215
+ const f = clone(obj);
216
+ if (!obj.hasOwnProperty(resources.page)) {
217
+ (obj as any)[resources.page] = page;
218
+ }
219
+ if (!obj.hasOwnProperty(resources.limit)) {
220
+ (obj as any)[resources.limit] = limit;
221
+ }
222
+ return f;
223
+ }
173
224
 
174
225
  export function jsonResult<T>(res: Response, result: SearchResult<T>, quick?: boolean, fields?: string[], config?: SearchConfig): void {
175
226
  if (quick && fields && fields.length > 0) {
@@ -354,10 +405,10 @@ const setKey = (_object: any, _isArrayKey: boolean, _key: string, _nextValue: an
354
405
  };
355
406
  export interface Limit {
356
407
  limit?: number;
357
- offset?: number;
408
+ page?: number;
358
409
  nextPageToken?: string;
359
410
  fields?: string[];
360
- offsetOrNextPageToken?: string | number;
411
+ pageOrNextPageToken?: string | number;
361
412
  }
362
413
  export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
363
414
  const o: any = obj;
@@ -382,16 +433,18 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
382
433
  const ipageSize = Math.floor(parseFloat(pageSize));
383
434
  if (ipageSize > 0) {
384
435
  r.limit = ipageSize;
436
+ /*
385
437
  const skip = o['skip'];
386
438
  if (skip && !isNaN(skip)) {
387
439
  const iskip = Math.floor(parseFloat(skip));
388
440
  if (iskip >= 0) {
389
- r.offset = iskip;
390
- r.offsetOrNextPageToken = r.offset;
441
+ r.page = iskip;
442
+ r.pageOrNextPageToken = r.page;
391
443
  deletePageInfo(o);
392
444
  return r;
393
445
  }
394
446
  }
447
+ */
395
448
  let pageIndex = o['page'];
396
449
  if (!pageIndex) {
397
450
  pageIndex = o['pageIndex'];
@@ -404,6 +457,7 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
404
457
  if (ipageIndex < 1) {
405
458
  ipageIndex = 1;
406
459
  }
460
+ /*
407
461
  let firstPageSize = o['firstLimit'];
408
462
  if (!firstPageSize) {
409
463
  firstPageSize = o['firstPageSize'];
@@ -414,27 +468,28 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
414
468
  if (firstPageSize && !isNaN(firstPageSize)) {
415
469
  const ifirstPageSize = Math.floor(parseFloat(firstPageSize));
416
470
  if (ifirstPageSize > 0) {
417
- r.offset = ipageSize * (ipageIndex - 2) + ifirstPageSize;
418
- r.offsetOrNextPageToken = r.offset;
471
+ r.page = ipageIndex;
472
+ r.pageOrNextPageToken = r.page;
419
473
  deletePageInfo(o);
420
474
  return r;
421
475
  }
422
476
  }
423
- r.offset = ipageSize * (ipageIndex - 1);
424
- r.offsetOrNextPageToken = r.offset;
477
+ */
478
+ r.page = ipageIndex;
479
+ r.pageOrNextPageToken = r.page;
425
480
  deletePageInfo(o);
426
481
  return r;
427
482
  }
428
- r.offset = 0;
483
+ r.page = 1;
429
484
  if (r.nextPageToken && r.nextPageToken.length > 0) {
430
- r.offsetOrNextPageToken = r.nextPageToken;
485
+ r.pageOrNextPageToken = r.nextPageToken;
431
486
  }
432
487
  deletePageInfo(o);
433
488
  return r;
434
489
  }
435
490
  }
436
491
  if (r.nextPageToken && r.nextPageToken.length > 0) {
437
- r.offsetOrNextPageToken = r.nextPageToken;
492
+ r.pageOrNextPageToken = r.nextPageToken;
438
493
  }
439
494
  deletePageInfo(o);
440
495
  return r;
@@ -474,8 +529,8 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
474
529
  if (skip && !isNaN(skip)) {
475
530
  const iskip = Math.floor(parseFloat(skip));
476
531
  if (iskip >= 0) {
477
- r.offset = iskip;
478
- r.offsetOrNextPageToken = r.offset;
532
+ r.page = iskip;
533
+ r.pageOrNextPageToken = r.page;
479
534
  deletePageInfo(o, arr);
480
535
  return r;
481
536
  }
@@ -498,27 +553,27 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
498
553
  if (firstPageSize && !isNaN(firstPageSize)) {
499
554
  const ifirstPageSize = Math.floor(parseFloat(firstPageSize));
500
555
  if (ifirstPageSize > 0) {
501
- r.offset = ipageSize * (ipageIndex - 2) + ifirstPageSize;
502
- r.offsetOrNextPageToken = r.offset;
556
+ r.page = ipageSize * (ipageIndex - 2) + ifirstPageSize;
557
+ r.pageOrNextPageToken = r.page;
503
558
  deletePageInfo(o, arr);
504
559
  return r;
505
560
  }
506
561
  }
507
- r.offset = ipageSize * (ipageIndex - 1);
508
- r.offsetOrNextPageToken = r.offset;
562
+ r.page = ipageSize * (ipageIndex - 1);
563
+ r.pageOrNextPageToken = r.page;
509
564
  deletePageInfo(o, arr);
510
565
  return r;
511
566
  }
512
- r.offset = 0;
567
+ r.page = 0;
513
568
  if (r.nextPageToken && r.nextPageToken.length > 0) {
514
- r.offsetOrNextPageToken = r.nextPageToken;
569
+ r.pageOrNextPageToken = r.nextPageToken;
515
570
  }
516
571
  deletePageInfo(o, arr);
517
572
  return r;
518
573
  }
519
574
  }
520
575
  if (r.nextPageToken && r.nextPageToken.length > 0) {
521
- r.offsetOrNextPageToken = r.nextPageToken;
576
+ r.pageOrNextPageToken = r.nextPageToken;
522
577
  }
523
578
  deletePageInfo(o, arr);
524
579
  return r;
@@ -741,3 +796,26 @@ export function format<T>(obj: T, dates?: string[], nums?: string[]): T {
741
796
  }
742
797
  return o;
743
798
  }
799
+ export function getMetadataFunc<T, ID>(
800
+ viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T>),
801
+ dates?: string[],
802
+ numbers?: string[],
803
+ keys?: Attributes | Attribute[] | string[],
804
+ ): Metadata | undefined {
805
+ const m: Metadata = { dates, numbers };
806
+ if ((m.dates && m.dates.length > 0) || (m.numbers && m.numbers.length > 0)) {
807
+ return m;
808
+ }
809
+ if (keys) {
810
+ if (!Array.isArray(keys)) {
811
+ return buildMetadata(keys);
812
+ }
813
+ }
814
+ if (typeof viewService !== 'function' && viewService.metadata) {
815
+ const metadata = viewService.metadata();
816
+ if (metadata) {
817
+ return buildMetadata(metadata);
818
+ }
819
+ }
820
+ return undefined;
821
+ }
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var search_1 = require("./search");
4
- function getMetadataFunc(viewService, dates, numbers, keys) {
5
- var m = { dates: dates, numbers: numbers };
6
- if (m.dates && m.dates.length > 0 || m.numbers && m.numbers.length > 0) {
7
- return m;
8
- }
9
- if (keys) {
10
- if (!Array.isArray(keys)) {
11
- return search_1.buildMetadata(keys);
12
- }
13
- }
14
- if (typeof viewService !== 'function' && viewService.metadata) {
15
- var metadata = viewService.metadata();
16
- if (metadata) {
17
- return search_1.buildMetadata(metadata);
18
- }
19
- }
20
- return undefined;
21
- }
22
- exports.getMetadataFunc = getMetadataFunc;
@@ -1,22 +0,0 @@
1
- import {ViewService} from './LoadController';
2
- import {Attribute, Attributes} from './metadata';
3
- import {buildMetadata, Metadata} from './search';
4
-
5
- export function getMetadataFunc<T, ID>(viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T>), dates?: string[], numbers?: string[], keys?: Attributes|Attribute[]|string[]): Metadata | undefined {
6
- const m: Metadata = { dates, numbers };
7
- if (m.dates && m.dates.length > 0 || m.numbers && m.numbers.length > 0) {
8
- return m;
9
- }
10
- if (keys) {
11
- if (!Array.isArray(keys)) {
12
- return buildMetadata(keys);
13
- }
14
- }
15
- if (typeof viewService !== 'function' && viewService.metadata) {
16
- const metadata = viewService.metadata();
17
- if (metadata) {
18
- return buildMetadata(metadata);
19
- }
20
- }
21
- return undefined;
22
- }