@travetto/model-indexed 8.0.0-alpha.13 → 8.0.0-alpha.14

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-indexed",
3
- "version": "8.0.0-alpha.13",
3
+ "version": "8.0.0-alpha.14",
4
4
  "type": "module",
5
5
  "description": "Basic indexing support for model sources that support it.",
6
6
  "keywords": [
package/src/indexes.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { type ModelType, ModelRegistryIndex } from '@travetto/model';
2
- import { type Class, type Any, castTo } from '@travetto/runtime';
1
+ import { type IndexConfig, type ModelType, ModelRegistryIndex } from '@travetto/model';
2
+ import { type Class, type Any, castTo, type ClassInstance } from '@travetto/runtime';
3
3
 
4
4
  import {
5
5
  type AllIndexes, type KeyedIndexSelection, type KeyedIndex,
@@ -81,3 +81,26 @@ export function sortedIndex<
81
81
 
82
82
  export const isModelIndexedIndex = <T extends ModelType>(idx: Any): idx is AllIndexes<T> =>
83
83
  typeof idx === 'object' && idx !== null && 'type' in idx && typeof idx.type === 'string' && idx.type.startsWith('indexed:');
84
+
85
+
86
+ export const warnIfIndexedUniqueIndex = (service: ClassInstance, cls: Class<ModelType>, indexes: IndexConfig[]): boolean => {
87
+ let warned = false;
88
+ for (const idx of indexes) {
89
+ if (isModelIndexedIndex(idx) && 'unique' in idx && idx.unique) {
90
+ console.debug('Unique indices are not supported', { cls: cls.Ⲑid, idx: idx.name, service: service.constructor.Ⲑid });
91
+ warned = true;
92
+ }
93
+ }
94
+ return warned;
95
+ };
96
+
97
+ export const warnIfNonIndexedIndex = (service: ClassInstance, cls: Class<ModelType>, indexes: IndexConfig[]): boolean => {
98
+ let warned = false;
99
+ for (const idx of indexes) {
100
+ if (!isModelIndexedIndex(idx)) {
101
+ console.debug('Non-indexed indices are not supported', { cls: cls.Ⲑid, idx: idx.name, service: service.constructor.Ⲑid });
102
+ warned = true;
103
+ }
104
+ }
105
+ return warned;
106
+ };
@@ -4,11 +4,11 @@ import timers from 'node:timers/promises';
4
4
  import { Suite, Test } from '@travetto/test';
5
5
  import { Schema } from '@travetto/schema';
6
6
  import { castTo, TimeUtil } from '@travetto/runtime';
7
- import { Model, NotFoundError } from '@travetto/model';
7
+ import { ExistsError, Model, NotFoundError } from '@travetto/model';
8
8
  import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
9
9
 
10
10
  import type { ModelIndexedSupport } from '../../src/types/service.ts';
11
- import { keyedIndex, sortedIndex } from '../../src/indexes.ts';
11
+ import { keyedIndex, sortedIndex, uniqueIndex } from '../../src/indexes.ts';
12
12
  import { IndexedFieldError } from '../../src/types/error.ts';
13
13
 
14
14
  @Model('index_user')
@@ -22,6 +22,17 @@ const userNameIndex = keyedIndex(User, {
22
22
  key: { name: true }
23
23
  });
24
24
 
25
+ @Model('index_unique_user')
26
+ class UniqueUser {
27
+ id: string;
28
+ name: string;
29
+ }
30
+
31
+ const userUniqueNameIndex = uniqueIndex(UniqueUser, {
32
+ name: 'userUniqueName',
33
+ key: { name: true }
34
+ });
35
+
25
36
  @Model('index_user_2')
26
37
  class User2 {
27
38
  id: string;
@@ -82,6 +93,7 @@ export abstract class ModelIndexedSuite extends BaseModelSuite<ModelIndexedSuppo
82
93
 
83
94
  indexLimitSkew = 0;
84
95
  supportsDeepIndexes = true;
96
+ supportsUniqueIndexes = true;
85
97
 
86
98
  @Test()
87
99
  async writeAndRead() {
@@ -103,6 +115,22 @@ export abstract class ModelIndexedSuite extends BaseModelSuite<ModelIndexedSuppo
103
115
  assert(found2.name === 'bob2');
104
116
  }
105
117
 
118
+ @Test({ skip: (self) => !castTo<ModelIndexedSuite>(self).supportsUniqueIndexes })
119
+ async writeRejectsDuplicateUniqueIndex() {
120
+ const service = await this.service;
121
+
122
+ const created = await service.create(UniqueUser, UniqueUser.from({ name: 'sam' }));
123
+
124
+ await assert.rejects(
125
+ () => service.create(UniqueUser, UniqueUser.from({ name: 'sam' })),
126
+ err => err instanceof ExistsError
127
+ );
128
+
129
+ const found = await service.getByIndex(UniqueUser, userUniqueNameIndex, { name: 'sam' });
130
+ assert(found.id === created.id);
131
+ assert(found.name === 'sam');
132
+ }
133
+
106
134
  @Test()
107
135
  async readByKeyedIndexUsingId() {
108
136
  const service = await this.service;