@travetto/model 8.0.3 → 8.0.4
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 +1 -1
- package/src/types/storage.ts +2 -2
- package/src/util/storage.ts +17 -0
- package/support/test/basic.ts +44 -1
- package/support/test/suite.ts +6 -14
package/package.json
CHANGED
package/src/types/storage.ts
CHANGED
|
@@ -38,11 +38,11 @@ export interface ModelStorageSupport {
|
|
|
38
38
|
/**
|
|
39
39
|
* Deletes model
|
|
40
40
|
*/
|
|
41
|
-
deleteModel
|
|
41
|
+
deleteModel<T extends ModelType>(cls: Class<T>): Promise<void>;
|
|
42
42
|
/**
|
|
43
43
|
* Removes all data from a model, but leaving the structure in place
|
|
44
44
|
*/
|
|
45
|
-
truncateModel
|
|
45
|
+
truncateModel<T extends ModelType>(cls: Class<T>): Promise<void>;
|
|
46
46
|
/**
|
|
47
47
|
* Truncate blob storage data
|
|
48
48
|
*/
|
package/src/util/storage.ts
CHANGED
|
@@ -46,4 +46,21 @@ export class ModelStorageUtil {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Runs a storage operation and ignores errors matching the not-found predicate
|
|
52
|
+
*/
|
|
53
|
+
static async runAndIgnoreNotFound<T = unknown>(
|
|
54
|
+
operation: () => Promise<T>,
|
|
55
|
+
notFoundPredicate: (error: unknown) => boolean
|
|
56
|
+
): Promise<T | undefined> {
|
|
57
|
+
try {
|
|
58
|
+
return await operation();
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (notFoundPredicate(error)) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
49
66
|
}
|
package/support/test/basic.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Model,
|
|
5
|
+
type ModelCrudSupport,
|
|
6
|
+
ModelCrudUtil,
|
|
7
|
+
ModelRegistryIndex,
|
|
8
|
+
ModelStorageUtil,
|
|
9
|
+
NotFoundError,
|
|
10
|
+
TransientField
|
|
11
|
+
} from '@travetto/model';
|
|
12
|
+
import { SchemaRegistryIndex } from '@travetto/schema';
|
|
4
13
|
import { Suite, Test } from '@travetto/test';
|
|
5
14
|
|
|
6
15
|
import { BaseModelSuite } from './base.ts';
|
|
@@ -25,6 +34,11 @@ class Person {
|
|
|
25
34
|
gender: 'm' | 'f';
|
|
26
35
|
}
|
|
27
36
|
|
|
37
|
+
@Model('basic_person_temp')
|
|
38
|
+
export class TempPerson {
|
|
39
|
+
id: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
28
42
|
@Suite()
|
|
29
43
|
export abstract class ModelBasicSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
30
44
|
@Test('create, read, delete')
|
|
@@ -100,4 +114,33 @@ export abstract class ModelBasicSuite extends BaseModelSuite<ModelCrudSupport> {
|
|
|
100
114
|
assert(prepared.nameUpper === undefined);
|
|
101
115
|
assert(prepared.ignoredField === undefined);
|
|
102
116
|
}
|
|
117
|
+
|
|
118
|
+
@Test('deleteModel should not fail when underlying storage item is not found')
|
|
119
|
+
async testDeleteModelNotExists() {
|
|
120
|
+
const service = await this.service;
|
|
121
|
+
if (ModelStorageUtil.isSupported(service)) {
|
|
122
|
+
await service.deleteModel(TempPerson);
|
|
123
|
+
// Run it again now that the storage item is definitely deleted/not found
|
|
124
|
+
await service.deleteModel(TempPerson);
|
|
125
|
+
if (service.upsertModel) {
|
|
126
|
+
await service.upsertModel(TempPerson);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@Test('deleteStorage should not fail when underlying storage is not found')
|
|
132
|
+
async testDeleteStorageNotExists() {
|
|
133
|
+
const service = await this.service;
|
|
134
|
+
if (ModelStorageUtil.isSupported(service)) {
|
|
135
|
+
await service.deleteStorage();
|
|
136
|
+
// Run it again now that storage has been deleted
|
|
137
|
+
await service.deleteStorage();
|
|
138
|
+
await service.createStorage();
|
|
139
|
+
if (service.upsertModel) {
|
|
140
|
+
for (const modelClass of ModelRegistryIndex.getClasses().filter(model => model === SchemaRegistryIndex.getBaseClass(model))) {
|
|
141
|
+
await service.upsertModel(modelClass);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
103
146
|
}
|
package/support/test/suite.ts
CHANGED
|
@@ -53,26 +53,18 @@ class ModelSuiteHandler<T extends { configClass: Class<ConfigType>; serviceClass
|
|
|
53
53
|
await service.truncateBlob();
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
await Promise.all(models.map(model => service.truncateModel!(model)));
|
|
58
|
-
} else if (service.deleteModel) {
|
|
59
|
-
await Promise.all(models.map(model => service.deleteModel!(model)));
|
|
60
|
-
} else {
|
|
61
|
-
await service.deleteStorage(); // Purge it all
|
|
62
|
-
}
|
|
56
|
+
await Promise.all(models.map(model => service.truncateModel(model)));
|
|
63
57
|
}
|
|
64
58
|
}
|
|
65
59
|
|
|
66
60
|
async afterAll(instance: T) {
|
|
67
61
|
const service = await DependencyRegistryIndex.getInstance<T>(instance.serviceClass, this.qualifier);
|
|
68
62
|
if (ModelStorageUtil.isSupported(service)) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
}
|
|
63
|
+
await Promise.all(
|
|
64
|
+
ModelRegistryIndex.getClasses()
|
|
65
|
+
.filter(model => model === SchemaRegistryIndex.getBaseClass(model))
|
|
66
|
+
.map(model => service.deleteModel(model))
|
|
67
|
+
);
|
|
76
68
|
await service.deleteStorage();
|
|
77
69
|
}
|
|
78
70
|
}
|