@travetto/model-query 3.0.0-rc.3 → 3.0.0-rc.6

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
@@ -1,5 +1,5 @@
1
1
  <!-- This file was generated by @travetto/doc and should not be modified directly -->
2
- <!-- Please modify https://github.com/travetto/travetto/tree/main/module/model-query/doc.ts and execute "npx trv doc" to rebuild -->
2
+ <!-- Please modify https://github.com/travetto/travetto/tree/main/module/model-query/DOC.ts and execute "npx trv doc" to rebuild -->
3
3
  # Data Model Querying
4
4
  ## Datastore abstraction for advanced query support.
5
5
 
@@ -241,41 +241,53 @@ To enforce that these contracts are honored, the module provides shared test sui
241
241
  ```typescript
242
242
  import { Suite } from '@travetto/test';
243
243
 
244
- import { ModelQuerySuite } from '@travetto/model-query/test-support/query';
245
- import { ModelQueryCrudSuite } from '@travetto/model-query/test-support/crud';
246
- import { ModelQueryFacetSuite } from '@travetto/model-query/test-support/facet';
247
- import { ModelQueryPolymorphismSuite } from '@travetto/model-query/test-support/polymorphism';
248
- import { ModelQuerySuggestSuite } from '@travetto/model-query/test-support/suggest';
244
+ import { ModelQuerySuite } from '@travetto/model-query/support/test/query';
245
+ import { ModelQueryCrudSuite } from '@travetto/model-query/support/test/crud';
246
+ import { ModelQueryFacetSuite } from '@travetto/model-query/support/test/facet';
247
+ import { ModelQueryPolymorphismSuite } from '@travetto/model-query/support/test/polymorphism';
248
+ import { ModelQuerySuggestSuite } from '@travetto/model-query/support/test/suggest';
249
+ import { ModelQueryCrudSupport } from '@travetto/model-query/src/service/crud';
250
+ import { ModelQuerySuggestSupport } from '@travetto/model-query/src/service/suggest';
251
+ import { ModelQueryFacetSupport } from '@travetto/model-query/src/service/facet';
252
+ import { Config } from '@travetto/config';
253
+ import { Injectable } from '@travetto/di';
249
254
 
250
- import { MongoModelConfig, MongoModelService } from '..';
255
+ import { QueryModelService } from './query-service';
256
+
257
+ @Config()
258
+ class CustomModelConfig { }
259
+
260
+ @Injectable()
261
+ class CustomModelService extends QueryModelService implements ModelQueryCrudSupport, ModelQueryFacetSupport, ModelQuerySuggestSupport {
262
+ }
251
263
 
252
264
  @Suite()
253
- export class MongoQuerySuite extends ModelQuerySuite {
254
- serviceClass = MongoModelService;
255
- configClass = MongoModelConfig;
265
+ export class CustomQuerySuite extends ModelQuerySuite {
266
+ serviceClass = CustomModelService;
267
+ configClass = CustomModelConfig;
256
268
  }
257
269
 
258
270
  @Suite()
259
- export class MongoQueryCrudSuite extends ModelQueryCrudSuite {
260
- serviceClass = MongoModelService;
261
- configClass = MongoModelConfig;
271
+ export class CustomQueryCrudSuite extends ModelQueryCrudSuite {
272
+ serviceClass = CustomModelService;
273
+ configClass = CustomModelConfig;
262
274
  }
263
275
 
264
276
  @Suite()
265
- export class MongoQueryFacetSuite extends ModelQueryFacetSuite {
266
- serviceClass = MongoModelService;
267
- configClass = MongoModelConfig;
277
+ export class CustomQueryFacetSuite extends ModelQueryFacetSuite {
278
+ serviceClass = CustomModelService;
279
+ configClass = CustomModelConfig;
268
280
  }
269
281
 
270
282
  @Suite()
271
- export class MongoQueryPolymorphismSuite extends ModelQueryPolymorphismSuite {
272
- serviceClass = MongoModelService;
273
- configClass = MongoModelConfig;
283
+ export class CustomQueryPolymorphismSuite extends ModelQueryPolymorphismSuite {
284
+ serviceClass = CustomModelService;
285
+ configClass = CustomModelConfig;
274
286
  }
275
287
 
276
288
  @Suite()
277
- export class MongoQuerySuggestSuite extends ModelQuerySuggestSuite {
278
- serviceClass = MongoModelService;
279
- configClass = MongoModelConfig;
289
+ export class CustomQuerySuggestSuite extends ModelQuerySuggestSuite {
290
+ serviceClass = CustomModelService;
291
+ configClass = CustomModelConfig;
280
292
  }
281
293
  ```
