@travetto/model-query 7.0.0-rc.1 → 7.0.0-rc.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 CHANGED
@@ -235,31 +235,31 @@ class CustomModelService extends QueryModelService implements ModelQueryCrudSupp
235
235
  }
236
236
 
237
237
  @Suite()
238
- export class CustomQuerySuite extends ModelQuerySuite {
238
+ class CustomQuerySuite extends ModelQuerySuite {
239
239
  serviceClass = CustomModelService;
240
240
  configClass = CustomModelConfig;
241
241
  }
242
242
 
243
243
  @Suite()
244
- export class CustomQueryCrudSuite extends ModelQueryCrudSuite {
244
+ class CustomQueryCrudSuite extends ModelQueryCrudSuite {
245
245
  serviceClass = CustomModelService;
246
246
  configClass = CustomModelConfig;
247
247
  }
248
248
 
249
249
  @Suite()
250
- export class CustomQueryFacetSuite extends ModelQueryFacetSuite {
250
+ class CustomQueryFacetSuite extends ModelQueryFacetSuite {
251
251
  serviceClass = CustomModelService;
252
252
  configClass = CustomModelConfig;
253
253
  }
254
254
 
255
255
  @Suite()
256
- export class CustomQueryPolymorphismSuite extends ModelQueryPolymorphismSuite {
256
+ class CustomQueryPolymorphismSuite extends ModelQueryPolymorphismSuite {
257
257
  serviceClass = CustomModelService;
258
258
  configClass = CustomModelConfig;
259
259
  }
260
260
 
261
261
  @Suite()
262
- export class CustomQuerySuggestSuite extends ModelQuerySuggestSuite {
262
+ class CustomQuerySuggestSuite extends ModelQuerySuggestSuite {
263
263
  serviceClass = CustomModelService;
264
264
  configClass = CustomModelConfig;
265
265
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-query",
3
- "version": "7.0.0-rc.1",
3
+ "version": "7.0.0-rc.3",
4
4
  "description": "Datastore abstraction for advanced query support.",
5
5
  "keywords": [
6
6
  "datastore",
@@ -26,12 +26,12 @@
26
26
  "directory": "module/model-query"
27
27
  },
28
28
  "dependencies": {
29
- "@travetto/di": "^7.0.0-rc.1",
30
- "@travetto/model": "^7.0.0-rc.1",
31
- "@travetto/schema": "^7.0.0-rc.1"
29
+ "@travetto/di": "^7.0.0-rc.3",
30
+ "@travetto/model": "^7.0.0-rc.3",
31
+ "@travetto/schema": "^7.0.0-rc.3"
32
32
  },
33
33
  "peerDependencies": {
34
- "@travetto/test": "^7.0.0-rc.1"
34
+ "@travetto/test": "^7.0.0-rc.3"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@travetto/test": {
@@ -1,8 +1,8 @@
1
1
  import { SchemaFieldConfig, Point } from '@travetto/schema';
2
2
  import { Class, toConcrete } from '@travetto/runtime';
3
3
 
4
- const st = (t: string | string[], isArr: boolean = false): Set<string> =>
5
- new Set((Array.isArray(t) ? t : [t]).map(v => isArr ? `${v}[]` : v));
4
+ const st = (value: string | string[], isArray: boolean = false): Set<string> =>
5
+ new Set((Array.isArray(value) ? value : [value]).map(item => isArray ? `${item}[]` : item));
6
6
 
7
7
  const basic = (types: Set<string>): Record<string, Set<string>> => ({ $ne: types, $eq: types, $exists: st('boolean') });
8
8
  const scalar = (types: Set<string>): Record<string, Set<string>> => ({ $in: types, $nin: types });
@@ -16,7 +16,7 @@ const geo = (type: string): Record<string, Set<string>> => ({
16
16
  $geoIntersects: st(type, true)
17
17
  });
18
18
 
19
- const PointImpl = toConcrete<Point>();
19
+ const PointConcrete = toConcrete<Point>();
20
20
 
21
21
  /**
22
22
  * Basic type support
@@ -36,17 +36,17 @@ export class TypeUtil {
36
36
  /**
37
37
  * Get declared type of a given field, only for primitive types
38
38
  */
39
- static getDeclaredType(f: SchemaFieldConfig | Class): keyof typeof TypeUtil.OPERATORS | undefined {
40
- const type = 'type' in f ? f.type : f;
39
+ static getDeclaredType(field: SchemaFieldConfig | Class): keyof typeof TypeUtil.OPERATORS | undefined {
40
+ const type = 'type' in field ? field.type : field;
41
41
  switch (type) {
42
42
  case String: return 'string';
43
43
  case Number: return 'number';
44
44
  case Boolean: return 'boolean';
45
45
  case Date: return 'Date';
46
- case PointImpl: return 'Point';
46
+ case PointConcrete: return 'Point';
47
47
  default: {
48
- if ('type' in f && f.array) {
49
- return this.getDeclaredType(f.type);
48
+ if ('type' in field && field.array) {
49
+ return this.getDeclaredType(field.type);
50
50
  }
51
51
  }
52
52
  }
@@ -55,22 +55,22 @@ export class TypeUtil {
55
55
  /**
56
56
  * Get the actual type of a given field, only for primitive types
57
57
  */
58
- static getActualType(v: unknown): string {
59
- const type = typeof v;
58
+ static getActualType(value: unknown): string {
59
+ const type = typeof value;
60
60
  if (['string', 'number', 'boolean'].includes(type)) {
61
61
  return type;
62
- } else if (v instanceof RegExp) {
62
+ } else if (value instanceof RegExp) {
63
63
  return 'RegExp';
64
- } else if (v instanceof Date) {
64
+ } else if (value instanceof Date) {
65
65
  return 'Date';
66
- } else if (Array.isArray(v)) {
67
- const typeString: string = `${this.getActualType(v[0])}[]`;
68
- if (v.length === 2 && typeString === 'number[]') {
66
+ } else if (Array.isArray(value)) {
67
+ const typeString: string = `${this.getActualType(value[0])}[]`;
68
+ if (value.length === 2 && typeString === 'number[]') {
69
69
  return 'Point';
70
70
  } else {
71
71
  return typeString;
72
72
  }
73
73
  }
74
- throw new Error(`Unknown type for ${v}`);
74
+ throw new Error(`Unknown type for ${value}`);
75
75
  }
76
76
  }
package/src/util/crud.ts CHANGED
@@ -12,15 +12,15 @@ export class ModelQueryCrudUtil {
12
12
  /**
13
13
  * Delete all expired
14
14
  */
15
- static async deleteExpired<T extends ModelType>(svc: ModelQueryCrudSupport & ModelCrudSupport, cls: Class<T>): Promise<number> {
15
+ static async deleteExpired<T extends ModelType>(service: ModelQueryCrudSupport & ModelCrudSupport, cls: Class<T>): Promise<number> {
16
16
  const expiry = await ModelRegistryIndex.getExpiryFieldName(cls);
17
- const res = await svc.deleteByQuery<ModelType>(cls, {
17
+ const count = await service.deleteByQuery<ModelType>(cls, {
18
18
  where: {
19
19
  [expiry]: {
20
20
  $lt: new Date()
21
21
  }
22
22
  }
23
23
  });
24
- return res ?? 0;
24
+ return count ?? 0;
25
25
  }
26
26
  }
package/src/util/query.ts CHANGED
@@ -17,14 +17,14 @@ export class ModelQueryUtil {
17
17
 
18
18
  /**
19
19
  * Resolve comparator
20
- * @param val
20
+ * @param value
21
21
  * @returns
22
22
  */
23
- static resolveComparator(val: unknown): unknown {
24
- if (typeof val === 'string' && TimeUtil.isTimeSpan(val)) {
25
- return TimeUtil.fromNow(val);
23
+ static resolveComparator(value: unknown): unknown {
24
+ if (typeof value === 'string' && TimeUtil.isTimeSpan(value)) {
25
+ return TimeUtil.fromNow(value);
26
26
  } else {
27
- return val;
27
+ return value;
28
28
  }
29
29
  }
30
30
 
@@ -41,9 +41,9 @@ export class ModelQueryUtil {
41
41
  if (requestedId) {
42
42
  throw new NotFoundError(cls, requestedId);
43
43
  } else {
44
- const err = new NotFoundError(cls, 'unknown');
45
- err.message = 'No results found for query';
46
- throw err;
44
+ const error = new NotFoundError(cls, 'unknown');
45
+ error.message = 'No results found for query';
46
+ throw error;
47
47
  }
48
48
  } else {
49
49
  throw new AppError(`Invalid number of results: ${result.length}`, { category: 'data' });
@@ -53,8 +53,8 @@ export class ModelQueryUtil {
53
53
  /**
54
54
  * Get a where clause with type
55
55
  */
56
- static getWhereClause<T extends ModelType>(cls: Class<T>, q: WhereClause<T> | undefined, checkExpiry = true): WhereClause<T> {
57
- const clauses: WhereClauseRaw<T>[] = (q ? [q] : []);
56
+ static getWhereClause<T extends ModelType>(cls: Class<T>, where: WhereClause<T> | undefined, checkExpiry = true): WhereClause<T> {
57
+ const clauses: WhereClauseRaw<T>[] = (where ? [where] : []);
58
58
 
59
59
  const polymorphicConfig = SchemaRegistryIndex.getDiscriminatedConfig(cls);
60
60
  if (polymorphicConfig) {
@@ -66,28 +66,28 @@ export class ModelQueryUtil {
66
66
  ));
67
67
  }
68
68
 
69
- const conf = ModelRegistryIndex.getConfig(cls);
70
- if (checkExpiry && conf.expiresAt) {
69
+ const indexConfig = ModelRegistryIndex.getConfig(cls);
70
+ if (checkExpiry && indexConfig.expiresAt) {
71
71
  clauses.push(castTo({
72
72
  $or: [
73
- { [conf.expiresAt]: { $exists: false } },
74
- { [conf.expiresAt]: undefined },
75
- { [conf.expiresAt]: { $gte: new Date() } },
73
+ { [indexConfig.expiresAt]: { $exists: false } },
74
+ { [indexConfig.expiresAt]: undefined },
75
+ { [indexConfig.expiresAt]: { $gte: new Date() } },
76
76
  ]
77
77
  }));
78
78
  }
79
79
  if (clauses.length > 1) {
80
- q = { $and: clauses };
80
+ where = { $and: clauses };
81
81
  } else {
82
- q = clauses[0];
82
+ where = clauses[0];
83
83
  }
84
- return q!;
84
+ return where!;
85
85
  }
86
86
 
87
- static has$And = (o: unknown): o is ({ $and: WhereClause<unknown>[] }) =>
88
- !!o && typeof o === 'object' && '$and' in o;
89
- static has$Or = (o: unknown): o is ({ $or: WhereClause<unknown>[] }) =>
90
- !!o && typeof o === 'object' && '$or' in o;
91
- static has$Not = (o: unknown): o is ({ $not: WhereClause<unknown> }) =>
92
- !!o && typeof o === 'object' && '$not' in o;
87
+ static has$And = (value: unknown): value is ({ $and: WhereClause<unknown>[] }) =>
88
+ !!value && typeof value === 'object' && '$and' in value;
89
+ static has$Or = (value: unknown): value is ({ $or: WhereClause<unknown>[] }) =>
90
+ !!value && typeof value === 'object' && '$or' in value;
91
+ static has$Not = (value: unknown): value is ({ $not: WhereClause<unknown> }) =>
92
+ !!value && typeof value === 'object' && '$not' in value;
93
93
  }
@@ -75,18 +75,18 @@ export class ModelQuerySuggestUtil {
75
75
  const pattern = this.getSuggestRegex(prefix);
76
76
 
77
77
  const out: ([string, U] | readonly [string, U])[] = [];
78
- for (const r of results) {
79
- const val = r[field];
80
- if (Array.isArray(val)) {
81
- out.push(...val.filter(f => pattern.test(f)).map((f: string) => [f, transform(f, r)] as const));
82
- } else if (typeof val === 'string') {
83
- out.push([val, transform(val, r)]);
78
+ for (const result of results) {
79
+ const resultValue = result[field];
80
+ if (Array.isArray(resultValue)) {
81
+ out.push(...resultValue.filter(item => pattern.test(item)).map((item: string) => [item, transform(item, result)] as const));
82
+ } else if (typeof resultValue === 'string') {
83
+ out.push([resultValue, transform(resultValue, result)]);
84
84
  }
85
85
  }
86
86
  return out
87
87
  .toSorted((a, b) => a[0].localeCompare(b[0]))
88
88
  .map((a) => a[1])
89
- .filter((x, i, arr) => x !== arr[i - 1])
89
+ .filter((result, i, arr) => result !== arr[i - 1])
90
90
  .slice(0, limit ?? 10);
91
91
  }
92
92
 
package/src/verifier.ts CHANGED
@@ -12,7 +12,7 @@ interface State {
12
12
  path: string;
13
13
  collect(element: string, message: string): void;
14
14
  extend(path: string): State;
15
- log(err: string): void;
15
+ log(error: string): void;
16
16
  }
17
17
 
18
18
  interface ProcessingHandler {
@@ -51,19 +51,19 @@ export class QueryVerifier {
51
51
  /**
52
52
  * Handle generic clauses
53
53
  */
54
- static processGenericClause<T>(state: State, cls: Class<T>, val: object, handler: ProcessingHandler): void {
54
+ static processGenericClause<T>(state: State, cls: Class<T>, clause: object, handler: ProcessingHandler): void {
55
55
  const view = SchemaRegistryIndex.getConfig(cls).fields;
56
56
 
57
- if (val === undefined || val === null) {
57
+ if (clause === undefined || clause === null) {
58
58
  state.log('Value cannot be undefined or null');
59
59
  return;
60
60
  }
61
61
 
62
- if (handler.preMember && handler.preMember(state, val)) {
62
+ if (handler.preMember && handler.preMember(state, clause)) {
63
63
  return;
64
64
  }
65
65
 
66
- for (const [key, value] of Object.entries(val)) {
66
+ for (const [key, value] of Object.entries(clause)) {
67
67
 
68
68
  // Validate value is correct, and key is valid
69
69
  if (value === undefined || value === null) {
@@ -82,19 +82,19 @@ export class QueryVerifier {
82
82
 
83
83
  // Find field
84
84
  const field = view[key];
85
- const op = TypeUtil.getDeclaredType(field);
85
+ const type = TypeUtil.getDeclaredType(field);
86
86
 
87
87
  // If a simple operation
88
- if (op) {
89
- handler.onSimpleType(state.extend(key), op, value, field.array ?? false);
88
+ if (type) {
89
+ handler.onSimpleType(state.extend(key), type, value, field.array ?? false);
90
90
  } else {
91
91
  // Otherwise recurse
92
92
  const subCls = field.type;
93
- const subVal = value;
94
- if (handler.onComplexType && handler.onComplexType(state, subCls, subVal, field.array ?? false)) {
93
+ const subValue = value;
94
+ if (handler.onComplexType && handler.onComplexType(state, subCls, subValue, field.array ?? false)) {
95
95
  continue;
96
96
  }
97
- this.processGenericClause(state.extend(key), subCls, subVal, handler);
97
+ this.processGenericClause(state.extend(key), subCls, subValue, handler);
98
98
  }
99
99
  }
100
100
  }
@@ -113,8 +113,8 @@ export class QueryVerifier {
113
113
  if (isArray) {
114
114
  if (Array.isArray(value)) {
115
115
  // Handle array literal
116
- for (const el of value) {
117
- this.checkOperatorClause(state, declaredType, el, allowed, false);
116
+ for (const item of value) {
117
+ this.checkOperatorClause(state, declaredType, item, allowed, false);
118
118
  }
119
119
  return;
120
120
  }
@@ -141,30 +141,30 @@ export class QueryVerifier {
141
141
  }
142
142
 
143
143
  // Should only be one?
144
- for (const [k, v] of Object.entries(value)) {
145
- if (k === '$all' || k === '$elemMatch' || k === '$in' || k === '$nin') {
146
- if (!Array.isArray(v)) {
147
- state.log(`${k} operator requires comparison to be an array, not ${typeof v}`);
144
+ for (const [key, keyValue] of Object.entries(value)) {
145
+ if (key === '$all' || key === '$elemMatch' || key === '$in' || key === '$nin') {
146
+ if (!Array.isArray(keyValue)) {
147
+ state.log(`${key} operator requires comparison to be an array, not ${typeof keyValue}`);
148
148
  return;
149
- } else if (v.length === 0) {
150
- state.log(`${k} operator requires comparison to be a non-empty array`);
149
+ } else if (keyValue.length === 0) {
150
+ state.log(`${key} operator requires comparison to be a non-empty array`);
151
151
  return;
152
152
  }
153
153
 
154
- for (const el of v) {
155
- const elAct = TypeUtil.getActualType(el);
156
- if (!this.typesMatch(declaredType, elAct)) {
157
- state.log(`${k} operator requires all values to be ${declaredType}, but ${elAct} was found`);
154
+ for (const item of keyValue) {
155
+ const itemType = TypeUtil.getActualType(item);
156
+ if (!this.typesMatch(declaredType, itemType)) {
157
+ state.log(`${key} operator requires all values to be ${declaredType}, but ${itemType} was found`);
158
158
  return;
159
159
  }
160
160
  }
161
- } else if (!(k in allowed)) {
162
- state.log(`Operation ${k}, not allowed for field of type ${declaredType}`);
161
+ } else if (!(key in allowed)) {
162
+ state.log(`Operation ${key}, not allowed for field of type ${declaredType}`);
163
163
  } else {
164
- const actualSubType = TypeUtil.getActualType(v)!;
164
+ const actualSubType = TypeUtil.getActualType(keyValue)!;
165
165
 
166
- if (!allowed[k].has(actualSubType)) {
167
- state.log(`Passed in value ${actualSubType} mismatches with expected type(s) ${Array.from(allowed[k])}`);
166
+ if (!allowed[key].has(actualSubType)) {
167
+ state.log(`Passed in value ${actualSubType} mismatches with expected type(s) ${Array.from(allowed[key])}`);
168
168
  }
169
169
  }
170
170
  }
@@ -190,8 +190,8 @@ export class QueryVerifier {
190
190
  state.log(`${firstKey} requires the value to be an array`);
191
191
  } else {
192
192
  // Iterate
193
- for (const el of sub) {
194
- this.processWhereClause(state, cls, el);
193
+ for (const item of sub) {
194
+ this.processWhereClause(state, cls, item);
195
195
  }
196
196
  return true;
197
197
  }
@@ -208,7 +208,7 @@ export class QueryVerifier {
208
208
  onSimpleType: (state: State, type: SimpleType, value: unknown, isArray: boolean) => {
209
209
  this.checkOperatorClause(state, type, value, TypeUtil.OPERATORS[type], isArray);
210
210
  },
211
- onComplexType: (state: State, subCls: Class<T>, subVal: T, isArray: boolean): boolean => false
211
+ onComplexType: (state: State, subCls: Class<T>, subValue: T, isArray: boolean): boolean => false
212
212
  });
213
213
  }
214
214
 
@@ -281,8 +281,8 @@ export class QueryVerifier {
281
281
  collect(path: string, message: string): void {
282
282
  errors.push({ message: `${path}: ${message}`, path, kind: 'model' });
283
283
  },
284
- log(err: string): void {
285
- this.collect(this.path, err);
284
+ log(error: string): void {
285
+ this.collect(this.path, error);
286
286
  },
287
287
  extend<S extends { path: string }>(this: S, sub: string): S {
288
288
  return { ...this, path: !this.path ? sub : `${this.path}.${sub}` };
@@ -302,15 +302,15 @@ export class QueryVerifier {
302
302
  continue;
303
303
  }
304
304
 
305
- const val = query[key];
305
+ const value = query[key];
306
306
  const subState = state.extend(key);
307
307
 
308
- if (Array.isArray(val)) {
309
- for (const el of val) {
310
- this[fn](subState, cls, el);
308
+ if (Array.isArray(value)) {
309
+ for (const item of value) {
310
+ this[fn](subState, cls, item);
311
311
  }
312
- } else if (typeof val !== 'string') {
313
- this[fn](subState, cls, val);
312
+ } else if (typeof value !== 'string') {
313
+ this[fn](subState, cls, value);
314
314
  }
315
315
  }
316
316
 
@@ -29,5 +29,5 @@ export const ModelQueryTypes = (fn: Function): DocJSXElement[] => {
29
29
  found.push(link);
30
30
  }
31
31
  }
32
- return found.map(v => <li>{v}</li>);
32
+ return found.map(type => <li>{type}</li>);
33
33
  };