@travetto/model 8.0.0-alpha.22 → 8.0.0-alpha.24
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 +72 -67
- package/__index__.ts +7 -9
- package/package.json +7 -7
- package/src/error/exists.ts +1 -1
- package/src/error/invalid-index.ts +5 -3
- package/src/error/invalid-sub-type.ts +1 -1
- package/src/error/not-found.ts +1 -1
- package/src/error/unique.ts +13 -0
- package/src/registry/decorator.ts +25 -19
- package/src/registry/registry-adapter.ts +7 -7
- package/src/registry/registry-index.ts +8 -7
- package/src/registry/types.ts +3 -3
- package/src/types/basic.ts +2 -2
- package/src/types/blob.ts +2 -3
- package/src/types/bulk.ts +4 -8
- package/src/types/crud.ts +2 -4
- package/src/types/expiry.ts +2 -2
- package/src/types/model.ts +2 -2
- package/src/types/storage.ts +1 -2
- package/src/util/blob.ts +2 -2
- package/src/util/bulk.ts +6 -3
- package/src/util/crud.ts +38 -28
- package/src/util/expiry.ts +4 -5
- package/src/util/storage.ts +3 -4
- package/support/base-command.ts +3 -5
- package/support/bin/candidate.ts +8 -11
- package/support/bin/export.ts +2 -2
- package/support/bin/install.ts +2 -2
- package/support/cli.model_export.ts +5 -4
- package/support/cli.model_install.ts +5 -4
- package/support/doc.support.tsx +16 -18
- package/support/test/base.ts +9 -7
- package/support/test/basic.ts +10 -8
- package/support/test/blob.ts +8 -9
- package/support/test/bulk.ts +16 -5
- package/support/test/crud.ts +108 -90
- package/support/test/expiry.ts +39 -21
- package/support/test/polymorphism.ts +39 -31
- package/support/test/suite.ts +15 -12
package/support/test/basic.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
|
+
import { Model, type ModelCrudSupport, ModelCrudUtil, NotFoundError, TransientField } from '@travetto/model';
|
|
3
4
|
import { Suite, Test } from '@travetto/test';
|
|
4
|
-
import { type ModelCrudSupport, Model, NotFoundError, ModelCrudUtil, TransientField } from '@travetto/model';
|
|
5
5
|
|
|
6
6
|
import { BaseModelSuite } from './base.ts';
|
|
7
7
|
|
|
@@ -27,7 +27,6 @@ class Person {
|
|
|
27
27
|
|
|
28
28
|
@Suite()
|
|
29
29
|
export abstract class ModelBasicSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
30
|
-
|
|
31
30
|
@Test('create, read, delete')
|
|
32
31
|
async create() {
|
|
33
32
|
const service = await this.service;
|
|
@@ -76,11 +75,14 @@ export abstract class ModelBasicSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
76
75
|
async testComputed() {
|
|
77
76
|
const service = await this.service;
|
|
78
77
|
const id = service.idSource.create();
|
|
79
|
-
await service.create(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
await service.create(
|
|
79
|
+
ComputedPerson,
|
|
80
|
+
ComputedPerson.from({
|
|
81
|
+
id,
|
|
82
|
+
name: 'Bob',
|
|
83
|
+
ignoredField: 'secret'
|
|
84
|
+
})
|
|
85
|
+
);
|
|
84
86
|
|
|
85
87
|
const retrieved = await service.get(ComputedPerson, id);
|
|
86
88
|
assert(retrieved.nameUpper === 'BOB');
|
|
@@ -98,4 +100,4 @@ export abstract class ModelBasicSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
98
100
|
assert(prepared.nameUpper === undefined);
|
|
99
101
|
assert(prepared.ignoredField === undefined);
|
|
100
102
|
}
|
|
101
|
-
}
|
|
103
|
+
}
|
package/support/test/blob.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
|
-
import { Suite, Test, TestFixtures } from '@travetto/test';
|
|
4
3
|
import { BinaryMetadataUtil, BinaryUtil, Util } from '@travetto/runtime';
|
|
4
|
+
import { Suite, Test, TestFixtures } from '@travetto/test';
|
|
5
5
|
|
|
6
6
|
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
7
7
|
|
|
@@ -10,7 +10,6 @@ import { ModelBlobUtil } from '../../src/util/blob.ts';
|
|
|
10
10
|
|
|
11
11
|
@Suite()
|
|
12
12
|
export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
13
|
-
|
|
14
13
|
fixture = new TestFixtures(['@travetto/model']);
|
|
15
14
|
|
|
16
15
|
@Test()
|
|
@@ -90,7 +89,7 @@ export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
|
90
89
|
const partialMeta = BinaryMetadataUtil.read(partial)!;
|
|
91
90
|
const subContent = await partial.text();
|
|
92
91
|
const range = BinaryMetadataUtil.enforceRange({ start: 10, end: 20 }, partialMeta);
|
|
93
|
-
assert(subContent.length ===
|
|
92
|
+
assert(subContent.length === range.end - range.start + 1);
|
|
94
93
|
|
|
95
94
|
const og = await this.fixture.readUTF8('/text.txt');
|
|
96
95
|
|
|
@@ -100,7 +99,7 @@ export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
|
100
99
|
const partialUnboundedMeta = BinaryMetadataUtil.read(partialUnbounded)!;
|
|
101
100
|
const subContent2 = await partialUnbounded.text();
|
|
102
101
|
const range2 = BinaryMetadataUtil.enforceRange({ start: 10 }, partialUnboundedMeta);
|
|
103
|
-
assert(subContent2.length ===
|
|
102
|
+
assert(subContent2.length === range2.end - range2.start + 1);
|
|
104
103
|
assert(subContent2.startsWith('klm'));
|
|
105
104
|
assert(subContent2.endsWith('xyz'));
|
|
106
105
|
|
|
@@ -156,19 +155,19 @@ export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
|
156
155
|
const service = await this.service;
|
|
157
156
|
|
|
158
157
|
const bytes = BinaryUtil.binaryArrayToBuffer(BinaryUtil.makeBinaryArray(1.5 * 10000));
|
|
159
|
-
for (let i = 0; i < bytes.byteLength; i
|
|
158
|
+
for (let i = 0; i < bytes.byteLength; i += 1) {
|
|
160
159
|
bytes.writeUInt8(Math.trunc(Math.random() * 255), i);
|
|
161
160
|
}
|
|
162
161
|
|
|
163
162
|
const writable = await service.getBlobWriteUrl!('largeFile/one', {
|
|
164
|
-
contentType: 'image/jpeg'
|
|
163
|
+
contentType: 'image/jpeg'
|
|
165
164
|
});
|
|
166
165
|
|
|
167
166
|
assert(writable);
|
|
168
167
|
|
|
169
168
|
const response = await fetch(writable, {
|
|
170
169
|
method: 'PUT',
|
|
171
|
-
body: new File([bytes], 'gary', { type: 'image/jpeg' })
|
|
170
|
+
body: new File([bytes], 'gary', { type: 'image/jpeg' })
|
|
172
171
|
});
|
|
173
172
|
|
|
174
173
|
console.error(await response.text());
|
|
@@ -179,7 +178,7 @@ export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
|
179
178
|
contentType: 'image/jpeg',
|
|
180
179
|
title: 'orange',
|
|
181
180
|
filename: 'gary',
|
|
182
|
-
size: bytes.byteLength
|
|
181
|
+
size: bytes.byteLength
|
|
183
182
|
});
|
|
184
183
|
|
|
185
184
|
const found = await service.getBlob('largeFile/one');
|
|
@@ -189,4 +188,4 @@ export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
|
189
188
|
assert(foundMeta.title === 'orange');
|
|
190
189
|
assert(foundMeta.filename === 'gary');
|
|
191
190
|
}
|
|
192
|
-
}
|
|
191
|
+
}
|
package/support/test/bulk.ts
CHANGED
|
@@ -14,7 +14,6 @@ class User {
|
|
|
14
14
|
|
|
15
15
|
@Suite()
|
|
16
16
|
export abstract class ModelBulkSuite extends BaseModelSuite<ModelBulkSupport> {
|
|
17
|
-
|
|
18
17
|
@Test()
|
|
19
18
|
async bulkInsert() {
|
|
20
19
|
const service = await this.service;
|
|
@@ -48,11 +47,17 @@ export abstract class ModelBulkSuite extends BaseModelSuite<ModelBulkSupport> {
|
|
|
48
47
|
const service = await this.service;
|
|
49
48
|
const users = [0, 1, 2, 4].map(x => User.from({ name: `name-${x}`, id: service.idSource.create() }));
|
|
50
49
|
|
|
51
|
-
const result = await service.processBulk(
|
|
50
|
+
const result = await service.processBulk(
|
|
51
|
+
User,
|
|
52
|
+
users.map(u => ({ insert: u }))
|
|
53
|
+
);
|
|
52
54
|
assert(result.counts.insert === 4);
|
|
53
55
|
assert(result.insertedIds.size === 4);
|
|
54
56
|
|
|
55
|
-
const res2 = await service.processBulk(
|
|
57
|
+
const res2 = await service.processBulk(
|
|
58
|
+
User,
|
|
59
|
+
users.map(u => ({ update: u }))
|
|
60
|
+
);
|
|
56
61
|
assert(res2.counts.update === 4);
|
|
57
62
|
assert(res2.insertedIds.size === 0);
|
|
58
63
|
}
|
|
@@ -62,11 +67,17 @@ export abstract class ModelBulkSuite extends BaseModelSuite<ModelBulkSupport> {
|
|
|
62
67
|
const service = await this.service;
|
|
63
68
|
const users = [0, 1, 2, 4].map(x => User.from({ name: `name-${x}`, id: service.idSource.create() }));
|
|
64
69
|
|
|
65
|
-
const result = await service.processBulk(
|
|
70
|
+
const result = await service.processBulk(
|
|
71
|
+
User,
|
|
72
|
+
users.map(u => ({ insert: u }))
|
|
73
|
+
);
|
|
66
74
|
assert(result.counts.insert === 4);
|
|
67
75
|
assert(result.insertedIds.size === 4);
|
|
68
76
|
|
|
69
|
-
const res2 = await service.processBulk(
|
|
77
|
+
const res2 = await service.processBulk(
|
|
78
|
+
User,
|
|
79
|
+
users.map(u => ({ delete: u }))
|
|
80
|
+
);
|
|
70
81
|
assert(res2.counts.delete === 4);
|
|
71
82
|
}
|
|
72
83
|
}
|
package/support/test/crud.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
import timers from 'node:timers/promises';
|
|
3
3
|
|
|
4
|
+
import { Model, type ModelCrudSupport, NotFoundError, PersistValue, PrePersist } from '@travetto/model';
|
|
5
|
+
import { Precision, Required, Schema, Text } from '@travetto/schema';
|
|
4
6
|
import { Suite, Test } from '@travetto/test';
|
|
5
|
-
import { Schema, Text, Precision, Required, } from '@travetto/schema';
|
|
6
|
-
import { type ModelCrudSupport, Model, NotFoundError, PersistValue, PrePersist } from '@travetto/model';
|
|
7
7
|
|
|
8
8
|
import { BaseModelSuite } from './base.ts';
|
|
9
9
|
|
|
@@ -42,7 +42,7 @@ class SimpleList {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
@Model()
|
|
45
|
-
@PrePersist(
|
|
45
|
+
@PrePersist(item => {
|
|
46
46
|
item.name = `${item.name}-suffix`;
|
|
47
47
|
})
|
|
48
48
|
class User2 {
|
|
@@ -75,28 +75,27 @@ class BigIntModel {
|
|
|
75
75
|
|
|
76
76
|
@Suite()
|
|
77
77
|
export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
78
|
-
|
|
79
78
|
indexLimitSkew = 0;
|
|
80
79
|
|
|
81
80
|
@Test('save it')
|
|
82
81
|
async save() {
|
|
83
82
|
const service = await this.service;
|
|
84
83
|
|
|
85
|
-
const people = [1, 2, 3, 8].map(x =>
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
await Promise.all(
|
|
97
|
-
people.map(el => service.upsert(Person, el))
|
|
84
|
+
const people = [1, 2, 3, 8].map(x =>
|
|
85
|
+
Person.from({
|
|
86
|
+
id: service.idSource.create(),
|
|
87
|
+
name: 'Bob',
|
|
88
|
+
age: 20 + x,
|
|
89
|
+
gender: 'm',
|
|
90
|
+
address: {
|
|
91
|
+
street1: 'a',
|
|
92
|
+
...(x === 1 ? { street2: 'b' } : {})
|
|
93
|
+
}
|
|
94
|
+
})
|
|
98
95
|
);
|
|
99
96
|
|
|
97
|
+
await Promise.all(people.map(el => service.upsert(Person, el)));
|
|
98
|
+
|
|
100
99
|
const single = await service.get(Person, people[2].id);
|
|
101
100
|
assert(single !== undefined);
|
|
102
101
|
assert(single.age === 23);
|
|
@@ -122,15 +121,18 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
122
121
|
@Test('Verify partial update with field removal')
|
|
123
122
|
async testPartialUpdate() {
|
|
124
123
|
const service = await this.service;
|
|
125
|
-
const o = await service.create(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
124
|
+
const o = await service.create(
|
|
125
|
+
Person,
|
|
126
|
+
Person.from({
|
|
127
|
+
name: 'bob',
|
|
128
|
+
age: 20,
|
|
129
|
+
gender: 'm',
|
|
130
|
+
address: {
|
|
131
|
+
street1: 'road',
|
|
132
|
+
street2: 'roader'
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
);
|
|
134
136
|
assert(o.id);
|
|
135
137
|
assert(o.name === 'bob');
|
|
136
138
|
|
|
@@ -147,7 +149,7 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
147
149
|
id: o2.id,
|
|
148
150
|
gender: 'f',
|
|
149
151
|
address: {
|
|
150
|
-
street1: 'changed\n'
|
|
152
|
+
street1: 'changed\n'
|
|
151
153
|
}
|
|
152
154
|
});
|
|
153
155
|
|
|
@@ -169,20 +171,23 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
169
171
|
@Test('Verify partial update with field removal and lists')
|
|
170
172
|
async testPartialUpdateList() {
|
|
171
173
|
const service = await this.service;
|
|
172
|
-
const o = await service.create(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
174
|
+
const o = await service.create(
|
|
175
|
+
SimpleList,
|
|
176
|
+
SimpleList.from({
|
|
177
|
+
names: ['a', 'b', 'c'],
|
|
178
|
+
simples: [
|
|
179
|
+
{
|
|
180
|
+
name: 'a'
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: 'b'
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: 'c'
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
})
|
|
190
|
+
);
|
|
186
191
|
|
|
187
192
|
const o2 = await service.updatePartial(SimpleList, {
|
|
188
193
|
id: o.id,
|
|
@@ -197,9 +202,12 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
197
202
|
@Test('Verify partial update with field removal and lists')
|
|
198
203
|
async testBlankPartialUpdate() {
|
|
199
204
|
const service = await this.service;
|
|
200
|
-
const o = await service.create(
|
|
201
|
-
|
|
202
|
-
|
|
205
|
+
const o = await service.create(
|
|
206
|
+
User2,
|
|
207
|
+
User2.from({
|
|
208
|
+
name: 'bob'
|
|
209
|
+
})
|
|
210
|
+
);
|
|
203
211
|
|
|
204
212
|
assert(o.address === undefined);
|
|
205
213
|
assert(o.name === 'bob-suffix');
|
|
@@ -247,21 +255,21 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
247
255
|
async list() {
|
|
248
256
|
const service = await this.service;
|
|
249
257
|
|
|
250
|
-
const people = [1, 2, 3].map(x =>
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
await Promise.all(
|
|
262
|
-
people.map(el => service.upsert(Person, el))
|
|
258
|
+
const people = [1, 2, 3].map(x =>
|
|
259
|
+
Person.from({
|
|
260
|
+
id: service.idSource.create(),
|
|
261
|
+
name: 'Bob',
|
|
262
|
+
age: 20 + x,
|
|
263
|
+
gender: 'm',
|
|
264
|
+
address: {
|
|
265
|
+
street1: 'a',
|
|
266
|
+
...(x === 1 ? { street2: 'b' } : {})
|
|
267
|
+
}
|
|
268
|
+
})
|
|
263
269
|
);
|
|
264
270
|
|
|
271
|
+
await Promise.all(people.map(el => service.upsert(Person, el)));
|
|
272
|
+
|
|
265
273
|
const found = (await this.toArray(service.list(Person))).toSorted((a, b) => a.age - b.age);
|
|
266
274
|
|
|
267
275
|
assert(found[0].age === people[0].age);
|
|
@@ -274,16 +282,21 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
274
282
|
const service = await this.service;
|
|
275
283
|
|
|
276
284
|
await Promise.all(
|
|
277
|
-
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x =>
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x =>
|
|
286
|
+
service.upsert(
|
|
287
|
+
Person,
|
|
288
|
+
Person.from({
|
|
289
|
+
id: service.idSource.create(),
|
|
290
|
+
name: 'Bob',
|
|
291
|
+
age: 20 + x,
|
|
292
|
+
gender: 'm',
|
|
293
|
+
address: {
|
|
294
|
+
street1: 'a',
|
|
295
|
+
...(x === 1 ? { street2: 'b' } : {})
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
)
|
|
299
|
+
)
|
|
287
300
|
);
|
|
288
301
|
|
|
289
302
|
const controller = new AbortController();
|
|
@@ -307,15 +320,17 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
307
320
|
const service = await this.service;
|
|
308
321
|
|
|
309
322
|
const people = await Promise.all(
|
|
310
|
-
[1, 2, 3, 8].map((x, i) =>
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
323
|
+
[1, 2, 3, 8].map((x, i) =>
|
|
324
|
+
service[i % 2 === 0 ? 'upsert' : 'create'](Person, {
|
|
325
|
+
name: 'Bob',
|
|
326
|
+
age: 20 + x,
|
|
327
|
+
gender: 'm',
|
|
328
|
+
address: {
|
|
329
|
+
street1: 'a',
|
|
330
|
+
...(x === 1 ? { street2: 'b' } : {})
|
|
331
|
+
}
|
|
332
|
+
})
|
|
333
|
+
)
|
|
319
334
|
);
|
|
320
335
|
|
|
321
336
|
const single = await service.get(Person, people[2].id);
|
|
@@ -365,10 +380,7 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
365
380
|
const service = await this.service;
|
|
366
381
|
const o = await service.create(SimpleList, {
|
|
367
382
|
names: ['rob', 'tom'],
|
|
368
|
-
simples: [
|
|
369
|
-
{ name: 'roger' },
|
|
370
|
-
{ name: 'dodger' }
|
|
371
|
-
]
|
|
383
|
+
simples: [{ name: 'roger' }, { name: 'dodger' }]
|
|
372
384
|
});
|
|
373
385
|
assert(o.names.length === 2);
|
|
374
386
|
assert(o.simples);
|
|
@@ -390,10 +402,13 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
390
402
|
const service = await this.service;
|
|
391
403
|
|
|
392
404
|
// Create with bigint values
|
|
393
|
-
const created = await service.create(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
405
|
+
const created = await service.create(
|
|
406
|
+
BigIntModel,
|
|
407
|
+
BigIntModel.from({
|
|
408
|
+
largeNumber: 9007199254740991n, // Number.MAX_SAFE_INTEGER as bigint
|
|
409
|
+
optionalBigInt: 1234567890123456789n
|
|
410
|
+
})
|
|
411
|
+
);
|
|
397
412
|
|
|
398
413
|
assert(created.id);
|
|
399
414
|
assert.strictEqual(created.largeNumber, 9007199254740991n);
|
|
@@ -405,11 +420,14 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
405
420
|
assert.strictEqual(retrieved.optionalBigInt, 1234567890123456789n);
|
|
406
421
|
|
|
407
422
|
// Update with new bigint value
|
|
408
|
-
const updated = await service.update(
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
423
|
+
const updated = await service.update(
|
|
424
|
+
BigIntModel,
|
|
425
|
+
BigIntModel.from({
|
|
426
|
+
id: created.id,
|
|
427
|
+
largeNumber: 18014398509481982n,
|
|
428
|
+
optionalBigInt: undefined
|
|
429
|
+
})
|
|
430
|
+
);
|
|
413
431
|
|
|
414
432
|
assert.strictEqual(updated.largeNumber, 18014398509481982n);
|
|
415
433
|
assert.strictEqual(updated.optionalBigInt, undefined);
|
|
@@ -419,4 +437,4 @@ export abstract class ModelCrudSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
419
437
|
assert.strictEqual(final.largeNumber, 18014398509481982n);
|
|
420
438
|
assert(!final.optionalBigInt);
|
|
421
439
|
}
|
|
422
|
-
}
|
|
440
|
+
}
|
package/support/test/expiry.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
import timers from 'node:timers/promises';
|
|
3
3
|
|
|
4
|
-
import { Suite, Test } from '@travetto/test';
|
|
5
4
|
import { type TimeSpan, TimeUtil } from '@travetto/runtime';
|
|
5
|
+
import { Suite, Test } from '@travetto/test';
|
|
6
6
|
|
|
7
|
+
import { NotFoundError } from '../../src/error/not-found.ts';
|
|
7
8
|
import { ExpiresAt, Model } from '../../src/registry/decorator.ts';
|
|
8
9
|
import type { ModelExpirySupport } from '../../src/types/expiry.ts';
|
|
9
10
|
import { ModelExpiryUtil } from '../../src/util/expiry.ts';
|
|
10
|
-
import { NotFoundError } from '../../src/error/not-found.ts';
|
|
11
11
|
import { BaseModelSuite } from './base.ts';
|
|
12
12
|
|
|
13
13
|
@Model('expiry-user')
|
|
@@ -20,7 +20,6 @@ export class ExpiryUser {
|
|
|
20
20
|
|
|
21
21
|
@Suite()
|
|
22
22
|
export abstract class ModelExpirySuite extends BaseModelSuite<ModelExpirySupport> {
|
|
23
|
-
|
|
24
23
|
delayFactor: number = 1;
|
|
25
24
|
|
|
26
25
|
async wait(input: TimeSpan | number | string) {
|
|
@@ -34,9 +33,12 @@ export abstract class ModelExpirySuite extends BaseModelSuite<ModelExpirySupport
|
|
|
34
33
|
@Test()
|
|
35
34
|
async basic() {
|
|
36
35
|
const service = await this.service;
|
|
37
|
-
const result = await service.upsert(
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
const result = await service.upsert(
|
|
37
|
+
ExpiryUser,
|
|
38
|
+
ExpiryUser.from({
|
|
39
|
+
expiresAt: this.timeFromNow('2s')
|
|
40
|
+
})
|
|
41
|
+
);
|
|
40
42
|
assert(result instanceof ExpiryUser);
|
|
41
43
|
|
|
42
44
|
const expiry = ModelExpiryUtil.getExpiryState(ExpiryUser, await service.get(ExpiryUser, result.id));
|
|
@@ -46,9 +48,12 @@ export abstract class ModelExpirySuite extends BaseModelSuite<ModelExpirySupport
|
|
|
46
48
|
@Test()
|
|
47
49
|
async aging() {
|
|
48
50
|
const service = await this.service;
|
|
49
|
-
const result = await service.upsert(
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
const result = await service.upsert(
|
|
52
|
+
ExpiryUser,
|
|
53
|
+
ExpiryUser.from({
|
|
54
|
+
expiresAt: this.timeFromNow(100)
|
|
55
|
+
})
|
|
56
|
+
);
|
|
52
57
|
|
|
53
58
|
assert(result instanceof ExpiryUser);
|
|
54
59
|
|
|
@@ -60,9 +65,12 @@ export abstract class ModelExpirySuite extends BaseModelSuite<ModelExpirySupport
|
|
|
60
65
|
@Test()
|
|
61
66
|
async updateExpired() {
|
|
62
67
|
const service = await this.service;
|
|
63
|
-
const result = await service.upsert(
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
const result = await service.upsert(
|
|
69
|
+
ExpiryUser,
|
|
70
|
+
ExpiryUser.from({
|
|
71
|
+
expiresAt: this.timeFromNow(100)
|
|
72
|
+
})
|
|
73
|
+
);
|
|
66
74
|
|
|
67
75
|
assert(result instanceof ExpiryUser);
|
|
68
76
|
|
|
@@ -74,14 +82,17 @@ export abstract class ModelExpirySuite extends BaseModelSuite<ModelExpirySupport
|
|
|
74
82
|
@Test()
|
|
75
83
|
async ageWithExtension() {
|
|
76
84
|
const service = await this.service;
|
|
77
|
-
const result = await service.upsert(
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
const result = await service.upsert(
|
|
86
|
+
ExpiryUser,
|
|
87
|
+
ExpiryUser.from({
|
|
88
|
+
expiresAt: this.timeFromNow('2s')
|
|
89
|
+
})
|
|
90
|
+
);
|
|
80
91
|
assert(result instanceof ExpiryUser);
|
|
81
92
|
|
|
82
93
|
await this.wait(50);
|
|
83
94
|
|
|
84
|
-
assert(!ModelExpiryUtil.getExpiryState(ExpiryUser,
|
|
95
|
+
assert(!ModelExpiryUtil.getExpiryState(ExpiryUser, await service.get(ExpiryUser, result.id)).expired);
|
|
85
96
|
|
|
86
97
|
await service.updatePartial(ExpiryUser, {
|
|
87
98
|
id: result.id,
|
|
@@ -97,16 +108,23 @@ export abstract class ModelExpirySuite extends BaseModelSuite<ModelExpirySupport
|
|
|
97
108
|
async culling() {
|
|
98
109
|
const service = await this.service;
|
|
99
110
|
|
|
100
|
-
let total;
|
|
111
|
+
let total: number;
|
|
101
112
|
|
|
102
113
|
total = await this.getSize(ExpiryUser);
|
|
103
114
|
assert(total === 0);
|
|
104
115
|
|
|
105
116
|
// Create
|
|
106
117
|
await Promise.all(
|
|
107
|
-
Array(10)
|
|
108
|
-
|
|
109
|
-
|
|
118
|
+
Array(10)
|
|
119
|
+
.fill(0)
|
|
120
|
+
.map((x, i) =>
|
|
121
|
+
service.upsert(
|
|
122
|
+
ExpiryUser,
|
|
123
|
+
ExpiryUser.from({
|
|
124
|
+
expiresAt: this.timeFromNow(300 + i * this.delayFactor)
|
|
125
|
+
})
|
|
126
|
+
)
|
|
127
|
+
)
|
|
110
128
|
);
|
|
111
129
|
|
|
112
130
|
// Let expire
|
|
@@ -124,4 +142,4 @@ export abstract class ModelExpirySuite extends BaseModelSuite<ModelExpirySupport
|
|
|
124
142
|
total = await this.getSize(ExpiryUser);
|
|
125
143
|
assert(total === 0);
|
|
126
144
|
}
|
|
127
|
-
}
|
|
145
|
+
}
|