rate-core 0.5.0 → 0.5.3
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/README.md +1 -1
- package/lib/index.js +44 -303
- package/lib/rate.js +1 -0
- package/package.json +1 -1
- package/src/core.ts +0 -74
- package/src/index.ts +38 -266
- package/src/rate.ts +7 -66
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# rate
|
|
1
|
+
# rate-core
|
package/lib/index.js
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
extendStatics(d, b);
|
|
11
|
-
function __() { this.constructor = d; }
|
|
12
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
13
|
-
};
|
|
14
|
-
})();
|
|
15
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
16
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
17
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -53,170 +40,11 @@ function __export(m) {
|
|
|
53
40
|
}
|
|
54
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
42
|
__export(require("./rate"));
|
|
56
|
-
var
|
|
57
|
-
function
|
|
58
|
-
this.find = find;
|
|
43
|
+
var RateService = (function () {
|
|
44
|
+
function RateService(repository, infoRepository) {
|
|
59
45
|
this.repository = repository;
|
|
60
46
|
this.infoRepository = infoRepository;
|
|
61
|
-
this.
|
|
62
|
-
this.reactionRepository = reactionRepository;
|
|
63
|
-
this.queryURL = queryURL;
|
|
64
|
-
this.search = this.search.bind(this);
|
|
65
|
-
this.load = this.load.bind(this);
|
|
66
|
-
this.getRate = this.getRate.bind(this);
|
|
67
|
-
this.setUseful = this.setUseful.bind(this);
|
|
68
|
-
this.removeUseful = this.removeUseful.bind(this);
|
|
69
|
-
this.comment = this.comment.bind(this);
|
|
70
|
-
this.removeComment = this.removeComment.bind(this);
|
|
71
|
-
this.updateComment = this.updateComment.bind(this);
|
|
72
|
-
this.getComments = this.getComments.bind(this);
|
|
73
|
-
this.getComment = this.getComment.bind(this);
|
|
74
|
-
}
|
|
75
|
-
BaseRateService.prototype.search = function (s, limit, offset, fields) {
|
|
76
|
-
var _this = this;
|
|
77
|
-
return this.find(s, limit, offset, fields).then(function (res) {
|
|
78
|
-
if (!_this.queryURL) {
|
|
79
|
-
return res;
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
if (res.list && res.list.length > 0) {
|
|
83
|
-
var ids = [];
|
|
84
|
-
for (var _i = 0, _a = res.list; _i < _a.length; _i++) {
|
|
85
|
-
var rate = _a[_i];
|
|
86
|
-
ids.push(rate.author);
|
|
87
|
-
}
|
|
88
|
-
return _this.queryURL(ids).then(function (urls) {
|
|
89
|
-
for (var _i = 0, _a = res.list; _i < _a.length; _i++) {
|
|
90
|
-
var rate = _a[_i];
|
|
91
|
-
var i = binarySearch(urls, rate.author);
|
|
92
|
-
if (i >= 0) {
|
|
93
|
-
rate.authorURL = urls[i].url;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return res;
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
return res;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
};
|
|
105
|
-
BaseRateService.prototype.load = function (id, author) {
|
|
106
|
-
return this.repository.load(id, author);
|
|
107
|
-
};
|
|
108
|
-
BaseRateService.prototype.getRate = function (id, author) {
|
|
109
|
-
return this.repository.load(id, author);
|
|
110
|
-
};
|
|
111
|
-
BaseRateService.prototype.setUseful = function (id, author, userId) {
|
|
112
|
-
return this.reactionRepository.save(id, author, userId, 1);
|
|
113
|
-
};
|
|
114
|
-
BaseRateService.prototype.removeUseful = function (id, author, userId) {
|
|
115
|
-
return this.reactionRepository.remove(id, author, userId);
|
|
116
|
-
};
|
|
117
|
-
BaseRateService.prototype.comment = function (comment) {
|
|
118
|
-
var _this = this;
|
|
119
|
-
return this.repository.load(comment.id, comment.author).then(function (checkRate) {
|
|
120
|
-
if (!checkRate) {
|
|
121
|
-
return -1;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
comment.time ? comment.time = comment.time : comment.time = new Date();
|
|
125
|
-
return _this.commentRepository.insert(comment);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
};
|
|
129
|
-
BaseRateService.prototype.removeComment = function (commentId, userId) {
|
|
130
|
-
var _this = this;
|
|
131
|
-
return this.commentRepository.load(commentId).then(function (comment) {
|
|
132
|
-
if (comment) {
|
|
133
|
-
if (userId === comment.author || userId === comment.userId) {
|
|
134
|
-
return _this.commentRepository.remove(commentId, comment.id, comment.author);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
return -2;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
return -1;
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
};
|
|
145
|
-
BaseRateService.prototype.updateComment = function (comment) {
|
|
146
|
-
var _this = this;
|
|
147
|
-
return this.commentRepository.load(comment.commentId).then(function (exist) {
|
|
148
|
-
if (!exist) {
|
|
149
|
-
return -1;
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
if (exist.userId !== comment.userId) {
|
|
153
|
-
return -2;
|
|
154
|
-
}
|
|
155
|
-
exist.updatedAt = new Date();
|
|
156
|
-
var c = { comment: exist.comment, time: exist.time };
|
|
157
|
-
if (exist.histories && exist.histories.length > 0) {
|
|
158
|
-
exist.histories.push(c);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
exist.histories = [c];
|
|
162
|
-
}
|
|
163
|
-
exist.comment = comment.comment;
|
|
164
|
-
var res = _this.commentRepository.update(exist);
|
|
165
|
-
return res;
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
};
|
|
169
|
-
BaseRateService.prototype.getComments = function (id, author, limit) {
|
|
170
|
-
var _this = this;
|
|
171
|
-
return this.commentRepository.getComments(id, author, limit).then(function (comments) {
|
|
172
|
-
if (_this.queryURL) {
|
|
173
|
-
var ids = [];
|
|
174
|
-
for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
|
|
175
|
-
var comment = comments_1[_i];
|
|
176
|
-
ids.push(comment.userId);
|
|
177
|
-
}
|
|
178
|
-
return _this.queryURL(ids).then(function (urls) {
|
|
179
|
-
for (var _i = 0, comments_2 = comments; _i < comments_2.length; _i++) {
|
|
180
|
-
var comment = comments_2[_i];
|
|
181
|
-
var i = binarySearch(urls, comment.userId);
|
|
182
|
-
if (i >= 0) {
|
|
183
|
-
comment.userURL = urls[i].url;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return comments;
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
return comments;
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
};
|
|
194
|
-
BaseRateService.prototype.getComment = function (id) {
|
|
195
|
-
var _this = this;
|
|
196
|
-
return this.commentRepository.load(id).then(function (comment) {
|
|
197
|
-
if (comment && _this.queryURL) {
|
|
198
|
-
return _this.queryURL([id]).then(function (urls) {
|
|
199
|
-
var i = binarySearch(urls, comment.userId);
|
|
200
|
-
if (i >= 0) {
|
|
201
|
-
comment.userURL = urls[i].url;
|
|
202
|
-
}
|
|
203
|
-
return comment;
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
return comment;
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
};
|
|
211
|
-
return BaseRateService;
|
|
212
|
-
}());
|
|
213
|
-
exports.BaseRateService = BaseRateService;
|
|
214
|
-
var RateService = (function (_super) {
|
|
215
|
-
__extends(RateService, _super);
|
|
216
|
-
function RateService(find, repository, infoRepository, commentRepository, reactionRepository, queryURL) {
|
|
217
|
-
var _this = _super.call(this, find, repository, infoRepository, commentRepository, reactionRepository, queryURL) || this;
|
|
218
|
-
_this.rate = _this.rate.bind(_this);
|
|
219
|
-
return _this;
|
|
47
|
+
this.rate = this.rate.bind(this);
|
|
220
48
|
}
|
|
221
49
|
RateService.prototype.rate = function (rate) {
|
|
222
50
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -225,7 +53,7 @@ var RateService = (function (_super) {
|
|
|
225
53
|
switch (_a.label) {
|
|
226
54
|
case 0:
|
|
227
55
|
rate.time = new Date();
|
|
228
|
-
return [4, this.infoRepository.
|
|
56
|
+
return [4, this.infoRepository.exist(rate.id)];
|
|
229
57
|
case 1:
|
|
230
58
|
info = _a.sent();
|
|
231
59
|
if (!!info) return [3, 3];
|
|
@@ -260,7 +88,7 @@ var RateService = (function (_super) {
|
|
|
260
88
|
});
|
|
261
89
|
};
|
|
262
90
|
return RateService;
|
|
263
|
-
}(
|
|
91
|
+
}());
|
|
264
92
|
exports.RateService = RateService;
|
|
265
93
|
function avg(n) {
|
|
266
94
|
var sum = 0;
|
|
@@ -271,19 +99,18 @@ function avg(n) {
|
|
|
271
99
|
return sum / n.length;
|
|
272
100
|
}
|
|
273
101
|
exports.avg = avg;
|
|
274
|
-
var RatesService = (function (
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
return _this;
|
|
102
|
+
var RatesService = (function () {
|
|
103
|
+
function RatesService(repository, infoRepository) {
|
|
104
|
+
this.repository = repository;
|
|
105
|
+
this.infoRepository = infoRepository;
|
|
106
|
+
this.rate = this.rate.bind(this);
|
|
280
107
|
}
|
|
281
108
|
RatesService.prototype.rate = function (rate) {
|
|
282
109
|
return __awaiter(this, void 0, void 0, function () {
|
|
283
110
|
var info, r0, exist, r1, sr, history, res;
|
|
284
111
|
return __generator(this, function (_a) {
|
|
285
112
|
switch (_a.label) {
|
|
286
|
-
case 0: return [4, this.infoRepository.
|
|
113
|
+
case 0: return [4, this.infoRepository.exist(rate.id)];
|
|
287
114
|
case 1:
|
|
288
115
|
info = _a.sent();
|
|
289
116
|
if (rate.rates && rate.rates.length > 0) {
|
|
@@ -322,126 +149,8 @@ var RatesService = (function (_super) {
|
|
|
322
149
|
});
|
|
323
150
|
};
|
|
324
151
|
return RatesService;
|
|
325
|
-
}(BaseRateService));
|
|
326
|
-
exports.RatesService = RatesService;
|
|
327
|
-
var CommentQuery = (function () {
|
|
328
|
-
function CommentQuery(find, repository, queryURL) {
|
|
329
|
-
this.find = find;
|
|
330
|
-
this.repository = repository;
|
|
331
|
-
this.queryURL = queryURL;
|
|
332
|
-
this.load = this.load.bind(this);
|
|
333
|
-
this.search = this.search.bind(this);
|
|
334
|
-
this.getComments = this.getComments.bind(this);
|
|
335
|
-
}
|
|
336
|
-
CommentQuery.prototype.load = function (id, ctx) {
|
|
337
|
-
var _this = this;
|
|
338
|
-
return this.repository.load(id, ctx).then(function (comment) {
|
|
339
|
-
if (comment && _this.queryURL) {
|
|
340
|
-
return _this.queryURL([id]).then(function (urls) {
|
|
341
|
-
var i = binarySearch(urls, comment.userId);
|
|
342
|
-
if (i >= 0) {
|
|
343
|
-
comment.userURL = urls[i].url;
|
|
344
|
-
}
|
|
345
|
-
return comment;
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
return comment;
|
|
350
|
-
}
|
|
351
|
-
});
|
|
352
|
-
};
|
|
353
|
-
CommentQuery.prototype.getComments = function (id, author, limit) {
|
|
354
|
-
var _this = this;
|
|
355
|
-
return this.repository.getComments(id, author, limit).then(function (comments) {
|
|
356
|
-
if (_this.queryURL) {
|
|
357
|
-
var ids = [];
|
|
358
|
-
for (var _i = 0, comments_3 = comments; _i < comments_3.length; _i++) {
|
|
359
|
-
var comment = comments_3[_i];
|
|
360
|
-
ids.push(comment.userId);
|
|
361
|
-
}
|
|
362
|
-
return _this.queryURL(ids).then(function (urls) {
|
|
363
|
-
for (var _i = 0, comments_4 = comments; _i < comments_4.length; _i++) {
|
|
364
|
-
var comment = comments_4[_i];
|
|
365
|
-
var i = binarySearch(urls, comment.userId);
|
|
366
|
-
if (i >= 0) {
|
|
367
|
-
comment.userURL = urls[i].url;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
return comments;
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
return comments;
|
|
375
|
-
}
|
|
376
|
-
});
|
|
377
|
-
};
|
|
378
|
-
CommentQuery.prototype.search = function (s, limit, offset, fields) {
|
|
379
|
-
var _this = this;
|
|
380
|
-
return this.find(s, limit, offset, fields).then(function (res) {
|
|
381
|
-
if (!_this.queryURL) {
|
|
382
|
-
return res;
|
|
383
|
-
}
|
|
384
|
-
else {
|
|
385
|
-
if (res.list && res.list.length > 0) {
|
|
386
|
-
var ids = [];
|
|
387
|
-
for (var _i = 0, _a = res.list; _i < _a.length; _i++) {
|
|
388
|
-
var rate = _a[_i];
|
|
389
|
-
ids.push(rate.userId);
|
|
390
|
-
}
|
|
391
|
-
return _this.queryURL(ids).then(function (urls) {
|
|
392
|
-
for (var _i = 0, _a = res.list; _i < _a.length; _i++) {
|
|
393
|
-
var rate = _a[_i];
|
|
394
|
-
var i = binarySearch(urls, rate.userId);
|
|
395
|
-
if (i >= 0) {
|
|
396
|
-
rate.userURL = urls[i].url;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
return res;
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
else {
|
|
403
|
-
return res;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
});
|
|
407
|
-
};
|
|
408
|
-
return CommentQuery;
|
|
409
|
-
}());
|
|
410
|
-
exports.CommentQuery = CommentQuery;
|
|
411
|
-
function binarySearch(ar, el) {
|
|
412
|
-
var m = 0;
|
|
413
|
-
var n = ar.length - 1;
|
|
414
|
-
while (m <= n) {
|
|
415
|
-
var k = (n + m) >> 1;
|
|
416
|
-
var cmp = compare(el, ar[k].id);
|
|
417
|
-
if (cmp > 0) {
|
|
418
|
-
m = k + 1;
|
|
419
|
-
}
|
|
420
|
-
else if (cmp < 0) {
|
|
421
|
-
n = k - 1;
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
return k;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
return -m - 1;
|
|
428
|
-
}
|
|
429
|
-
function compare(s1, s2) {
|
|
430
|
-
return s1.localeCompare(s2);
|
|
431
|
-
}
|
|
432
|
-
var CommentValidator = (function () {
|
|
433
|
-
function CommentValidator(attributes, check) {
|
|
434
|
-
this.attributes = attributes;
|
|
435
|
-
this.check = check;
|
|
436
|
-
this.validate = this.validate.bind(this);
|
|
437
|
-
}
|
|
438
|
-
CommentValidator.prototype.validate = function (comment) {
|
|
439
|
-
var errs = this.check(comment, this.attributes);
|
|
440
|
-
return Promise.resolve(errs);
|
|
441
|
-
};
|
|
442
|
-
return CommentValidator;
|
|
443
152
|
}());
|
|
444
|
-
exports.
|
|
153
|
+
exports.RatesService = RatesService;
|
|
445
154
|
var RateValidator = (function () {
|
|
446
155
|
function RateValidator(attributes, check, max) {
|
|
447
156
|
this.attributes = attributes;
|
|
@@ -468,6 +177,38 @@ var RateValidator = (function () {
|
|
|
468
177
|
return RateValidator;
|
|
469
178
|
}());
|
|
470
179
|
exports.RateValidator = RateValidator;
|
|
180
|
+
var RatesValidator = (function () {
|
|
181
|
+
function RatesValidator(attributes, check, max, length) {
|
|
182
|
+
this.attributes = attributes;
|
|
183
|
+
this.check = check;
|
|
184
|
+
this.max = max;
|
|
185
|
+
this.length = length;
|
|
186
|
+
this.validate = this.validate.bind(this);
|
|
187
|
+
}
|
|
188
|
+
RatesValidator.prototype.validate = function (rate) {
|
|
189
|
+
var errs = this.check(rate, this.attributes);
|
|
190
|
+
if (!rate.rates || rate.rates.length === 0) {
|
|
191
|
+
var err = createError('rates', 'required');
|
|
192
|
+
errs.push(err);
|
|
193
|
+
return Promise.resolve(errs);
|
|
194
|
+
}
|
|
195
|
+
if (rate.rates.length !== this.length) {
|
|
196
|
+
var err = createError('rates', 'length', this.length);
|
|
197
|
+
errs.push(err);
|
|
198
|
+
return Promise.resolve(errs);
|
|
199
|
+
}
|
|
200
|
+
for (var _i = 0, _a = rate.rates; _i < _a.length; _i++) {
|
|
201
|
+
var r = _a[_i];
|
|
202
|
+
if (r > this.max) {
|
|
203
|
+
var err = createError('rates', 'max', this.max);
|
|
204
|
+
errs.push(err);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return Promise.resolve(errs);
|
|
208
|
+
};
|
|
209
|
+
return RatesValidator;
|
|
210
|
+
}());
|
|
211
|
+
exports.RatesValidator = RatesValidator;
|
|
471
212
|
function createError(field, code, param) {
|
|
472
213
|
if (!code) {
|
|
473
214
|
code = 'string';
|
package/lib/rate.js
CHANGED
package/package.json
CHANGED
package/src/core.ts
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
export interface StringMap {
|
|
2
|
-
[key: string]: string;
|
|
3
|
-
}
|
|
4
|
-
export interface Statement {
|
|
5
|
-
query: string;
|
|
6
|
-
params?: any[];
|
|
7
|
-
}
|
|
8
|
-
export interface DB {
|
|
9
|
-
driver: string;
|
|
10
|
-
param(i: number): string;
|
|
11
|
-
exec(sql: string, args?: any[], ctx?: any): Promise<number>;
|
|
12
|
-
execBatch(statements: Statement[], firstSuccess?: boolean, ctx?: any): Promise<number>;
|
|
13
|
-
query<T>(sql: string, args?: any[], m?: StringMap, bools?: Attribute[], ctx?: any): Promise<T[]>;
|
|
14
|
-
}
|
|
15
1
|
export type DataType = 'ObjectId' | 'date' | 'datetime' | 'time'
|
|
16
2
|
| 'boolean' | 'number' | 'integer' | 'string' | 'text'
|
|
17
3
|
| 'object' | 'array' | 'binary'
|
|
@@ -73,63 +59,3 @@ export interface Filter {
|
|
|
73
59
|
pageIndex?: number;
|
|
74
60
|
pageSize?: number;
|
|
75
61
|
}
|
|
76
|
-
export interface ViewRepository<T, ID> {
|
|
77
|
-
metadata?(): Attributes|undefined;
|
|
78
|
-
keys?(): string[];
|
|
79
|
-
all?(ctx?: any): Promise<T[]>;
|
|
80
|
-
load(id: ID, ctx?: any): Promise<T|null>;
|
|
81
|
-
exist?(id: ID, ctx?: any): Promise<boolean>;
|
|
82
|
-
}
|
|
83
|
-
export interface Repository<T, ID> extends ViewRepository<T, ID> {
|
|
84
|
-
insert(obj: T, ctx?: any): Promise<number>;
|
|
85
|
-
update(obj: T, ctx?: any): Promise<number>;
|
|
86
|
-
patch?(obj: T, ctx?: any): Promise<number>;
|
|
87
|
-
save?(obj: T, ctx?: any): Promise<number>;
|
|
88
|
-
delete(id: ID, ctx?: any): Promise<number>;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface ViewService<T, ID> {
|
|
92
|
-
metadata?(): Attributes|undefined;
|
|
93
|
-
keys?(): string[];
|
|
94
|
-
all?(ctx?: any): Promise<T[]>;
|
|
95
|
-
load(id: ID, ctx?: any): Promise<T|null>;
|
|
96
|
-
exist?(id: ID, ctx?: any): Promise<boolean>;
|
|
97
|
-
}
|
|
98
|
-
export interface GenericService<T, ID, R> extends ViewService<T, ID> {
|
|
99
|
-
insert(obj: T, ctx?: any): Promise<R>;
|
|
100
|
-
update(obj: T, ctx?: any): Promise<R>;
|
|
101
|
-
patch?(obj: T, ctx?: any): Promise<R>;
|
|
102
|
-
save?(obj: T, ctx?: any): Promise<R>;
|
|
103
|
-
delete?(id: ID, ctx?: any): Promise<number>;
|
|
104
|
-
}
|
|
105
|
-
export interface SearchResult<T> {
|
|
106
|
-
list: T[];
|
|
107
|
-
total?: number;
|
|
108
|
-
last?: boolean;
|
|
109
|
-
nextPageToken?: string;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export interface ErrorMessage {
|
|
113
|
-
field: string;
|
|
114
|
-
code: string;
|
|
115
|
-
param?: string|number|Date;
|
|
116
|
-
message?: string;
|
|
117
|
-
}
|
|
118
|
-
export interface ResultInfo<T> {
|
|
119
|
-
status: number|string;
|
|
120
|
-
errors?: ErrorMessage[];
|
|
121
|
-
value?: T;
|
|
122
|
-
message?: string;
|
|
123
|
-
}
|
|
124
|
-
export type Result<T> = number | ResultInfo<T>;
|
|
125
|
-
export interface SearchService<T, F extends Filter> {
|
|
126
|
-
keys?(): string[];
|
|
127
|
-
search(s: F, limit?: number, offset?: number|string, fields?: string[], ctx?: any): Promise<SearchResult<T>>;
|
|
128
|
-
}
|
|
129
|
-
export interface GenericSearchService<T, ID, R, F extends Filter>
|
|
130
|
-
extends GenericService<T, ID, R>, SearchService<T, F> {
|
|
131
|
-
}
|
|
132
|
-
export interface Service<T, ID, F extends Filter> extends GenericSearchService<T, ID, Result<T>, F> {
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
export type Search<T, F> = (s: F, limit?: number, offset?: number | string, fields?: string[]) => Promise<SearchResult<T>>;
|
package/src/index.ts
CHANGED
|
@@ -1,169 +1,18 @@
|
|
|
1
|
-
import { Attributes
|
|
2
|
-
import {
|
|
3
|
-
BaseRate, Comment, CommentFilter, InfoRepository, Rate, RateCommentQuery, RateCommentRepository, RateFilter, Rater, RateReactionRepository, RateRepository,
|
|
4
|
-
Rates, RatesFilter, ShortComment, ShortRate, ShortRates
|
|
5
|
-
} from './rate';
|
|
1
|
+
import { Attributes } from './core';
|
|
2
|
+
import { BaseRepository, InfoRepository, Rate, Rater, Rates, ShortRate, ShortRates } from './rate';
|
|
6
3
|
|
|
7
4
|
export * from './rate';
|
|
8
5
|
|
|
9
|
-
export interface URL {
|
|
10
|
-
id: string;
|
|
11
|
-
url: string;
|
|
12
|
-
}
|
|
13
|
-
export class BaseRateService<R extends BaseRate, F, O> {
|
|
14
|
-
constructor(protected find: Search<R, F>,
|
|
15
|
-
public repository: RateRepository<R>,
|
|
16
|
-
protected infoRepository: InfoRepository<O>,
|
|
17
|
-
protected commentRepository: RateCommentRepository,
|
|
18
|
-
protected reactionRepository: RateReactionRepository,
|
|
19
|
-
protected queryURL?: (ids: string[]) => Promise<URL[]>) {
|
|
20
|
-
this.search = this.search.bind(this);
|
|
21
|
-
this.load = this.load.bind(this);
|
|
22
|
-
this.getRate = this.getRate.bind(this);
|
|
23
|
-
this.setUseful = this.setUseful.bind(this);
|
|
24
|
-
this.removeUseful = this.removeUseful.bind(this);
|
|
25
|
-
this.comment = this.comment.bind(this);
|
|
26
|
-
this.removeComment = this.removeComment.bind(this);
|
|
27
|
-
this.updateComment = this.updateComment.bind(this);
|
|
28
|
-
this.getComments = this.getComments.bind(this);
|
|
29
|
-
this.getComment = this.getComment.bind(this);
|
|
30
|
-
}
|
|
31
|
-
search(s: F, limit?: number, offset?: number | string, fields?: string[]): Promise<SearchResult<R>> {
|
|
32
|
-
return this.find(s, limit, offset, fields).then(res => {
|
|
33
|
-
if (!this.queryURL) {
|
|
34
|
-
return res;
|
|
35
|
-
} else {
|
|
36
|
-
if (res.list && res.list.length > 0) {
|
|
37
|
-
const ids: string[] = [];
|
|
38
|
-
for (const rate of res.list) {
|
|
39
|
-
ids.push(rate.author);
|
|
40
|
-
}
|
|
41
|
-
return this.queryURL(ids).then(urls => {
|
|
42
|
-
for (const rate of res.list) {
|
|
43
|
-
const i = binarySearch(urls, rate.author);
|
|
44
|
-
if (i >= 0) {
|
|
45
|
-
rate.authorURL = urls[i].url;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return res;
|
|
49
|
-
});
|
|
50
|
-
} else {
|
|
51
|
-
return res;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
load(id: string, author: string): Promise<R | null> {
|
|
57
|
-
return this.repository.load(id, author);
|
|
58
|
-
}
|
|
59
|
-
getRate(id: string, author: string): Promise<R | null> {
|
|
60
|
-
return this.repository.load(id, author);
|
|
61
|
-
}
|
|
62
|
-
setUseful(id: string, author: string, userId: string): Promise<number> {
|
|
63
|
-
return this.reactionRepository.save(id, author, userId, 1);
|
|
64
|
-
}
|
|
65
|
-
removeUseful(id: string, author: string, userId: string): Promise<number> {
|
|
66
|
-
return this.reactionRepository.remove(id, author, userId);
|
|
67
|
-
}
|
|
68
|
-
comment(comment: Comment): Promise<number> {
|
|
69
|
-
return this.repository.load(comment.id, comment.author).then(checkRate => {
|
|
70
|
-
if (!checkRate) {
|
|
71
|
-
return -1;
|
|
72
|
-
} else {
|
|
73
|
-
comment.time ? comment.time = comment.time : comment.time = new Date();
|
|
74
|
-
return this.commentRepository.insert(comment);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
removeComment(commentId: string, userId: string): Promise<number> {
|
|
79
|
-
return this.commentRepository.load(commentId).then(comment => {
|
|
80
|
-
if (comment) {
|
|
81
|
-
if (userId === comment.author || userId === comment.userId) {
|
|
82
|
-
return this.commentRepository.remove(commentId, comment.id, comment.author);
|
|
83
|
-
} else {
|
|
84
|
-
return -2;
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
return -1;
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
updateComment(comment: Comment): Promise<number> {
|
|
92
|
-
return this.commentRepository.load(comment.commentId).then(exist => {
|
|
93
|
-
if (!exist) {
|
|
94
|
-
return -1;
|
|
95
|
-
} else {
|
|
96
|
-
if (exist.userId !== comment.userId) {
|
|
97
|
-
return -2;
|
|
98
|
-
}
|
|
99
|
-
exist.updatedAt = new Date();
|
|
100
|
-
const c: ShortComment = { comment: exist.comment, time: exist.time };
|
|
101
|
-
if (exist.histories && exist.histories.length > 0) {
|
|
102
|
-
exist.histories.push(c);
|
|
103
|
-
} else {
|
|
104
|
-
exist.histories = [c];
|
|
105
|
-
}
|
|
106
|
-
exist.comment = comment.comment;
|
|
107
|
-
const res = this.commentRepository.update(exist);
|
|
108
|
-
return res;
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
getComments(id: string, author: string, limit?: number): Promise<Comment[]> {
|
|
113
|
-
return this.commentRepository.getComments(id, author, limit).then(comments => {
|
|
114
|
-
if (this.queryURL) {
|
|
115
|
-
const ids: string[] = [];
|
|
116
|
-
for (const comment of comments) {
|
|
117
|
-
ids.push(comment.userId);
|
|
118
|
-
}
|
|
119
|
-
return this.queryURL(ids).then(urls => {
|
|
120
|
-
for (const comment of comments) {
|
|
121
|
-
const i = binarySearch(urls, comment.userId);
|
|
122
|
-
if (i >= 0) {
|
|
123
|
-
comment.userURL = urls[i].url;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return comments;
|
|
127
|
-
});
|
|
128
|
-
} else {
|
|
129
|
-
return comments;
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
getComment(id: string): Promise<Comment | null> {
|
|
134
|
-
return this.commentRepository.load(id).then(comment => {
|
|
135
|
-
if (comment && this.queryURL) {
|
|
136
|
-
return this.queryURL([id]).then(urls => {
|
|
137
|
-
const i = binarySearch(urls, comment.userId);
|
|
138
|
-
if (i >= 0) {
|
|
139
|
-
comment.userURL = urls[i].url;
|
|
140
|
-
}
|
|
141
|
-
return comment;
|
|
142
|
-
});
|
|
143
|
-
} else {
|
|
144
|
-
return comment;
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
export interface CommentRepository {
|
|
150
|
-
load(commentId: string, ctx?: any): Promise<Comment | null>;
|
|
151
|
-
getComments(id: string, author: string, limit?: number): Promise<Comment[]>;
|
|
152
|
-
}
|
|
153
6
|
// tslint:disable-next-line:max-classes-per-file
|
|
154
|
-
export class RateService
|
|
155
|
-
constructor(
|
|
156
|
-
repository:
|
|
157
|
-
infoRepository: InfoRepository
|
|
158
|
-
commentRepository: RateCommentRepository,
|
|
159
|
-
reactionRepository: RateReactionRepository,
|
|
160
|
-
queryURL?: (ids: string[]) => Promise<URL[]>) {
|
|
161
|
-
super(find, repository, infoRepository, commentRepository, reactionRepository, queryURL);
|
|
7
|
+
export class RateService implements Rater<Rate> {
|
|
8
|
+
constructor(
|
|
9
|
+
public repository: BaseRepository<Rate>,
|
|
10
|
+
public infoRepository: InfoRepository) {
|
|
162
11
|
this.rate = this.rate.bind(this);
|
|
163
12
|
}
|
|
164
13
|
async rate(rate: Rate): Promise<number> {
|
|
165
14
|
rate.time = new Date();
|
|
166
|
-
const info = await this.infoRepository.
|
|
15
|
+
const info = await this.infoRepository.exist(rate.id);
|
|
167
16
|
if (!info) {
|
|
168
17
|
const r0 = await this.repository.insert(rate, true);
|
|
169
18
|
return r0;
|
|
@@ -193,18 +42,14 @@ export function avg(n: number[]): number {
|
|
|
193
42
|
return sum / n.length;
|
|
194
43
|
}
|
|
195
44
|
// tslint:disable-next-line:max-classes-per-file
|
|
196
|
-
export class RatesService
|
|
197
|
-
constructor(
|
|
198
|
-
repository:
|
|
199
|
-
infoRepository: InfoRepository
|
|
200
|
-
commentRepository: RateCommentRepository,
|
|
201
|
-
reactionRepository: RateReactionRepository,
|
|
202
|
-
queryURL?: (ids: string[]) => Promise<URL[]>) {
|
|
203
|
-
super(find, repository, infoRepository, commentRepository, reactionRepository, queryURL);
|
|
45
|
+
export class RatesService implements Rater<Rates> {
|
|
46
|
+
constructor(
|
|
47
|
+
public repository: BaseRepository<Rates>,
|
|
48
|
+
public infoRepository: InfoRepository) {
|
|
204
49
|
this.rate = this.rate.bind(this);
|
|
205
50
|
}
|
|
206
51
|
async rate(rate: Rates): Promise<number> {
|
|
207
|
-
const info = await this.infoRepository.
|
|
52
|
+
const info = await this.infoRepository.exist(rate.id);
|
|
208
53
|
if (rate.rates && rate.rates.length > 0) {
|
|
209
54
|
rate.rate = avg(rate.rates);
|
|
210
55
|
}
|
|
@@ -230,95 +75,6 @@ export class RatesService<O> extends BaseRateService<Rates, RatesFilter, O> impl
|
|
|
230
75
|
return res;
|
|
231
76
|
}
|
|
232
77
|
}
|
|
233
|
-
// tslint:disable-next-line:max-classes-per-file
|
|
234
|
-
export class CommentQuery implements RateCommentQuery {
|
|
235
|
-
constructor(protected find: Search<Comment, CommentFilter>, protected repository: CommentRepository, private queryURL?: (ids: string[]) => Promise<URL[]>) {
|
|
236
|
-
this.load = this.load.bind(this);
|
|
237
|
-
this.search = this.search.bind(this);
|
|
238
|
-
this.getComments = this.getComments.bind(this);
|
|
239
|
-
}
|
|
240
|
-
load(id: string, ctx?: any): Promise<Comment | null> {
|
|
241
|
-
return this.repository.load(id, ctx).then(comment => {
|
|
242
|
-
if (comment && this.queryURL) {
|
|
243
|
-
return this.queryURL([id]).then(urls => {
|
|
244
|
-
const i = binarySearch(urls, comment.userId);
|
|
245
|
-
if (i >= 0) {
|
|
246
|
-
comment.userURL = urls[i].url;
|
|
247
|
-
}
|
|
248
|
-
return comment;
|
|
249
|
-
});
|
|
250
|
-
} else {
|
|
251
|
-
return comment;
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
getComments(id: string, author: string, limit?: number): Promise<Comment[]> {
|
|
256
|
-
return this.repository.getComments(id, author, limit).then(comments => {
|
|
257
|
-
if (this.queryURL) {
|
|
258
|
-
const ids: string[] = [];
|
|
259
|
-
for (const comment of comments) {
|
|
260
|
-
ids.push(comment.userId);
|
|
261
|
-
}
|
|
262
|
-
return this.queryURL(ids).then(urls => {
|
|
263
|
-
for (const comment of comments) {
|
|
264
|
-
const i = binarySearch(urls, comment.userId);
|
|
265
|
-
if (i >= 0) {
|
|
266
|
-
comment.userURL = urls[i].url;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
return comments;
|
|
270
|
-
});
|
|
271
|
-
} else {
|
|
272
|
-
return comments;
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
search(s: CommentFilter, limit?: number, offset?: number | string, fields?: string[]): Promise<SearchResult<Comment>> {
|
|
277
|
-
return this.find(s, limit, offset, fields).then(res => {
|
|
278
|
-
if (!this.queryURL) {
|
|
279
|
-
return res;
|
|
280
|
-
} else {
|
|
281
|
-
if (res.list && res.list.length > 0) {
|
|
282
|
-
const ids: string[] = [];
|
|
283
|
-
for (const rate of res.list) {
|
|
284
|
-
ids.push(rate.userId);
|
|
285
|
-
}
|
|
286
|
-
return this.queryURL(ids).then(urls => {
|
|
287
|
-
for (const rate of res.list) {
|
|
288
|
-
const i = binarySearch(urls, rate.userId);
|
|
289
|
-
if (i >= 0) {
|
|
290
|
-
rate.userURL = urls[i].url;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
return res;
|
|
294
|
-
});
|
|
295
|
-
} else {
|
|
296
|
-
return res;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
function binarySearch(ar: URL[], el: string): number {
|
|
303
|
-
let m = 0;
|
|
304
|
-
let n = ar.length - 1;
|
|
305
|
-
while (m <= n) {
|
|
306
|
-
// tslint:disable-next-line:no-bitwise
|
|
307
|
-
const k = (n + m) >> 1;
|
|
308
|
-
const cmp = compare(el, ar[k].id);
|
|
309
|
-
if (cmp > 0) {
|
|
310
|
-
m = k + 1;
|
|
311
|
-
} else if (cmp < 0) {
|
|
312
|
-
n = k - 1;
|
|
313
|
-
} else {
|
|
314
|
-
return k;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
return -m - 1;
|
|
318
|
-
}
|
|
319
|
-
function compare(s1: string, s2: string): number {
|
|
320
|
-
return s1.localeCompare(s2);
|
|
321
|
-
}
|
|
322
78
|
interface ErrorMessage {
|
|
323
79
|
field: string;
|
|
324
80
|
code: string;
|
|
@@ -326,16 +82,6 @@ interface ErrorMessage {
|
|
|
326
82
|
message?: string;
|
|
327
83
|
}
|
|
328
84
|
// tslint:disable-next-line:max-classes-per-file
|
|
329
|
-
export class CommentValidator {
|
|
330
|
-
constructor(protected attributes: Attributes, protected check: (obj: any, attributes: Attributes) => ErrorMessage[]) {
|
|
331
|
-
this.validate = this.validate.bind(this);
|
|
332
|
-
}
|
|
333
|
-
validate(comment: Comment): Promise<ErrorMessage[]> {
|
|
334
|
-
const errs = this.check(comment, this.attributes);
|
|
335
|
-
return Promise.resolve(errs);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
// tslint:disable-next-line:max-classes-per-file
|
|
339
85
|
export class RateValidator {
|
|
340
86
|
constructor(protected attributes: Attributes, protected check: (obj: any, attributes: Attributes) => ErrorMessage[], protected max: number) {
|
|
341
87
|
this.validate = this.validate.bind(this);
|
|
@@ -355,6 +101,32 @@ export class RateValidator {
|
|
|
355
101
|
}
|
|
356
102
|
}
|
|
357
103
|
}
|
|
104
|
+
// tslint:disable-next-line:max-classes-per-file
|
|
105
|
+
export class RatesValidator {
|
|
106
|
+
constructor(protected attributes: Attributes, protected check: (obj: any, attributes: Attributes) => ErrorMessage[], protected max: number, protected length: number) {
|
|
107
|
+
this.validate = this.validate.bind(this);
|
|
108
|
+
}
|
|
109
|
+
validate(rate: Rates): Promise<ErrorMessage[]> {
|
|
110
|
+
const errs = this.check(rate, this.attributes);
|
|
111
|
+
if (!rate.rates || rate.rates.length === 0) {
|
|
112
|
+
const err = createError('rates', 'required');
|
|
113
|
+
errs.push(err);
|
|
114
|
+
return Promise.resolve(errs);
|
|
115
|
+
}
|
|
116
|
+
if (rate.rates.length !== this.length) {
|
|
117
|
+
const err = createError('rates', 'length', this.length);
|
|
118
|
+
errs.push(err);
|
|
119
|
+
return Promise.resolve(errs);
|
|
120
|
+
}
|
|
121
|
+
for (const r of rate.rates) {
|
|
122
|
+
if (r > this.max) {
|
|
123
|
+
const err = createError('rates', 'max', this.max);
|
|
124
|
+
errs.push(err);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return Promise.resolve(errs);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
358
130
|
function createError(field: string, code?: string, param?: string | number | Date): ErrorMessage {
|
|
359
131
|
if (!code) {
|
|
360
132
|
code = 'string';
|
package/src/rate.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Attributes, Filter
|
|
1
|
+
import { Attributes, Filter } from './core';
|
|
2
2
|
|
|
3
3
|
export interface RateId {
|
|
4
4
|
id: string;
|
|
@@ -64,41 +64,14 @@ export interface RatesFilter extends RateFilter {
|
|
|
64
64
|
rate9: number;
|
|
65
65
|
rate10: number;
|
|
66
66
|
}
|
|
67
|
-
export interface
|
|
68
|
-
// save(obj: Rate, info?: T, ctx?: any): Promise<number>;
|
|
67
|
+
export interface BaseRepository<R> {
|
|
69
68
|
insert(rate: R, newInfo?: boolean): Promise<number>;
|
|
70
69
|
update(rate: R, oldRate: number): Promise<number>;
|
|
71
70
|
load(id: string, author: string): Promise<R | null>;
|
|
72
71
|
}
|
|
73
|
-
export interface Rater<R, F extends Filter> {
|
|
74
|
-
search(s: F, limit?: number, offset?: number | string, fields?: string[], ctx?: any): Promise<SearchResult<R>>;
|
|
75
|
-
load(id: string, author: string): Promise<R | null>;
|
|
76
|
-
rate(rate: R): Promise<number>;
|
|
77
|
-
setUseful(id: string, author: string, userId: string, ctx?: any): Promise<number>;
|
|
78
|
-
removeUseful(id: string, author: string, userId: string, ctx?: any): Promise<number>;
|
|
79
|
-
comment(comment: Comment): Promise<number>;
|
|
80
|
-
removeComment(id: string, author: string, ctx?: any): Promise<number>;
|
|
81
|
-
updateComment(comment: Comment): Promise<number>;
|
|
82
|
-
getComments(id: string, author: string, limit?: number): Promise<Comment[]>;
|
|
83
|
-
getComment(id: string): Promise<Comment | null>;
|
|
84
|
-
}
|
|
85
|
-
export interface RateReactionRepository {
|
|
86
|
-
remove(id: string, author: string, userId: string, ctx?: any): Promise<number>;
|
|
87
|
-
save(id: string, author: string, userId: string, type: number): Promise<number>;
|
|
88
|
-
}
|
|
89
72
|
|
|
90
|
-
export interface
|
|
91
|
-
|
|
92
|
-
getComments(id: string, author: string, limit?: number): Promise<Comment[]>;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export interface Query<T, ID, S> {
|
|
96
|
-
search: (s: S, limit?: number, skip?: number | string, fields?: string[]) => Promise<SearchResult<T>>;
|
|
97
|
-
metadata?(): Attributes | undefined;
|
|
98
|
-
load(id: ID, ctx?: any): Promise<T | null>;
|
|
99
|
-
}
|
|
100
|
-
export interface RateCommentQuery extends Query<Comment, string, CommentFilter> {
|
|
101
|
-
getComments(id: string, author: string, limit?: number): Promise<Comment[]>;
|
|
73
|
+
export interface Rater<R> {
|
|
74
|
+
rate(rate: R): Promise<number>;
|
|
102
75
|
}
|
|
103
76
|
export const rateHistoryModel: Attributes = {
|
|
104
77
|
rate: {
|
|
@@ -245,40 +218,8 @@ export interface Info10 {
|
|
|
245
218
|
count: number;
|
|
246
219
|
score: number;
|
|
247
220
|
}
|
|
248
|
-
export interface InfoRepository
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
export interface CommentId {
|
|
252
|
-
id: string;
|
|
253
|
-
author: string;
|
|
254
|
-
userId: string;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export interface Comment {
|
|
258
|
-
commentId: string;
|
|
259
|
-
id: string;
|
|
260
|
-
author: string;
|
|
261
|
-
userId: string;
|
|
262
|
-
comment: string;
|
|
263
|
-
time: Date;
|
|
264
|
-
updatedAt?: Date;
|
|
265
|
-
histories?: ShortComment[];
|
|
266
|
-
userURL?: string;
|
|
267
|
-
authorURL?: string;
|
|
268
|
-
}
|
|
269
|
-
export interface ShortComment {
|
|
270
|
-
comment: string;
|
|
271
|
-
time: Date;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
export interface CommentFilter extends Filter {
|
|
275
|
-
commentId?: string;
|
|
276
|
-
id?: string;
|
|
277
|
-
author?: string;
|
|
278
|
-
userId?: string;
|
|
279
|
-
comment?: string;
|
|
280
|
-
time?: Date;
|
|
281
|
-
updatedAt?: Date;
|
|
221
|
+
export interface InfoRepository {
|
|
222
|
+
exist(id: string, ctx?: any): Promise<boolean>;
|
|
282
223
|
}
|
|
283
224
|
|
|
284
225
|
export const rateInfoModel: Attributes = {
|
|
@@ -295,7 +236,6 @@ export const rateInfoModel: Attributes = {
|
|
|
295
236
|
type: 'number',
|
|
296
237
|
}
|
|
297
238
|
};
|
|
298
|
-
|
|
299
239
|
export const ratesModel: Attributes = {
|
|
300
240
|
id: {
|
|
301
241
|
key: true,
|
|
@@ -309,6 +249,7 @@ export const ratesModel: Attributes = {
|
|
|
309
249
|
type: 'number'
|
|
310
250
|
},
|
|
311
251
|
rates: {
|
|
252
|
+
required: true,
|
|
312
253
|
type: 'integers'
|
|
313
254
|
},
|
|
314
255
|
time: {
|