@travetto/model-query 8.0.0-alpha.24 → 8.0.0-alpha.26
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/package.json +5 -5
- package/src/model/where-clause.ts +1 -1
- package/src/util/suggest.ts +1 -1
- package/support/test/crud.ts +2 -2
- package/support/test/model.ts +32 -0
- package/support/test/query.ts +234 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-query",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.26",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Datastore abstraction for advanced query support.",
|
|
6
6
|
"keywords": [
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"directory": "module/model-query"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@travetto/di": "^8.0.0-alpha.
|
|
31
|
-
"@travetto/model": "^8.0.0-alpha.
|
|
32
|
-
"@travetto/schema": "^8.0.0-alpha.
|
|
30
|
+
"@travetto/di": "^8.0.0-alpha.21",
|
|
31
|
+
"@travetto/model": "^8.0.0-alpha.24",
|
|
32
|
+
"@travetto/schema": "^8.0.0-alpha.23"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@travetto/test": "^8.0.0-alpha.
|
|
35
|
+
"@travetto/test": "^8.0.0-alpha.22"
|
|
36
36
|
},
|
|
37
37
|
"peerDependenciesMeta": {
|
|
38
38
|
"@travetto/test": {
|
|
@@ -45,7 +45,7 @@ type GeoField = {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
export type PropWhereClause<T> = {
|
|
48
|
-
[P in keyof T]?: T[P] extends number | undefined
|
|
48
|
+
-readonly [P in keyof T]?: T[P] extends number | undefined
|
|
49
49
|
? General<number> | ScalarField<number> | ComparableField<number> | number
|
|
50
50
|
: T[P] extends bigint | undefined
|
|
51
51
|
? General<bigint> | ScalarField<bigint> | ComparableField<bigint> | bigint
|
package/src/util/suggest.ts
CHANGED
|
@@ -86,7 +86,7 @@ export class ModelQuerySuggestUtil {
|
|
|
86
86
|
|
|
87
87
|
for (const result of results) {
|
|
88
88
|
let resultValue = result[castKey<T>(parts[0])];
|
|
89
|
-
for (let i = 1; i < parts.length; i
|
|
89
|
+
for (let i = 1; i < parts.length; i += 1) {
|
|
90
90
|
resultValue = resultValue[castKey(parts[i])];
|
|
91
91
|
}
|
|
92
92
|
if (Array.isArray(resultValue)) {
|
package/support/test/crud.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Model, type ModelCrudSupport, NotFoundError, UniqueError } from '@travetto/model';
|
|
4
4
|
import { castTo } from '@travetto/runtime';
|
|
5
5
|
import { Suite, Test } from '@travetto/test';
|
|
6
6
|
|
|
@@ -29,7 +29,7 @@ export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudS
|
|
|
29
29
|
async testUnique() {
|
|
30
30
|
const svc = await this.service;
|
|
31
31
|
await svc.create(UniqueUser2, UniqueUser2.from({ name: 'bob' }));
|
|
32
|
-
await assert.rejects(() => svc.create(UniqueUser2, UniqueUser2.from({ name: 'bob' })),
|
|
32
|
+
await assert.rejects(() => svc.create(UniqueUser2, UniqueUser2.from({ name: 'bob' })), UniqueError);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
@Test()
|
package/support/test/model.ts
CHANGED
|
@@ -99,3 +99,35 @@ export class BigIntModel {
|
|
|
99
99
|
largeNumber: bigint;
|
|
100
100
|
optionalBigInt?: bigint;
|
|
101
101
|
}
|
|
102
|
+
|
|
103
|
+
@Schema()
|
|
104
|
+
export class Child {
|
|
105
|
+
name: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@Schema()
|
|
109
|
+
export class Family {
|
|
110
|
+
children?: Child[];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@Model()
|
|
114
|
+
export class PersonFamily implements ModelType {
|
|
115
|
+
id: string;
|
|
116
|
+
family?: Family;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@Schema()
|
|
120
|
+
export class RecipeIngredient {
|
|
121
|
+
name: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@Schema()
|
|
125
|
+
export class RecipeSection {
|
|
126
|
+
ingredients: RecipeIngredient[] = [];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@Model()
|
|
130
|
+
export class Recipe implements ModelType {
|
|
131
|
+
id: string;
|
|
132
|
+
sections: RecipeSection[] = [];
|
|
133
|
+
}
|
package/support/test/query.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { Suite, Test } from '@travetto/test';
|
|
|
7
7
|
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
8
8
|
|
|
9
9
|
import type { ModelQuerySupport } from '../../src/types/query.ts';
|
|
10
|
-
import { Aged, Location, Names, Note, Person, SimpleList, WithNestedLists, WithNestedNestedLists } from './model.ts';
|
|
10
|
+
import { Aged, Location, Names, Note, Person, PersonFamily, Recipe, SimpleList, WithNestedLists, WithNestedNestedLists } from './model.ts';
|
|
11
11
|
|
|
12
12
|
@Suite()
|
|
13
13
|
export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport & ModelCrudSupport> {
|
|
@@ -263,8 +263,8 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
263
263
|
|
|
264
264
|
const toAdd = [];
|
|
265
265
|
|
|
266
|
-
for (let i = 0; i < 5; i
|
|
267
|
-
for (let j = 0; j < 5; j
|
|
266
|
+
for (let i = 0; i < 5; i += 1) {
|
|
267
|
+
for (let j = 0; j < 5; j += 1) {
|
|
268
268
|
toAdd.push(
|
|
269
269
|
Location.from({
|
|
270
270
|
point: [i, j]
|
|
@@ -537,4 +537,235 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
537
537
|
|
|
538
538
|
assert(total === 1);
|
|
539
539
|
}
|
|
540
|
+
|
|
541
|
+
@Test('Verify queries on nested arrays of schemas')
|
|
542
|
+
async verifyNestedArraySchemaQuery() {
|
|
543
|
+
const service = await this.service;
|
|
544
|
+
|
|
545
|
+
await service.create(
|
|
546
|
+
Recipe,
|
|
547
|
+
Recipe.from({
|
|
548
|
+
sections: [
|
|
549
|
+
{
|
|
550
|
+
ingredients: [{ name: 'garlic' }, { name: 'onion' }]
|
|
551
|
+
}
|
|
552
|
+
]
|
|
553
|
+
})
|
|
554
|
+
);
|
|
555
|
+
|
|
556
|
+
await service.create(
|
|
557
|
+
Recipe,
|
|
558
|
+
Recipe.from({
|
|
559
|
+
sections: [
|
|
560
|
+
{
|
|
561
|
+
ingredients: [{ name: 'paprika' }, { name: 'salt' }]
|
|
562
|
+
}
|
|
563
|
+
]
|
|
564
|
+
})
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
await service.create(
|
|
568
|
+
Recipe,
|
|
569
|
+
Recipe.from({
|
|
570
|
+
sections: [
|
|
571
|
+
{
|
|
572
|
+
ingredients: [{ name: 'garlic' }, { name: 'thyme' }]
|
|
573
|
+
}
|
|
574
|
+
]
|
|
575
|
+
})
|
|
576
|
+
);
|
|
577
|
+
|
|
578
|
+
const matchSingle = await service.query(Recipe, {
|
|
579
|
+
where: {
|
|
580
|
+
sections: {
|
|
581
|
+
ingredients: {
|
|
582
|
+
name: 'garlic'
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
assert(matchSingle.length === 2);
|
|
588
|
+
|
|
589
|
+
const matchIn = await service.query(Recipe, {
|
|
590
|
+
where: {
|
|
591
|
+
sections: {
|
|
592
|
+
ingredients: {
|
|
593
|
+
name: { $in: ['onion', 'salt'] }
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
assert(matchIn.length === 2);
|
|
599
|
+
|
|
600
|
+
const matchNotEqual = await service.query(Recipe, {
|
|
601
|
+
where: {
|
|
602
|
+
sections: {
|
|
603
|
+
ingredients: {
|
|
604
|
+
name: { $ne: 'garlic' }
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
assert(matchNotEqual.length === 1);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
@Test('Verify array of objects property queries')
|
|
613
|
+
async verifyArrayOfObjectsProperty() {
|
|
614
|
+
const service = await this.service;
|
|
615
|
+
|
|
616
|
+
await service.create(
|
|
617
|
+
Note,
|
|
618
|
+
Note.from({
|
|
619
|
+
entities: [
|
|
620
|
+
{ id: '1', label: 'one' },
|
|
621
|
+
{ id: '2', label: 'two' }
|
|
622
|
+
]
|
|
623
|
+
})
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
await service.create(
|
|
627
|
+
Note,
|
|
628
|
+
Note.from({
|
|
629
|
+
entities: [
|
|
630
|
+
{ id: '3', label: 'three' },
|
|
631
|
+
{ id: '4', label: 'four' }
|
|
632
|
+
]
|
|
633
|
+
})
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
await service.create(
|
|
637
|
+
Note,
|
|
638
|
+
Note.from({
|
|
639
|
+
entities: [{ id: '5', label: 'five' }]
|
|
640
|
+
})
|
|
641
|
+
);
|
|
642
|
+
|
|
643
|
+
const inResults = await service.query(Note, {
|
|
644
|
+
where: {
|
|
645
|
+
entities: {
|
|
646
|
+
label: {
|
|
647
|
+
$in: ['one', 'four', 'missing']
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
assert(inResults.length === 2);
|
|
653
|
+
|
|
654
|
+
const eqResults = await service.query(Note, {
|
|
655
|
+
where: {
|
|
656
|
+
entities: {
|
|
657
|
+
label: 'five'
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
assert(eqResults.length === 1);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
@Test('Verify nested object array property queries')
|
|
665
|
+
async verifyNestedObjectArrayProperty() {
|
|
666
|
+
const service = await this.service;
|
|
667
|
+
|
|
668
|
+
await service.create(
|
|
669
|
+
PersonFamily,
|
|
670
|
+
PersonFamily.from({
|
|
671
|
+
family: {
|
|
672
|
+
children: [{ name: 'one' }, { name: 'two' }]
|
|
673
|
+
}
|
|
674
|
+
})
|
|
675
|
+
);
|
|
676
|
+
|
|
677
|
+
await service.create(
|
|
678
|
+
PersonFamily,
|
|
679
|
+
PersonFamily.from({
|
|
680
|
+
family: {
|
|
681
|
+
children: [{ name: 'three' }, { name: 'four' }]
|
|
682
|
+
}
|
|
683
|
+
})
|
|
684
|
+
);
|
|
685
|
+
|
|
686
|
+
await service.create(
|
|
687
|
+
PersonFamily,
|
|
688
|
+
PersonFamily.from({
|
|
689
|
+
family: {
|
|
690
|
+
children: [{ name: 'five' }]
|
|
691
|
+
}
|
|
692
|
+
})
|
|
693
|
+
);
|
|
694
|
+
|
|
695
|
+
const inResults = await service.query(PersonFamily, {
|
|
696
|
+
where: {
|
|
697
|
+
family: {
|
|
698
|
+
children: {
|
|
699
|
+
name: {
|
|
700
|
+
$in: ['one', 'two', 'three']
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
});
|
|
706
|
+
assert(inResults.length === 2);
|
|
707
|
+
|
|
708
|
+
const eqResults = await service.query(PersonFamily, {
|
|
709
|
+
where: {
|
|
710
|
+
family: {
|
|
711
|
+
children: {
|
|
712
|
+
name: 'five'
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
assert(eqResults.length === 1);
|
|
718
|
+
|
|
719
|
+
const neResults = await service.query(PersonFamily, {
|
|
720
|
+
where: {
|
|
721
|
+
family: {
|
|
722
|
+
children: {
|
|
723
|
+
name: {
|
|
724
|
+
$ne: 'five'
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
assert(neResults.length === 2);
|
|
731
|
+
|
|
732
|
+
const ninResults = await service.query(PersonFamily, {
|
|
733
|
+
where: {
|
|
734
|
+
family: {
|
|
735
|
+
children: {
|
|
736
|
+
name: {
|
|
737
|
+
$nin: ['one', 'two']
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
});
|
|
743
|
+
assert(ninResults.length === 2);
|
|
744
|
+
|
|
745
|
+
const allResults = await service.query(PersonFamily, {
|
|
746
|
+
where: {
|
|
747
|
+
family: {
|
|
748
|
+
children: {
|
|
749
|
+
name: {
|
|
750
|
+
$all: ['one', 'two']
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
});
|
|
756
|
+
assert(allResults.length === 1);
|
|
757
|
+
|
|
758
|
+
const existsResults = await service.query(PersonFamily, {
|
|
759
|
+
where: {
|
|
760
|
+
family: {
|
|
761
|
+
children: {
|
|
762
|
+
name: {
|
|
763
|
+
$exists: true
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
assert(existsResults.length === 3);
|
|
770
|
+
}
|
|
540
771
|
}
|