@travetto/model 3.1.0-rc.1 → 3.1.0-rc.10
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 +5 -7
- package/__index__.ts +1 -0
- package/package.json +7 -7
- package/src/internal/service/bulk.ts +2 -1
- package/src/internal/service/crud.ts +38 -5
- package/src/provider/file.ts +3 -6
- package/src/provider/memory.ts +2 -5
- package/src/service/crud.ts +3 -4
- package/src/service/types.ts +4 -0
- package/src/internal/util.ts +0 -7
package/README.md
CHANGED
|
@@ -60,10 +60,9 @@ The [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/servi
|
|
|
60
60
|
export interface ModelCrudSupport extends ModelBasicSupport {
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
* @param value The optional value to generate a uuid around. Passing the same value multiple times produces the same output.
|
|
63
|
+
* Uuid Generator
|
|
65
64
|
*/
|
|
66
|
-
uuid
|
|
65
|
+
uuid: UuidGenerator;
|
|
67
66
|
|
|
68
67
|
/**
|
|
69
68
|
* Update an item
|
|
@@ -234,8 +233,8 @@ All fields are optional, but the `id` and `type` are important as those field ty
|
|
|
234
233
|
|[Redis Model Support](https://github.com/travetto/travetto/tree/main/module/model-redis#readme "Redis backing for the travetto model module.")|X|X|X|X| ||
|
|
235
234
|
|[S3 Model Support](https://github.com/travetto/travetto/tree/main/module/model-s3#readme "S3 backing for the travetto model module.")|X|X| |X|X| |
|
|
236
235
|
|[SQL Model Service](https://github.com/travetto/travetto/tree/main/module/model-sql#readme "SQL backing for the travetto model module, with real-time modeling support for SQL schemas.")|X|X|X|X| |X|
|
|
237
|
-
|[MemoryModelService](https://github.com/travetto/travetto/tree/main/module/model/src/provider/memory.ts#
|
|
238
|
-
|[FileModelService](https://github.com/travetto/travetto/tree/main/module/model/src/provider/file.ts#
|
|
236
|
+
|[MemoryModelService](https://github.com/travetto/travetto/tree/main/module/model/src/provider/memory.ts#L53)|X|X|X|X|X|X|
|
|
237
|
+
|[FileModelService](https://github.com/travetto/travetto/tree/main/module/model/src/provider/file.ts#L50)|X|X| |X|X|X|
|
|
239
238
|
|
|
240
239
|
## Custom Model Service
|
|
241
240
|
In addition to the provided contracts, the module also provides common utilities and shared test suites. The common utilities are useful for repetitive functionality, that is unable to be shared due to not relying upon inheritance (this was an intentional design decision). This allows for all the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations.") implementations to completely own the functionality and also to be able to provide additional/unique functionality that goes beyond the interface.
|
|
@@ -262,7 +261,6 @@ import { ModelIndexedUtil } from '../internal/service/indexed';
|
|
|
262
261
|
import { ModelStorageUtil } from '../internal/service/storage';
|
|
263
262
|
import { StreamModel, STREAMS } from '../internal/service/stream';
|
|
264
263
|
import { IndexConfig } from '../registry/types';
|
|
265
|
-
import { ModelUtil } from '../internal/util';
|
|
266
264
|
const STREAM_META = `${STREAMS}_meta`;
|
|
267
265
|
type StoreType = Map<string, Buffer>;
|
|
268
266
|
@Config('model.memory')
|
|
@@ -291,11 +289,11 @@ export class MemoryModelService implements ModelCrudSupport, ModelStreamSupport,
|
|
|
291
289
|
sorted: new Map<string, Map<string, Map<string, number>>>(),
|
|
292
290
|
unsorted: new Map<string, Map<string, Set<string>>>()
|
|
293
291
|
};
|
|
292
|
+
uuid = ModelCrudUtil.uuidGenerator();
|
|
294
293
|
get client(): Map<string, StoreType>;
|
|
295
294
|
constructor(public readonly config: MemoryModelConfig) { }
|
|
296
295
|
async postConstruct(): Promise<void>;
|
|
297
296
|
// CRUD Support
|
|
298
|
-
uuid(): string;
|
|
299
297
|
async get<T extends ModelType>(cls: Class<T>, id: string): Promise<T>;
|
|
300
298
|
async create<T extends ModelType>(cls: Class<T>, item: OptionalId<T>): Promise<T>;
|
|
301
299
|
async update<T extends ModelType>(cls: Class<T>, item: T): Promise<T>;
|
package/__index__.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from './src/service/indexed';
|
|
|
9
9
|
export * from './src/service/expiry';
|
|
10
10
|
export * from './src/service/storage';
|
|
11
11
|
export * from './src/service/stream';
|
|
12
|
+
export * from './src/service/types';
|
|
12
13
|
|
|
13
14
|
export * from './src/provider/file';
|
|
14
15
|
export * from './src/provider/memory';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model",
|
|
3
|
-
"version": "3.1.0-rc.
|
|
3
|
+
"version": "3.1.0-rc.10",
|
|
4
4
|
"description": "Datastore abstraction for core operations.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"datastore",
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
"directory": "module/model"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@travetto/config": "^3.1.0-rc.
|
|
30
|
-
"@travetto/di": "^3.1.0-rc.
|
|
31
|
-
"@travetto/registry": "^3.1.0-rc.
|
|
32
|
-
"@travetto/schema": "^3.1.0-rc.
|
|
29
|
+
"@travetto/config": "^3.1.0-rc.8",
|
|
30
|
+
"@travetto/di": "^3.1.0-rc.5",
|
|
31
|
+
"@travetto/registry": "^3.1.0-rc.3",
|
|
32
|
+
"@travetto/schema": "^3.1.0-rc.6"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@travetto/cli": "^3.1.0-rc.
|
|
36
|
-
"@travetto/test": "^3.1.0-rc.
|
|
35
|
+
"@travetto/cli": "^3.1.0-rc.9",
|
|
36
|
+
"@travetto/test": "^3.1.0-rc.4"
|
|
37
37
|
},
|
|
38
38
|
"peerDependenciesMeta": {
|
|
39
39
|
"@travetto/cli": {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Class } from '@travetto/base';
|
|
2
2
|
|
|
3
3
|
import { BulkOp } from '../../service/bulk';
|
|
4
|
+
import { ModelUuidGenerator } from '../../service/types';
|
|
4
5
|
import { ModelType } from '../../types/model';
|
|
5
6
|
import { ModelCrudUtil } from './crud';
|
|
6
7
|
|
|
@@ -19,7 +20,7 @@ export class ModelBulkUtil {
|
|
|
19
20
|
* @param operations
|
|
20
21
|
* @param idSource
|
|
21
22
|
*/
|
|
22
|
-
static async preStore<T extends ModelType>(cls: Class<T>, operations: BulkOp<T>[], idSource: { uuid
|
|
23
|
+
static async preStore<T extends ModelType>(cls: Class<T>, operations: BulkOp<T>[], idSource: { uuid: ModelUuidGenerator }): Promise<BulkPreStore<T>> {
|
|
23
24
|
const insertedIds = new Map<number, string>();
|
|
24
25
|
const upsertedIds = new Map<number, string>();
|
|
25
26
|
const updatedIds = new Map<number, string>();
|
|
@@ -1,19 +1,38 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
|
|
3
|
-
import { Class, ObjectUtil } from '@travetto/base';
|
|
4
|
-
import { SchemaRegistry, SchemaValidator } from '@travetto/schema';
|
|
3
|
+
import { Class, ObjectUtil, Util } from '@travetto/base';
|
|
4
|
+
import { SchemaRegistry, SchemaValidator, ValidationError, ValidationResultError } from '@travetto/schema';
|
|
5
5
|
|
|
6
6
|
import { ModelRegistry } from '../../registry/model';
|
|
7
7
|
import { ModelType, OptionalId } from '../../types/model';
|
|
8
8
|
import { NotFoundError } from '../../error/not-found';
|
|
9
9
|
import { ExistsError } from '../../error/exists';
|
|
10
10
|
import { SubTypeNotSupportedError } from '../../error/invalid-sub-type';
|
|
11
|
+
import { ModelUuidGenerator } from '../../service/types';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Crud utilities
|
|
14
15
|
*/
|
|
15
16
|
export class ModelCrudUtil {
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Build a uuid generator
|
|
20
|
+
*/
|
|
21
|
+
static uuidGenerator(create: () => string, valid: (id: string) => boolean): ModelUuidGenerator;
|
|
22
|
+
static uuidGenerator(len?: number): ModelUuidGenerator;
|
|
23
|
+
static uuidGenerator(lenOrCreate: (() => string) | number = 32, valid?: (id: string) => boolean): ModelUuidGenerator {
|
|
24
|
+
if (typeof lenOrCreate === 'number') {
|
|
25
|
+
const len = lenOrCreate;
|
|
26
|
+
const create = (): string => Util.uuid(len);
|
|
27
|
+
create.valid = (id: string): boolean => id.length === len && /^[0-9a-f]+$/i.test(id);
|
|
28
|
+
return create;
|
|
29
|
+
} else {
|
|
30
|
+
const create = (): string => lenOrCreate();
|
|
31
|
+
create.valid = valid!;
|
|
32
|
+
return create;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
17
36
|
/**
|
|
18
37
|
* Provide hash value
|
|
19
38
|
* @param value Input value
|
|
@@ -61,7 +80,7 @@ export class ModelCrudUtil {
|
|
|
61
80
|
* @param cls Type to store for
|
|
62
81
|
* @param item Item to store
|
|
63
82
|
*/
|
|
64
|
-
static async preStore<T extends ModelType>(cls: Class<T>, item: Partial<OptionalId<T>>, idSource: { uuid
|
|
83
|
+
static async preStore<T extends ModelType>(cls: Class<T>, item: Partial<OptionalId<T>>, idSource: { uuid: ModelUuidGenerator }): Promise<T> {
|
|
65
84
|
if (!item.id) {
|
|
66
85
|
item.id = idSource.uuid();
|
|
67
86
|
}
|
|
@@ -77,12 +96,26 @@ export class ModelCrudUtil {
|
|
|
77
96
|
SchemaRegistry.ensureInstanceTypeField(cls, item);
|
|
78
97
|
}
|
|
79
98
|
|
|
80
|
-
await SchemaValidator.validate(cls, item);
|
|
81
|
-
|
|
82
99
|
if (item.prePersist) {
|
|
83
100
|
await item.prePersist();
|
|
84
101
|
}
|
|
85
102
|
|
|
103
|
+
let errors: ValidationError[] = [];
|
|
104
|
+
try {
|
|
105
|
+
await SchemaValidator.validate(cls, item);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
if (err instanceof ValidationResultError) {
|
|
108
|
+
errors = err.errors;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!idSource.uuid.valid(item.id!)) {
|
|
113
|
+
errors.push({ kind: 'invalid', path: 'id', value: item.id!, type: 'string', message: `${item.id!} is an invalid value for \`id\`` });
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (errors.length) {
|
|
117
|
+
throw new ValidationResultError(errors);
|
|
118
|
+
}
|
|
86
119
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
87
120
|
return item as T;
|
|
88
121
|
}
|
package/src/provider/file.ts
CHANGED
|
@@ -22,7 +22,6 @@ import { ModelExpiryUtil } from '../internal/service/expiry';
|
|
|
22
22
|
import { NotFoundError } from '../error/not-found';
|
|
23
23
|
import { ExistsError } from '../error/exists';
|
|
24
24
|
import { StreamModel, STREAMS } from '../internal/service/stream';
|
|
25
|
-
import { ModelUtil } from '../internal/util';
|
|
26
25
|
|
|
27
26
|
type Suffix = '.bin' | '.meta' | '.json' | '.expires';
|
|
28
27
|
|
|
@@ -38,7 +37,7 @@ export class FileModelConfig {
|
|
|
38
37
|
cullRate?: number | TimeSpan;
|
|
39
38
|
|
|
40
39
|
async postConstruct(): Promise<void> {
|
|
41
|
-
this.folder ??= path.resolve(os.tmpdir(), `trv_file_${RootIndex.
|
|
40
|
+
this.folder ??= path.resolve(os.tmpdir(), `trv_file_${RootIndex.mainModuleName.replace(/[^a-z]/ig, '_')}`);
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
43
|
|
|
@@ -60,6 +59,8 @@ export class FileModelService implements ModelCrudSupport, ModelStreamSupport, M
|
|
|
60
59
|
}
|
|
61
60
|
}
|
|
62
61
|
|
|
62
|
+
uuid = ModelCrudUtil.uuidGenerator();
|
|
63
|
+
|
|
63
64
|
get client(): string {
|
|
64
65
|
return this.config.folder;
|
|
65
66
|
}
|
|
@@ -105,10 +106,6 @@ export class FileModelService implements ModelCrudSupport, ModelStreamSupport, M
|
|
|
105
106
|
return item;
|
|
106
107
|
}
|
|
107
108
|
|
|
108
|
-
uuid(): string {
|
|
109
|
-
return ModelUtil.uuid(32);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
109
|
async get<T extends ModelType>(cls: Class<T>, id: string): Promise<T> {
|
|
113
110
|
await this.#find(cls, '.json', id);
|
|
114
111
|
|
package/src/provider/memory.ts
CHANGED
|
@@ -20,7 +20,6 @@ import { ModelIndexedUtil } from '../internal/service/indexed';
|
|
|
20
20
|
import { ModelStorageUtil } from '../internal/service/storage';
|
|
21
21
|
import { StreamModel, STREAMS } from '../internal/service/stream';
|
|
22
22
|
import { IndexConfig } from '../registry/types';
|
|
23
|
-
import { ModelUtil } from '../internal/util';
|
|
24
23
|
|
|
25
24
|
const STREAM_META = `${STREAMS}_meta`;
|
|
26
25
|
|
|
@@ -58,6 +57,8 @@ export class MemoryModelService implements ModelCrudSupport, ModelStreamSupport,
|
|
|
58
57
|
sorted: new Map<string, Map<string, Map<string, number>>>(),
|
|
59
58
|
unsorted: new Map<string, Map<string, Set<string>>>()
|
|
60
59
|
};
|
|
60
|
+
|
|
61
|
+
uuid = ModelCrudUtil.uuidGenerator();
|
|
61
62
|
get client(): Map<string, StoreType> { return this.#store; }
|
|
62
63
|
|
|
63
64
|
constructor(public readonly config: MemoryModelConfig) { }
|
|
@@ -168,10 +169,6 @@ export class MemoryModelService implements ModelCrudSupport, ModelStreamSupport,
|
|
|
168
169
|
}
|
|
169
170
|
|
|
170
171
|
// CRUD Support
|
|
171
|
-
uuid(): string {
|
|
172
|
-
return ModelUtil.uuid(32);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
172
|
async get<T extends ModelType>(cls: Class<T>, id: string): Promise<T> {
|
|
176
173
|
const store = this.#getStore(cls);
|
|
177
174
|
if (store.has(id)) {
|
package/src/service/crud.ts
CHANGED
|
@@ -2,19 +2,18 @@ import { Class } from '@travetto/base';
|
|
|
2
2
|
|
|
3
3
|
import { ModelType, OptionalId } from '../types/model';
|
|
4
4
|
import { ModelBasicSupport } from './basic';
|
|
5
|
+
import { UuidGenerator } from './types';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Interface for simple CRUD
|
|
8
|
-
*
|
|
9
9
|
* @concrete ../internal/service/common:ModelCrudSupportTarget
|
|
10
10
|
*/
|
|
11
11
|
export interface ModelCrudSupport extends ModelBasicSupport {
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
* @param value The optional value to generate a uuid around. Passing the same value multiple times produces the same output.
|
|
14
|
+
* Uuid Generator
|
|
16
15
|
*/
|
|
17
|
-
uuid
|
|
16
|
+
uuid: UuidGenerator;
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* Update an item
|