unconventional 0.0.2 → 0.0.4

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.
Files changed (88) hide show
  1. package/dist/core/abstractbase.controller.d.ts +34 -1
  2. package/dist/core/abstractbase.controller.js +101 -10
  3. package/dist/core/api-error.d.ts +0 -1
  4. package/dist/core/api-error.js +5 -1
  5. package/dist/core/base.cache.d.ts +6 -1
  6. package/dist/core/base.cache.js +31 -14
  7. package/dist/core/base.model.d.ts +0 -1
  8. package/dist/core/base.model.js +51 -46
  9. package/dist/core/base.options.d.ts +12 -1
  10. package/dist/core/base.options.js +2 -1
  11. package/dist/core/base.service.d.ts +46 -1
  12. package/dist/core/base.service.js +82 -30
  13. package/dist/core/index.d.ts +0 -1
  14. package/dist/core/index.js +22 -6
  15. package/dist/core/pg.driver.d.ts +1 -1
  16. package/dist/core/pg.driver.js +6 -1
  17. package/dist/decorators/index.d.ts +0 -1
  18. package/dist/decorators/index.decorator.d.ts +10 -1
  19. package/dist/decorators/index.decorator.js +16 -2
  20. package/dist/decorators/index.js +20 -4
  21. package/dist/decorators/prop.decorator.d.ts +14 -1
  22. package/dist/decorators/prop.decorator.js +19 -1
  23. package/dist/decorators/timestamp.decorator.d.ts +8 -1
  24. package/dist/decorators/timestamp.decorator.js +14 -2
  25. package/dist/decorators/utils.d.ts +5 -1
  26. package/dist/decorators/utils.js +10 -1
  27. package/dist/index.d.ts +0 -1
  28. package/dist/index.js +21 -5
  29. package/dist/server.d.ts +11 -1
  30. package/dist/server.js +30 -10
  31. package/dist/types/api.types.d.ts +0 -1
  32. package/dist/types/api.types.js +11 -8
  33. package/dist/types/db.types.d.ts +0 -1
  34. package/dist/types/db.types.js +10 -7
  35. package/dist/types/decorator.types.d.ts +31 -1
  36. package/dist/types/decorator.types.js +9 -2
  37. package/dist/types/index.d.ts +0 -1
  38. package/dist/types/index.js +20 -4
  39. package/dist/types/server.types.d.ts +0 -1
  40. package/dist/types/server.types.js +2 -1
  41. package/dist/utils/api.utils.d.ts +15 -1
  42. package/dist/utils/api.utils.js +34 -8
  43. package/dist/utils/array.utils.d.ts +2 -1
  44. package/dist/utils/array.utils.js +9 -2
  45. package/dist/utils/cache.utils.d.ts +0 -1
  46. package/dist/utils/cache.utils.js +9 -2
  47. package/dist/utils/crypto.utils.d.ts +1 -1
  48. package/dist/utils/crypto.utils.js +7 -1
  49. package/dist/utils/db.utils.d.ts +5 -1
  50. package/dist/utils/db.utils.js +55 -36
  51. package/dist/utils/function.utils.d.ts +1 -1
  52. package/dist/utils/function.utils.js +6 -3
  53. package/dist/utils/index.d.ts +0 -1
  54. package/dist/utils/index.js +24 -8
  55. package/dist/utils/middleware.utils.d.ts +4 -1
  56. package/dist/utils/middleware.utils.js +9 -1
  57. package/dist/utils/server.utils.d.ts +3 -1
  58. package/dist/utils/server.utils.js +20 -9
  59. package/package.json +1 -1
  60. package/dist/core/abstractbase.controller.d.ts.map +0 -1
  61. package/dist/core/api-error.d.ts.map +0 -1
  62. package/dist/core/base.cache.d.ts.map +0 -1
  63. package/dist/core/base.model.d.ts.map +0 -1
  64. package/dist/core/base.options.d.ts.map +0 -1
  65. package/dist/core/base.service.d.ts.map +0 -1
  66. package/dist/core/index.d.ts.map +0 -1
  67. package/dist/core/pg.driver.d.ts.map +0 -1
  68. package/dist/decorators/index.d.ts.map +0 -1
  69. package/dist/decorators/index.decorator.d.ts.map +0 -1
  70. package/dist/decorators/prop.decorator.d.ts.map +0 -1
  71. package/dist/decorators/timestamp.decorator.d.ts.map +0 -1
  72. package/dist/decorators/utils.d.ts.map +0 -1
  73. package/dist/index.d.ts.map +0 -1
  74. package/dist/server.d.ts.map +0 -1
  75. package/dist/types/api.types.d.ts.map +0 -1
  76. package/dist/types/db.types.d.ts.map +0 -1
  77. package/dist/types/decorator.types.d.ts.map +0 -1
  78. package/dist/types/index.d.ts.map +0 -1
  79. package/dist/types/server.types.d.ts.map +0 -1
  80. package/dist/utils/api.utils.d.ts.map +0 -1
  81. package/dist/utils/array.utils.d.ts.map +0 -1
  82. package/dist/utils/cache.utils.d.ts.map +0 -1
  83. package/dist/utils/crypto.utils.d.ts.map +0 -1
  84. package/dist/utils/db.utils.d.ts.map +0 -1
  85. package/dist/utils/function.utils.d.ts.map +0 -1
  86. package/dist/utils/index.d.ts.map +0 -1
  87. package/dist/utils/middleware.utils.d.ts.map +0 -1
  88. package/dist/utils/server.utils.d.ts.map +0 -1
