@travetto/model-query 6.0.0-rc.1 → 6.0.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/README.md +12 -13
- package/__index__.ts +13 -7
- package/package.json +5 -5
- package/src/internal/{util/types.ts → types.ts} +7 -7
- package/src/model/query.ts +1 -1
- package/src/model/where-clause.ts +1 -7
- package/src/{service → types}/crud.ts +3 -3
- package/src/{service → types}/facet.ts +7 -5
- package/src/{service → types}/query.ts +2 -2
- package/src/{service → types}/suggest.ts +4 -4
- package/src/{internal/service/expiry.ts → util/crud.ts} +9 -9
- package/src/util/facet.ts +10 -0
- package/src/{internal/service → util}/query.ts +15 -10
- package/src/{internal/service → util}/suggest.ts +10 -4
- package/src/verifier.ts +5 -4
- package/support/doc.support.tsx +17 -7
- package/support/test/crud.ts +5 -5
- package/support/test/facet.ts +4 -3
- package/support/test/{types.ts → model.ts} +1 -3
- package/support/test/polymorphism.ts +14 -12
- package/support/test/query.ts +9 -9
- package/support/test/suggest.ts +4 -3
- package/src/internal/model/point.ts +0 -16
- package/src/internal/service/common.ts +0 -31
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ export interface ModelQuerySupport {
|
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
### Crud
|
|
49
|
-
Reinforcing the complexity provided in these contracts, the [Query Crud](https://github.com/travetto/travetto/tree/main/module/model-query/src/
|
|
49
|
+
Reinforcing the complexity provided in these contracts, the [Query Crud](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/crud.ts#L11) contract allows for bulk update/deletion by query. This requires the underlying implementation to support these operations.
|
|
50
50
|
|
|
51
51
|
**Code: Query Crud**
|
|
52
52
|
```typescript
|
|
@@ -86,7 +86,7 @@ export interface ModelQueryFacetSupport extends ModelQuerySupport {
|
|
|
86
86
|
* @param field The field to facet on
|
|
87
87
|
* @param query Additional query filtering
|
|
88
88
|
*/
|
|
89
|
-
facet<T extends ModelType>(cls: Class<T>, field: ValidStringFields<T>, query?: ModelQuery<T>): Promise<
|
|
89
|
+
facet<T extends ModelType>(cls: Class<T>, field: ValidStringFields<T>, query?: ModelQuery<T>): Promise<ModelQueryFacet[]>;
|
|
90
90
|
}
|
|
91
91
|
```
|
|
92
92
|
|
|
@@ -173,12 +173,13 @@ One of the complexities of abstracting multiple storage mechanisms, is providing
|
|
|
173
173
|
* `{ $and: [] }` provides a grouping in which all sub clauses are require,
|
|
174
174
|
* `{ $or: [] }` provides a grouping in which at least one of the sub clauses is require,
|
|
175
175
|
* `{ $not: { } }` negates a clause
|
|
176
|
+
|
|
176
177
|
A sample query for `User`'s might be:
|
|
177
178
|
|
|
178
179
|
**Code: Using the query structure for specific queries**
|
|
179
180
|
```typescript
|
|
180
181
|
import { ModelQuerySupport } from '@travetto/model-query';
|
|
181
|
-
import { User } from './user';
|
|
182
|
+
import { User } from './user.ts';
|
|
182
183
|
|
|
183
184
|
export class UserSearch {
|
|
184
185
|
service: ModelQuerySupport;
|
|
@@ -214,19 +215,17 @@ In addition to the provided contracts, the module also provides common utilities
|
|
|
214
215
|
**Code: MongoDB Service Test Configuration**
|
|
215
216
|
```typescript
|
|
216
217
|
import { Suite } from '@travetto/test';
|
|
217
|
-
|
|
218
|
-
import { ModelQuerySuite } from '@travetto/model-query/support/test/query';
|
|
219
|
-
import { ModelQueryCrudSuite } from '@travetto/model-query/support/test/crud';
|
|
220
|
-
import { ModelQueryFacetSuite } from '@travetto/model-query/support/test/facet';
|
|
221
|
-
import { ModelQueryPolymorphismSuite } from '@travetto/model-query/support/test/polymorphism';
|
|
222
|
-
import { ModelQuerySuggestSuite } from '@travetto/model-query/support/test/suggest';
|
|
223
|
-
import { ModelQueryCrudSupport } from '@travetto/model-query/src/service/crud';
|
|
224
|
-
import { ModelQuerySuggestSupport } from '@travetto/model-query/src/service/suggest';
|
|
225
|
-
import { ModelQueryFacetSupport } from '@travetto/model-query/src/service/facet';
|
|
226
218
|
import { Config } from '@travetto/config';
|
|
227
219
|
import { Injectable } from '@travetto/di';
|
|
220
|
+
import { ModelQueryFacetSupport, ModelQuerySuggestSupport, ModelQueryCrudSupport } from '@travetto/model-query';
|
|
221
|
+
|
|
222
|
+
import { ModelQuerySuite } from '@travetto/model-query/support/test/query.ts';
|
|
223
|
+
import { ModelQueryCrudSuite } from '@travetto/model-query/support/test/crud.ts';
|
|
224
|
+
import { ModelQueryFacetSuite } from '@travetto/model-query/support/test/facet.ts';
|
|
225
|
+
import { ModelQueryPolymorphismSuite } from '@travetto/model-query/support/test/polymorphism.ts';
|
|
226
|
+
import { ModelQuerySuggestSuite } from '@travetto/model-query/support/test/suggest.ts';
|
|
228
227
|
|
|
229
|
-
import { QueryModelService } from './query-service';
|
|
228
|
+
import { QueryModelService } from './query-service.ts';
|
|
230
229
|
|
|
231
230
|
@Config('model.custom')
|
|
232
231
|
class CustomModelConfig { }
|
package/__index__.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
export * from './src/model/query';
|
|
2
|
-
export * from './src/model/where-clause';
|
|
3
|
-
export * from './src/
|
|
4
|
-
export * from './src/
|
|
5
|
-
export * from './src/
|
|
6
|
-
export * from './src/
|
|
7
|
-
|
|
1
|
+
export * from './src/model/query.ts';
|
|
2
|
+
export * from './src/model/where-clause.ts';
|
|
3
|
+
export * from './src/types/crud.ts';
|
|
4
|
+
export * from './src/types/query.ts';
|
|
5
|
+
export * from './src/types/facet.ts';
|
|
6
|
+
export * from './src/types/suggest.ts';
|
|
7
|
+
|
|
8
|
+
export * from './src/util/query.ts';
|
|
9
|
+
export * from './src/util/suggest.ts';
|
|
10
|
+
export * from './src/util/facet.ts';
|
|
11
|
+
export * from './src/util/crud.ts';
|
|
12
|
+
|
|
13
|
+
export * from './src/verifier.ts';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-query",
|
|
3
|
-
"version": "6.0.0
|
|
3
|
+
"version": "6.0.0",
|
|
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": "^6.0.0
|
|
30
|
-
"@travetto/model": "^6.0.0
|
|
31
|
-
"@travetto/schema": "^6.0.0
|
|
29
|
+
"@travetto/di": "^6.0.0",
|
|
30
|
+
"@travetto/model": "^6.0.0",
|
|
31
|
+
"@travetto/schema": "^6.0.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@travetto/test": "^6.0.0
|
|
34
|
+
"@travetto/test": "^6.0.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependenciesMeta": {
|
|
37
37
|
"@travetto/test": {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { FieldConfig } from '@travetto/schema';
|
|
2
|
-
import { Class } from '@travetto/runtime';
|
|
3
|
-
|
|
4
|
-
import { PointImpl } from '../model/point';
|
|
1
|
+
import { FieldConfig, Point } from '@travetto/schema';
|
|
2
|
+
import { Class, toConcrete } from '@travetto/runtime';
|
|
5
3
|
|
|
6
4
|
const st = (t: string | string[], isArr: boolean = false): Set<string> =>
|
|
7
5
|
new Set((Array.isArray(t) ? t : [t]).map(v => isArr ? `${v}[]` : v));
|
|
@@ -18,6 +16,8 @@ const geo = (type: string): Record<string, Set<string>> => ({
|
|
|
18
16
|
$geoIntersects: st(type, true)
|
|
19
17
|
});
|
|
20
18
|
|
|
19
|
+
const PointImpl = toConcrete<Point>();
|
|
20
|
+
|
|
21
21
|
/**
|
|
22
22
|
* Basic type support
|
|
23
23
|
*/
|
|
@@ -64,11 +64,11 @@ export class TypeUtil {
|
|
|
64
64
|
} else if (v instanceof Date) {
|
|
65
65
|
return 'Date';
|
|
66
66
|
} else if (Array.isArray(v)) {
|
|
67
|
-
const
|
|
68
|
-
if (v.length === 2 &&
|
|
67
|
+
const typeString: string = `${this.getActualType(v[0])}[]`;
|
|
68
|
+
if (v.length === 2 && typeString === 'number[]') {
|
|
69
69
|
return 'Point';
|
|
70
70
|
} else {
|
|
71
|
-
return
|
|
71
|
+
return typeString;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
throw new Error(`Unknown type for ${v}`);
|
package/src/model/query.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { Primitive, TimeSpan } from '@travetto/runtime';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Point as [number,number] with validation and binding support
|
|
5
|
-
*
|
|
6
|
-
* @concrete ../internal/model/point#PointImpl
|
|
7
|
-
*/
|
|
8
|
-
export type Point = [number, number];
|
|
2
|
+
import { Point } from '@travetto/schema';
|
|
9
3
|
|
|
10
4
|
export type QueryPrimitive = Primitive | Point;
|
|
11
5
|
export type QueryPrimitiveArray = QueryPrimitive[];
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Class } from '@travetto/runtime';
|
|
2
2
|
import { ModelCrudSupport, ModelType } from '@travetto/model';
|
|
3
3
|
|
|
4
|
-
import { ModelQuerySupport } from './query';
|
|
5
|
-
import { ModelQuery } from '../model/query';
|
|
4
|
+
import { ModelQuerySupport } from './query.ts';
|
|
5
|
+
import { ModelQuery } from '../model/query.ts';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* The contract for a model service with query support
|
|
9
|
-
* @concrete
|
|
9
|
+
* @concrete
|
|
10
10
|
*/
|
|
11
11
|
export interface ModelQueryCrudSupport extends ModelCrudSupport, ModelQuerySupport {
|
|
12
12
|
/**
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Class } from '@travetto/runtime';
|
|
2
2
|
import { ModelType } from '@travetto/model';
|
|
3
3
|
|
|
4
|
-
import { ModelQuery } from '../model/query';
|
|
5
|
-
import { ModelQuerySupport } from './query';
|
|
6
|
-
import { ValidStringFields } from '../model/where-clause';
|
|
4
|
+
import { ModelQuery } from '../model/query.ts';
|
|
5
|
+
import { ModelQuerySupport } from './query.ts';
|
|
6
|
+
import { ValidStringFields } from '../model/where-clause.ts';
|
|
7
|
+
|
|
8
|
+
export type ModelQueryFacet = { key: string, count: number };
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* The contract for a model service with faceting support
|
|
10
|
-
* @concrete
|
|
12
|
+
* @concrete
|
|
11
13
|
*/
|
|
12
14
|
export interface ModelQueryFacetSupport extends ModelQuerySupport {
|
|
13
15
|
/**
|
|
@@ -16,5 +18,5 @@ export interface ModelQueryFacetSupport extends ModelQuerySupport {
|
|
|
16
18
|
* @param field The field to facet on
|
|
17
19
|
* @param query Additional query filtering
|
|
18
20
|
*/
|
|
19
|
-
facet<T extends ModelType>(cls: Class<T>, field: ValidStringFields<T>, query?: ModelQuery<T>): Promise<
|
|
21
|
+
facet<T extends ModelType>(cls: Class<T>, field: ValidStringFields<T>, query?: ModelQuery<T>): Promise<ModelQueryFacet[]>;
|
|
20
22
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Class } from '@travetto/runtime';
|
|
2
2
|
import { ModelType } from '@travetto/model';
|
|
3
3
|
|
|
4
|
-
import { ModelQuery, PageableModelQuery } from '../model/query';
|
|
4
|
+
import { ModelQuery, PageableModelQuery } from '../model/query.ts';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The contract for a model service with query support
|
|
8
|
-
* @concrete
|
|
8
|
+
* @concrete
|
|
9
9
|
*/
|
|
10
10
|
export interface ModelQuerySupport {
|
|
11
11
|
/**
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Class } from '@travetto/runtime';
|
|
2
2
|
import { ModelType } from '@travetto/model';
|
|
3
3
|
|
|
4
|
-
import { PageableModelQuery } from '../model/query';
|
|
5
|
-
import { ModelQuerySupport } from './query';
|
|
6
|
-
import { ValidStringFields } from '../model/where-clause';
|
|
4
|
+
import { PageableModelQuery } from '../model/query.ts';
|
|
5
|
+
import { ModelQuerySupport } from './query.ts';
|
|
6
|
+
import { ValidStringFields } from '../model/where-clause.ts';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The contract for a model service with suggesting support
|
|
10
|
-
* @concrete
|
|
10
|
+
* @concrete
|
|
11
11
|
*/
|
|
12
12
|
export interface ModelQuerySuggestSupport extends ModelQuerySupport {
|
|
13
13
|
/**
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Class } from '@travetto/runtime';
|
|
2
|
-
import { ModelCrudSupport } from '@travetto/model';
|
|
3
|
-
import { ModelRegistry } from '@travetto/model/src/registry/model';
|
|
4
|
-
import { ModelType } from '@travetto/model/src/types/model';
|
|
1
|
+
import { Class, hasFunction } from '@travetto/runtime';
|
|
2
|
+
import { ModelType, ModelCrudSupport, ModelRegistry } from '@travetto/model';
|
|
5
3
|
|
|
6
|
-
import { ModelQueryCrudSupport } from '
|
|
4
|
+
import { ModelQueryCrudSupport } from '../types/crud.ts';
|
|
5
|
+
|
|
6
|
+
export class ModelQueryCrudUtil {
|
|
7
|
+
/**
|
|
8
|
+
* Type guard for determining if service supports query crud operations
|
|
9
|
+
*/
|
|
10
|
+
static isSupported = hasFunction<ModelQueryCrudSupport>('deleteByQuery');
|
|
7
11
|
|
|
8
|
-
/**
|
|
9
|
-
* Utils for query expiry support
|
|
10
|
-
*/
|
|
11
|
-
export class ModelQueryExpiryUtil {
|
|
12
12
|
/**
|
|
13
13
|
* Delete all expired
|
|
14
14
|
*/
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { hasFunction } from '@travetto/runtime';
|
|
2
|
+
|
|
3
|
+
import { ModelQueryFacetSupport } from '../types/facet.ts';
|
|
4
|
+
|
|
5
|
+
export class ModelQueryFacetUtil {
|
|
6
|
+
/**
|
|
7
|
+
* Type guard for determining if service supports query facet operations
|
|
8
|
+
*/
|
|
9
|
+
static isSupported = hasFunction<ModelQueryFacetSupport>('facet');
|
|
10
|
+
}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import { Class, AppError, TimeUtil, castTo } from '@travetto/runtime';
|
|
2
|
-
import { ModelRegistry, NotFoundError } from '@travetto/model';
|
|
3
|
-
import { ModelType } from '@travetto/model/src/types/model';
|
|
1
|
+
import { Class, AppError, TimeUtil, castTo, hasFunction } from '@travetto/runtime';
|
|
2
|
+
import { ModelType, ModelRegistry, NotFoundError } from '@travetto/model';
|
|
4
3
|
import { SchemaRegistry } from '@travetto/schema';
|
|
5
4
|
|
|
6
|
-
import { WhereClause, WhereClauseRaw } from '
|
|
5
|
+
import { WhereClause, WhereClauseRaw } from '../model/where-clause.ts';
|
|
6
|
+
import { ModelQuerySupport } from '../types/query.ts';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Common model utils, that should be usable by end users
|
|
10
10
|
*/
|
|
11
11
|
export class ModelQueryUtil {
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Type guard for determining if service supports query operations
|
|
15
|
+
*/
|
|
16
|
+
static isSupported = hasFunction<ModelQuerySupport>('query');
|
|
17
|
+
|
|
13
18
|
/**
|
|
14
19
|
* Resolve comparator
|
|
15
20
|
* @param val
|
|
@@ -26,13 +31,13 @@ export class ModelQueryUtil {
|
|
|
26
31
|
/**
|
|
27
32
|
* Verify result set is singular, and decide if failing on many should happen
|
|
28
33
|
*/
|
|
29
|
-
static verifyGetSingleCounts<T extends ModelType>(cls: Class<T>, failOnMany: boolean,
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
return
|
|
34
|
+
static verifyGetSingleCounts<T extends ModelType>(cls: Class<T>, failOnMany: boolean, result?: T[], where?: WhereClause<T>): T {
|
|
35
|
+
result = result ?? [];
|
|
36
|
+
if (result.length === 1 || result.length > 1 && !failOnMany) {
|
|
37
|
+
return result[0]!;
|
|
33
38
|
}
|
|
34
39
|
const requestedId = ((where && 'id' in where && typeof where.id === 'string') ? where.id : undefined);
|
|
35
|
-
if (
|
|
40
|
+
if (result.length === 0) {
|
|
36
41
|
if (requestedId) {
|
|
37
42
|
throw new NotFoundError(cls, requestedId);
|
|
38
43
|
} else {
|
|
@@ -41,7 +46,7 @@ export class ModelQueryUtil {
|
|
|
41
46
|
throw err;
|
|
42
47
|
}
|
|
43
48
|
} else {
|
|
44
|
-
throw new AppError(`Invalid number of results: ${
|
|
49
|
+
throw new AppError(`Invalid number of results: ${result.length}`, { category: 'data' });
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
52
|
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { ModelRegistry, ModelType } from '@travetto/model';
|
|
2
|
-
import { castTo, Class } from '@travetto/runtime';
|
|
2
|
+
import { castTo, Class, hasFunction } from '@travetto/runtime';
|
|
3
3
|
import { SchemaRegistry } from '@travetto/schema';
|
|
4
4
|
|
|
5
|
-
import { PageableModelQuery, Query } from '
|
|
6
|
-
import { ValidStringFields, WhereClauseRaw } from '
|
|
5
|
+
import { PageableModelQuery, Query } from '../model/query.ts';
|
|
6
|
+
import { ValidStringFields, WhereClauseRaw } from '../model/where-clause.ts';
|
|
7
|
+
import { ModelQuerySuggestSupport } from '../types/suggest.ts';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Tools for building suggestion queries
|
|
10
11
|
*/
|
|
11
12
|
export class ModelQuerySuggestUtil {
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Type guard for determining if service supports query suggest operations
|
|
16
|
+
*/
|
|
17
|
+
static isSupported = hasFunction<ModelQuerySuggestSupport>('suggest');
|
|
18
|
+
|
|
13
19
|
/**
|
|
14
20
|
* Build regex for suggesting
|
|
15
21
|
*/
|
|
@@ -68,7 +74,7 @@ export class ModelQuerySuggestUtil {
|
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
76
|
return out
|
|
71
|
-
.
|
|
77
|
+
.toSorted((a, b) => a[0].localeCompare(b[0]))
|
|
72
78
|
.map((a) => a[1])
|
|
73
79
|
.filter((x, i, arr) => x !== arr[i - 1])
|
|
74
80
|
.slice(0, limit ?? 10);
|
package/src/verifier.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
/* eslint @typescript-eslint/no-unused-vars: ["error", { "args": "none"} ] */
|
|
1
2
|
import { DataUtil, SchemaRegistry, ValidationResultError, ValidationError } from '@travetto/schema';
|
|
2
3
|
import { Class } from '@travetto/runtime';
|
|
3
4
|
|
|
4
|
-
import { ModelQuery, Query, PageableModelQuery } from './model/query';
|
|
5
|
+
import { ModelQuery, Query, PageableModelQuery } from './model/query.ts';
|
|
5
6
|
|
|
6
|
-
import { TypeUtil } from './internal/
|
|
7
|
+
import { TypeUtil } from './internal/types.ts';
|
|
7
8
|
|
|
8
9
|
type SimpleType = keyof typeof TypeUtil.OPERATORS;
|
|
9
10
|
|
|
@@ -127,7 +128,7 @@ export class QueryVerifier {
|
|
|
127
128
|
}
|
|
128
129
|
return;
|
|
129
130
|
} else {
|
|
130
|
-
const keys = Object.keys(value).
|
|
131
|
+
const keys = Object.keys(value).toSorted();
|
|
131
132
|
|
|
132
133
|
if (keys.length !== 1 && !(
|
|
133
134
|
keys.length >= 2 &&
|
|
@@ -215,7 +216,7 @@ export class QueryVerifier {
|
|
|
215
216
|
* Handle group by clause
|
|
216
217
|
*/
|
|
217
218
|
static processGroupByClause(state: State, value: object): void {
|
|
218
|
-
|
|
219
|
+
// TODO: Handle group by?
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
/**
|
package/support/doc.support.tsx
CHANGED
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
/** @jsxImportSource @travetto/doc */
|
|
2
2
|
import { d, DocJSXElementByFn, DocJSXElement, DocFileUtil } from '@travetto/doc';
|
|
3
|
+
import { Runtime, toConcrete } from '@travetto/runtime';
|
|
4
|
+
|
|
5
|
+
import { ModelQueryCrudSupport } from '../src/types/crud.ts';
|
|
6
|
+
import { ModelQuerySupport } from '../src/types/query.ts';
|
|
7
|
+
import { ModelQueryFacetSupport, } from '../src/types/facet.ts';
|
|
8
|
+
import { ModelQuerySuggestSupport } from '../src/types/suggest.ts';
|
|
9
|
+
|
|
10
|
+
const toLink = (title: string, target: Function): DocJSXElementByFn<'CodeLink'> =>
|
|
11
|
+
d.codeLink(title, Runtime.getSourceFile(target), new RegExp(`\\binterface\\s+${target.name}`));
|
|
3
12
|
|
|
4
13
|
export const Links = {
|
|
5
|
-
QueryCrud:
|
|
6
|
-
QueryFacet:
|
|
7
|
-
QuerySuggest:
|
|
8
|
-
Query:
|
|
14
|
+
QueryCrud: toLink('Query Crud', toConcrete<ModelQueryCrudSupport>()),
|
|
15
|
+
QueryFacet: toLink('Facet', toConcrete<ModelQueryFacetSupport>()),
|
|
16
|
+
QuerySuggest: toLink('Suggest', toConcrete<ModelQuerySuggestSupport>()),
|
|
17
|
+
Query: toLink('Query', toConcrete<ModelQuerySupport>()),
|
|
9
18
|
};
|
|
10
19
|
|
|
11
20
|
export const ModelQueryTypes = (fn: Function): DocJSXElement[] => {
|
|
12
21
|
const { content } = DocFileUtil.readSource(fn);
|
|
13
22
|
const found: DocJSXElementByFn<'CodeLink'>[] = [];
|
|
14
|
-
const seen = new Set();
|
|
23
|
+
const seen = new Set<string>();
|
|
15
24
|
for (const [, key] of content.matchAll(/Model(Query(Suggest|Facet|Crud)?)Support/g)) {
|
|
16
|
-
if (!seen.has(key)) {
|
|
25
|
+
if (!seen.has(key) && key in Links) {
|
|
17
26
|
seen.add(key);
|
|
18
27
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
19
|
-
|
|
28
|
+
const link = Links[key as keyof typeof Links];
|
|
29
|
+
found.push(link);
|
|
20
30
|
}
|
|
21
31
|
}
|
|
22
32
|
return found.map(v => <li>{v}</li>);
|
package/support/test/crud.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
3
|
import { Suite, Test } from '@travetto/test';
|
|
4
|
-
import {
|
|
5
|
-
import { ModelCrudSupport } from '@travetto/model/src/service/crud';
|
|
6
|
-
import { NotFoundError } from '@travetto/model';
|
|
4
|
+
import { ModelCrudSupport, NotFoundError } from '@travetto/model';
|
|
7
5
|
|
|
8
|
-
import {
|
|
9
|
-
|
|
6
|
+
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
7
|
+
|
|
8
|
+
import { Address, Person, Todo } from './model.ts';
|
|
9
|
+
import { ModelQueryCrudSupport } from '../../src/types/crud.ts';
|
|
10
10
|
|
|
11
11
|
@Suite()
|
|
12
12
|
export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudSupport & ModelCrudSupport> {
|
package/support/test/facet.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
3
|
import { ModelCrudSupport } from '@travetto/model';
|
|
4
|
-
import { BaseModelSuite } from '@travetto/model/support/test/base';
|
|
5
4
|
import { Suite, Test } from '@travetto/test';
|
|
6
5
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
6
|
+
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
7
|
+
|
|
8
|
+
import { Person } from './model.ts';
|
|
9
|
+
import { ModelQueryFacetSupport } from '../../src/types/facet.ts';
|
|
9
10
|
|
|
10
11
|
const pick = <T>(arr: T[] | readonly T[]): T => arr[Math.trunc(Math.random() * arr.length)]!;
|
|
11
12
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { Precision, Schema, Text } from '@travetto/schema';
|
|
1
|
+
import { Precision, Schema, Text, Point } from '@travetto/schema';
|
|
2
2
|
import { Model, ModelType } from '@travetto/model';
|
|
3
3
|
|
|
4
|
-
import { Point } from '../../src/model/where-clause';
|
|
5
|
-
|
|
6
4
|
@Schema()
|
|
7
5
|
export class Address {
|
|
8
6
|
@Text() street1: string;
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
3
|
import { Suite, Test } from '@travetto/test';
|
|
4
|
-
import {
|
|
5
|
-
import { ModelCrudSupport } from '@travetto/model/src/service/crud';
|
|
6
|
-
import { Doctor, Engineer, Worker, Firefighter } from '@travetto/model/support/test/polymorphism';
|
|
7
|
-
import { NotFoundError } from '@travetto/model';
|
|
4
|
+
import { NotFoundError, ModelCrudSupport } from '@travetto/model';
|
|
8
5
|
import { castTo } from '@travetto/runtime';
|
|
9
6
|
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { ModelQueryFacetSupport } from '../../src/service/facet';
|
|
13
|
-
import { ModelQuerySuggestSupport } from '../../src/service/suggest';
|
|
7
|
+
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
8
|
+
import { Doctor, Engineer, Worker, Firefighter } from '@travetto/model/support/test/polymorphism.ts';
|
|
14
9
|
|
|
15
|
-
import {
|
|
10
|
+
import { ModelQueryCrudSupport } from '../../src/types/crud.ts';
|
|
11
|
+
import { ModelQuerySupport } from '../../src/types/query.ts';
|
|
12
|
+
import { ModelQueryFacetSupport } from '../../src/types/facet.ts';
|
|
13
|
+
import { ModelQuerySuggestSupport } from '../../src/types/suggest.ts';
|
|
14
|
+
|
|
15
|
+
import { ModelQueryFacetUtil } from '../../src/util/facet.ts';
|
|
16
|
+
import { ModelQuerySuggestUtil } from '../../src/util/suggest.ts';
|
|
17
|
+
import { ModelQueryCrudUtil } from '../../src/util/crud.ts';
|
|
16
18
|
|
|
17
19
|
@Suite()
|
|
18
20
|
export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<ModelQuerySupport & ModelCrudSupport> {
|
|
@@ -42,7 +44,7 @@ export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<ModelQu
|
|
|
42
44
|
await assert.rejects(() => svc.queryOne(Firefighter, { where: { name: 'bob' } }), NotFoundError);
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
@Test({ skip: ModelQueryPolymorphismSuite.ifNot(
|
|
47
|
+
@Test({ skip: ModelQueryPolymorphismSuite.ifNot(ModelQueryCrudUtil.isSupported) })
|
|
46
48
|
async testCrudQuery() {
|
|
47
49
|
const svc: ModelQueryCrudSupport & ModelQuerySupport = castTo(await this.service);
|
|
48
50
|
const [doc, doc2, fire, eng] = [
|
|
@@ -68,7 +70,7 @@ export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<ModelQu
|
|
|
68
70
|
assert(await this.getSize(Firefighter) === 0);
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
@Test({ skip: ModelQueryPolymorphismSuite.ifNot(
|
|
73
|
+
@Test({ skip: ModelQueryPolymorphismSuite.ifNot(ModelQuerySuggestUtil.isSupported) })
|
|
72
74
|
async testSuggestQuery() {
|
|
73
75
|
const svc: ModelQuerySuggestSupport & ModelQuerySupport = castTo(await this.service);
|
|
74
76
|
const [doc, doc2, fire, eng] = [
|
|
@@ -92,7 +94,7 @@ export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<ModelQu
|
|
|
92
94
|
assert((await svc.suggestValues(Firefighter, 'name', 'r'))[0] === 'rob');
|
|
93
95
|
}
|
|
94
96
|
|
|
95
|
-
@Test({ skip: ModelQueryPolymorphismSuite.ifNot(
|
|
97
|
+
@Test({ skip: ModelQueryPolymorphismSuite.ifNot(ModelQueryFacetUtil.isSupported) })
|
|
96
98
|
async testFacetQuery() {
|
|
97
99
|
const svc: ModelQueryFacetSupport & ModelQuerySupport = castTo(await this.service);
|
|
98
100
|
const [doc, doc2, fire, eng] = [
|
package/support/test/query.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
3
|
import { Suite, Test } from '@travetto/test';
|
|
4
|
-
import { BaseModelSuite } from '@travetto/model/support/test/base';
|
|
5
|
-
import { ModelCrudSupport } from '@travetto/model/src/service/crud';
|
|
6
4
|
import { TimeUtil } from '@travetto/runtime';
|
|
7
|
-
import { NotFoundError } from '@travetto/model';
|
|
5
|
+
import { NotFoundError, ModelCrudSupport } from '@travetto/model';
|
|
8
6
|
|
|
9
|
-
import {
|
|
7
|
+
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
10
8
|
|
|
11
|
-
import {
|
|
9
|
+
import { Aged, Location, Names, Note, Person, SimpleList, WithNestedLists, WithNestedNestedLists } from './model.ts';
|
|
10
|
+
|
|
11
|
+
import { ModelQuerySupport } from '../../src/types/query.ts';
|
|
12
12
|
|
|
13
13
|
@Suite()
|
|
14
14
|
export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport & ModelCrudSupport> {
|
|
@@ -41,8 +41,8 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
41
41
|
const none = await svc.queryCount(Person, { where: { id: { $ne: people[0].id } } });
|
|
42
42
|
assert(none === 3);
|
|
43
43
|
|
|
44
|
-
const
|
|
45
|
-
assert(
|
|
44
|
+
const noneIds = await svc.query(Person, { where: { id: { $ne: people[0].id } } });
|
|
45
|
+
assert(noneIds.every(x => x.id !== people[0].id));
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
@Test('verify word boundary')
|
|
@@ -255,7 +255,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
255
255
|
|
|
256
256
|
assert(await svc.queryCount(Location, {}) === 25);
|
|
257
257
|
|
|
258
|
-
const
|
|
258
|
+
const result = await svc.query(Location, {
|
|
259
259
|
limit: 100,
|
|
260
260
|
where: {
|
|
261
261
|
point: {
|
|
@@ -264,7 +264,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
264
264
|
}
|
|
265
265
|
});
|
|
266
266
|
|
|
267
|
-
assert(
|
|
267
|
+
assert(result.length === 25);
|
|
268
268
|
|
|
269
269
|
const rad = await svc.query(Location, {
|
|
270
270
|
limit: 100,
|
package/support/test/suggest.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
3
|
import { ModelCrudSupport } from '@travetto/model';
|
|
4
|
-
import { BaseModelSuite } from '@travetto/model/support/test/base';
|
|
5
4
|
import { Suite, Test } from '@travetto/test';
|
|
6
5
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
6
|
+
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
7
|
+
|
|
8
|
+
import { Person } from './model.ts';
|
|
9
|
+
import { ModelQuerySuggestSupport } from '../../src/types/suggest.ts';
|
|
9
10
|
|
|
10
11
|
@Suite()
|
|
11
12
|
export abstract class ModelQuerySuggestSuite extends BaseModelSuite<ModelQuerySuggestSupport & ModelCrudSupport> {
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { DataUtil } from '@travetto/schema';
|
|
2
|
-
|
|
3
|
-
export class PointImpl {
|
|
4
|
-
static validateSchema(input: unknown): 'type' | undefined {
|
|
5
|
-
const ret = this.bindSchema(input);
|
|
6
|
-
return ret && !isNaN(ret[0]) && !isNaN(ret[1]) ? undefined : 'type';
|
|
7
|
-
}
|
|
8
|
-
static bindSchema(input: unknown): [number, number] | undefined {
|
|
9
|
-
if (Array.isArray(input) && input.length === 2) {
|
|
10
|
-
return [
|
|
11
|
-
DataUtil.coerceType(input[0], Number, false),
|
|
12
|
-
DataUtil.coerceType(input[1], Number, false)
|
|
13
|
-
];
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { hasFunction } from '@travetto/runtime';
|
|
2
|
-
|
|
3
|
-
import type { ModelQueryCrudSupport } from '../../service/crud';
|
|
4
|
-
import type { ModelQueryFacetSupport } from '../../service/facet';
|
|
5
|
-
import type { ModelQuerySupport } from '../../service/query';
|
|
6
|
-
import type { ModelQuerySuggestSupport } from '../../service/suggest';
|
|
7
|
-
|
|
8
|
-
export class ModelQuerySupportTarget { }
|
|
9
|
-
export class ModelQueryCrudSupportTarget { }
|
|
10
|
-
export class ModelQueryFacetSupportTarget { }
|
|
11
|
-
export class ModelQuerySuggestSupportTarget { }
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Type guard for determining if service supports query operations
|
|
15
|
-
*/
|
|
16
|
-
export const isQuerySupported = hasFunction<ModelQuerySupport>('query');
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Type guard for determining if service supports query crud operations
|
|
20
|
-
*/
|
|
21
|
-
export const isQueryCrudSupported = hasFunction<ModelQueryCrudSupport>('deleteByQuery');
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Type guard for determining if service supports query facet operations
|
|
25
|
-
*/
|
|
26
|
-
export const isQueryFacetSupported = hasFunction<ModelQueryFacetSupport>('facet');
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Type guard for determining if service supports query suggest operations
|
|
30
|
-
*/
|
|
31
|
-
export const isQuerySuggestSupported = hasFunction<ModelQuerySuggestSupport>('suggest');
|