express-ext 0.1.20 → 0.1.23

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.
@@ -20,10 +20,11 @@ var resources_1 = require("./resources");
20
20
  var view_1 = require("./view");
21
21
  var GenericController = (function (_super) {
22
22
  __extends(GenericController, _super);
23
- function GenericController(log, service, status, validate) {
23
+ function GenericController(log, service, status, validate, build) {
24
24
  var _this = _super.call(this, log, service) || this;
25
25
  _this.service = service;
26
26
  _this.validate = validate;
27
+ _this.build = build;
27
28
  _this.status = edit_1.initializeStatus(status);
28
29
  if (service.metadata) {
29
30
  var m = service.metadata();
@@ -46,18 +47,18 @@ var GenericController = (function (_super) {
46
47
  return this.insert(req, res);
47
48
  };
48
49
  GenericController.prototype.insert = function (req, res) {
49
- validateAndCreate(req, res, this.status, this.service.insert, this.log, this.validate);
50
+ validateAndCreate(req, res, this.status, this.service.insert, this.log, this.validate, this.build);
50
51
  };
51
52
  GenericController.prototype.update = function (req, res) {
52
53
  var id = buildAndCheckIdWithBody(req, res, this.keys, this.service.update);
53
54
  if (id) {
54
- validateAndUpdate(res, this.status, req.body, false, this.service.update, this.log, this.validate);
55
+ validateAndUpdate(res, this.status, req.body, false, this.service.update, this.log, this.validate, this.build);
55
56
  }
56
57
  };
57
58
  GenericController.prototype.patch = function (req, res) {
58
59
  var id = buildAndCheckIdWithBody(req, res, this.keys, this.service.patch);
59
60
  if (id && this.service.patch) {
60
- validateAndUpdate(res, this.status, req.body, true, this.service.patch, this.log, this.validate);
61
+ validateAndUpdate(res, this.status, req.body, true, this.service.patch, this.log, this.validate, this.build);
61
62
  }
62
63
  };
63
64
  GenericController.prototype.delete = function (req, res) {
@@ -77,7 +78,7 @@ var GenericController = (function (_super) {
77
78
  return GenericController;
78
79
  }(LoadController_1.LoadController));
79
80
  exports.GenericController = GenericController;
80
- function validateAndCreate(req, res, status, save, log, validate) {
81
+ function validateAndCreate(req, res, status, save, log, validate, build) {
81
82
  var obj = req.body;
82
83
  if (!obj || obj === '') {
83
84
  res.status(400).end('The request body cannot be empty.');
@@ -90,6 +91,9 @@ function validateAndCreate(req, res, status, save, log, validate) {
90
91
  res.status(getStatusCode(errors)).json(r).end();
91
92
  }
92
93
  else {
94
+ if (build) {
95
+ build(res, obj, true);
96
+ }
93
97
  edit_1.create(res, status, obj, save, log);
94
98
  }
95
99
  }).catch(function (err) { return http_1.handleError(err, res, log); });
@@ -100,7 +104,7 @@ function validateAndCreate(req, res, status, save, log, validate) {
100
104
  }
101
105
  }
102
106
  exports.validateAndCreate = validateAndCreate;
103
- function validateAndUpdate(res, status, obj, isPatch, save, log, validate) {
107
+ function validateAndUpdate(res, status, obj, isPatch, save, log, validate, build) {
104
108
  if (validate) {
105
109
  validate(obj, isPatch).then(function (errors) {
106
110
  if (errors && errors.length > 0) {
@@ -108,6 +112,9 @@ function validateAndUpdate(res, status, obj, isPatch, save, log, validate) {
108
112
  res.status(getStatusCode(errors)).json(r).end();
109
113
  }
110
114
  else {
115
+ if (build) {
116
+ build(res, obj, false, isPatch);
117
+ }
111
118
  edit_1.update(res, status, obj, save, log);
112
119
  }
113
120
  }).catch(function (err) { return http_1.handleError(err, res, log); });
@@ -156,3 +163,73 @@ function getStatusCode(errs) {
156
163
  return (edit_1.isTypeError(errs) ? 400 : 422);
157
164
  }
158
165
  exports.getStatusCode = getStatusCode;
166
+ function useBuild(c, generate) {
167
+ var b = new Builder(generate, c.id ? c.id : '', c.payload ? c.payload : '', c.user ? c.user : '', c.updatedBy ? c.updatedBy : '', c.updatedAt ? c.updatedAt : '', c.createdBy ? c.createdBy : '', c.createdAt ? c.createdAt : '', c.version ? c.version : '');
168
+ return b.build;
169
+ }
170
+ exports.useBuild = useBuild;
171
+ var Builder = (function () {
172
+ function Builder(generate, id, payload, user, updatedBy, updatedAt, createdBy, createdAt, version) {
173
+ this.generate = generate;
174
+ this.id = id;
175
+ this.payload = payload;
176
+ this.user = user;
177
+ this.updatedBy = updatedBy;
178
+ this.updatedAt = updatedAt;
179
+ this.createdBy = createdBy;
180
+ this.createdAt = createdAt;
181
+ this.version = version;
182
+ this.build = this.build.bind(this);
183
+ }
184
+ Builder.prototype.build = function (res, obj, isCreate, isPatch) {
185
+ var o = obj;
186
+ var usr = '';
187
+ if (this.user.length > 0) {
188
+ if (this.payload.length > 0) {
189
+ var payload = res.locals[this.payload];
190
+ if (payload) {
191
+ usr = payload[this.user];
192
+ }
193
+ }
194
+ else {
195
+ usr = res.locals[this.user];
196
+ }
197
+ }
198
+ if (!usr) {
199
+ usr = '';
200
+ }
201
+ var now = new Date();
202
+ if (isCreate) {
203
+ if (this.generate && this.id.length > 0) {
204
+ o[this.id] = this.generate();
205
+ }
206
+ if (usr.length > 0) {
207
+ if (this.createdAt.length > 0) {
208
+ o[this.createdAt] = now;
209
+ }
210
+ if (this.createdBy.length > 0) {
211
+ o[this.createdBy] = usr;
212
+ }
213
+ }
214
+ if (this.version.length > 0) {
215
+ o[this.version] = 1;
216
+ }
217
+ }
218
+ else if (isPatch) {
219
+ var keys = Object.keys(o);
220
+ if (keys.length === 0) {
221
+ return;
222
+ }
223
+ }
224
+ if (usr.length > 0) {
225
+ if (this.updatedAt.length > 0) {
226
+ o[this.updatedAt] = now;
227
+ }
228
+ if (this.updatedBy.length > 0) {
229
+ o[this.updatedBy] = usr;
230
+ }
231
+ }
232
+ };
233
+ return Builder;
234
+ }());
235
+ exports.Builder = Builder;
package/lib/client.js ADDED
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var http = require("http");
4
+ var https = require("https");
5
+ function getHealthSecure(url, timeout) {
6
+ return new Promise(function (resolve) {
7
+ https.get(url, { rejectUnauthorized: false }, function (res) {
8
+ var data = '';
9
+ res.on('data', function (d) {
10
+ data += d;
11
+ });
12
+ res.on('end', function () {
13
+ resolve({ statusCode: res.statusCode, data: data, statusMessage: res.statusMessage });
14
+ });
15
+ }).on('error', function (e) {
16
+ return { statusCode: 500, statusMessage: e };
17
+ });
18
+ setTimeout(function () { return resolve({ statusCode: 408, statusMessage: 'Time out' }); }, timeout);
19
+ });
20
+ }
21
+ function getHealth(url, timeout) {
22
+ return new Promise(function (resolve) {
23
+ http.get(url, function (res) {
24
+ var data = '';
25
+ res.on('data', function (d) {
26
+ data += d;
27
+ });
28
+ res.on('end', function () {
29
+ resolve({ statusCode: res.statusCode, data: data, statusMessage: res.statusMessage });
30
+ });
31
+ }).on('error', function (e) {
32
+ return { statusCode: 500, statusMessage: e };
33
+ });
34
+ setTimeout(function () { return resolve({ statusCode: 408, statusMessage: 'Time out' }); }, timeout);
35
+ });
36
+ }
37
+ var ClientChecker = (function () {
38
+ function ClientChecker(service, url, timeout) {
39
+ this.service = service;
40
+ this.url = url;
41
+ this.timeout = (timeout ? timeout : 4200);
42
+ this.check = this.check.bind(this);
43
+ this.name = this.name.bind(this);
44
+ this.build = this.build.bind(this);
45
+ }
46
+ ClientChecker.prototype.check = function () {
47
+ var obj = {};
48
+ if (this.url.startsWith('https://')) {
49
+ return getHealthSecure(this.url, this.timeout).then(function (r) { return obj = r; });
50
+ }
51
+ else {
52
+ return getHealth(this.url, this.timeout).then(function (r) { return obj = r; });
53
+ }
54
+ };
55
+ ClientChecker.prototype.name = function () {
56
+ return this.service;
57
+ };
58
+ ClientChecker.prototype.build = function (data, err) {
59
+ if (err) {
60
+ if (!data) {
61
+ data = {};
62
+ }
63
+ data['error'] = err;
64
+ }
65
+ return data;
66
+ };
67
+ return ClientChecker;
68
+ }());
69
+ exports.ClientChecker = ClientChecker;
package/lib/index.js CHANGED
@@ -1 +1,74 @@
1
- "use strict";function __export(r){for(var e in r)exports.hasOwnProperty(e)||(exports[e]=r[e])}Object.defineProperty(exports,"__esModule",{value:!0});var GenericController_1=require("./GenericController");exports.GenericHandler=GenericController_1.GenericController;var GenericSearchController_1=require("./GenericSearchController");exports.GenericSearchHandler=GenericSearchController_1.GenericSearchController;var HealthController_1=require("./HealthController");exports.HealthHandler=HealthController_1.HealthController;var LoadController_1=require("./LoadController");exports.LoadHandler=LoadController_1.LoadController,exports.ViewHandler=LoadController_1.LoadController,exports.ViewController=LoadController_1.LoadController;var LoadSearchController_1=require("./LoadSearchController");exports.LoadSearchHandler=LoadSearchController_1.LoadSearchController;var LogController_1=require("./LogController");exports.LogHandler=LogController_1.LogController;var LowCodeController_1=require("./LowCodeController");exports.LowCodeHandler=LowCodeController_1.Controller,exports.LowCodeController=LowCodeController_1.Controller;var SearchController_1=require("./SearchController");function allow(r){return function(e,o,l){o.header("Access-Control-Allow-Origin",r.origin),o.header("Access-Control-Allow-Credentials",r.credentials),o.header("Access-Control-Allow-Methods",r.methods),o.setHeader("Access-Control-Allow-Headers",r.headers),l()}}exports.SearchHandler=SearchController_1.SearchController,__export(require("./health")),__export(require("./HealthController")),__export(require("./LogController")),__export(require("./log")),__export(require("./http")),__export(require("./view")),__export(require("./LoadController")),__export(require("./search_func")),__export(require("./search")),__export(require("./SearchController")),__export(require("./LoadSearchController")),__export(require("./resources")),__export(require("./edit")),__export(require("./GenericController")),__export(require("./GenericSearchController")),__export(require("./LowCodeController")),exports.allow=allow;
1
+ "use strict";
2
+ function __export(m) {
3
+ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
4
+ }
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var GenericController_1 = require("./GenericController");
7
+ exports.GenericHandler = GenericController_1.GenericController;
8
+ var GenericSearchController_1 = require("./GenericSearchController");
9
+ exports.GenericSearchHandler = GenericSearchController_1.GenericSearchController;
10
+ var HealthController_1 = require("./HealthController");
11
+ exports.HealthHandler = HealthController_1.HealthController;
12
+ var LoadController_1 = require("./LoadController");
13
+ exports.LoadHandler = LoadController_1.LoadController;
14
+ exports.ViewHandler = LoadController_1.LoadController;
15
+ exports.ViewController = LoadController_1.LoadController;
16
+ var LoadSearchController_1 = require("./LoadSearchController");
17
+ exports.LoadSearchHandler = LoadSearchController_1.LoadSearchController;
18
+ var LogController_1 = require("./LogController");
19
+ exports.LogHandler = LogController_1.LogController;
20
+ var LowCodeController_1 = require("./LowCodeController");
21
+ exports.LowCodeHandler = LowCodeController_1.Controller;
22
+ exports.LowCodeController = LowCodeController_1.Controller;
23
+ var SearchController_1 = require("./SearchController");
24
+ exports.SearchHandler = SearchController_1.SearchController;
25
+ __export(require("./health"));
26
+ __export(require("./client"));
27
+ __export(require("./HealthController"));
28
+ __export(require("./LogController"));
29
+ __export(require("./log"));
30
+ __export(require("./http"));
31
+ __export(require("./view"));
32
+ __export(require("./LoadController"));
33
+ __export(require("./search_func"));
34
+ __export(require("./search"));
35
+ __export(require("./SearchController"));
36
+ __export(require("./LoadSearchController"));
37
+ __export(require("./resources"));
38
+ __export(require("./edit"));
39
+ __export(require("./GenericController"));
40
+ __export(require("./GenericSearchController"));
41
+ __export(require("./LowCodeController"));
42
+ function allow(access) {
43
+ var ao = access.origin;
44
+ if (typeof ao === 'string') {
45
+ return function (req, res, next) {
46
+ res.header('Access-Control-Allow-Origin', access.origin);
47
+ res.header('Access-Control-Allow-Credentials', access.credentials);
48
+ res.header('Access-Control-Allow-Methods', access.methods);
49
+ res.setHeader('Access-Control-Allow-Headers', access.headers);
50
+ next();
51
+ };
52
+ }
53
+ else if (Array.isArray(ao) && ao.length > 0) {
54
+ return function (req, res, next) {
55
+ var origin = req.headers.origin;
56
+ if (origin) {
57
+ if (ao.includes(origin)) {
58
+ res.setHeader('Access-Control-Allow-Origin', origin);
59
+ }
60
+ }
61
+ res.header('Access-Control-Allow-Credentials', access.credentials);
62
+ res.header('Access-Control-Allow-Methods', access.methods);
63
+ res.setHeader('Access-Control-Allow-Headers', access.headers);
64
+ next();
65
+ };
66
+ }
67
+ return function (req, res, next) {
68
+ res.header('Access-Control-Allow-Credentials', access.credentials);
69
+ res.header('Access-Control-Allow-Methods', access.methods);
70
+ res.setHeader('Access-Control-Allow-Headers', access.headers);
71
+ next();
72
+ };
73
+ }
74
+ exports.allow = allow;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-ext",
3
- "version": "0.1.20",
3
+ "version": "0.1.23",
4
4
  "description": "express-ext",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./src/index.ts",
@@ -6,18 +6,21 @@ import {Attribute, Attributes, ErrorMessage} from './metadata';
6
6
  import {resources} from './resources';
7
7
  import {buildAndCheckId, buildId} from './view';
8
8
 
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|ResultInfo<T>>;
9
12
  export interface GenericService<T, ID, R> {
10
13
  metadata?(): Attributes|undefined;
11
14
  load(id: ID, ctx?: any): Promise<T|null>;
12
15
  insert(obj: T, ctx?: any): Promise<R>;
13
16
  update(obj: T, ctx?: any): Promise<R>;
14
- patch?(obj: T, ctx?: any): Promise<R>;
17
+ patch?(obj: Partial<T>, ctx?: any): Promise<R>;
15
18
  delete?(id: ID, ctx?: any): Promise<number>;
16
19
  }
17
20
  export class GenericController<T, ID> extends LoadController<T, ID> {
18
21
  status: StatusConfig;
19
22
  metadata?: Attributes;
20
- constructor(log: Log, public service: GenericService<T, ID, number|ResultInfo<T>>, status?: StatusConfig, public validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>) {
23
+ constructor(log: Log, public service: GenericService<T, ID, number|ResultInfo<T>>, status?: StatusConfig, public validate?: Validate<T>, public build?: Build<T>) {
21
24
  super(log, service);
22
25
  this.status = initializeStatus(status);
23
26
  if (service.metadata) {
@@ -40,18 +43,18 @@ export class GenericController<T, ID> extends LoadController<T, ID> {
40
43
  return this.insert(req, res);
41
44
  }
42
45
  insert(req: Request, res: Response): void {
43
- validateAndCreate(req, res, this.status, this.service.insert, this.log, this.validate);
46
+ validateAndCreate(req, res, this.status, this.service.insert, this.log, this.validate, this.build);
44
47
  }
45
48
  update(req: Request, res: Response): void {
46
49
  const id = buildAndCheckIdWithBody<T, ID, any>(req, res, this.keys, this.service.update);
47
50
  if (id) {
48
- validateAndUpdate(res, this.status, req.body, false, this.service.update, this.log, this.validate);
51
+ validateAndUpdate(res, this.status, req.body, false, this.service.update, this.log, this.validate, this.build);
49
52
  }
50
53
  }
51
54
  patch(req: Request, res: Response): void {
52
55
  const id = buildAndCheckIdWithBody<T, ID, any>(req, res, this.keys, this.service.patch);
53
56
  if (id && this.service.patch) {
54
- validateAndUpdate(res, this.status, req.body, true, this.service.patch, this.log, this.validate);
57
+ validateAndUpdate(res, this.status, req.body, true, this.service.patch, this.log, this.validate, this.build);
55
58
  }
56
59
  }
57
60
  delete(req: Request, res: Response): void {
@@ -67,7 +70,7 @@ export class GenericController<T, ID> extends LoadController<T, ID> {
67
70
  }
68
71
  }
69
72
  }
70
- export function validateAndCreate<T>(req: Request, res: Response, status: StatusConfig, save: (obj: T, ctx?: any) => Promise<number|ResultInfo<T>>, log: Log, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>): void {
73
+ export function validateAndCreate<T>(req: Request, res: Response, status: StatusConfig, save: Save<T>, log: Log, validate?: Validate<T>, build?: Build<T>): void {
71
74
  const obj = req.body;
72
75
  if (!obj || obj === '') {
73
76
  res.status(400).end('The request body cannot be empty.');
@@ -78,6 +81,9 @@ export function validateAndCreate<T>(req: Request, res: Response, status: Status
78
81
  const r: ResultInfo<T> = {status: status.validation_error, errors};
79
82
  res.status(getStatusCode(errors)).json(r).end();
80
83
  } else {
84
+ if (build) {
85
+ build(res, obj, true);
86
+ }
81
87
  create(res, status, obj, save, log);
82
88
  }
83
89
  }).catch(err => handleError(err, res, log));
@@ -86,13 +92,16 @@ export function validateAndCreate<T>(req: Request, res: Response, status: Status
86
92
  }
87
93
  }
88
94
  }
89
- export function validateAndUpdate<T>(res: Response, status: StatusConfig, obj: T, isPatch: boolean, save: (obj: T, ctx?: any) => Promise<number|ResultInfo<T>>, log: Log, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>): void {
95
+ export function validateAndUpdate<T>(res: Response, status: StatusConfig, obj: T, isPatch: boolean, save: Save<T>, log: Log, validate?: Validate<T>, build?: Build<T>): void {
90
96
  if (validate) {
91
97
  validate(obj, isPatch).then(errors => {
92
98
  if (errors && errors.length > 0) {
93
99
  const r: ResultInfo<T> = {status: status.validation_error, errors};
94
100
  res.status(getStatusCode(errors)).json(r).end();
95
101
  } else {
102
+ if (build) {
103
+ build(res, obj, false, isPatch);
104
+ }
96
105
  update(res, status, obj, save, log);
97
106
  }
98
107
  }).catch(err => handleError(err, res, log));
@@ -134,3 +143,69 @@ export function getDeleteStatus(count: number): number {
134
143
  export function getStatusCode(errs: ErrorMessage[]): number {
135
144
  return (isTypeError(errs) ? 400 : 422);
136
145
  }
146
+ export interface ModelConfig {
147
+ id?: string;
148
+ payload?: string;
149
+ user?: string;
150
+ updatedBy?: string;
151
+ updatedAt?: string;
152
+ createdBy?: string;
153
+ createdAt?: string;
154
+ version?: string;
155
+ }
156
+ export function useBuild<T>(c: ModelConfig, generate?: (() => string)): Build<T> {
157
+ const b = new Builder<T>(generate, c.id ? c.id : '', c.payload ? c.payload : '', c.user ? c.user : '', c.updatedBy ? c.updatedBy : '', c.updatedAt ? c.updatedAt : '', c.createdBy ? c.createdBy : '', c.createdAt ? c.createdAt : '', c.version ? c.version : '');
158
+ return b.build;
159
+ }
160
+ export class Builder<T> {
161
+ constructor(public generate: (() => string)|undefined, public id: string, public payload: string, public user: string, public updatedBy: string, public updatedAt: string, public createdBy: string, public createdAt: string, public version: string) {
162
+ this.build = this.build.bind(this);
163
+ }
164
+ build(res: Response, obj: T, isCreate?: boolean, isPatch?: boolean): void {
165
+ let o: any = obj;
166
+ let usr = '';
167
+ if (this.user.length > 0) {
168
+ if (this.payload.length > 0) {
169
+ const payload = res.locals[this.payload];
170
+ if (payload) {
171
+ usr = payload[this.user];
172
+ }
173
+ } else {
174
+ usr = res.locals[this.user];
175
+ }
176
+ }
177
+ if (!usr) {
178
+ usr = '';
179
+ }
180
+ const now = new Date();
181
+ if (isCreate) {
182
+ if (this.generate && this.id.length > 0) {
183
+ o[this.id] = this.generate();
184
+ }
185
+ if (usr.length > 0) {
186
+ if (this.createdAt.length > 0) {
187
+ o[this.createdAt] = now;
188
+ }
189
+ if (this.createdBy.length > 0) {
190
+ o[this.createdBy] = usr;
191
+ }
192
+ }
193
+ if (this.version.length > 0) {
194
+ o[this.version] = 1;
195
+ }
196
+ } else if (isPatch) {
197
+ const keys = Object.keys(o);
198
+ if (keys.length === 0) {
199
+ return;
200
+ }
201
+ }
202
+ if (usr.length > 0) {
203
+ if (this.updatedAt.length > 0) {
204
+ o[this.updatedAt] = now;
205
+ }
206
+ if (this.updatedBy.length > 0) {
207
+ o[this.updatedBy] = usr;
208
+ }
209
+ }
210
+ }
211
+ }
@@ -7,13 +7,14 @@ export interface ViewService<T, ID> {
7
7
  metadata?(): Attributes|undefined;
8
8
  load(id: ID, ctx?: any): Promise<T|null>;
9
9
  }
10
- function getViewFunc<T, ID>(viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T|null>)): (id: ID, ctx?: any) => Promise<T|null> {
10
+ export type Load<T, ID> = ((id: ID, ctx?: any) => Promise<T|null>);
11
+ function getViewFunc<T, ID>(viewService: ViewService<T, ID> | Load<T, ID>): (id: ID, ctx?: any) => Promise<T|null> {
11
12
  if (typeof viewService === 'function') {
12
13
  return viewService;
13
14
  }
14
15
  return viewService.load;
15
16
  }
16
- function getKeysFunc<T, ID>(viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T>), keys?: Attributes|Attribute[]|string[]): Attribute[] | undefined {
17
+ function getKeysFunc<T, ID>(viewService: ViewService<T, ID> | Load<T, ID>, keys?: Attributes|Attribute[]|string[]): Attribute[] | undefined {
17
18
  if (keys) {
18
19
  if (Array.isArray(keys)) {
19
20
  if (keys.length > 0) {
@@ -38,8 +39,8 @@ function getKeysFunc<T, ID>(viewService: ViewService<T, ID> | ((id: ID, ctx?: an
38
39
  }
39
40
  export class LoadController<T, ID> {
40
41
  protected keys?: Attribute[];
41
- protected view: (id: ID, ctx?: any) => Promise<T|null>;
42
- constructor(protected log: Log, viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T|null>), keys?: Attributes|Attribute[]|string[]) {
42
+ protected view: Load<T, ID>;
43
+ constructor(protected log: Log, viewService: ViewService<T, ID> | Load<T, ID>, keys?: Attributes|Attribute[]|string[]) {
43
44
  this.load = this.load.bind(this);
44
45
  this.view = getViewFunc(viewService);
45
46
  this.keys = getKeysFunc(viewService, keys);
package/src/client.ts ADDED
@@ -0,0 +1,69 @@
1
+ import * as http from 'http';
2
+ import * as https from 'https';
3
+ import { AnyMap, HealthChecker } from './health';
4
+
5
+ function getHealthSecure(url: string, timeout: number): Promise<AnyMap> {
6
+ return new Promise((resolve) => {
7
+ https.get(url, { rejectUnauthorized: false }, (res: any) => {
8
+ let data = '';
9
+ res.on('data', (d: any) => {
10
+ data += d;
11
+ });
12
+ res.on('end', () => {
13
+ resolve({ statusCode: res.statusCode, data, statusMessage: res.statusMessage });
14
+ });
15
+ }).on('error', (e: any) => {
16
+ return { statusCode: 500, statusMessage: e };
17
+ });
18
+ setTimeout(() => resolve({ statusCode: 408, statusMessage: 'Time out' }), timeout);
19
+ });
20
+ }
21
+ function getHealth(url: string, timeout: number): Promise<AnyMap> {
22
+ return new Promise((resolve) => {
23
+ http.get(url, (res: any) => {
24
+ let data = '';
25
+ res.on('data', (d: any) => {
26
+ data += d;
27
+ });
28
+ res.on('end', () => {
29
+ resolve({ statusCode: res.statusCode, data, statusMessage: res.statusMessage });
30
+ });
31
+ }).on('error', (e: any) => {
32
+ return { statusCode: 500, statusMessage: e };
33
+ });
34
+ setTimeout(() => resolve({ statusCode: 408, statusMessage: 'Time out' }), timeout);
35
+ });
36
+ }
37
+ export class ClientChecker implements HealthChecker {
38
+ timeout: number;
39
+ constructor(private service: string, private url: string, timeout: number) {
40
+ this.timeout = (timeout ? timeout : 4200);
41
+ this.check = this.check.bind(this);
42
+ this.name = this.name.bind(this);
43
+ this.build = this.build.bind(this);
44
+ }
45
+ check(): Promise<AnyMap> {
46
+ let obj = {} as AnyMap;
47
+ if (this.url.startsWith('https://')) {
48
+ return getHealthSecure(this.url, this.timeout).then(
49
+ r => obj = r
50
+ );
51
+ } else {
52
+ return getHealth(this.url, this.timeout).then(
53
+ r => obj = r
54
+ );
55
+ }
56
+ }
57
+ name(): string {
58
+ return this.service;
59
+ }
60
+ build(data: AnyMap, err: any): AnyMap {
61
+ if (err) {
62
+ if (!data) {
63
+ data = {} as AnyMap;
64
+ }
65
+ data['error'] = err;
66
+ }
67
+ return data;
68
+ }
69
+ }
package/src/index.ts CHANGED
@@ -25,6 +25,7 @@ export {Controller as LowCodeController};
25
25
  export {Service as LowCodeService};
26
26
 
27
27
  export * from './health';
28
+ export * from './client';
28
29
  export * from './HealthController';
29
30
  export * from './LogController';
30
31
  export * from './log';
@@ -43,15 +44,37 @@ export * from './GenericSearchController';
43
44
  export * from './LowCodeController';
44
45
 
45
46
  export interface AccessConfig {
46
- origin: string;
47
- credentials: string;
48
- methods: string;
49
- headers: string;
47
+ origin?: string | string[];
48
+ credentials?: string | string[];
49
+ methods?: string | string[];
50
+ headers: number | string | ReadonlyArray<string>;
50
51
  }
51
52
  export type AccessControlAllowConfig = AccessConfig;
52
53
  export function allow(access: AccessConfig): (req: Request, res: Response, next: NextFunction) => void {
54
+ const ao = access.origin;
55
+ if (typeof ao === 'string') {
56
+ return (req: Request, res: Response, next: NextFunction) => {
57
+ res.header('Access-Control-Allow-Origin', access.origin);
58
+ res.header('Access-Control-Allow-Credentials', access.credentials);
59
+ res.header('Access-Control-Allow-Methods', access.methods);
60
+ res.setHeader('Access-Control-Allow-Headers', access.headers);
61
+ next();
62
+ };
63
+ } else if (Array.isArray(ao) && ao.length > 0) {
64
+ return (req: Request, res: Response, next: NextFunction) => {
65
+ const origin = req.headers.origin;
66
+ if (origin) {
67
+ if (ao.includes(origin)) {
68
+ res.setHeader('Access-Control-Allow-Origin', origin);
69
+ }
70
+ }
71
+ res.header('Access-Control-Allow-Credentials', access.credentials);
72
+ res.header('Access-Control-Allow-Methods', access.methods);
73
+ res.setHeader('Access-Control-Allow-Headers', access.headers);
74
+ next();
75
+ };
76
+ }
53
77
  return (req: Request, res: Response, next: NextFunction) => {
54
- res.header('Access-Control-Allow-Origin', access.origin);
55
78
  res.header('Access-Control-Allow-Credentials', access.credentials);
56
79
  res.header('Access-Control-Allow-Methods', access.methods);
57
80
  res.setHeader('Access-Control-Allow-Headers', access.headers);