@@ -10,6 +10,7 @@ export default abstract class AbstractBaseController<M extends typeof BaseModel,
10
10
  protected _pageLimitDefault: number;
11
11
  protected _pageLimitMax: number;
12
12
  protected _options: ControllerOptions;
13
+ /** A controller providing CRUD endpoints for any BaseModel */
13
14
  constructor(model: M, options?: ControllerOptions);
14
15
  create(options?: ControllerMethodOptions<M, E>): BaseHandler<E>;
15
16
  createMany(options?: ControllerMethodOptions<M, E, PI<M>[], I<M>[]>): BaseHandler<E>;
@@ -19,18 +20,50 @@ export default abstract class AbstractBaseController<M extends typeof BaseModel,
19
20
  updateMany(options?: ControllerMethodOptions<M, E, PI<M>[], I<M>[]>): BaseHandler<E>;
20
21
  delete(options?: ControllerMethodOptions<M, E>): BaseHandler<E>;
21
22
  deleteMany(options?: ControllerMethodOptions<M, E, PI<M>[], I<M>[]>): BaseHandler<E>;
23
+ /**
24
+ * Creates and returns a new instance of the model M from the provided data. Request body should be a Partial<InstanceType<M>>.
25
+ * @param req.body - A partial model instance containing all the fields to be modified and their new values.
26
+ */
22
27
  private _create;
28
+ /**
29
+ * Creates and returns an array of new instances of the model M from the provided data. Request body should be a Partial<InstanceType<M>>[].
30
+ * @param req.body - An array of partial model instances containing all the fields to be modified and their new values.
31
+ */
23
32
  private _createMany;
33
+ /** Gets one instance of the model M.
34
+ * @param req.params.id - The id or key of a model. If type is a valid ObjectId, lookup will be done with the model's idColumn. Otherwise, keyColumn is used.
35
+ */
24
36
  private _get;
37
+ /**
38
+ * Gets all instances (paginated) of the model. Supported query params: limit, cursor, sort.
39
+ * Default limit is 12. Max limit is 100.
40
+ */
25
41
  private _getAll;
42
+ /**
43
+ * Patches all fields in an indicated instance of model M. Certain fields may be restricted.
44
+ * @param req.params.id - The id or key of a model. If type is a valid ObjectId, lookup will be done with the model's idColumn. Otherwise, keyColumn is used.
45
+ * @param req.body - A Partial<InstanceType<M>> containing all the fields to be modified and their new values.
46
+ */
26
47
  private _update;
