@travetto/model-query 8.0.0-alpha.26 → 8.0.0-alpha.28
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/indexes.ts +1 -1
- package/src/util/suggest.ts +1 -1
- package/support/test/query.ts +37 -122
- package/support/test/suggest.ts +53 -1
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.28",
|
|
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.22",
|
|
31
|
+
"@travetto/model": "^8.0.0-alpha.26",
|
|
32
|
+
"@travetto/schema": "^8.0.0-alpha.25"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@travetto/test": "^8.0.0-alpha.
|
|
35
|
+
"@travetto/test": "^8.0.0-alpha.23"
|
|
36
36
|
},
|
|
37
37
|
"peerDependenciesMeta": {
|
|
38
38
|
"@travetto/test": {
|
package/src/model/indexes.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type IndexField<T extends ModelType> = IndexClauseRaw<RetainPrimitiveFiel
|
|
|
12
12
|
/**
|
|
13
13
|
* Index options
|
|
14
14
|
*/
|
|
15
|
-
export interface QueryIndexConfig<T extends ModelType> extends IndexConfig<'query'> {
|
|
15
|
+
export interface QueryIndexConfig<T extends ModelType> extends IndexConfig<'query', T> {
|
|
16
16
|
/**
|
|
17
17
|
* Fields and sort order
|
|
18
18
|
*/
|
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 += 1) {
|
|
89
|
+
for (let i = 1; i < parts.length && resultValue !== undefined && resultValue !== null; i += 1) {
|
|
90
90
|
resultValue = resultValue[castKey(parts[i])];
|
|
91
91
|
}
|
|
92
92
|
if (Array.isArray(resultValue)) {
|
package/support/test/query.ts
CHANGED
|
@@ -399,28 +399,13 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
399
399
|
@Test()
|
|
400
400
|
async verifyArrayEmptyVsNot() {
|
|
401
401
|
const service = await this.service;
|
|
402
|
-
await
|
|
403
|
-
tags: ['a', 'b']
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
names: [
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
await service.create(WithNestedLists, {
|
|
411
|
-
names: ['c', 'd'],
|
|
412
|
-
tags: ['e', 'f']
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
await service.create(WithNestedLists, {
|
|
416
|
-
names: ['g', 'h'],
|
|
417
|
-
tags: []
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
await service.create(WithNestedLists, {
|
|
421
|
-
names: [],
|
|
422
|
-
tags: []
|
|
423
|
-
});
|
|
402
|
+
await this.saveAll(WithNestedLists, [
|
|
403
|
+
WithNestedLists.from({ tags: ['a', 'b'] }),
|
|
404
|
+
WithNestedLists.from({ names: ['c', 'd'] }),
|
|
405
|
+
WithNestedLists.from({ names: ['c', 'd'], tags: ['e', 'f'] }),
|
|
406
|
+
WithNestedLists.from({ names: ['g', 'h'], tags: [] }),
|
|
407
|
+
WithNestedLists.from({ names: [], tags: [] })
|
|
408
|
+
]);
|
|
424
409
|
|
|
425
410
|
let total = await service.queryCount(WithNestedLists, {
|
|
426
411
|
where: {
|
|
@@ -428,6 +413,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
428
413
|
}
|
|
429
414
|
});
|
|
430
415
|
assert(total === 3);
|
|
416
|
+
|
|
431
417
|
total = await service.queryCount(WithNestedLists, {
|
|
432
418
|
where: {
|
|
433
419
|
names: { $exists: false }
|
|
@@ -463,35 +449,20 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
463
449
|
names: { $exists: true }
|
|
464
450
|
}
|
|
465
451
|
});
|
|
466
|
-
|
|
467
452
|
assert(total === 1);
|
|
468
453
|
}
|
|
469
454
|
|
|
470
455
|
@Test()
|
|
471
456
|
async verifyNestedArrayEmptyVsNot() {
|
|
472
457
|
const service = await this.service;
|
|
473
|
-
await service.create(WithNestedNestedLists, {
|
|
474
|
-
tags: ['a', 'b']
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
await service.create(WithNestedNestedLists, {
|
|
478
|
-
sub: { names: ['c', 'd'] }
|
|
479
|
-
});
|
|
480
458
|
|
|
481
|
-
await
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
tags: []
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
await service.create(WithNestedNestedLists, {
|
|
492
|
-
sub: {},
|
|
493
|
-
tags: []
|
|
494
|
-
});
|
|
459
|
+
await this.saveAll(WithNestedNestedLists, [
|
|
460
|
+
WithNestedNestedLists.from({ tags: ['a', 'b'] }),
|
|
461
|
+
WithNestedNestedLists.from({ sub: { names: ['c', 'd'] } }),
|
|
462
|
+
WithNestedNestedLists.from({ sub: { names: ['c', 'd'] }, tags: ['e', 'f'] }),
|
|
463
|
+
WithNestedNestedLists.from({ sub: { names: ['g', 'h'] }, tags: [] }),
|
|
464
|
+
WithNestedNestedLists.from({ sub: {}, tags: [] })
|
|
465
|
+
]);
|
|
495
466
|
|
|
496
467
|
let total = await service.queryCount(WithNestedNestedLists, {
|
|
497
468
|
where: {
|
|
@@ -499,6 +470,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
499
470
|
}
|
|
500
471
|
});
|
|
501
472
|
assert(total === 3);
|
|
473
|
+
|
|
502
474
|
total = await service.queryCount(WithNestedNestedLists, {
|
|
503
475
|
where: {
|
|
504
476
|
sub: { names: { $exists: false } }
|
|
@@ -542,68 +514,35 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
542
514
|
async verifyNestedArraySchemaQuery() {
|
|
543
515
|
const service = await this.service;
|
|
544
516
|
|
|
545
|
-
await
|
|
546
|
-
Recipe,
|
|
517
|
+
await this.saveAll(Recipe, [
|
|
547
518
|
Recipe.from({
|
|
548
|
-
sections: [
|
|
549
|
-
|
|
550
|
-
ingredients: [{ name: 'garlic' }, { name: 'onion' }]
|
|
551
|
-
}
|
|
552
|
-
]
|
|
553
|
-
})
|
|
554
|
-
);
|
|
555
|
-
|
|
556
|
-
await service.create(
|
|
557
|
-
Recipe,
|
|
519
|
+
sections: [{ ingredients: [{ name: 'garlic' }, { name: 'onion' }] }]
|
|
520
|
+
}),
|
|
558
521
|
Recipe.from({
|
|
559
|
-
sections: [
|
|
560
|
-
|
|
561
|
-
ingredients: [{ name: 'paprika' }, { name: 'salt' }]
|
|
562
|
-
}
|
|
563
|
-
]
|
|
564
|
-
})
|
|
565
|
-
);
|
|
566
|
-
|
|
567
|
-
await service.create(
|
|
568
|
-
Recipe,
|
|
522
|
+
sections: [{ ingredients: [{ name: 'paprika' }, { name: 'salt' }] }]
|
|
523
|
+
}),
|
|
569
524
|
Recipe.from({
|
|
570
|
-
sections: [
|
|
571
|
-
{
|
|
572
|
-
ingredients: [{ name: 'garlic' }, { name: 'thyme' }]
|
|
573
|
-
}
|
|
574
|
-
]
|
|
525
|
+
sections: [{ ingredients: [{ name: 'garlic' }, { name: 'thyme' }] }]
|
|
575
526
|
})
|
|
576
|
-
);
|
|
527
|
+
]);
|
|
577
528
|
|
|
578
529
|
const matchSingle = await service.query(Recipe, {
|
|
579
530
|
where: {
|
|
580
|
-
sections: {
|
|
581
|
-
ingredients: {
|
|
582
|
-
name: 'garlic'
|
|
583
|
-
}
|
|
584
|
-
}
|
|
531
|
+
sections: { ingredients: { name: 'garlic' } }
|
|
585
532
|
}
|
|
586
533
|
});
|
|
587
534
|
assert(matchSingle.length === 2);
|
|
588
535
|
|
|
589
536
|
const matchIn = await service.query(Recipe, {
|
|
590
537
|
where: {
|
|
591
|
-
sections: {
|
|
592
|
-
ingredients: {
|
|
593
|
-
name: { $in: ['onion', 'salt'] }
|
|
594
|
-
}
|
|
595
|
-
}
|
|
538
|
+
sections: { ingredients: { name: { $in: ['onion', 'salt'] } } }
|
|
596
539
|
}
|
|
597
540
|
});
|
|
598
541
|
assert(matchIn.length === 2);
|
|
599
542
|
|
|
600
543
|
const matchNotEqual = await service.query(Recipe, {
|
|
601
544
|
where: {
|
|
602
|
-
sections: {
|
|
603
|
-
ingredients: {
|
|
604
|
-
name: { $ne: 'garlic' }
|
|
605
|
-
}
|
|
606
|
-
}
|
|
545
|
+
sections: { ingredients: { name: { $ne: 'garlic' } } }
|
|
607
546
|
}
|
|
608
547
|
});
|
|
609
548
|
assert(matchNotEqual.length === 1);
|
|
@@ -613,32 +552,23 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
613
552
|
async verifyArrayOfObjectsProperty() {
|
|
614
553
|
const service = await this.service;
|
|
615
554
|
|
|
616
|
-
await
|
|
617
|
-
Note,
|
|
555
|
+
await this.saveAll(Note, [
|
|
618
556
|
Note.from({
|
|
619
557
|
entities: [
|
|
620
558
|
{ id: '1', label: 'one' },
|
|
621
559
|
{ id: '2', label: 'two' }
|
|
622
560
|
]
|
|
623
|
-
})
|
|
624
|
-
);
|
|
625
|
-
|
|
626
|
-
await service.create(
|
|
627
|
-
Note,
|
|
561
|
+
}),
|
|
628
562
|
Note.from({
|
|
629
563
|
entities: [
|
|
630
564
|
{ id: '3', label: 'three' },
|
|
631
565
|
{ id: '4', label: 'four' }
|
|
632
566
|
]
|
|
633
|
-
})
|
|
634
|
-
);
|
|
635
|
-
|
|
636
|
-
await service.create(
|
|
637
|
-
Note,
|
|
567
|
+
}),
|
|
638
568
|
Note.from({
|
|
639
569
|
entities: [{ id: '5', label: 'five' }]
|
|
640
570
|
})
|
|
641
|
-
);
|
|
571
|
+
]);
|
|
642
572
|
|
|
643
573
|
const inResults = await service.query(Note, {
|
|
644
574
|
where: {
|
|
@@ -665,32 +595,17 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
665
595
|
async verifyNestedObjectArrayProperty() {
|
|
666
596
|
const service = await this.service;
|
|
667
597
|
|
|
668
|
-
await
|
|
669
|
-
PersonFamily,
|
|
598
|
+
await this.saveAll(PersonFamily, [
|
|
670
599
|
PersonFamily.from({
|
|
671
|
-
family: {
|
|
672
|
-
|
|
673
|
-
}
|
|
674
|
-
})
|
|
675
|
-
);
|
|
676
|
-
|
|
677
|
-
await service.create(
|
|
678
|
-
PersonFamily,
|
|
600
|
+
family: { children: [{ name: 'one' }, { name: 'two' }] }
|
|
601
|
+
}),
|
|
679
602
|
PersonFamily.from({
|
|
680
|
-
family: {
|
|
681
|
-
|
|
682
|
-
}
|
|
683
|
-
})
|
|
684
|
-
);
|
|
685
|
-
|
|
686
|
-
await service.create(
|
|
687
|
-
PersonFamily,
|
|
603
|
+
family: { children: [{ name: 'three' }, { name: 'four' }] }
|
|
604
|
+
}),
|
|
688
605
|
PersonFamily.from({
|
|
689
|
-
family: {
|
|
690
|
-
children: [{ name: 'five' }]
|
|
691
|
-
}
|
|
606
|
+
family: { children: [{ name: 'five' }] }
|
|
692
607
|
})
|
|
693
|
-
);
|
|
608
|
+
]);
|
|
694
609
|
|
|
695
610
|
const inResults = await service.query(PersonFamily, {
|
|
696
611
|
where: {
|
package/support/test/suggest.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { Suite, Test } from '@travetto/test';
|
|
|
6
6
|
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
7
7
|
|
|
8
8
|
import type { ModelQuerySuggestSupport } from '../../src/types/suggest.ts';
|
|
9
|
-
import { Person } from './model.ts';
|
|
9
|
+
import { Person, WithNestedLists, WithNestedNestedLists } from './model.ts';
|
|
10
10
|
|
|
11
11
|
@Suite()
|
|
12
12
|
export abstract class ModelQuerySuggestSuite extends BaseModelSuite<ModelQuerySuggestSupport & ModelCrudSupport> {
|
|
@@ -27,6 +27,23 @@ export abstract class ModelQuerySuggestSuite extends BaseModelSuite<ModelQuerySu
|
|
|
27
27
|
await this.saveAll(Person, people);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
async #loadNestedLists() {
|
|
31
|
+
await this.saveAll(WithNestedLists, [
|
|
32
|
+
WithNestedLists.from({ tags: ['apple', 'banana', 'apricot'], names: ['alex', 'amber'] }),
|
|
33
|
+
WithNestedLists.from({ tags: ['blueberry', 'avocado'], names: ['bob', 'bill'] }),
|
|
34
|
+
WithNestedLists.from({ tags: ['cherry', 'date'], names: ['charlie'] })
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async #loadNestedNestedLists() {
|
|
39
|
+
await this.saveAll(WithNestedNestedLists, [
|
|
40
|
+
WithNestedNestedLists.from({ tags: ['apple', 'banana'], sub: { names: ['alex', 'amber'] } }),
|
|
41
|
+
WithNestedNestedLists.from({ tags: ['blueberry'], sub: { names: ['avocado', 'bill'] } }),
|
|
42
|
+
WithNestedNestedLists.from({ tags: ['cherry'], sub: { names: ['charlie'] } }),
|
|
43
|
+
WithNestedNestedLists.from({ tags: ['date'] })
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
|
|
30
47
|
@Test('Verify value suggestion')
|
|
31
48
|
async testSuggestion() {
|
|
32
49
|
const service = await this.service;
|
|
@@ -65,4 +82,39 @@ export abstract class ModelQuerySuggestSuite extends BaseModelSuite<ModelQuerySu
|
|
|
65
82
|
assert(suggestedEntities[0] instanceof Person);
|
|
66
83
|
assert(suggestedEntities[1] instanceof Person);
|
|
67
84
|
}
|
|
85
|
+
|
|
86
|
+
@Test('Verify suggestion on string arrays')
|
|
87
|
+
async verifyStringArraySuggestions() {
|
|
88
|
+
const service = await this.service;
|
|
89
|
+
|
|
90
|
+
await this.#loadNestedLists();
|
|
91
|
+
|
|
92
|
+
const suggestedValues = await service.suggestValuesByQuery(WithNestedLists, 'tags', 'ap');
|
|
93
|
+
assert(suggestedValues.length === 2);
|
|
94
|
+
assert(suggestedValues[0] === 'apple');
|
|
95
|
+
assert(suggestedValues[1] === 'apricot');
|
|
96
|
+
|
|
97
|
+
const suggestedEntities = await service.suggestByQuery(WithNestedLists, 'tags', 'ap');
|
|
98
|
+
assert(suggestedEntities.length === 1);
|
|
99
|
+
assert(suggestedEntities[0] instanceof WithNestedLists);
|
|
100
|
+
assert(suggestedEntities[0].tags?.includes('apple'));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@Test('Verify suggestion on nested string arrays')
|
|
104
|
+
async verifyNestedStringArraySuggestions() {
|
|
105
|
+
const service = await this.service;
|
|
106
|
+
|
|
107
|
+
await this.#loadNestedNestedLists();
|
|
108
|
+
|
|
109
|
+
const suggestedValues = await service.suggestValuesByQuery(WithNestedNestedLists, 'sub.names', 'a');
|
|
110
|
+
assert(suggestedValues.length === 3);
|
|
111
|
+
assert(suggestedValues[0] === 'alex');
|
|
112
|
+
assert(suggestedValues[1] === 'amber');
|
|
113
|
+
assert(suggestedValues[2] === 'avocado');
|
|
114
|
+
|
|
115
|
+
const suggestedEntities = await service.suggestByQuery(WithNestedNestedLists, 'sub.names', 'al');
|
|
116
|
+
assert(suggestedEntities.length === 1);
|
|
117
|
+
assert(suggestedEntities[0] instanceof WithNestedNestedLists);
|
|
118
|
+
assert(suggestedEntities[0].sub?.names?.includes('alex'));
|
|
119
|
+
}
|
|
68
120
|
}
|