File without changes
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-query",
3
- "displayName": "Data Model Querying",
4
- "version": "3.0.0-rc.3",
3
+ "version": "3.0.0-rc.6",
5
4
  "description": "Datastore abstraction for advanced query support.",
6
5
  "keywords": [
7
6
  "datastore",
@@ -18,24 +17,30 @@
18
17
  "name": "Travetto Framework"
19
18
  },
20
19
  "files": [
21
- "index.ts",
20
+ "__index__.ts",
22
21
  "src",
23
- "test-support"
22
+ "support"
24
23
  ],
25
- "main": "index.ts",
24
+ "main": "__index__.ts",
26
25
  "repository": {
27
26
  "url": "https://github.com/travetto/travetto.git",
28
27
  "directory": "module/model-query"
29
28
  },
30
29
  "dependencies": {
31
- "@travetto/di": "^3.0.0-rc.3",
32
- "@travetto/model": "^3.0.0-rc.3",
33
- "@travetto/schema": "^3.0.0-rc.3"
30
+ "@travetto/di": "^3.0.0-rc.6",
31
+ "@travetto/model": "^3.0.0-rc.6",
32
+ "@travetto/schema": "^3.0.0-rc.6"
34
33
  },
35
- "docDependencies": {
36
- "@travetto/model-mongo": true,
37
- "@travetto/model-elasticsearch": true,
38
- "@travetto/model-sql": true
34
+ "peerDependencies": {
35
+ "@travetto/test": "^3.0.0-rc.6"
36
+ },
37
+ "peerDependenciesMeta": {
38
+ "@travetto/test": {
39
+ "optional": true
40
+ }
41
+ },
42
+ "travetto": {
43
+ "displayName": "Data Model Querying"
39
44
  },
40
45
  "publishConfig": {
41
46
  "access": "public"
@@ -1,4 +1,4 @@
1
- import { Util } from '@travetto/base';
1
+ import { DataUtil } from '@travetto/base';
2
2
 
3
3
  export class PointImpl {
4
4
  static validateSchema(input: unknown): 'type' | undefined {
@@ -7,8 +7,10 @@ export class PointImpl {
7
7
  }
8
8
  static bindSchema(input: unknown): [number, number] | undefined {
9
9
  if (Array.isArray(input) && input.length === 2) {
10
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
11
- return input.map(x => Util.coerceType(x, Number, false)) as [number, number];
10
+ return [
11
+ DataUtil.coerceType(input[0], Number, false),
12
+ DataUtil.coerceType(input[1], Number, false)
13
+ ];
12
14
  }
13
15
  }
14
16
  }
@@ -1,4 +1,4 @@
1
- import { Util } from '@travetto/base';
1
+ import { TimeUtil } from '@travetto/base';
2
2
  import { Token, TokenizeState, TokenType } from './types';
3
3
 
4
4
  const OPEN_PARENS = 0x28, CLOSE_PARENS = 0x29, OPEN_BRACKET = 0x5b, CLOSE_BRACKET = 0x5d, COMMA = 0x2c;
@@ -61,7 +61,7 @@ export class QueryLanguageTokenizer {
61
61
  value = parseInt(text, 10);
62
62
  } else if (/^-?\d+[.]\d+$/.test(text)) {
63
63
  value = parseFloat(text);
64
- } else if (Util.isTimeSpan(text)) {
64
+ } else if (TimeUtil.isTimeSpan(text)) {
65
65
  value = text;
66
66
  } else {
67
67
  state.mode = 'identifier';
@@ -1,5 +1,5 @@
1
1
  import { SchemaRegistry, ValidationResultError, ValidationError } from '@travetto/schema';
2
- import { Class, Util } from '@travetto/base';
2
+ import { Class, ObjectUtil } from '@travetto/base';
3
3
 
4
4
  import { ModelQuery, Query, PageableModelQuery } from '../../model/query';
5
5
 
@@ -37,12 +37,12 @@ const MULTIPLE_KEYS_ALLOWED = new Set([
37
37
  /**
38
38
  * Query verification service. Used to verify the query is valid before running.
39
39
  */
40
- class $QueryVerifier {
40
+ export class QueryVerifier {
41
41
 
42
42
  /**
43
43
  * Internal mapping for various clauses
44
44
  */
45
- #mapping = [
45
+ static #mapping = [
46
46
  [SELECT, 'processSelectClause'] as const,
47
47
  [WHERE, 'processWhereClause'] as const,
48
48
  [SORT, 'processSortClause'] as const,
@@ -51,7 +51,7 @@ class $QueryVerifier {
51
51
  /**
52
52
  * Handle generic clauses
53
53
  */
54
- processGenericClause<T>(state: State, cls: Class<T>, val: object, handler: ProcessingHandler): void {
54
+ static processGenericClause<T>(state: State, cls: Class<T>, val: object, handler: ProcessingHandler): void {
55
55
  const view = SchemaRegistry.getViewSchema(cls);
56
56
 
57
57
  if (val === undefined || val === null) {
@@ -102,14 +102,14 @@ class $QueryVerifier {
102
102
  /**
103
103
  * Ensure types match
104
104
  */
105
- typesMatch(declared: string, actual: string | undefined): boolean {
105
+ static typesMatch(declared: string, actual: string | undefined): boolean {
106
106
  return declared === actual;
107
107
  }
108
108
 
109
109
  /**
110
110
  * Check operator clause
111
111
  */
112
- checkOperatorClause(state: State, declaredType: SimpleType, value: unknown, allowed: Record<string, Set<string>>, isArray: boolean): void {
112
+ static checkOperatorClause(state: State, declaredType: SimpleType, value: unknown, allowed: Record<string, Set<string>>, isArray: boolean): void {
113
113
  if (isArray) {
114
114
  if (Array.isArray(value)) {
115
115
  // Handle array literal
@@ -120,7 +120,7 @@ class $QueryVerifier {
120
120
  }
121
121
  }
122
122
 
123
- if (!Util.isPlainObject(value)) {
123
+ if (!ObjectUtil.isPlainObject(value)) {
124
124
  // Handle literal
125
125
  const actualType = TypeUtil.getActualType(value);
126
126
  if (!this.typesMatch(declaredType, actualType)) {
@@ -173,7 +173,7 @@ class $QueryVerifier {
173
173
  /**
174
174
  * Process where clause
175
175
  */
176
- processWhereClause<T>(st: State, cls: Class<T>, passed: object): void {
176
+ static processWhereClause<T>(st: State, cls: Class<T>, passed: object): void {
177
177
  return this.processGenericClause(st, cls, passed, {
178
178
  preMember: (state: State, value: Record<string, unknown>) => {
179
179
  const keys = Object.keys(value);
@@ -196,7 +196,7 @@ class $QueryVerifier {
196
196
  return true;
197
197
  }
198
198
  } else if (firstKey === '$not') {
199
- if (Util.isPlainObject(sub)) {
199
+ if (ObjectUtil.isPlainObject(sub)) {
200
200
  this.processWhereClause(state, cls, sub);
201
201
  return true;
202
202
  } else {
@@ -215,14 +215,14 @@ class $QueryVerifier {
215
215
  /**
216
216
  * Handle group by clause
217
217
  */
218
- processGroupByClause(state: State, value: object): void {
218
+ static processGroupByClause(state: State, value: object): void {
219
219
 
220
220
  }
221
221
 
222
222
  /**
223
223
  * Handle sort clause
224
224
  */
225
- processSortClause<T>(st: State, cls: Class<T>, passed: object): void {
225
+ static processSortClause<T>(st: State, cls: Class<T>, passed: object): void {
226
226
  return this.processGenericClause(st, cls, passed, {
227
227
  onSimpleType: (state, type, value) => {
228
228
  if (value === 1 || value === -1 || typeof value === 'boolean') {
@@ -236,7 +236,7 @@ class $QueryVerifier {
236
236
  /**
237
237
  * Handle select clause
238
238
  */
239
- processSelectClause<T>(st: State, cls: Class<T>, passed: object): void {
239
+ static processSelectClause<T>(st: State, cls: Class<T>, passed: object): void {
240
240
  return this.processGenericClause(st, cls, passed, {
241
241
  onSimpleType: (state, type, value) => {
242
242
  const actual = TypeUtil.getActualType(value);
@@ -269,7 +269,7 @@ class $QueryVerifier {
269
269
  /**
270
270
  * Verify the query
271
271
  */
272
- verify<T>(cls: Class<T>, query: ModelQuery<T> | Query<T> | PageableModelQuery<T>): void {
272
+ static verify<T>(cls: Class<T>, query: ModelQuery<T> | Query<T> | PageableModelQuery<T>): void {
273
273
  const errors: ValidationError[] = [];
274
274
 
275
275
  const state = {
@@ -314,6 +314,4 @@ class $QueryVerifier {
314
314
  throw new ValidationResultError(errors);
315
315
  }
316
316
  }
317
- }
318
-
319
- export const QueryVerifier = new $QueryVerifier();
317
+ }
@@ -1,4 +1,4 @@
1
- import { Class, AppError, Util } from '@travetto/base';
1
+ import { Class, AppError, TimeUtil } from '@travetto/base';
2
2
  import { ModelRegistry, NotFoundError } from '@travetto/model';
3
3
  import { ModelType } from '@travetto/model/src/types/model';
4
4
  import { SchemaRegistry } from '@travetto/schema';
@@ -21,7 +21,7 @@ export class ModelQueryUtil {
21
21
  static resolveComparator(val: unknown): unknown {
22
22
  if (typeof val === 'string') {
23
23
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
24
- return Util.timeFromNow(val as '1m');
24
+ return TimeUtil.timeFromNow(val as '1m');
25
25
  } else {
26
26
  return val;
27
27
  }
@@ -1,5 +1,4 @@
1
- import { Primitive as Prim } from '@travetto/base/src/internal/global-types';
2
- import { TimeSpan } from '@travetto/base/src/util';
1
+ import { TimeSpan, Primitive } from '@travetto/base';
3
2
 
4
3
  /**
5
4
  * Point as [number,number] with validation and binding support
@@ -8,13 +7,13 @@ import { TimeSpan } from '@travetto/base/src/util';
8
7
  */
9
8
  export type Point = [number, number];
10
9
 
11
- export type Primitive = Prim | Point;
12
- export type PrimitiveArray = Primitive[];
10
+ export type QueryPrimitive = Primitive | Point;
11
+ export type QueryPrimitiveArray = QueryPrimitive[];
13
12
  export type DistanceUnit = 'mi' | 'm' | 'km' | 'ft' | 'rad';
14
13
 
15
14
  export type ValidFieldNames<T> = {
16
15
  [K in keyof T]:
17
- (T[K] extends (Primitive | undefined) ? K :
16
+ (T[K] extends (QueryPrimitive | undefined) ? K :
18
17
  (T[K] extends (Function | undefined) ? never :
19
18
  K))
20
19
  }[keyof T];
@@ -0,0 +1,29 @@
1
+ import { readFileSync } from 'fs';
2
+
3
+ import { RootIndex } from '@travetto/manifest';
4
+ import { d } from '@travetto/doc';
5
+ import { AllTypeMap } from '@travetto/doc/src/nodes';
6
+
7
+ export const Links = {
8
+ QueryCrud: d.SnippetLink('Query Crud', '@travetto/model-query/src/service/crud.ts', /export interface/),
9
+ QueryFacet: d.SnippetLink('Facet', '@travetto/model-query/src/service/facet.ts', /export interface/),
10
+ QuerySuggest: d.SnippetLink('Suggest', '@travetto/model-query/src/service/suggest.ts', /export interface/),
11
+ Query: d.SnippetLink('Query', '@travetto/model-query/src/service/query.ts', /export interface/),
12
+ };
13
+
14
+ export const ModelQueryTypes = (file: string | Function): AllTypeMap['SnippetLink'][] => {
15
+ if (typeof file !== 'string') {
16
+ file = RootIndex.getFunctionMetadata(file)!.source;
17
+ }
18
+ const contents = readFileSync(file, 'utf8');
19
+ const found: AllTypeMap['SnippetLink'][] = [];
20
+ const seen = new Set();
21
+ for (const [, key] of contents.matchAll(/Model(Query(Suggest|Facet|Crud)?)Support/g)) {
22
+ if (!seen.has(key)) {
23
+ seen.add(key);
24
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
25
+ found.push(Links[key as keyof typeof Links]);
26
+ }
27
+ }
28
+ return found;
29
+ };
@@ -1,11 +1,11 @@
1
- import * as assert from 'assert';
1
+ import assert from 'assert';
2
2
 
3
3
  import { Suite, Test } from '@travetto/test';
4
- import { BaseModelSuite } from '@travetto/model/test-support/base';
4
+ import { BaseModelSuite } from '@travetto/model/support/test/base';
5
5
  import { ModelCrudSupport } from '@travetto/model/src/service/crud';
6
6
 
7
7
  import { Address, Person } from './types';
8
- import { ModelQueryCrudSupport } from '../src/service/crud';
8
+ import { ModelQueryCrudSupport } from '../../src/service/crud';
9
9
 
10
10
  @Suite()
11
11
  export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudSupport & ModelCrudSupport> {
@@ -1,11 +1,11 @@
1
- import * as assert from 'assert';
1
+ import assert from 'assert';
2
2
 
3
3
  import { ModelCrudSupport } from '@travetto/model';
4
- import { BaseModelSuite } from '@travetto/model/test-support/base';
4
+ import { BaseModelSuite } from '@travetto/model/support/test/base';
5
5
  import { Suite, Test } from '@travetto/test';
6
6
 
7
7
  import { Person } from './types';
8
- import { ModelQueryFacetSupport } from '../src/service/facet';
8
+ import { ModelQueryFacetSupport } from '../../src/service/facet';
9
9
 
10
10
  const pick = <T>(arr: T[]): T => arr[Math.trunc(Math.random() * arr.length)]!;
11
11
 
@@ -1,17 +1,17 @@
1
- import * as assert from 'assert';
1
+ import assert from 'assert';
2
2
 
3
3
  import { Suite, Test } from '@travetto/test';
4
- import { BaseModelSuite } from '@travetto/model/test-support/base';
4
+ import { BaseModelSuite } from '@travetto/model/support/test/base';
5
5
  import { ModelCrudSupport } from '@travetto/model/src/service/crud';
6
- import { Doctor, Engineer, Worker, Firefighter } from '@travetto/model/test-support/polymorphism';
6
+ import { Doctor, Engineer, Worker, Firefighter } from '@travetto/model/support/test/polymorphism';
7
7
  import { NotFoundError } from '@travetto/model/src/error/not-found';
8
8
 
9
- import { ModelQueryCrudSupport } from '../src/service/crud';
10
- import { ModelQuerySupport } from '../src/service/query';
11
- import { ModelQueryFacetSupport } from '../src/service/facet';
12
- import { ModelQuerySuggestSupport } from '../src/service/suggest';
9
+ import { ModelQueryCrudSupport } from '../../src/service/crud';
10
+ import { ModelQuerySupport } from '../../src/service/query';
11
+ import { ModelQueryFacetSupport } from '../../src/service/facet';
12
+ import { ModelQuerySuggestSupport } from '../../src/service/suggest';
13
13
 
14
- import { isQueryCrudSupported, isQueryFacetSupported, isQuerySuggestSupported } from '../src/internal/service/common';
14
+ import { isQueryCrudSupported, isQueryFacetSupported, isQuerySuggestSupported } from '../../src/internal/service/common';
15
15
 
16
16
  @Suite()
17
17
  export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<ModelQuerySupport & ModelCrudSupport> {
@@ -1,13 +1,14 @@
1
- import * as assert from 'assert';
1
+ import assert from 'assert';
2
2
 
3
3
  import { Suite, Test } from '@travetto/test';
4
- import { BaseModelSuite } from '@travetto/model/test-support/base';
4
+ import { BaseModelSuite } from '@travetto/model/support/test/base';
5
5
  import { ModelCrudSupport } from '@travetto/model/src/service/crud';
6
- import { Util } from '@travetto/base';
6
+ import { TimeUtil } from '@travetto/base';
7
7
 
8
- import { ModelQuerySupport } from '../src/service/query';
9
8
  import { Aged, Location, Names, Note, Person, SimpleList } from './types';
10
9
 
10
+ import { ModelQuerySupport } from '../../src/service/query';
11
+
11
12
  @Suite()
12
13
  export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport & ModelCrudSupport> {
13
14
 
@@ -253,7 +254,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
253
254
  async verifyDateRange() {
254
255
  const service = await this.service;
255
256
  await this.saveAll(Aged, (['-5d', '-4d', '-3d', '-2d', '-1d', '0d', '1d', '2d', '3d', '4d', '5d'] as const).map(delta =>
256
- Aged.from({ createdAt: Util.timeFromNow(delta) })
257
+ Aged.from({ createdAt: TimeUtil.timeFromNow(delta) })
257
258
  ));
258
259
 
259
260
  const simple = await service.queryCount(Aged, {
@@ -290,7 +291,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
290
291
  where: {
291
292
  createdAt: {
292
293
  $gt: new Date(),
293
- $lt: Util.timeFromNow('3d')
294
+ $lt: TimeUtil.timeFromNow('3d')
294
295
  }
295
296
  }
296
297
  });
@@ -1,11 +1,11 @@
1
- import * as assert from 'assert';
1
+ import assert from 'assert';
2
2
 
3
3
  import { ModelCrudSupport } from '@travetto/model';
4
- import { BaseModelSuite } from '@travetto/model/test-support/base';
4
+ import { BaseModelSuite } from '@travetto/model/support/test/base';
5
5
  import { Suite, Test } from '@travetto/test';
6
6
 
7
7
  import { Person } from './types';
8
- import { ModelQuerySuggestSupport } from '../src/service/suggest';
8
+ import { ModelQuerySuggestSupport } from '../../src/service/suggest';
9
9
 
10
10
  @Suite()
11
11
  export abstract class ModelQuerySuggestSuite extends BaseModelSuite<ModelQuerySuggestSupport & ModelCrudSupport> {
@@ -1,7 +1,7 @@
1
1
  import { Precision, Schema, Text } from '@travetto/schema';
2
2
  import { Model, ModelType } from '@travetto/model';
3
3
 
4
- import { Point } from '../src/model/where-clause';
4
+ import { Point } from '../../src/model/where-clause';
5
5
 
6
6
  @Schema()
7
7
  export class Address {