48
+ /**
49
+ * Patches all fields in the array of instances of model M. Certain fields may be restricted.
50
+ * @param req.body - An array of Partial<InstanceType<M>> containing all the fields to be modified and their new values.
51
+ */
27
52
  private _updateMany;
53
+ /**
54
+ * Deletes the model with the given identifier.
55
+ * @param req.params.id - The id or key of a model. If type is a valid ObjectId, lookup will be done with the model's idColumn. Otherwise, keyColumn is used.
56
+ */
28
57
  private _delete;
58
+ /** Deletes models matching the provided filter. */
29
59
  private _deleteMany;
30
60
  protected getRequestContext<T extends PI<M> | PI<M>[] = PI<M>>(ctx: Context<E>, hasBody?: boolean): Promise<RequestContext<M, E, T>>;
61
+ /** Gets the cache namespace for the given request. Route-level cache flags take precedence over controller-level. */
31
62
  protected getCache(ctx: Context, controllerLevel: boolean | undefined, routeLevel: boolean | undefined): KVNamespace | undefined;
63
+ /** Removes the model's private fields from the given response object */
32
64
  protected abstract maskPrivateFields(req: RequestContext<M, E>, response: InstanceType<M> | InstanceType<M>[]): Promise<void>;
65
+ /** Removes the model's uneditable fields from the given request body */
33
66
  protected abstract removeSystemFields<T extends PI<M> | PI<M>[] = PI<M>>(req: RequestContext<M, E, T>): void;
67
+ /** Prevents insecure direct object references (IDOR) */
34
68
  protected abstract preventIDOR<T extends PI<M> | PI<M>[] = PI<M>>(req: RequestContext<M, E, T>): Promise<void>;
35
69
  }
