@travetto/model 2.1.3 → 2.2.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.
@@ -30,31 +30,32 @@ class $ModelRegistry extends MetadataRegistry<ModelOptions<ModelType>> {
30
30
  * by requested store name. This is the state at the
31
31
  * start of the application.
32
32
  */
33
- intialModelNameMapping = new Map<string, Class[]>();
33
+ initialModelNameMapping = new Map<string, Class[]>();
34
34
 
35
35
  constructor() {
36
36
  // Listen to schema and dependency
37
37
  super(SchemaRegistry, DependencyRegistry);
38
38
  }
39
39
 
40
- getInitialNameMapping() {
41
- if (this.intialModelNameMapping.size === 0) {
40
+ getInitialNameMapping(): Map<string, Class[]> {
41
+ if (this.initialModelNameMapping.size === 0) {
42
42
  for (const cls of this.getClasses()) {
43
43
  const store = this.get(cls).store ?? cls.name;
44
- if (!this.intialModelNameMapping.has(store)) {
45
- this.intialModelNameMapping.set(store, []);
44
+ if (!this.initialModelNameMapping.has(store)) {
45
+ this.initialModelNameMapping.set(store, []);
46
46
  }
47
- this.intialModelNameMapping.get(store)!.push(cls);
47
+ this.initialModelNameMapping.get(store)!.push(cls);
48
48
  }
49
49
  }
50
- return this.intialModelNameMapping;
50
+ return this.initialModelNameMapping;
51
51
  }
52
52
 
53
53
  createPending(cls: Class): Partial<ModelOptions<ModelType>> {
54
54
  return { class: cls, indices: [], autoCreate: true, baseType: cls.ᚕabstract };
55
55
  }
56
56
 
57
- onInstallFinalize(cls: Class) {
57
+ onInstallFinalize(cls: Class): ModelOptions<ModelType> {
58
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
58
59
  const config = this.pending.get(cls.ᚕid)! as ModelOptions<ModelType>;
59
60
 
60
61
  const schema = SchemaRegistry.get(cls);
@@ -68,7 +69,7 @@ class $ModelRegistry extends MetadataRegistry<ModelOptions<ModelType>> {
68
69
  return config;
69
70
  }
70
71
 
71
- override onUninstallFinalize(cls: Class) {
72
+ override onUninstallFinalize(cls: Class): void {
72
73
  this.stores.delete(cls);
73
74
 
74
75
  // Force system to recompute on uninstall
@@ -97,7 +98,7 @@ class $ModelRegistry extends MetadataRegistry<ModelOptions<ModelType>> {
97
98
  /**
98
99
  * Find all classes by their base types
99
100
  */
100
- getAllClassesByBaseType() {
101
+ getAllClassesByBaseType(): Map<Class, Class[]> {
101
102
  if (!this.baseModelGrouped.size) {
102
103
  const out = new Map<Class, Class[]>();
103
104
  for (const el of this.entries.keys()) {
@@ -122,7 +123,7 @@ class $ModelRegistry extends MetadataRegistry<ModelOptions<ModelType>> {
122
123
  /**
123
124
  * Get all classes for a given base type
124
125
  */
125
- getClassesByBaseType(base: Class) {
126
+ getClassesByBaseType(base: Class): Class[] {
126
127
  return this.getAllClassesByBaseType().get(base) ?? [];
127
128
  }
128
129
 
@@ -162,7 +163,7 @@ class $ModelRegistry extends MetadataRegistry<ModelOptions<ModelType>> {
162
163
  * Get Index
163
164
  */
164
165
  getIndex<T extends ModelType, K extends IndexType[]>(cls: Class<T>, name: string, supportedTypes?: K): IndexConfig<T> & { type: K[number] } {
165
- const cfg = this.get(cls).indices?.find(x => x.name === name) as IndexConfig<T>;
166
+ const cfg = this.get(cls).indices?.find((x): x is IndexConfig<T> => x.name === name);
166
167
  if (!cfg) {
167
168
  throw new NotFoundError(`${cls.name} Index`, `${name}`);
168
169
  }
@@ -176,14 +177,14 @@ class $ModelRegistry extends MetadataRegistry<ModelOptions<ModelType>> {
176
177
  * Get Indices
177
178
  */
178
179
  getIndices<T extends ModelType, K extends IndexType[]>(cls: Class<T>, supportedTypes?: K): (IndexConfig<T> & { type: K[number] })[] {
179
- return (this.get(cls).indices ?? []).filter(x => !supportedTypes || supportedTypes.includes(x.type)) as IndexConfig<T>[];
180
+ return (this.get(cls).indices ?? []).filter((x): x is IndexConfig<T> => !supportedTypes || supportedTypes.includes(x.type));
180
181
  }
181
182
 
182
183
  /**
183
184
  * Get expiry field
184
185
  * @param cls
185
186
  */
186
- getExpiry(cls: Class) {
187
+ getExpiry(cls: Class): string {
187
188
  const expiry = this.get(cls).expiresAt;
188
189
  if (!expiry) {
189
190
  throw new AppError(`${cls.name} is not configured with expiry support, please use @ExpiresAt to declare expiration behavior`, 'general');
@@ -22,7 +22,7 @@ export interface ModelBasicSupport<C = unknown> {
22
22
  /**
23
23
  * Create new item
24
24
  * @param item The document to create
25
- * @throws {ExistsError} When an item with the provdided id already exists
25
+ * @throws {ExistsError} When an item with the provided id already exists
26
26
  */
27
27
  create<T extends ModelType>(cls: Class<T>, item: OptionalId<T>): Promise<T>;
28
28
 
@@ -20,11 +20,11 @@ export type BulkOp<T extends ModelType> =
20
20
  /**
21
21
  * Bulk response provides a summary of all the operations
22
22
  */
23
- export interface BulkResponse {
23
+ export interface BulkResponse<E = unknown> {
24
24
  /**
25
25
  * Errors returned
26
26
  */
27
- errors: unknown[];
27
+ errors: E[];
28
28
  /**
29
29
  * Ids that were added
30
30
  */
@@ -45,14 +45,14 @@ export interface BulkResponse {
45
45
  * Bulk processing error
46
46
  */
47
47
  export class BulkProcessError extends AppError {
48
- constructor(public errors: { idx: number, error: Error }[]) {
48
+ constructor(public errors: { idx: number, error: ValidationResultError }[]) {
49
49
  super('Bulk processing errors have occurred', 'data', { errors });
50
50
  }
51
51
 
52
52
  /**
53
53
  * Provide full results back, with validation errors
54
54
  */
55
- override toJSON(extra: Record<string, unknown> = {}) {
55
+ override toJSON(extra: Record<string, unknown> = {}): unknown {
56
56
  return {
57
57
  ...extra,
58
58
  at: new Date(),
@@ -60,7 +60,7 @@ export class BulkProcessError extends AppError {
60
60
  category: this.category,
61
61
  type: this.type,
62
62
  errors: this.errors.map(x => {
63
- const { message, type, errors, payload } = x.error as ValidationResultError;
63
+ const { message, type, errors, payload } = x.error;
64
64
  return { message, type, errors: errors ?? payload, idx: x.idx };
65
65
  })
66
66
  };
@@ -27,7 +27,7 @@ export interface ModelIndexedSupport extends ModelBasicSupport {
27
27
  deleteByIndex<T extends ModelType>(cls: Class<T>, idx: string, body: DeepPartial<T>): Promise<void>;
28
28
 
29
29
  /**
30
- * List entity by rangeable index as defined by fields of idx and the body fields
30
+ * List entity by ranged index as defined by fields of idx and the body fields
31
31
  * @param cls The type to search by
32
32
  * @param idx The index name to search against
33
33
  * @param body The payload of fields needed to search
@@ -1,3 +1,5 @@
1
+ import { Readable } from 'stream';
2
+
1
3
  export interface StreamMeta {
2
4
  /**
3
5
  * File size
@@ -30,13 +32,13 @@ export interface ModelStreamSupport {
30
32
  * @param input The actual stream to write
31
33
  * @param meta The stream metadata
32
34
  */
33
- upsertStream(location: string, input: NodeJS.ReadableStream, meta: StreamMeta): Promise<void>;
35
+ upsertStream(location: string, input: Readable, meta: StreamMeta): Promise<void>;
34
36
 
35
37
  /**
36
38
  * Get stream from asset store
37
39
  * @param location The location of the stream
38
40
  */
39
- getStream(location: string): Promise<NodeJS.ReadableStream>;
41
+ getStream(location: string): Promise<Readable>;
40
42
 
41
43
  /**
42
44
  * Get metadata for stream
@@ -10,14 +10,14 @@ type ServiceClass = { serviceClass: { new(): unknown } };
10
10
  @ModelSuite()
11
11
  export abstract class BaseModelSuite<T> {
12
12
 
13
- static ifNot(pred: (svc: unknown) => boolean) {
13
+ static ifNot(pred: (svc: unknown) => boolean): (x: unknown) => Promise<boolean> {
14
14
  return async (x: unknown) => !pred(new (x as ServiceClass).serviceClass());
15
15
  }
16
16
 
17
17
  serviceClass: Class<T>;
18
18
  configClass: Class;
19
19
 
20
- async getSize<U extends ModelType>(cls: Class<U>) {
20
+ async getSize<U extends ModelType>(cls: Class<U>): Promise<number> {
21
21
  const svc = (await this.service);
22
22
  if (isCrudSupported(svc)) {
23
23
  let i = 0;
@@ -30,7 +30,7 @@ export abstract class BaseModelSuite<T> {
30
30
  }
31
31
  }
32
32
 
33
- async saveAll<M extends ModelType>(cls: Class<M>, items: M[]) {
33
+ async saveAll<M extends ModelType>(cls: Class<M>, items: M[]): Promise<number> {
34
34
  const svc = await this.service;
35
35
  if (isBulkSupported(svc)) {
36
36
  const res = await svc.processBulk(cls, items.map(x => ({ insert: x })));
@@ -47,7 +47,7 @@ export abstract class BaseModelSuite<T> {
47
47
  }
48
48
  }
49
49
 
50
- get service() {
51
- return DependencyRegistry.getInstance(this.serviceClass) as Promise<T>;
50
+ get service(): Promise<T> {
51
+ return DependencyRegistry.getInstance(this.serviceClass);
52
52
  }
53
53
  }
@@ -153,7 +153,7 @@ export abstract class ModelPolymorphismSuite extends BaseModelSuite<ModelCrudSup
153
153
  await assert.rejects(
154
154
  () =>
155
155
  service.upsert(Doctor, Doctor.from({
156
- id: fire.id, name: 'drob', specialty: 'eyes'
156
+ id: fire.id, name: 'gob', specialty: 'eyes'
157
157
  })),
158
158
  e => (e instanceof SubTypeNotSupportedError || e instanceof ExistsError) ? undefined : e
159
159
  );
@@ -165,7 +165,7 @@ export abstract class ModelPolymorphismSuite extends BaseModelSuite<ModelCrudSup
165
165
 
166
166
  try {
167
167
  const res = await service.upsert(Doctor, Doctor.from({
168
- id: doc.id, name: 'drob', specialty: 'eyes'
168
+ id: doc.id, name: 'gob', specialty: 'eyes'
169
169
  }));
170
170
 
171
171
  assert(res.updatedDate!.getTime() > update.getTime());
@@ -174,7 +174,7 @@ export abstract class ModelPolymorphismSuite extends BaseModelSuite<ModelCrudSup
174
174
  }
175
175
 
176
176
  const resAlt = await service.upsert(Worker, Doctor.from({
177
- id: doc.id, name: 'drob', specialty: 'eyes'
177
+ id: doc.id, name: 'gob', specialty: 'eyes'
178
178
  }));
179
179
 
180
180
  assert(resAlt.updatedDate!.getTime() > update.getTime());
@@ -225,8 +225,8 @@ export abstract class ModelPolymorphismSuite extends BaseModelSuite<ModelCrudSup
225
225
  name: 'rob'
226
226
  });
227
227
  assert(res2 instanceof IndexedFirefighter); // If service allows for get by subtype
228
- } catch (e) {
229
- assert(e instanceof SubTypeNotSupportedError || e instanceof NotFoundError); // If it does not
228
+ } catch (err) {
229
+ assert(err instanceof SubTypeNotSupportedError || err instanceof NotFoundError); // If it does not
230
230
  }
231
231
  }
232
232
 
@@ -257,8 +257,8 @@ export abstract class ModelPolymorphismSuite extends BaseModelSuite<ModelCrudSup
257
257
  age: now,
258
258
  name: 'rob'
259
259
  });
260
- } catch (e) {
261
- assert(e instanceof SubTypeNotSupportedError || e instanceof NotFoundError);
260
+ } catch (err) {
261
+ assert(err instanceof SubTypeNotSupportedError || err instanceof NotFoundError);
262
262
  }
263
263
 
264
264
  try {
@@ -266,8 +266,8 @@ export abstract class ModelPolymorphismSuite extends BaseModelSuite<ModelCrudSup
266
266
  age: now,
267
267
  name: 'bob'
268
268
  });
269
- } catch (e) {
270
- assert(e instanceof SubTypeNotSupportedError || e instanceof NotFoundError);
269
+ } catch (err) {
270
+ assert(err instanceof SubTypeNotSupportedError || err instanceof NotFoundError);
271
271
  }
272
272
  }
273
273
  }
@@ -2,6 +2,7 @@ import * as assert from 'assert';
2
2
  import * as fs from 'fs/promises';
3
3
  import { createReadStream } from 'fs';
4
4
  import * as crypto from 'crypto';
5
+ import { Readable } from 'stream';
5
6
 
6
7
  import { PathUtil } from '@travetto/boot';
7
8
  import { BeforeAll, Suite, Test } from '@travetto/test';
@@ -13,7 +14,7 @@ import { ModelStreamSupport } from '../src/service/stream';
13
14
  @Suite()
14
15
  export abstract class ModelStreamSuite extends BaseModelSuite<ModelStreamSupport> {
15
16
 
16
- async getHash(stream: NodeJS.ReadableStream) {
17
+ async getHash(stream: Readable) {
17
18
  const hash = crypto.createHash('sha1');
18
19
  hash.setEncoding('hex');
19
20
  await new Promise((res, rej) => {
@@ -11,7 +11,7 @@ import { ModelRegistry } from '../src/registry/model';
11
11
  const Loaded = Symbol();
12
12
 
13
13
  export function ModelSuite<T extends { configClass: Class<{ autoCreate?: boolean, namespace?: string }>, serviceClass: Class }>(qualifier?: symbol) {
14
- return (target: Class<T>) => {
14
+ return (target: Class<T>): void => {
15
15
  SuiteRegistry.registerPendingListener(
16
16
  target,
17
17
  async function (this: T & { [Loaded]?: boolean }) {