rate-core 0.0.6 → 0.5.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/index.js CHANGED
@@ -1,4 +1,17 @@
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
+ })();
2
15
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
16
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
17
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -40,15 +53,14 @@ function __export(m) {
40
53
  }
41
54
  Object.defineProperty(exports, "__esModule", { value: true });
42
55
  __export(require("./rate"));
43
- var RateService = (function () {
44
- function RateService(find, repository, infoRepository, commentRepository, rateReactionRepository, queryURL) {
56
+ var BaseRateService = (function () {
57
+ function BaseRateService(find, repository, infoRepository, commentRepository, reactionRepository, queryURL) {
45
58
  this.find = find;
46
59
  this.repository = repository;
47
60
  this.infoRepository = infoRepository;
48
61
  this.commentRepository = commentRepository;
49
- this.rateReactionRepository = rateReactionRepository;
62
+ this.reactionRepository = reactionRepository;
50
63
  this.queryURL = queryURL;
51
- this.rate = this.rate.bind(this);
52
64
  this.search = this.search.bind(this);
53
65
  this.load = this.load.bind(this);
54
66
  this.getRate = this.getRate.bind(this);
@@ -60,48 +72,7 @@ var RateService = (function () {
60
72
  this.getComments = this.getComments.bind(this);
61
73
  this.getComment = this.getComment.bind(this);
62
74
  }
63
- RateService.prototype.rate = function (rate) {
64
- return __awaiter(this, void 0, void 0, function () {
65
- var info, r0, exist, r1, sr, history, res;
66
- return __generator(this, function (_a) {
67
- switch (_a.label) {
68
- case 0:
69
- rate.time = new Date();
70
- return [4, this.infoRepository.load(rate.id)];
71
- case 1:
72
- info = _a.sent();
73
- if (!!info) return [3, 3];
74
- return [4, this.repository.insert(rate, true)];
75
- case 2:
76
- r0 = _a.sent();
77
- return [2, r0];
78
- case 3: return [4, this.repository.load(rate.id, rate.author)];
79
- case 4:
80
- exist = _a.sent();
81
- if (!!exist) return [3, 6];
82
- return [4, this.repository.insert(rate)];
83
- case 5:
84
- r1 = _a.sent();
85
- return [2, r1];
86
- case 6:
87
- sr = { review: exist.review, rate: exist.rate, time: exist.time };
88
- if (exist.histories && exist.histories.length > 0) {
89
- history = exist.histories;
90
- history.push(sr);
91
- rate.histories = history;
92
- }
93
- else {
94
- rate.histories = [sr];
95
- }
96
- return [4, this.repository.update(rate, exist.rate)];
97
- case 7:
98
- res = _a.sent();
99
- return [2, res];
100
- }
101
- });
102
- });
103
- };
104
- RateService.prototype.search = function (s, limit, offset, fields) {
75
+ BaseRateService.prototype.search = function (s, limit, offset, fields) {
105
76
  var _this = this;
106
77
  return this.find(s, limit, offset, fields).then(function (res) {
107
78
  if (!_this.queryURL) {
@@ -131,19 +102,19 @@ var RateService = (function () {
131
102
  }
132
103
  });
133
104
  };
134
- RateService.prototype.load = function (id, author) {
105
+ BaseRateService.prototype.load = function (id, author) {
135
106
  return this.repository.load(id, author);
136
107
  };
137
- RateService.prototype.getRate = function (id, author) {
108
+ BaseRateService.prototype.getRate = function (id, author) {
138
109
  return this.repository.load(id, author);
139
110
  };
140
- RateService.prototype.setUseful = function (id, author, userId) {
141
- return this.rateReactionRepository.save(id, author, userId, 1);
111
+ BaseRateService.prototype.setUseful = function (id, author, userId) {
112
+ return this.reactionRepository.save(id, author, userId, 1);
142
113
  };
143
- RateService.prototype.removeUseful = function (id, author, userId) {
144
- return this.rateReactionRepository.remove(id, author, userId);
114
+ BaseRateService.prototype.removeUseful = function (id, author, userId) {
115
+ return this.reactionRepository.remove(id, author, userId);
145
116
  };
146
- RateService.prototype.comment = function (comment) {
117
+ BaseRateService.prototype.comment = function (comment) {
147
118
  var _this = this;
148
119
  return this.repository.load(comment.id, comment.author).then(function (checkRate) {
149
120
  if (!checkRate) {
@@ -155,7 +126,7 @@ var RateService = (function () {
155
126
  }
156
127
  });
157
128
  };
158
- RateService.prototype.removeComment = function (commentId, userId) {
129
+ BaseRateService.prototype.removeComment = function (commentId, userId) {
159
130
  var _this = this;
160
131
  return this.commentRepository.load(commentId).then(function (comment) {
161
132
  if (comment) {
@@ -171,7 +142,7 @@ var RateService = (function () {
171
142
  }
172
143
  });
173
144
  };
174
- RateService.prototype.updateComment = function (comment) {
145
+ BaseRateService.prototype.updateComment = function (comment) {
175
146
  var _this = this;
176
147
  return this.commentRepository.load(comment.commentId).then(function (exist) {
177
148
  if (!exist) {
@@ -195,15 +166,164 @@ var RateService = (function () {
195
166
  }
196
167
  });
197
168
  };
198
- RateService.prototype.getComments = function (id, author, limit) {
199
- return this.commentRepository.getComments(id, author, limit);
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
+ });
200
193
  };
201
- RateService.prototype.getComment = function (id) {
202
- return this.commentRepository.load(id);
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
+ });
203
210
  };
204
- return RateService;
211
+ return BaseRateService;
205
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;
220
+ }
221
+ RateService.prototype.rate = function (rate) {
222
+ return __awaiter(this, void 0, void 0, function () {
223
+ var info, r0, exist, r1, sr, history, res;
224
+ return __generator(this, function (_a) {
225
+ switch (_a.label) {
226
+ case 0:
227
+ rate.time = new Date();
228
+ return [4, this.infoRepository.load(rate.id)];
229
+ case 1:
230
+ info = _a.sent();
231
+ if (!!info) return [3, 3];
232
+ return [4, this.repository.insert(rate, true)];
233
+ case 2:
234
+ r0 = _a.sent();
235
+ return [2, r0];
236
+ case 3: return [4, this.repository.load(rate.id, rate.author)];
237
+ case 4:
238
+ exist = _a.sent();
239
+ if (!!exist) return [3, 6];
240
+ return [4, this.repository.insert(rate)];
241
+ case 5:
242
+ r1 = _a.sent();
243
+ return [2, r1];
244
+ case 6:
245
+ sr = { review: exist.review, rate: exist.rate, time: exist.time };
246
+ if (exist.histories && exist.histories.length > 0) {
247
+ history = exist.histories;
248
+ history.push(sr);
249
+ rate.histories = history;
250
+ }
251
+ else {
252
+ rate.histories = [sr];
253
+ }
254
+ return [4, this.repository.update(rate, exist.rate)];
255
+ case 7:
256
+ res = _a.sent();
257
+ return [2, res];
258
+ }
259
+ });
260
+ });
261
+ };
262
+ return RateService;
263
+ }(BaseRateService));
206
264
  exports.RateService = RateService;
265
+ function avg(n) {
266
+ var sum = 0;
267
+ for (var _i = 0, n_1 = n; _i < n_1.length; _i++) {
268
+ var s = n_1[_i];
269
+ sum = sum + s;
270
+ }
271
+ return sum / n.length;
272
+ }
273
+ exports.avg = avg;
274
+ var RatesService = (function (_super) {
275
+ __extends(RatesService, _super);
276
+ function RatesService(find, repository, infoRepository, commentRepository, reactionRepository, queryURL) {
277
+ var _this = _super.call(this, find, repository, infoRepository, commentRepository, reactionRepository, queryURL) || this;
278
+ _this.rate = _this.rate.bind(_this);
279
+ return _this;
280
+ }
281
+ RatesService.prototype.rate = function (rate) {
282
+ return __awaiter(this, void 0, void 0, function () {
283
+ var info, r0, exist, r1, sr, history, res;
284
+ return __generator(this, function (_a) {
285
+ switch (_a.label) {
286
+ case 0: return [4, this.infoRepository.load(rate.id)];
287
+ case 1:
288
+ info = _a.sent();
289
+ if (rate.rates && rate.rates.length > 0) {
290
+ rate.rate = avg(rate.rates);
291
+ }
292
+ rate.time = new Date();
293
+ if (!!info) return [3, 3];
294
+ return [4, this.repository.insert(rate, true)];
295
+ case 2:
296
+ r0 = _a.sent();
297
+ return [2, r0];
298
+ case 3: return [4, this.repository.load(rate.id, rate.author)];
299
+ case 4:
300
+ exist = _a.sent();
301
+ if (!!exist) return [3, 6];
302
+ return [4, this.repository.insert(rate)];
303
+ case 5:
304
+ r1 = _a.sent();
305
+ return [2, r1];
306
+ case 6:
307
+ sr = { review: exist.review, rates: exist.rates, time: exist.time };
308
+ if (exist.histories && exist.histories.length > 0) {
309
+ history = exist.histories;
310
+ history.push(sr);
311
+ rate.histories = history;
312
+ }
313
+ else {
314
+ rate.histories = [sr];
315
+ }
316
+ return [4, this.repository.update(rate, exist.rate)];
317
+ case 7:
318
+ res = _a.sent();
319
+ return [2, res];
320
+ }
321
+ });
322
+ });
323
+ };
324
+ return RatesService;
325
+ }(BaseRateService));
326
+ exports.RatesService = RatesService;
207
327
  var CommentQuery = (function () {
208
328
  function CommentQuery(find, repository, queryURL) {
209
329
  this.find = find;
@@ -214,10 +334,46 @@ var CommentQuery = (function () {
214
334
  this.getComments = this.getComments.bind(this);
215
335
  }
216
336
  CommentQuery.prototype.load = function (id, ctx) {
217
- return this.repository.load(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
+ });
218
352
  };
219
353
  CommentQuery.prototype.getComments = function (id, author, limit) {
220
- return this.repository.getComments(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
+ });
221
377
  };
222
378
  CommentQuery.prototype.search = function (s, limit, offset, fields) {
223
379
  var _this = this;
package/lib/rate.js CHANGED
@@ -116,3 +116,37 @@ exports.info10Model = {
116
116
  type: 'number',
117
117
  }
118
118
  };
119
+ exports.rateInfoModel = {
120
+ id: {
121
+ key: true
122
+ },
123
+ rate: {
124
+ type: 'number',
125
+ },
126
+ count: {
127
+ type: 'integer',
128
+ },
129
+ score: {
130
+ type: 'number',
131
+ }
132
+ };
133
+ exports.ratesModel = {
134
+ id: {
135
+ key: true,
136
+ match: 'equal'
137
+ },
138
+ author: {
139
+ key: true,
140
+ match: 'equal'
141
+ },
142
+ rate: {
143
+ type: 'number'
144
+ },
145
+ rates: {
146
+ type: 'integers'
147
+ },
148
+ time: {
149
+ type: 'datetime'
150
+ },
151
+ review: {},
152
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rate-core",
3
- "version": "0.0.6",
3
+ "version": "0.5.0",
4
4
  "description": "rate",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./src/index.ts",
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Attributes, Search, SearchResult } from './core';
2
2
  import {
3
- Comment, CommentFilter, InfoRepository, Rate, RateCommentQuery, RateCommentRepository, RateFilter, Rater,
4
- RateReactionRepository, RateRepository, ShortComment, ShortRate
3
+ BaseRate, Comment, CommentFilter, InfoRepository, Rate, RateCommentQuery, RateCommentRepository, RateFilter, Rater, RateReactionRepository, RateRepository,
4
+ Rates, RatesFilter, ShortComment, ShortRate, ShortRates
5
5
  } from './rate';
6
6
 
7
7
  export * from './rate';
@@ -10,14 +10,13 @@ export interface URL {
10
10
  id: string;
11
11
  url: string;
12
12
  }
13
- export class RateService<O> implements Rater {
14
- constructor(protected find: Search<Rate, RateFilter>,
15
- public repository: RateRepository,
16
- private infoRepository: InfoRepository<O>,
17
- private commentRepository: RateCommentRepository,
18
- private rateReactionRepository: RateReactionRepository,
19
- private queryURL?: (ids: string[]) => Promise<URL[]>) {
20
- this.rate = this.rate.bind(this);
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[]>) {
21
20
  this.search = this.search.bind(this);
22
21
  this.load = this.load.bind(this);
23
22
  this.getRate = this.getRate.bind(this);
@@ -29,30 +28,7 @@ export class RateService<O> implements Rater {
29
28
  this.getComments = this.getComments.bind(this);
30
29
  this.getComment = this.getComment.bind(this);
31
30
  }
32
- async rate(rate: Rate): Promise<number> {
33
- rate.time = new Date();
34
- const info = await this.infoRepository.load(rate.id);
35
- if (!info) {
36
- const r0 = await this.repository.insert(rate, true);
37
- return r0;
38
- }
39
- const exist = await this.repository.load(rate.id, rate.author);
40
- if (!exist) {
41
- const r1 = await this.repository.insert(rate);
42
- return r1;
43
- }
44
- const sr: ShortRate = { review: exist.review, rate: exist.rate, time: exist.time };
45
- if (exist.histories && exist.histories.length > 0) {
46
- const history = exist.histories;
47
- history.push(sr);
48
- rate.histories = history;
49
- } else {
50
- rate.histories = [sr];
51
- }
52
- const res = await this.repository.update(rate, exist.rate);
53
- return res;
54
- }
55
- search(s: RateFilter, limit?: number, offset?: number | string, fields?: string[]): Promise<SearchResult<Rate>> {
31
+ search(s: F, limit?: number, offset?: number | string, fields?: string[]): Promise<SearchResult<R>> {
56
32
  return this.find(s, limit, offset, fields).then(res => {
57
33
  if (!this.queryURL) {
58
34
  return res;
@@ -77,17 +53,17 @@ export class RateService<O> implements Rater {
77
53
  }
78
54
  });
79
55
  }
80
- load(id: string, author: string): Promise<Rate | null> {
56
+ load(id: string, author: string): Promise<R | null> {
81
57
  return this.repository.load(id, author);
82
58
  }
83
- getRate(id: string, author: string): Promise<Rate | null> {
59
+ getRate(id: string, author: string): Promise<R | null> {
84
60
  return this.repository.load(id, author);
85
61
  }
86
62
  setUseful(id: string, author: string, userId: string): Promise<number> {
87
- return this.rateReactionRepository.save(id, author, userId, 1);
63
+ return this.reactionRepository.save(id, author, userId, 1);
88
64
  }
89
65
  removeUseful(id: string, author: string, userId: string): Promise<number> {
90
- return this.rateReactionRepository.remove(id, author, userId);
66
+ return this.reactionRepository.remove(id, author, userId);
91
67
  }
92
68
  comment(comment: Comment): Promise<number> {
93
69
  return this.repository.load(comment.id, comment.author).then(checkRate => {
@@ -128,34 +104,174 @@ export class RateService<O> implements Rater {
128
104
  exist.histories = [c];
129
105
  }
130
106
  exist.comment = comment.comment;
131
- const res = this.commentRepository.update(exist);
107
+ const res = this.commentRepository.update(exist);
132
108
  return res;
133
109
  }
134
110
  });
135
111
  }
136
112
  getComments(id: string, author: string, limit?: number): Promise<Comment[]> {
137
- return this.commentRepository.getComments(id, author, limit);
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
+ });
138
132
  }
139
- getComment(id: string): Promise<Comment|null> {
140
- return this.commentRepository.load(id);
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
+ });
141
147
  }
142
148
  }
143
149
  export interface CommentRepository {
144
- load(commentId: string, ctx?: any): Promise<Comment|null>;
150
+ load(commentId: string, ctx?: any): Promise<Comment | null>;
145
151
  getComments(id: string, author: string, limit?: number): Promise<Comment[]>;
146
152
  }
147
153
  // tslint:disable-next-line:max-classes-per-file
154
+ export class RateService<O> extends BaseRateService<Rate, RateFilter, O> implements Rater<Rate, RateFilter> {
155
+ constructor(find: Search<Rate, RateFilter>,
156
+ repository: RateRepository<Rate>,
157
+ infoRepository: InfoRepository<O>,
158
+ commentRepository: RateCommentRepository,
159
+ reactionRepository: RateReactionRepository,
160
+ queryURL?: (ids: string[]) => Promise<URL[]>) {
161
+ super(find, repository, infoRepository, commentRepository, reactionRepository, queryURL);
162
+ this.rate = this.rate.bind(this);
163
+ }
164
+ async rate(rate: Rate): Promise<number> {
165
+ rate.time = new Date();
166
+ const info = await this.infoRepository.load(rate.id);
167
+ if (!info) {
168
+ const r0 = await this.repository.insert(rate, true);
169
+ return r0;
170
+ }
171
+ const exist = await this.repository.load(rate.id, rate.author);
172
+ if (!exist) {
173
+ const r1 = await this.repository.insert(rate);
174
+ return r1;
175
+ }
176
+ const sr: ShortRate = { review: exist.review, rate: exist.rate, time: exist.time };
177
+ if (exist.histories && exist.histories.length > 0) {
178
+ const history = exist.histories;
179
+ history.push(sr);
180
+ rate.histories = history;
181
+ } else {
182
+ rate.histories = [sr];
183
+ }
184
+ const res = await this.repository.update(rate, exist.rate);
185
+ return res;
186
+ }
187
+ }
188
+ export function avg(n: number[]): number {
189
+ let sum = 0;
190
+ for (const s of n) {
191
+ sum = sum + s;
192
+ }
193
+ return sum / n.length;
194
+ }
195
+ // tslint:disable-next-line:max-classes-per-file
196
+ export class RatesService<O> extends BaseRateService<Rates, RatesFilter, O> implements Rater<Rates, RatesFilter> {
197
+ constructor(find: Search<Rates, RatesFilter>,
198
+ repository: RateRepository<Rates>,
199
+ infoRepository: InfoRepository<O>,
200
+ commentRepository: RateCommentRepository,
201
+ reactionRepository: RateReactionRepository,
202
+ queryURL?: (ids: string[]) => Promise<URL[]>) {
203
+ super(find, repository, infoRepository, commentRepository, reactionRepository, queryURL);
204
+ this.rate = this.rate.bind(this);
205
+ }
206
+ async rate(rate: Rates): Promise<number> {
207
+ const info = await this.infoRepository.load(rate.id);
208
+ if (rate.rates && rate.rates.length > 0) {
209
+ rate.rate = avg(rate.rates);
210
+ }
211
+ rate.time = new Date();
212
+ if (!info) {
213
+ const r0 = await this.repository.insert(rate, true);
214
+ return r0;
215
+ }
216
+ const exist = await this.repository.load(rate.id, rate.author);
217
+ if (!exist) {
218
+ const r1 = await this.repository.insert(rate);
219
+ return r1;
220
+ }
221
+ const sr: ShortRates = { review: exist.review, rates: exist.rates, time: exist.time };
222
+ if (exist.histories && exist.histories.length > 0) {
223
+ const history = exist.histories;
224
+ history.push(sr);
225
+ rate.histories = history;
226
+ } else {
227
+ rate.histories = [sr];
228
+ }
229
+ const res = await this.repository.update(rate, exist.rate);
230
+ return res;
231
+ }
232
+ }
233
+ // tslint:disable-next-line:max-classes-per-file
148
234
  export class CommentQuery implements RateCommentQuery {
149
235
  constructor(protected find: Search<Comment, CommentFilter>, protected repository: CommentRepository, private queryURL?: (ids: string[]) => Promise<URL[]>) {
150
236
  this.load = this.load.bind(this);
151
237
  this.search = this.search.bind(this);
152
238
  this.getComments = this.getComments.bind(this);
153
239
  }
154
- load(id: string, ctx?: any): Promise<Comment|null> {
155
- return this.repository.load(id, ctx);
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
+ });
156
254
  }
157
255
  getComments(id: string, author: string, limit?: number): Promise<Comment[]> {
158
- return this.repository.getComments(id, author, limit);
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
+ });
159
275
  }
160
276
  search(s: CommentFilter, limit?: number, offset?: number | string, fields?: string[]): Promise<SearchResult<Comment>> {
161
277
  return this.find(s, limit, offset, fields).then(res => {
@@ -187,16 +303,16 @@ function binarySearch(ar: URL[], el: string): number {
187
303
  let m = 0;
188
304
  let n = ar.length - 1;
189
305
  while (m <= n) {
190
- // tslint:disable-next-line:no-bitwise
191
- const k = (n + m) >> 1;
192
- const cmp = compare(el, ar[k].id);
193
- if (cmp > 0) {
194
- m = k + 1;
195
- } else if (cmp < 0) {
196
- n = k - 1;
197
- } else {
198
- return k;
199
- }
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
+ }
200
316
  }
201
317
  return -m - 1;
202
318
  }
@@ -206,7 +322,7 @@ function compare(s1: string, s2: string): number {
206
322
  interface ErrorMessage {
207
323
  field: string;
208
324
  code: string;
209
- param?: string|number|Date;
325
+ param?: string | number | Date;
210
326
  message?: string;
211
327
  }
212
328
  // tslint:disable-next-line:max-classes-per-file
package/src/rate.ts CHANGED
@@ -4,12 +4,13 @@ export interface RateId {
4
4
  id: string;
5
5
  author: string;
6
6
  }
7
-
8
- export interface Rate {
9
- id: string;
7
+ export interface BaseRate {
10
8
  author: string;
11
9
  authorURL?: string;
12
10
  rate: number;
11
+ }
12
+ export interface Rate extends BaseRate {
13
+ id: string;
13
14
  time: Date;
14
15
  review: string;
15
16
  usefulCount: number;
@@ -30,24 +31,56 @@ export interface RateFilter extends Filter {
30
31
  usefulCount?: number;
31
32
  replyCount?: number;
32
33
  }
33
-
34
- export interface RateRepository {
34
+ export interface RateInfo {
35
+ id: string;
36
+ rate: number;
37
+ count: number;
38
+ score: number;
39
+ }
40
+ export interface ShortRates {
41
+ rates: number[];
42
+ time: Date;
43
+ review: string;
44
+ }
45
+ export interface Rates extends BaseRate {
46
+ id: string;
47
+ rates: number[];
48
+ time: Date;
49
+ review: string;
50
+ usefulCount: number;
51
+ replyCount: number;
52
+ histories?: ShortRates[];
53
+ }
54
+ export interface RatesFilter extends RateFilter {
55
+ rates?: number[];
56
+ rate1: number;
57
+ rate2: number;
58
+ rate3: number;
59
+ rate4: number;
60
+ rate5: number;
61
+ rate6: number;
62
+ rate7: number;
63
+ rate8: number;
64
+ rate9: number;
65
+ rate10: number;
66
+ }
67
+ export interface RateRepository<R> {
35
68
  // save(obj: Rate, info?: T, ctx?: any): Promise<number>;
36
- insert(rate: Rate, newInfo?: boolean): Promise<number>;
37
- update(rate: Rate, oldRate: number): Promise<number>;
38
- load(id: string, author: string): Promise<Rate | null>;
39
- }
40
- export interface Rater {
41
- search(s: RateFilter, limit?: number, offset?: number | string, fields?: string[], ctx?: any): Promise<SearchResult<Rate>>;
42
- load(id: string, author: string): Promise<Rate | null>;
43
- rate(rate: Rate): Promise<number>;
69
+ insert(rate: R, newInfo?: boolean): Promise<number>;
70
+ update(rate: R, oldRate: number): Promise<number>;
71
+ load(id: string, author: string): Promise<R | null>;
72
+ }
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>;
44
77
  setUseful(id: string, author: string, userId: string, ctx?: any): Promise<number>;
45
78
  removeUseful(id: string, author: string, userId: string, ctx?: any): Promise<number>;
46
79
  comment(comment: Comment): Promise<number>;
47
80
  removeComment(id: string, author: string, ctx?: any): Promise<number>;
48
81
  updateComment(comment: Comment): Promise<number>;
49
82
  getComments(id: string, author: string, limit?: number): Promise<Comment[]>;
50
- getComment(id: string): Promise<Comment|null>;
83
+ getComment(id: string): Promise<Comment | null>;
51
84
  }
52
85
  export interface RateReactionRepository {
53
86
  remove(id: string, author: string, userId: string, ctx?: any): Promise<number>;
@@ -60,9 +93,9 @@ export interface RateCommentRepository extends Repository<Comment, string> {
60
93
  }
61
94
 
62
95
  export interface Query<T, ID, S> {
63
- search: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>;
64
- metadata?(): Attributes|undefined;
65
- load(id: ID, ctx?: any): Promise<T|null>;
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>;
66
99
  }
67
100
  export interface RateCommentQuery extends Query<Comment, string, CommentFilter> {
68
101
  getComments(id: string, author: string, limit?: number): Promise<Comment[]>;
@@ -247,3 +280,39 @@ export interface CommentFilter extends Filter {
247
280
  time?: Date;
248
281
  updatedAt?: Date;
249
282
  }
283
+
284
+ export const rateInfoModel: Attributes = {
285
+ id: {
286
+ key: true
287
+ },
288
+ rate: {
289
+ type: 'number',
290
+ },
291
+ count: {
292
+ type: 'integer',
293
+ },
294
+ score: {
295
+ type: 'number',
296
+ }
297
+ };
298
+
299
+ export const ratesModel: Attributes = {
300
+ id: {
301
+ key: true,
302
+ match: 'equal'
303
+ },
304
+ author: {
305
+ key: true,
306
+ match: 'equal'
307
+ },
308
+ rate: {
309
+ type: 'number'
310
+ },
311
+ rates: {
312
+ type: 'integers'
313
+ },
314
+ time: {
315
+ type: 'datetime'
316
+ },
317
+ review: {},
318
+ };