36
- //# sourceMappingURL=abstractbase.controller.d.ts.map
@@ -1,14 +1,20 @@
1
- import { BaseEnvKey, Query } from "../types/api.types";
2
- import BaseService from "./base.service";
3
- export default class AbstractBaseController {
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const api_types_1 = require("../types/api.types");
7
+ const base_service_1 = __importDefault(require("./base.service"));
8
+ class AbstractBaseController {
4
9
  _model;
5
10
  _service;
6
11
  _pageLimitDefault = 12;
7
12
  _pageLimitMax = 100;
8
13
  _options = {};
14
+ /** A controller providing CRUD endpoints for any BaseModel */
9
15
  constructor(model, options) {
10
16
  this._model = model;
11
- this._service = new BaseService(model);
17
+ this._service = new base_service_1.default(model);
12
18
  this._options = options || {};
13
19
  }
14
20
  create(options) { return this._create.bind(this, options); }
@@ -19,17 +25,26 @@ export default class AbstractBaseController {
19
25
  updateMany(options) { return this._updateMany.bind(this, options); }
20
26
  delete(options) { return this._delete.bind(this, options); }
21
27
  deleteMany(options) { return this._deleteMany.bind(this, options); }
28
+ /**
29
+ * Creates and returns a new instance of the model M from the provided data. Request body should be a Partial<InstanceType<M>>.
30
+ * @param req.body - A partial model instance containing all the fields to be modified and their new values.
31
+ */
22
32
  async _create(options, ctx) {
33
+ // Context
23
34
  const reqContext = await this.getRequestContext(ctx);
35
+ // Pre-processing
24
36
  await this.preventIDOR(reqContext);
25
37
  if (options?.before)
26
38
  await options.before(reqContext);
27
- const isPrivileged = ctx.get(BaseEnvKey.isPrivileged);
39
+ const isPrivileged = ctx.get(api_types_1.BaseEnvKey.isPrivileged);
40
+ // Avoid overriding owner field if it's privileged user
28
41
  if (this._model.ownerField && !(reqContext.body[this._model.ownerField] && isPrivileged)) {
29
- const ownerId = ctx.get(BaseEnvKey.ownerId);
42
+ // Add owner
43
+ const ownerId = ctx.get(api_types_1.BaseEnvKey.ownerId);
30
44
  if (ownerId && this._model.ownerField)
31
45
  reqContext.body[this._model.ownerField] = ownerId;
32
46
  }
47
+ // Configure service
33
48
  const config = {
34
49
  cache: this.getCache(ctx, this._options.cache, options?.cache),
35
50
  cacheTTL: this._options.cacheTTL ?? options?.cacheTTL,
@@ -37,24 +52,36 @@ export default class AbstractBaseController {
37
52
  constraint: options?.upsertContraint
38
53
  }
39
54
  };
55
+ // Request
40
56
  let response = await this._service.create(reqContext.body, config);
57
+ // Post-processing
41
58
  if (options?.after)
42
59
  await options.after(reqContext, response);
60
+ // Response
43
61
  return ctx.json(response);
44
62
  }
63
+ /**
64
+ * Creates and returns an array of new instances of the model M from the provided data. Request body should be a Partial<InstanceType<M>>[].
65
+ * @param req.body - An array of partial model instances containing all the fields to be modified and their new values.
66
+ */
45
67
  async _createMany(options, ctx) {
68
+ // Context
46
69
  const reqContext = await this.getRequestContext(ctx);
70
+ // Pre-processing
47
71
  await this.preventIDOR(reqContext);
48
72
  if (options?.before)
49
73
  await options.before(reqContext);
50
- const isPrivileged = ctx.get(BaseEnvKey.isPrivileged);
74
+ const isPrivileged = ctx.get(api_types_1.BaseEnvKey.isPrivileged);
75
+ // Avoid overriding owner field if it's privileged user
51
76
  reqContext.body.forEach(x => {
52
77
  if (this._model.ownerField && !(x[this._model.ownerField] && isPrivileged)) {
53
- const ownerId = ctx.get(BaseEnvKey.ownerId);
78
+ // Add owner
79
+ const ownerId = ctx.get(api_types_1.BaseEnvKey.ownerId);
54
80
  if (ownerId && this._model.ownerField)
55
81
  x[this._model.ownerField] = ownerId;
56
82
  }
57
83
  });
84
+ // Configure service
58
85
  const config = {
59
86
  cache: this.getCache(ctx, this._options.cache, options?.cache),
60
87
  cacheTTL: this._options.cacheTTL ?? options?.cacheTTL,
@@ -62,25 +89,37 @@ export default class AbstractBaseController {
62
89
  constraint: options?.upsertContraint
63
90
  }
64
91
  };
92
+ // Request
65
93
  let response = await this._service.createMany(reqContext.body, config);
94
+ // Post-processing
66
95
  if (options?.after)
67
96
  await options.after(reqContext, response);
97
+ // Response
68
98
  return ctx.json(response);
69
99
  }
100
+ /** Gets one instance of the model M.
101
+ * @param req.params.id - The id or key of a model. If type is a valid ObjectId, lookup will be done with the model's idColumn. Otherwise, keyColumn is used.
102
+ */
70
103
  async _get(options, ctx) {
104
+ // Context
71
105
  const reqContext = await this.getRequestContext(ctx, false);
106
+ // Pre-processing
72
107
  if (options?.before)
73
108
  await options.before(reqContext);
74
109
  const identifier = reqContext.params.id;
110
+ // Configure service
75
111
  const config = {
76
- expand: reqContext.queries[Query.Expand] || undefined,
112
+ expand: reqContext.queries[api_types_1.Query.Expand] || undefined,
77
113
  cache: this.getCache(ctx, this._options.cache, options?.cache),
78
114
  cacheTTL: this._options.cacheTTL ?? options?.cacheTTL
79
115
  };
116
+ // Request
80
117
  let response = await this._service.get(identifier, config);
118
+ // Post-processing
81
119
  if (options?.after)
82
120
  await options.after(reqContext, response);
83
121
  await this.maskPrivateFields(reqContext, response);
122
+ // Download hook
84
123
  if (options?.download) {
85
124
  const downloadRes = await options.download(reqContext, response);
86
125
  const headers = {
@@ -90,89 +129,139 @@ export default class AbstractBaseController {
90
129
  return ctx.body(downloadRes.buffer, 200, headers);
91
130
  }
92
131
  else
132
+ // Response
93
133
  return ctx.json(response);
94
134
  }
135
+ /**
136
+ * Gets all instances (paginated) of the model. Supported query params: limit, cursor, sort.
137
+ * Default limit is 12. Max limit is 100.
138
+ */
95
139
  async _getAll(options, ctx) {
140
+ // Context
96
141
  const reqContext = await this.getRequestContext(ctx, false);
142
+ // Pre-processing
97
143
  if (options?.before)
98
144
  await options.before(reqContext);
145
+ // Configuration
99
146
  const queryParams = reqContext.queries;
100
147
  let limit = parseInt(queryParams.limit) || this._pageLimitDefault;
101
148
  if (limit > this._pageLimitMax && !options?.limitOverride)
102
149
  limit = this._pageLimitMax;
150
+ // Request
103
151
  let response = await this._service.getAll({
104
152
  limit: limit,
105
153
  cursor: queryParams.cursor,
106
154
  sort: queryParams.orderBy,
107
155
  filter: queryParams.filter,
108
- expand: reqContext.queries[Query.Expand] || undefined,
156
+ expand: reqContext.queries[api_types_1.Query.Expand] || undefined,
109
157
  cache: this.getCache(ctx, this._options.cache, options?.cache),
110
158
  cacheTTL: this._options.cacheTTL ?? options?.cacheTTL
111
159
  });
160
+ // Post-processing
112
161
  if (options?.after)
113
162
  await options.after(reqContext, response);
114
163
  await this.maskPrivateFields(reqContext, response);
164
+ // Response
115
165
  return ctx.json(response);
116
166
  }
167
+ /**
168
+ * Patches all fields in an indicated instance of model M. Certain fields may be restricted.
169
+ * @param req.params.id - The id or key of a model. If type is a valid ObjectId, lookup will be done with the model's idColumn. Otherwise, keyColumn is used.
170
+ * @param req.body - A Partial<InstanceType<M>> containing all the fields to be modified and their new values.
171
+ */
117
172
  async _update(options, ctx) {
173
+ // Context
118
174
  const reqContext = await this.getRequestContext(ctx);
175
+ // Pre-processing
119
176
  await this.preventIDOR(reqContext);
120
177
  this.removeSystemFields(reqContext);
121
178
  if (options?.before)
122
179
  await options.before(reqContext);
123
180
  const identifier = reqContext.params.id;
181
+ // Configure service
124
182
  const config = {
125
183
  cache: this.getCache(ctx, this._options.cache, options?.cache),
126
184
  cacheTTL: this._options.cacheTTL ?? options?.cacheTTL
127
185
  };
186
+ // Request
128
187
  let response = await this._service.update(identifier, reqContext.body, config);
188
+ // Post-processing
129
189
  if (options?.after)
130
190
  await options.after(reqContext, response);
191
+ // Response
131
192
  return ctx.json(response);
132
193
  }
194
+ /**
195
+ * Patches all fields in the array of instances of model M. Certain fields may be restricted.
196
+ * @param req.body - An array of Partial<InstanceType<M>> containing all the fields to be modified and their new values.
197
+ */
133
198
  async _updateMany(options, ctx) {
199
+ // Context
134
200
  const reqContext = await this.getRequestContext(ctx);
201
+ // Pre-processing
135
202
  await this.preventIDOR(reqContext);
136
203
  this.removeSystemFields(reqContext);
137
204
  if (options?.before)
138
205
  await options.before(reqContext);
206
+ // Configure service
139
207
  const config = {
140
208
  cache: this.getCache(ctx, this._options.cache, options?.cache),
141
209
  cacheTTL: this._options.cacheTTL ?? options?.cacheTTL
142
210
  };
211
+ // Request
143
212
  let response = await this._service.updateMany(reqContext.body, config);
213
+ // Post-processing
144
214
  if (options?.after)
145
215
  await options.after(reqContext, response);
216
+ // Response
146
217
  return ctx.json(response);
147
218
  }
219
+ /**
220
+ * Deletes the model with the given identifier.
221
+ * @param req.params.id - The id or key of a model. If type is a valid ObjectId, lookup will be done with the model's idColumn. Otherwise, keyColumn is used.
222
+ */
148
223
  async _delete(options, ctx) {
224
+ // Context
149
225
  const reqContext = await this.getRequestContext(ctx);
226
+ // Pre-processing
150
227
  if (options?.before)
151
228
  await options.before(reqContext);
152
229
  const identifier = reqContext.params.id;
230
+ // Configure service
153
231
  const config = {
154
232
  cache: this.getCache(ctx, this._options.cache, options?.cache),
155
233
  cacheTTL: this._options.cacheTTL ?? options?.cacheTTL
156
234
  };
235
+ // Request
157
236
  let response = await this._service.delete(identifier, config);
237
+ // Post-processing
158
238
  if (options?.after)
159
239
  await options.after(reqContext, response);
240
+ // Response
160
241
  return ctx.json({ success: !!response });
161
242
  }
243
+ /** Deletes models matching the provided filter. */
162
244
  async _deleteMany(options, ctx) {
245
+ // Context
163
246
  const reqContext = await this.getRequestContext(ctx);
247
+ // Pre-processing
164
248
  if (options?.before)
165
249
  await options.before(reqContext);
250
+ // Configure service
166
251
  const config = {
167
252
  filter: reqContext.queries.filter,
168
253
  cache: this.getCache(ctx, this._options.cache, options?.cache),
169
254
  cacheTTL: this._options.cacheTTL ?? options?.cacheTTL
170
255
  };
256
+ // Request
171
257
  let response = await this._service.deleteMany(config);
258
+ // Post-processing
172
259
  if (options?.after)
173
260
  await options.after(reqContext, response);
261
+ // Response
174
262
  return ctx.json({ success: !!response });
175
263
  }
264
+ //#region Helpers
176
265
  async getRequestContext(ctx, hasBody = true) {
177
266
  let body = {};
178
267
  if (hasBody) {
@@ -191,8 +280,10 @@ export default class AbstractBaseController {
191
280
  get: (key) => { return ctx.get(key); }
192
281
  };
193
282
  }
283
+ /** Gets the cache namespace for the given request. Route-level cache flags take precedence over controller-level. */
194
284
  getCache(ctx, controllerLevel, routeLevel) {
195
285
  const useCache = routeLevel ?? controllerLevel;
196
286
  return useCache ? ctx.env.CACHE : undefined;
197
287
  }
198
288
  }
289
+ exports.default = AbstractBaseController;
@@ -26,4 +26,3 @@ export declare class APIError extends Error {
26
26
  static errTemporarilyUnavailable(message?: string, data?: any, internalProperties?: any): APIError;
27
27
  static errServerError(data?: any, internalProperties?: any): APIError;
28
28
  }
29
- //# sourceMappingURL=api-error.d.ts.map
@@ -1,4 +1,7 @@
1
- export class APIError extends Error {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.APIError = void 0;
4
+ class APIError extends Error {
2
5
  data;
3
6
  internalProperties;
4
7
  statusCode;
@@ -76,3 +79,4 @@ export class APIError extends Error {
76
79
  return new APIError('Internal Server Error', 'Request could not be carried out.', 500, data, internalProperties);
77
80
  }
78
81
  }
82
+ exports.APIError = APIError;
@@ -5,12 +5,17 @@ export default class BaseCache {
5
5
  static get<T>(cache: KVNamespace, key: string): Promise<T | null>;
6
6
  static set<T>(cache: KVNamespace, key: string, value: T, ttl?: number): Promise<void>;
7
7
  static delete(cache: KVNamespace, key: string): Promise<void>;
8
+ /** Sets a model in the cache. Use @param modifier for non-standard responses. */
8
9
  static setModel<T extends BaseModel>(cache: KVNamespace, model: T, modifier?: object, ttl?: number): Promise<void>;
10
+ /** Gets a model from the cache. Use @param modifier for non-standard lookups. */
9
11
  static getModel<U extends typeof BaseModel>(cache: KVNamespace, model: U, identifier: string | number, modifier?: object): Promise<InstanceType<U> | null>;
12
+ /** Deletes a model from the cache. Deletes all modified versions too. */
10
13
  static clearModel<T extends BaseModel>(cache: KVNamespace, model: T | undefined): Promise<void>;
14
+ /** Sets a page in the cache. Use @param modifier for non-standard responses. */
11
15
  static setPage<T extends BaseModel>(cache: KVNamespace, page: T[], modifier?: object, ttl?: number): Promise<void>;
16
+ /** Gets a page from the cache. Use @param modifier for non-standard lookups. */
12
17
  static getPage<U extends typeof BaseModel>(cache: KVNamespace, model: U, modifier?: object): Promise<InstanceType<U>[] | null>;
18
+ /** Deletes a page from the cache. Deletes all modified versions too. */
13
19
  static clearPage<T extends typeof BaseModel>(cache: KVNamespace, model: T): Promise<void>;
14
20
  private static getModifier;
15
21
  }
16
- //# sourceMappingURL=base.cache.d.ts.map
@@ -1,7 +1,9 @@
1
- import { CachePrefix, DefaultCacheTTL } from "../types/api.types";
2
- import { isEmpty } from "../utils/array.utils";
3
- import { sha256 } from "../utils/crypto.utils";
4
- export default class BaseCache {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const api_types_1 = require("../types/api.types");
4
+ const array_utils_1 = require("../utils/array.utils");
5
+ const crypto_utils_1 = require("../utils/crypto.utils");
6
+ class BaseCache {
5
7
  static kvKeySizeLimit = 512;
6
8
  static async get(cache, key) {
7
9
  if (key.length > this.kvKeySizeLimit)
@@ -11,62 +13,77 @@ export default class BaseCache {
11
13
  return null;
12
14
  return JSON.parse(response);
13
15
  }
14
- static async set(cache, key, value, ttl = DefaultCacheTTL) {
16
+ static async set(cache, key, value, ttl = api_types_1.DefaultCacheTTL) {
15
17
  key.length <= this.kvKeySizeLimit && await cache.put(key, JSON.stringify(value), { expirationTtl: ttl });
16
18
  }
17
19
  static async delete(cache, key) {
18
20
  key.length <= this.kvKeySizeLimit && await cache.delete(key);
19
21
  }
22
+ //#region Model Methods
23
+ /** Sets a model in the cache. Use @param modifier for non-standard responses. */
20
24
  static async setModel(cache, model, modifier, ttl) {
21
25
  const identifier = model?.$id();
22
26
  if (!identifier)
23
27
  return;
24
28
  const modifierTag = await this.getModifier(modifier);
25
- await this.set(cache, `${CachePrefix.Record}${model.constructor.name}:${identifier.toString()}:${modifierTag}`, model, ttl);
29
+ await this.set(cache, `${api_types_1.CachePrefix.Record}${model.constructor.name}:${identifier.toString()}:${modifierTag}`, model, ttl);
26
30
  if (model.$key()) {
27
- await this.set(cache, `${CachePrefix.Record}${model.constructor.name}:${model.$key()}:${modifierTag}`, model, ttl);
31
+ await this.set(cache, `${api_types_1.CachePrefix.Record}${model.constructor.name}:${model.$key()}:${modifierTag}`, model, ttl);
28
32
  }
29
33
  }
34
+ /** Gets a model from the cache. Use @param modifier for non-standard lookups. */
30
35
  static async getModel(cache, model, identifier, modifier) {
31
36
  const modifierTag = await this.getModifier(modifier);
32
- return await this.get(cache, `${CachePrefix.Record}${model.name}:${identifier.toString()}:${modifierTag}`);
37
+ return await this.get(cache, `${api_types_1.CachePrefix.Record}${model.name}:${identifier.toString()}:${modifierTag}`);
33
38
  }
39
+ /** Deletes a model from the cache. Deletes all modified versions too. */
34
40
  static async clearModel(cache, model) {
35
41
  if (!model)
36
42
  return;
37
43
  const identifier = model?.$id();
38
44
  if (!identifier)
39
45
  return;
40
- const idList = await cache.list({ prefix: `${CachePrefix.Record}${model.constructor.name}:${identifier.toString()}` });
46
+ // Delete by ID
47
+ const idList = await cache.list({ prefix: `${api_types_1.CachePrefix.Record}${model.constructor.name}:${identifier.toString()}` });
41
48
  const idPromises = idList.keys.map(async (key) => {
42
49
  await this.delete(cache, key.name);
43
50
  });
51
+ // Delete by Key
44
52
  let keyPromises = [];
45
53
  if (model.$key()) {
46
- const keyList = await cache.list({ prefix: `${CachePrefix.Record}${model.constructor.name}:${model.$key()}` });
54
+ const keyList = await cache.list({ prefix: `${api_types_1.CachePrefix.Record}${model.constructor.name}:${model.$key()}` });
47
55
  keyPromises = keyList.keys.map(async (key) => {
48
56
  await this.delete(cache, key.name);
49
57
  });
50
58
  }
59
+ // Execute
51
60
  await Promise.all([...idPromises, ...keyPromises]);
52
61
  }
62
+ //#endregion
63
+ //#region Page Methods
64
+ /** Sets a page in the cache. Use @param modifier for non-standard responses. */
53
65
  static async setPage(cache, page, modifier, ttl) {
54
66
  if (!page.length)
55
67
  return;
56
68
  const modifierTag = await this.getModifier(modifier);
57
- await this.set(cache, `${CachePrefix.Page}${page[0].constructor.name}:${modifierTag}`, page, ttl);
69
+ await this.set(cache, `${api_types_1.CachePrefix.Page}${page[0].constructor.name}:${modifierTag}`, page, ttl);
58
70
  }
71
+ /** Gets a page from the cache. Use @param modifier for non-standard lookups. */
59
72
  static async getPage(cache, model, modifier) {
60
73
  const modifierTag = await this.getModifier(modifier);
61
- return await this.get(cache, `${CachePrefix.Page}${model.name}:${modifierTag}`);
74
+ return await this.get(cache, `${api_types_1.CachePrefix.Page}${model.name}:${modifierTag}`);
62
75
  }
76
+ /** Deletes a page from the cache. Deletes all modified versions too. */
63
77
  static async clearPage(cache, model) {
64
- const list = await cache.list({ prefix: `${CachePrefix.Page}${model.name}` });
78
+ const list = await cache.list({ prefix: `${api_types_1.CachePrefix.Page}${model.name}` });
65
79
  Promise.all(list.keys.map(async (key) => {
66
80
  await this.delete(cache, key.name);
67
81
  }));
68
82
  }
83
+ //#endregion
84
+ //#region Helpers
69
85
  static async getModifier(modifier) {
70
- return modifier && !isEmpty(modifier) ? await sha256(JSON.stringify(modifier)) : "";
86
+ return modifier && !(0, array_utils_1.isEmpty)(modifier) ? await (0, crypto_utils_1.sha256)(JSON.stringify(modifier)) : "";
71
87
  }
72
88
  }
89
+ exports.default = BaseCache;
@@ -37,4 +37,3 @@ export declare abstract class TimeStamped extends BaseModel {
37
37
  updatedAt?: Date;
38
38
  }
39
39
  export {};
40
- //# sourceMappingURL=base.model.d.ts.map