express-ext 0.2.7 → 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/lib/GenericController.js +89 -66
- package/lib/GenericSearchController.js +2 -3
- package/lib/LoadSearchController.js +4 -5
- package/lib/LowCodeController.js +4 -5
- package/lib/SearchController.js +1 -1
- package/lib/edit.js +58 -34
- package/lib/index.js +6 -1
- package/lib/resources.js +7 -1
- package/lib/search.js +33 -40
- package/package.json +1 -1
- package/src/GenericController.ts +92 -41
- package/src/GenericSearchController.ts +4 -4
- package/src/LoadSearchController.ts +3 -4
- package/src/LowCodeController.ts +6 -6
- package/src/SearchController.ts +1 -1
- package/src/edit.ts +65 -31
- package/src/index.ts +5 -1
- package/src/resources.ts +7 -2
- package/src/search.ts +48 -20
- package/lib/search_func.js +0 -22
- package/src/search_func.ts +0 -22
package/src/GenericController.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {Request, Response} from 'express';
|
|
2
|
-
import {checkId, create, isTypeError, update} from './edit';
|
|
3
|
-
import {handleError, Log} from './http';
|
|
4
|
-
import {LoadController} from './LoadController';
|
|
5
|
-
import {Attribute, Attributes, ErrorMessage} from './metadata';
|
|
6
|
-
import {resources} from './resources';
|
|
7
|
-
import {buildAndCheckId, buildId} from './view';
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
import { checkId, create, isTypeError, update } from './edit';
|
|
3
|
+
import { handleError, Log } from './http';
|
|
4
|
+
import { LoadController } from './LoadController';
|
|
5
|
+
import { Attribute, Attributes, ErrorMessage } from './metadata';
|
|
6
|
+
import { resources, StringMap } from './resources';
|
|
7
|
+
import { buildAndCheckId, buildId } from './view';
|
|
8
8
|
|
|
9
9
|
export type Build<T> = (res: Response, obj: T, isCreate?: boolean, isPatch?: boolean) => void;
|
|
10
|
-
export type Validate<T> = (obj: T, patch?: boolean) => Promise<ErrorMessage[]>;
|
|
11
|
-
export type Save<T> = (obj: T, ctx?: any) => Promise<number|T|ErrorMessage[]>;
|
|
10
|
+
export type Validate<T> = (obj: T, resource?: StringMap, patch?: boolean) => Promise<ErrorMessage[]>;
|
|
11
|
+
export type Save<T> = (obj: T, ctx?: any) => Promise<number | T | ErrorMessage[]>;
|
|
12
12
|
export interface GenericService<T, ID, R> {
|
|
13
|
-
metadata?(): Attributes|undefined;
|
|
14
|
-
load(id: ID, ctx?: any): Promise<T|null>;
|
|
13
|
+
metadata?(): Attributes | undefined;
|
|
14
|
+
load(id: ID, ctx?: any): Promise<T | null>;
|
|
15
15
|
create(obj: T, ctx?: any): Promise<R>;
|
|
16
16
|
update(obj: T, ctx?: any): Promise<R>;
|
|
17
17
|
patch?(obj: Partial<T>, ctx?: any): Promise<R>;
|
|
@@ -20,7 +20,13 @@ export interface GenericService<T, ID, R> {
|
|
|
20
20
|
export class GenericController<T, ID> extends LoadController<T, ID> {
|
|
21
21
|
metadata?: Attributes;
|
|
22
22
|
returnNumber?: boolean;
|
|
23
|
-
constructor(
|
|
23
|
+
constructor(
|
|
24
|
+
log: Log,
|
|
25
|
+
public service: GenericService<T, ID, number | T | ErrorMessage[]>,
|
|
26
|
+
public build?: Build<T>,
|
|
27
|
+
public validate?: Validate<T>,
|
|
28
|
+
returnNumber?: boolean,
|
|
29
|
+
) {
|
|
24
30
|
super(log, service);
|
|
25
31
|
this.returnNumber = returnNumber;
|
|
26
32
|
if (service.metadata) {
|
|
@@ -44,13 +50,13 @@ export class GenericController<T, ID> extends LoadController<T, ID> {
|
|
|
44
50
|
update(req: Request, res: Response): void {
|
|
45
51
|
const id = buildAndCheckIdWithBody<T, ID, any>(req, res, this.keys, this.service.update);
|
|
46
52
|
if (id) {
|
|
47
|
-
validateAndUpdate(res, req.body, false, this.service.update, this.log, this.validate, this.build);
|
|
53
|
+
validateAndUpdate(res, req.body, false, this.service.update, this.log, this.validate, undefined, this.build);
|
|
48
54
|
}
|
|
49
55
|
}
|
|
50
56
|
patch(req: Request, res: Response): void {
|
|
51
57
|
const id = buildAndCheckIdWithBody<T, ID, any>(req, res, this.keys, this.service.patch);
|
|
52
58
|
if (id && this.service.patch) {
|
|
53
|
-
validateAndUpdate(res, req.body, true, this.service.patch, this.log, this.validate, this.build);
|
|
59
|
+
validateAndUpdate(res, req.body, true, this.service.patch, this.log, this.validate, undefined, this.build);
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
62
|
delete(req: Request, res: Response): void {
|
|
@@ -59,46 +65,71 @@ export class GenericController<T, ID> extends LoadController<T, ID> {
|
|
|
59
65
|
if (!this.service.delete) {
|
|
60
66
|
res.status(405).end('Method Not Allowed');
|
|
61
67
|
} else {
|
|
62
|
-
this.service
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
this.service
|
|
69
|
+
.delete(id)
|
|
70
|
+
.then((count) => {
|
|
71
|
+
res.status(getDeleteStatus(count)).json(count).end();
|
|
72
|
+
})
|
|
73
|
+
.catch((err) => handleError(err, res, this.log));
|
|
65
74
|
}
|
|
66
75
|
}
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
|
-
export function validateAndCreate<T>(
|
|
78
|
+
export function validateAndCreate<T>(
|
|
79
|
+
req: Request,
|
|
80
|
+
res: Response,
|
|
81
|
+
save: Save<T>,
|
|
82
|
+
log: Log,
|
|
83
|
+
validate?: Validate<T>,
|
|
84
|
+
build?: Build<T>,
|
|
85
|
+
returnNumber?: boolean,
|
|
86
|
+
): void {
|
|
70
87
|
const obj = req.body;
|
|
71
88
|
if (!obj || obj === '') {
|
|
72
89
|
res.status(400).end('The request body cannot be empty.');
|
|
73
90
|
} else {
|
|
74
91
|
if (validate) {
|
|
75
|
-
validate(obj)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
build
|
|
92
|
+
validate(obj)
|
|
93
|
+
.then((errors) => {
|
|
94
|
+
if (errors && errors.length > 0) {
|
|
95
|
+
res.status(getStatusCode(errors)).json(errors).end();
|
|
96
|
+
} else {
|
|
97
|
+
if (build) {
|
|
98
|
+
build(res, obj, true);
|
|
99
|
+
}
|
|
100
|
+
create(res, obj, save, log, returnNumber);
|
|
81
101
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}).catch(err => handleError(err, res, log));
|
|
102
|
+
})
|
|
103
|
+
.catch((err) => handleError(err, res, log));
|
|
85
104
|
} else {
|
|
86
105
|
create(res, obj, save, log, returnNumber);
|
|
87
106
|
}
|
|
88
107
|
}
|
|
89
108
|
}
|
|
90
|
-
export function validateAndUpdate<T>(
|
|
109
|
+
export function validateAndUpdate<T>(
|
|
110
|
+
res: Response,
|
|
111
|
+
obj: T,
|
|
112
|
+
isPatch: boolean,
|
|
113
|
+
save: Save<T>,
|
|
114
|
+
log: Log,
|
|
115
|
+
validate?: Validate<T>,
|
|
116
|
+
resource?: StringMap,
|
|
117
|
+
build?: Build<T>,
|
|
118
|
+
returnNumber?: boolean,
|
|
119
|
+
): void {
|
|
91
120
|
if (validate) {
|
|
92
|
-
validate(obj, isPatch)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
build
|
|
121
|
+
validate(obj, resource, isPatch)
|
|
122
|
+
.then((errors) => {
|
|
123
|
+
if (errors && errors.length > 0) {
|
|
124
|
+
res.status(getStatusCode(errors)).json(errors).end();
|
|
125
|
+
} else {
|
|
126
|
+
if (build) {
|
|
127
|
+
build(res, obj, false, isPatch);
|
|
128
|
+
}
|
|
129
|
+
update(res, obj, save, log, returnNumber);
|
|
98
130
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}).catch(err => handleError(err, res, log));
|
|
131
|
+
})
|
|
132
|
+
.catch((err) => handleError(err, res, log));
|
|
102
133
|
} else {
|
|
103
134
|
update(res, obj, save, log, returnNumber);
|
|
104
135
|
}
|
|
@@ -135,7 +166,7 @@ export function getDeleteStatus(count: number): number {
|
|
|
135
166
|
}
|
|
136
167
|
}
|
|
137
168
|
export function getStatusCode(errs: ErrorMessage[]): number {
|
|
138
|
-
return
|
|
169
|
+
return isTypeError(errs) ? 400 : 422;
|
|
139
170
|
}
|
|
140
171
|
export interface ModelConfig {
|
|
141
172
|
id?: string;
|
|
@@ -147,13 +178,33 @@ export interface ModelConfig {
|
|
|
147
178
|
createdAt?: string;
|
|
148
179
|
version?: string;
|
|
149
180
|
}
|
|
150
|
-
export function useBuild<T>(c: ModelConfig, generate?: (
|
|
151
|
-
const b = new Builder<T>(
|
|
181
|
+
export function useBuild<T>(c: ModelConfig, generate?: () => string): Build<T> {
|
|
182
|
+
const b = new Builder<T>(
|
|
183
|
+
generate,
|
|
184
|
+
c.id ? c.id : '',
|
|
185
|
+
c.payload ? c.payload : '',
|
|
186
|
+
c.user ? c.user : '',
|
|
187
|
+
c.updatedBy ? c.updatedBy : '',
|
|
188
|
+
c.updatedAt ? c.updatedAt : '',
|
|
189
|
+
c.createdBy ? c.createdBy : '',
|
|
190
|
+
c.createdAt ? c.createdAt : '',
|
|
191
|
+
c.version ? c.version : '',
|
|
192
|
+
);
|
|
152
193
|
return b.build;
|
|
153
194
|
}
|
|
154
195
|
// tslint:disable-next-line:max-classes-per-file
|
|
155
196
|
export class Builder<T> {
|
|
156
|
-
constructor(
|
|
197
|
+
constructor(
|
|
198
|
+
public generate: (() => string) | undefined,
|
|
199
|
+
public id: string,
|
|
200
|
+
public payload: string,
|
|
201
|
+
public user: string,
|
|
202
|
+
public updatedBy: string,
|
|
203
|
+
public updatedAt: string,
|
|
204
|
+
public createdBy: string,
|
|
205
|
+
public createdAt: string,
|
|
206
|
+
public version: string,
|
|
207
|
+
) {
|
|
157
208
|
this.build = this.build.bind(this);
|
|
158
209
|
}
|
|
159
210
|
build(res: Response, obj: T, isCreate?: boolean, isPatch?: boolean): void {
|
|
@@ -2,8 +2,8 @@ import { Request, Response } from 'express';
|
|
|
2
2
|
import { Build, GenericController, GenericService } from './GenericController';
|
|
3
3
|
import { handleError, Log } from './http';
|
|
4
4
|
import { ErrorMessage } from './metadata';
|
|
5
|
-
import {
|
|
6
|
-
import { getMetadataFunc } from './
|
|
5
|
+
import { StringMap } from './resources';
|
|
6
|
+
import { buildArray, Filter, format, fromRequest, getMetadataFunc, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult } from './search';
|
|
7
7
|
|
|
8
8
|
export class GenericSearchController<T, ID, S extends Filter> extends GenericController<T, ID> {
|
|
9
9
|
config?: SearchConfig;
|
|
@@ -19,7 +19,7 @@ export class GenericSearchController<T, ID, S extends Filter> extends GenericCon
|
|
|
19
19
|
service: GenericService<T, ID, number | ErrorMessage[]>,
|
|
20
20
|
config?: SearchConfig,
|
|
21
21
|
build?: Build<T>,
|
|
22
|
-
validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>,
|
|
22
|
+
validate?: (obj: T, resource?: StringMap, patch?: boolean) => Promise<ErrorMessage[]>,
|
|
23
23
|
dates?: string[],
|
|
24
24
|
numbers?: string[],
|
|
25
25
|
) {
|
|
@@ -44,7 +44,7 @@ export class GenericSearchController<T, ID, S extends Filter> extends GenericCon
|
|
|
44
44
|
const s = fromRequest<S>(req, buildArray(this.array, this.fields, this.excluding));
|
|
45
45
|
const l = getParameters(s, this.config);
|
|
46
46
|
const s2 = format(s, this.dates, this.numbers);
|
|
47
|
-
this.find(s2, l.limit, l.
|
|
47
|
+
this.find(s2, l.limit, l.pageOrNextPageToken, l.fields)
|
|
48
48
|
.then((result) => jsonResult(res, result, this.csv, l.fields, this.config))
|
|
49
49
|
.catch((err) => handleError(err, res, this.log));
|
|
50
50
|
}
|
|
@@ -2,8 +2,7 @@ import { Request, Response } from 'express';
|
|
|
2
2
|
import { handleError, Log } from './http';
|
|
3
3
|
import { LoadController, ViewService } from './LoadController';
|
|
4
4
|
import { Attribute, Attributes } from './metadata';
|
|
5
|
-
import { buildArray, Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult } from './search';
|
|
6
|
-
import { getMetadataFunc } from './search_func';
|
|
5
|
+
import { buildArray, Filter, format, fromRequest, getMetadataFunc, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult } from './search';
|
|
7
6
|
|
|
8
7
|
export interface Search {
|
|
9
8
|
search(req: Request, res: Response): void;
|
|
@@ -79,7 +78,7 @@ export class LoadSearchController<T, ID, S extends Filter> extends LoadControlle
|
|
|
79
78
|
const s = fromRequest<S>(req, buildArray(this.array, this.fields, this.excluding));
|
|
80
79
|
const l = getParameters(s, this.config);
|
|
81
80
|
const s2 = format(s, this.dates, this.numbers);
|
|
82
|
-
this.find(s2, l.limit, l.
|
|
81
|
+
this.find(s2, l.limit, l.pageOrNextPageToken, l.fields)
|
|
83
82
|
.then((result) => jsonResult(res, result, this.csv, l.fields, this.config))
|
|
84
83
|
.catch((err) => handleError(err, res, this.log));
|
|
85
84
|
}
|
|
@@ -122,7 +121,7 @@ export class QueryController<T, ID, S extends Filter> extends LoadController<T,
|
|
|
122
121
|
const l = getParameters(s, this.config);
|
|
123
122
|
const s2 = format(s, this.dates, this.numbers);
|
|
124
123
|
this.query
|
|
125
|
-
.search(s2, l.limit, l.
|
|
124
|
+
.search(s2, l.limit, l.pageOrNextPageToken, l.fields)
|
|
126
125
|
.then((result) => jsonResult(res, result, this.csv, l.fields, this.config))
|
|
127
126
|
.catch((err) => handleError(err, res, this.log));
|
|
128
127
|
}
|
package/src/LowCodeController.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { Request, Response } from 'express';
|
|
|
2
2
|
import { Build, GenericController, GenericService } from './GenericController';
|
|
3
3
|
import { handleError, Log } from './http';
|
|
4
4
|
import { ErrorMessage } from './metadata';
|
|
5
|
-
import {
|
|
6
|
-
import { getMetadataFunc } from './
|
|
5
|
+
import { StringMap } from './resources';
|
|
6
|
+
import { buildArray, Filter, format, fromRequest, getMetadataFunc, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult } from './search';
|
|
7
7
|
|
|
8
8
|
export interface Service<T, ID, R, S extends Filter> extends GenericService<T, ID, R> {
|
|
9
9
|
search: (s: S, limit?: number, skip?: number | string, fields?: string[]) => Promise<SearchResult<T>>;
|
|
@@ -21,7 +21,7 @@ export class LowcodeController<T, ID, S extends Filter> extends GenericControlle
|
|
|
21
21
|
public lowCodeService: Service<T, ID, number | ErrorMessage[], S>,
|
|
22
22
|
config?: SearchConfig,
|
|
23
23
|
build?: Build<T>,
|
|
24
|
-
validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>,
|
|
24
|
+
validate?: (obj: T, resource?: StringMap, patch?: boolean) => Promise<ErrorMessage[]>,
|
|
25
25
|
dates?: string[],
|
|
26
26
|
numbers?: string[],
|
|
27
27
|
) {
|
|
@@ -47,7 +47,7 @@ export class LowcodeController<T, ID, S extends Filter> extends GenericControlle
|
|
|
47
47
|
const l = getParameters(s, this.config);
|
|
48
48
|
const s2 = format(s, this.dates, this.numbers);
|
|
49
49
|
this.lowCodeService
|
|
50
|
-
.search(s2, l.limit, l.
|
|
50
|
+
.search(s2, l.limit, l.pageOrNextPageToken, l.fields)
|
|
51
51
|
.then((result) => jsonResult(res, result, this.csv, l.fields, this.config))
|
|
52
52
|
.catch((err) => handleError(err, res, this.log));
|
|
53
53
|
}
|
|
@@ -65,7 +65,7 @@ export class Controller<T, ID, S extends Filter> extends GenericController<T, ID
|
|
|
65
65
|
log: Log,
|
|
66
66
|
public lowCodeService: Service<T, ID, number | T | ErrorMessage[], S>,
|
|
67
67
|
build?: Build<T>,
|
|
68
|
-
validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>,
|
|
68
|
+
validate?: (obj: T, resource?: StringMap, patch?: boolean) => Promise<ErrorMessage[]>,
|
|
69
69
|
config?: SearchConfig,
|
|
70
70
|
dates?: string[],
|
|
71
71
|
numbers?: string[],
|
|
@@ -92,7 +92,7 @@ export class Controller<T, ID, S extends Filter> extends GenericController<T, ID
|
|
|
92
92
|
const l = getParameters(s, this.config);
|
|
93
93
|
const s2 = format(s, this.dates, this.numbers);
|
|
94
94
|
this.lowCodeService
|
|
95
|
-
.search(s2, l.limit, l.
|
|
95
|
+
.search(s2, l.limit, l.pageOrNextPageToken, l.fields)
|
|
96
96
|
.then((result) => jsonResult(res, result, this.csv, l.fields, this.config))
|
|
97
97
|
.catch((err) => handleError(err, res, this.log));
|
|
98
98
|
}
|
package/src/SearchController.ts
CHANGED
|
@@ -36,7 +36,7 @@ export class SearchController<T, S extends Filter> {
|
|
|
36
36
|
const s = fromRequest<S>(req, buildArray(this.array, this.fields, this.excluding));
|
|
37
37
|
const l = getParameters(s, this.config);
|
|
38
38
|
const s2 = format(s, this.dates, this.numbers);
|
|
39
|
-
this.find(s2, l.limit, l.
|
|
39
|
+
this.find(s2, l.limit, l.pageOrNextPageToken, l.fields)
|
|
40
40
|
.then((result) => jsonResult(res, result, this.csv, l.fields, this.config))
|
|
41
41
|
.catch((err) => handleError(err, res, this.log));
|
|
42
42
|
}
|
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 =
|
|
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>(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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(
|
|
86
|
+
res.status(201).json(result).end();
|
|
72
87
|
}
|
|
73
|
-
}
|
|
74
|
-
|
|
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>(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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(
|
|
114
|
+
res.status(200).json(result).end();
|
|
89
115
|
}
|
|
90
|
-
}
|
|
91
|
-
|
|
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 (
|
|
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
|
@@ -9,7 +9,8 @@ export interface StringMap {
|
|
|
9
9
|
}
|
|
10
10
|
// tslint:disable-next-line:class-name
|
|
11
11
|
export class resources {
|
|
12
|
-
static
|
|
12
|
+
static limits = [12, 24, 60, 100, 120, 180, 300, 600];
|
|
13
|
+
static component = 'page';
|
|
13
14
|
static page = 'page';
|
|
14
15
|
static limit = 'limit';
|
|
15
16
|
static defaultLimit = 12;
|
|
@@ -19,9 +20,13 @@ export class resources {
|
|
|
19
20
|
static check: (obj: any, attributes: Attributes, allowUndefined?: boolean, patch?: boolean) => ErrorMessage[];
|
|
20
21
|
static encoding?: BufferEncoding = 'utf-8';
|
|
21
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
|
+
}
|
|
22
27
|
|
|
23
28
|
export interface Validator<T> {
|
|
24
|
-
validate(obj: T,
|
|
29
|
+
validate(obj: T, resource?: StringMap, patch?: boolean): Promise<ErrorMessage[]>;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
// tslint:disable-next-line:max-classes-per-file
|
package/src/search.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
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
|
|
|
@@ -404,10 +405,10 @@ const setKey = (_object: any, _isArrayKey: boolean, _key: string, _nextValue: an
|
|
|
404
405
|
};
|
|
405
406
|
export interface Limit {
|
|
406
407
|
limit?: number;
|
|
407
|
-
|
|
408
|
+
page?: number;
|
|
408
409
|
nextPageToken?: string;
|
|
409
410
|
fields?: string[];
|
|
410
|
-
|
|
411
|
+
pageOrNextPageToken?: string | number;
|
|
411
412
|
}
|
|
412
413
|
export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
|
|
413
414
|
const o: any = obj;
|
|
@@ -432,16 +433,18 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
|
|
|
432
433
|
const ipageSize = Math.floor(parseFloat(pageSize));
|
|
433
434
|
if (ipageSize > 0) {
|
|
434
435
|
r.limit = ipageSize;
|
|
436
|
+
/*
|
|
435
437
|
const skip = o['skip'];
|
|
436
438
|
if (skip && !isNaN(skip)) {
|
|
437
439
|
const iskip = Math.floor(parseFloat(skip));
|
|
438
440
|
if (iskip >= 0) {
|
|
439
|
-
r.
|
|
440
|
-
r.
|
|
441
|
+
r.page = iskip;
|
|
442
|
+
r.pageOrNextPageToken = r.page;
|
|
441
443
|
deletePageInfo(o);
|
|
442
444
|
return r;
|
|
443
445
|
}
|
|
444
446
|
}
|
|
447
|
+
*/
|
|
445
448
|
let pageIndex = o['page'];
|
|
446
449
|
if (!pageIndex) {
|
|
447
450
|
pageIndex = o['pageIndex'];
|
|
@@ -454,6 +457,7 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
|
|
|
454
457
|
if (ipageIndex < 1) {
|
|
455
458
|
ipageIndex = 1;
|
|
456
459
|
}
|
|
460
|
+
/*
|
|
457
461
|
let firstPageSize = o['firstLimit'];
|
|
458
462
|
if (!firstPageSize) {
|
|
459
463
|
firstPageSize = o['firstPageSize'];
|
|
@@ -464,27 +468,28 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
|
|
|
464
468
|
if (firstPageSize && !isNaN(firstPageSize)) {
|
|
465
469
|
const ifirstPageSize = Math.floor(parseFloat(firstPageSize));
|
|
466
470
|
if (ifirstPageSize > 0) {
|
|
467
|
-
r.
|
|
468
|
-
r.
|
|
471
|
+
r.page = ipageIndex;
|
|
472
|
+
r.pageOrNextPageToken = r.page;
|
|
469
473
|
deletePageInfo(o);
|
|
470
474
|
return r;
|
|
471
475
|
}
|
|
472
476
|
}
|
|
473
|
-
|
|
474
|
-
r.
|
|
477
|
+
*/
|
|
478
|
+
r.page = ipageIndex;
|
|
479
|
+
r.pageOrNextPageToken = r.page;
|
|
475
480
|
deletePageInfo(o);
|
|
476
481
|
return r;
|
|
477
482
|
}
|
|
478
|
-
r.
|
|
483
|
+
r.page = 1;
|
|
479
484
|
if (r.nextPageToken && r.nextPageToken.length > 0) {
|
|
480
|
-
r.
|
|
485
|
+
r.pageOrNextPageToken = r.nextPageToken;
|
|
481
486
|
}
|
|
482
487
|
deletePageInfo(o);
|
|
483
488
|
return r;
|
|
484
489
|
}
|
|
485
490
|
}
|
|
486
491
|
if (r.nextPageToken && r.nextPageToken.length > 0) {
|
|
487
|
-
r.
|
|
492
|
+
r.pageOrNextPageToken = r.nextPageToken;
|
|
488
493
|
}
|
|
489
494
|
deletePageInfo(o);
|
|
490
495
|
return r;
|
|
@@ -524,8 +529,8 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
|
|
|
524
529
|
if (skip && !isNaN(skip)) {
|
|
525
530
|
const iskip = Math.floor(parseFloat(skip));
|
|
526
531
|
if (iskip >= 0) {
|
|
527
|
-
r.
|
|
528
|
-
r.
|
|
532
|
+
r.page = iskip;
|
|
533
|
+
r.pageOrNextPageToken = r.page;
|
|
529
534
|
deletePageInfo(o, arr);
|
|
530
535
|
return r;
|
|
531
536
|
}
|
|
@@ -548,27 +553,27 @@ export function getParameters<T>(obj: T, config?: SearchConfig): Limit {
|
|
|
548
553
|
if (firstPageSize && !isNaN(firstPageSize)) {
|
|
549
554
|
const ifirstPageSize = Math.floor(parseFloat(firstPageSize));
|
|
550
555
|
if (ifirstPageSize > 0) {
|
|
551
|
-
r.
|
|
552
|
-
r.
|
|
556
|
+
r.page = ipageSize * (ipageIndex - 2) + ifirstPageSize;
|
|
557
|
+
r.pageOrNextPageToken = r.page;
|
|
553
558
|
deletePageInfo(o, arr);
|
|
554
559
|
return r;
|
|
555
560
|
}
|
|
556
561
|
}
|
|
557
|
-
r.
|
|
558
|
-
r.
|
|
562
|
+
r.page = ipageSize * (ipageIndex - 1);
|
|
563
|
+
r.pageOrNextPageToken = r.page;
|
|
559
564
|
deletePageInfo(o, arr);
|
|
560
565
|
return r;
|
|
561
566
|
}
|
|
562
|
-
r.
|
|
567
|
+
r.page = 0;
|
|
563
568
|
if (r.nextPageToken && r.nextPageToken.length > 0) {
|
|
564
|
-
r.
|
|
569
|
+
r.pageOrNextPageToken = r.nextPageToken;
|
|
565
570
|
}
|
|
566
571
|
deletePageInfo(o, arr);
|
|
567
572
|
return r;
|
|
568
573
|
}
|
|
569
574
|
}
|
|
570
575
|
if (r.nextPageToken && r.nextPageToken.length > 0) {
|
|
571
|
-
r.
|
|
576
|
+
r.pageOrNextPageToken = r.nextPageToken;
|
|
572
577
|
}
|
|
573
578
|
deletePageInfo(o, arr);
|
|
574
579
|
return r;
|
|
@@ -791,3 +796,26 @@ export function format<T>(obj: T, dates?: string[], nums?: string[]): T {
|
|
|
791
796
|
}
|
|
792
797
|
return o;
|
|
793
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
|
+
}
|
package/lib/search_func.js
DELETED
|
@@ -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;
|