nesoi 3.1.0 → 3.1.2
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/lib/compiler/apps/monolyth/stages/2_build_typescript_stage.js +1 -0
- package/lib/compiler/elements/bucket.element.d.ts +2 -2
- package/lib/compiler/elements/bucket.element.js +25 -13
- package/lib/compiler/elements/element.js +2 -1
- package/lib/compiler/elements/machine.element.js +2 -2
- package/lib/compiler/elements/message.element.js +3 -2
- package/lib/compiler/helpers/dump_helpers.d.ts +5 -5
- package/lib/compiler/helpers/dump_helpers.js +37 -30
- package/lib/compiler/typescript/typescript_compiler.js +3 -0
- package/lib/elements/entities/bucket/adapters/bucket_adapter.d.ts +1 -1
- package/lib/elements/entities/bucket/adapters/memory.bucket_adapter.d.ts +7 -0
- package/lib/elements/entities/bucket/adapters/memory.bucket_adapter.js +46 -36
- package/lib/elements/entities/bucket/bucket.js +35 -27
- package/lib/elements/entities/bucket/cache/bucket_cache.d.ts +1 -4
- package/lib/elements/entities/bucket/model/bucket_model.infer.d.ts +2 -6
- package/lib/elements/entities/bucket/model/bucket_model.schema.d.ts +4 -1
- package/lib/elements/entities/bucket/model/bucket_model.schema.js +125 -5
- package/lib/elements/entities/bucket/model/bucket_model_field.builder.d.ts +7 -7
- package/lib/elements/entities/bucket/query/nql.schema.d.ts +1 -1
- package/lib/elements/entities/message/template/message_template_parser.js +6 -3
- package/lib/engine/space.js +1 -1
- package/lib/engine/transaction/nodes/bucket.trx_node.d.ts +15 -0
- package/lib/engine/transaction/nodes/bucket.trx_node.js +24 -0
- package/lib/engine/transaction/trx_engine.config.d.ts +3 -2
- package/lib/engine/transaction/trx_engine.d.ts +9 -1
- package/lib/engine/transaction/trx_engine.js +52 -9
- package/lib/engine/util/deep.js +4 -0
- package/lib/engine/util/parse.js +2 -2
- package/package.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -88,6 +88,7 @@ class BuildTypescriptStage {
|
|
|
88
88
|
}
|
|
89
89
|
libPaths.forEach(lib => {
|
|
90
90
|
lib = space_1.Space.relPath(compiler.space, lib);
|
|
91
|
+
// TODO: flatten sub-directory of modules
|
|
91
92
|
replacePaths[lib] = path.resolve(dirs.build, lib);
|
|
92
93
|
tsPaths['.nesoi/*'] = [space_1.Space.path(compiler.space, '.nesoi') + '/*'];
|
|
93
94
|
tsPaths[lib + '/*'] = [space_1.Space.path(compiler.space, lib) + '/*'];
|
|
@@ -13,8 +13,8 @@ export declare class BucketElement extends Element<$Bucket> {
|
|
|
13
13
|
};
|
|
14
14
|
private buildModelFieldType;
|
|
15
15
|
private buildCompositionType;
|
|
16
|
-
buildModelType(fields?: $BucketModelFields): ObjTypeAsObj;
|
|
17
|
-
buildModelpath(
|
|
16
|
+
buildModelType(fields?: $BucketModelFields, singleLine?: boolean): ObjTypeAsObj;
|
|
17
|
+
buildModelpath(): Record<string, TypeAsObj>;
|
|
18
18
|
buildQuerypath(fields?: $BucketModelFields): Record<string, TypeAsObj>;
|
|
19
19
|
private buildGraphType;
|
|
20
20
|
private buildViewsType;
|
|
@@ -65,7 +65,7 @@ class BucketElement extends element_1.Element {
|
|
|
65
65
|
bucket
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
-
buildModelFieldType(field) {
|
|
68
|
+
buildModelFieldType(field, singleLine = false) {
|
|
69
69
|
let type = 'unknown';
|
|
70
70
|
if (field.type === 'boolean') {
|
|
71
71
|
type = 'boolean';
|
|
@@ -91,10 +91,10 @@ class BucketElement extends element_1.Element {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
else if (Array.isArray(options)) {
|
|
94
|
-
type = options.map(v => dump_helpers_1.DumpHelpers.dumpValueToType(v));
|
|
94
|
+
type = options.map(v => dump_helpers_1.DumpHelpers.dumpValueToType(v, undefined, singleLine));
|
|
95
95
|
}
|
|
96
96
|
else if (typeof options === 'object') {
|
|
97
|
-
type = Object.values(options || []).map(v => dump_helpers_1.DumpHelpers.dumpValueToType(v));
|
|
97
|
+
type = Object.values(options || []).map(v => dump_helpers_1.DumpHelpers.dumpValueToType(v, undefined, singleLine));
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
else if (field.type === 'file') {
|
|
@@ -110,7 +110,7 @@ class BucketElement extends element_1.Element {
|
|
|
110
110
|
type = 'string';
|
|
111
111
|
}
|
|
112
112
|
else if (field.type === 'obj') {
|
|
113
|
-
type = this.buildModelType(field.children);
|
|
113
|
+
type = this.buildModelType(field.children, singleLine);
|
|
114
114
|
}
|
|
115
115
|
else if (field.type === 'unknown') {
|
|
116
116
|
type = 'unknown';
|
|
@@ -118,7 +118,7 @@ class BucketElement extends element_1.Element {
|
|
|
118
118
|
else if (field.type === 'dict') {
|
|
119
119
|
type = this.buildModelType({
|
|
120
120
|
'[x in string]': field.children['#']
|
|
121
|
-
});
|
|
121
|
+
}, singleLine);
|
|
122
122
|
}
|
|
123
123
|
else if (field.type === 'list') {
|
|
124
124
|
type = this.buildModelFieldType(field.children['#']);
|
|
@@ -130,12 +130,12 @@ class BucketElement extends element_1.Element {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
else if (field.type === 'union') {
|
|
133
|
-
const types = Object.values(this.buildModelType(field.children));
|
|
134
|
-
type = dump_helpers_1.DumpHelpers.dumpUnionType(types);
|
|
133
|
+
const types = Object.values(this.buildModelType(field.children, singleLine));
|
|
134
|
+
type = dump_helpers_1.DumpHelpers.dumpUnionType(types, singleLine);
|
|
135
135
|
}
|
|
136
136
|
if (!field.required) {
|
|
137
137
|
type = '('
|
|
138
|
-
+ dump_helpers_1.DumpHelpers.dumpType(type)
|
|
138
|
+
+ dump_helpers_1.DumpHelpers.dumpType(type, singleLine)
|
|
139
139
|
+ ' | null | undefined'
|
|
140
140
|
+ ')';
|
|
141
141
|
}
|
|
@@ -155,19 +155,31 @@ class BucketElement extends element_1.Element {
|
|
|
155
155
|
});
|
|
156
156
|
return composition;
|
|
157
157
|
}
|
|
158
|
-
buildModelType(fields = this.schema.model.fields) {
|
|
158
|
+
buildModelType(fields = this.schema.model.fields, singleLine = false) {
|
|
159
159
|
const model = {};
|
|
160
160
|
Object.entries(fields).forEach(([key, field]) => {
|
|
161
|
-
model[key] = this.buildModelFieldType(field);
|
|
161
|
+
model[key] = this.buildModelFieldType(field, singleLine);
|
|
162
162
|
});
|
|
163
163
|
return model;
|
|
164
164
|
}
|
|
165
|
-
buildModelpath(
|
|
166
|
-
const modelpath = {
|
|
165
|
+
buildModelpath() {
|
|
166
|
+
const modelpath = {
|
|
167
|
+
'[x: string]': 'any'
|
|
168
|
+
};
|
|
169
|
+
// const fields = $BucketModel.getModelpaths(this.schema.model);
|
|
170
|
+
// console.log({fields});
|
|
171
|
+
// for (const k in fields) {
|
|
172
|
+
// modelpath[k] = DumpHelpers.dumpUnionType(
|
|
173
|
+
// fields[k].map(field => this.buildModelFieldType(field, true))
|
|
174
|
+
// , true)
|
|
175
|
+
// console.log(k, modelpath[k]);
|
|
176
|
+
// }
|
|
167
177
|
return modelpath;
|
|
168
178
|
}
|
|
169
179
|
buildQuerypath(fields = this.schema.model.fields) {
|
|
170
|
-
const querypath = {
|
|
180
|
+
const querypath = {
|
|
181
|
+
'[x: string]': 'any'
|
|
182
|
+
};
|
|
171
183
|
return querypath;
|
|
172
184
|
}
|
|
173
185
|
buildGraphType() {
|
|
@@ -77,9 +77,10 @@ class Element {
|
|
|
77
77
|
const msgName = name_helpers_1.NameHelpers.names(schema);
|
|
78
78
|
return msgName.type;
|
|
79
79
|
});
|
|
80
|
+
const _input = new Set(input);
|
|
80
81
|
const output = schema['#output'] || this.makeOutputType(compiler, schema);
|
|
81
82
|
return {
|
|
82
|
-
input:
|
|
83
|
+
input: _input.size ? [..._input].join(' | ') : 'never',
|
|
83
84
|
output
|
|
84
85
|
};
|
|
85
86
|
}
|
|
@@ -81,7 +81,7 @@ class MachineElement extends element_1.Element {
|
|
|
81
81
|
Object.entries(stateTransitions).forEach(([msg, msgTransitions]) => {
|
|
82
82
|
type[state][msg] = [];
|
|
83
83
|
Object.values(msgTransitions).forEach(transition => {
|
|
84
|
-
const t = dump_helpers_1.DumpHelpers.dumpValueToType(transition, undefined, 4);
|
|
84
|
+
const t = dump_helpers_1.DumpHelpers.dumpValueToType(transition, undefined, undefined, 4);
|
|
85
85
|
Object.assign(t, {
|
|
86
86
|
'#authn': element_1.Element.makeAuthnType(transition.authn),
|
|
87
87
|
'#input': element_1.Element.makeIOType(this.compiler, transition).input,
|
|
@@ -89,7 +89,7 @@ class MachineElement extends element_1.Element {
|
|
|
89
89
|
});
|
|
90
90
|
type[state][msg].push(t);
|
|
91
91
|
});
|
|
92
|
-
type[state][msg] = '[' + type[state][msg].map((v) => dump_helpers_1.DumpHelpers.dumpType(v, 4)).join(', ') + ']';
|
|
92
|
+
type[state][msg] = '[' + type[state][msg].map((v) => dump_helpers_1.DumpHelpers.dumpType(v, undefined, 4)).join(', ') + ']';
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
95
|
return type;
|
|
@@ -161,8 +161,9 @@ class MessageElement extends element_1.Element {
|
|
|
161
161
|
output[key] = 'unknown';
|
|
162
162
|
}
|
|
163
163
|
if (!field.required || field.nullable) {
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
const inkey = field.type === 'id' ? `${key}_id` : key;
|
|
165
|
+
input[inkey] = '('
|
|
166
|
+
+ dump_helpers_1.DumpHelpers.dumpType(input[inkey])
|
|
166
167
|
+ (!field.required ? ' | undefined' : '')
|
|
167
168
|
+ (field.nullable ? ' | null' : '')
|
|
168
169
|
+ ')';
|
|
@@ -3,11 +3,11 @@ type TransformTypes = {
|
|
|
3
3
|
[x: string]: TransformTypes | ((v?: any) => TypeAsObj);
|
|
4
4
|
};
|
|
5
5
|
export declare class DumpHelpers {
|
|
6
|
-
static dumpUnionType(types: TypeAsObj[]): string;
|
|
7
|
-
static dumpIntersectionType(types: TypeAsObj[]): string;
|
|
8
|
-
static dumpType(type: TypeAsObj, d?: number): string;
|
|
9
|
-
static dumpSchema(val: any, d?: number): string;
|
|
6
|
+
static dumpUnionType(types: TypeAsObj[], singleLine?: boolean): string;
|
|
7
|
+
static dumpIntersectionType(types: TypeAsObj[], singleLine?: boolean): string;
|
|
8
|
+
static dumpType(type: TypeAsObj, singleLine?: boolean, d?: number): string;
|
|
9
|
+
static dumpSchema(val: any, singleLine?: boolean, d?: number): string;
|
|
10
10
|
private static dumpFunction;
|
|
11
|
-
static dumpValueToType(value: any, transform?: TransformTypes, d?: number): TypeAsObj;
|
|
11
|
+
static dumpValueToType(value: any, transform?: TransformTypes, singleLine?: boolean, d?: number): TypeAsObj;
|
|
12
12
|
}
|
|
13
13
|
export {};
|
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DumpHelpers = void 0;
|
|
4
4
|
class DumpHelpers {
|
|
5
|
-
static dumpUnionType(types) {
|
|
5
|
+
static dumpUnionType(types, singleLine = false) {
|
|
6
6
|
if (types.length < 2)
|
|
7
|
-
return this.dumpType(types[0]);
|
|
8
|
-
return '(' + types.map(t => this.dumpType(t)).join(' | ') + ')';
|
|
7
|
+
return this.dumpType(types[0], singleLine);
|
|
8
|
+
return '(' + types.map(t => this.dumpType(t, singleLine)).join(' | ') + ')';
|
|
9
9
|
}
|
|
10
|
-
static dumpIntersectionType(types) {
|
|
10
|
+
static dumpIntersectionType(types, singleLine = false) {
|
|
11
11
|
if (types.length < 2)
|
|
12
|
-
return this.dumpType(types[0]);
|
|
13
|
-
return '(' + types.map(t => this.dumpType(t)).join(' | ') + ')';
|
|
12
|
+
return this.dumpType(types[0], singleLine);
|
|
13
|
+
return '(' + types.map(t => this.dumpType(t, singleLine)).join(' | ') + ')';
|
|
14
14
|
}
|
|
15
|
-
static dumpType(type, d = 0) {
|
|
16
|
-
const pad0 = ' '.repeat(d);
|
|
17
|
-
const pad1 = ' '.repeat(d + 1);
|
|
15
|
+
static dumpType(type, singleLine = false, d = 0) {
|
|
16
|
+
const pad0 = singleLine ? ' ' : ' '.repeat(d);
|
|
17
|
+
const pad1 = singleLine ? ' ' : ' '.repeat(d + 1);
|
|
18
|
+
const lb = singleLine ? '' : '\n';
|
|
18
19
|
let str = '';
|
|
19
20
|
if (typeof type === 'undefined') {
|
|
20
21
|
str = 'never';
|
|
@@ -27,20 +28,25 @@ class DumpHelpers {
|
|
|
27
28
|
}
|
|
28
29
|
else if (Array.isArray(type)) {
|
|
29
30
|
if (type.length) {
|
|
30
|
-
str = '(' + type.map(t => this.dumpType(t)).join(' | ') + ')';
|
|
31
|
+
str = '(' + type.map(t => this.dumpType(t, singleLine)).join(' | ') + ')';
|
|
31
32
|
}
|
|
32
33
|
else {
|
|
33
34
|
str = 'never';
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
else {
|
|
37
|
-
str = '{
|
|
38
|
+
str = '{' + lb +
|
|
38
39
|
Object.entries(type)
|
|
39
40
|
.filter(([key]) => !['__array', '__optional', '__or'].includes(key))
|
|
40
41
|
.map(([key, value]) => {
|
|
41
42
|
let k = key;
|
|
43
|
+
// If key contains ${, it's a template string
|
|
44
|
+
if (k.includes('${')) {
|
|
45
|
+
// Put single quotes around non-alphanumeric keys
|
|
46
|
+
k = '[_: `' + key + '`]';
|
|
47
|
+
}
|
|
42
48
|
// If key is not a special [],
|
|
43
|
-
if (!(k.startsWith('[') && k.endsWith(']'))
|
|
49
|
+
else if (!(k.startsWith('[') && k.endsWith(']'))
|
|
44
50
|
&& !(k.startsWith('`') && k.endsWith('`'))) {
|
|
45
51
|
// Put single quotes around non-alphanumeric keys
|
|
46
52
|
k = /[^\w]/.exec(key) ? `'${key}'` : key;
|
|
@@ -58,14 +64,14 @@ class DumpHelpers {
|
|
|
58
64
|
k += '?';
|
|
59
65
|
}
|
|
60
66
|
// Dump element type
|
|
61
|
-
const t = this.dumpType(value, d + 1);
|
|
67
|
+
const t = this.dumpType(value, singleLine, d + 1);
|
|
62
68
|
return `${pad1}${k}: ${t}`;
|
|
63
|
-
}).join('
|
|
64
|
-
+
|
|
69
|
+
}).join(',' + lb)
|
|
70
|
+
+ `${lb}${pad0}}`;
|
|
65
71
|
}
|
|
66
72
|
if (typeof type === 'object') {
|
|
67
73
|
if (type.__or) {
|
|
68
|
-
str += ' | ' + this.dumpType(type.__or, d);
|
|
74
|
+
str += ' | ' + this.dumpType(type.__or, singleLine, d);
|
|
69
75
|
}
|
|
70
76
|
if (type.__array) {
|
|
71
77
|
str = `(${str})[]`;
|
|
@@ -76,9 +82,10 @@ class DumpHelpers {
|
|
|
76
82
|
}
|
|
77
83
|
return str;
|
|
78
84
|
}
|
|
79
|
-
static dumpSchema(val, d = 0) {
|
|
80
|
-
const pad0 = ' '.repeat(d);
|
|
81
|
-
const pad1 = ' '.repeat(d + 1);
|
|
85
|
+
static dumpSchema(val, singleLine = false, d = 0) {
|
|
86
|
+
const pad0 = singleLine ? ' ' : ' '.repeat(d);
|
|
87
|
+
const pad1 = singleLine ? ' ' : ' '.repeat(d + 1);
|
|
88
|
+
const lb = singleLine ? '' : '\n';
|
|
82
89
|
if (typeof val === 'undefined') {
|
|
83
90
|
return 'undefined';
|
|
84
91
|
}
|
|
@@ -95,22 +102,22 @@ class DumpHelpers {
|
|
|
95
102
|
return val.description || 'undefined';
|
|
96
103
|
}
|
|
97
104
|
else if (Array.isArray(val)) {
|
|
98
|
-
return '[
|
|
105
|
+
return '[' + lb +
|
|
99
106
|
val.map(child => {
|
|
100
|
-
return `${pad1}${this.dumpSchema(child, d + 1)}`;
|
|
101
|
-
}).join('
|
|
102
|
-
+
|
|
107
|
+
return `${pad1}${this.dumpSchema(child, singleLine, d + 1)}`;
|
|
108
|
+
}).join(',' + lb)
|
|
109
|
+
+ `${lb}${pad0}]`;
|
|
103
110
|
}
|
|
104
111
|
else if (typeof val === 'object') {
|
|
105
112
|
if ('__fn' in val) {
|
|
106
113
|
return val.__fn;
|
|
107
114
|
}
|
|
108
|
-
return '{
|
|
115
|
+
return '{' + lb +
|
|
109
116
|
Object.entries(val).map(([key, child]) => {
|
|
110
117
|
const _key = key.match(/\W/) ? `'${key}'` : key;
|
|
111
|
-
return `${pad1}${_key}: ${this.dumpSchema(child, d + 1)}`;
|
|
112
|
-
}).join('
|
|
113
|
-
+
|
|
118
|
+
return `${pad1}${_key}: ${this.dumpSchema(child, singleLine, d + 1)}`;
|
|
119
|
+
}).join(',' + lb)
|
|
120
|
+
+ `${lb}${pad0}}`;
|
|
114
121
|
}
|
|
115
122
|
else if (typeof val === 'function') {
|
|
116
123
|
return this.dumpFunction(val, pad0);
|
|
@@ -122,7 +129,7 @@ class DumpHelpers {
|
|
|
122
129
|
// if not, we try to use the JS version.
|
|
123
130
|
return `/* TS BRIDGE WARN: function not properly extracted from source. Attempting JS version (imports will not work) */ (${fn.toString()}) as any`;
|
|
124
131
|
}
|
|
125
|
-
static dumpValueToType(value, transform = {}, d = 2) {
|
|
132
|
+
static dumpValueToType(value, transform = {}, singleLine = false, d = 2) {
|
|
126
133
|
if (value === undefined) {
|
|
127
134
|
return 'undefined';
|
|
128
135
|
}
|
|
@@ -143,7 +150,7 @@ class DumpHelpers {
|
|
|
143
150
|
if (value.length === 0) {
|
|
144
151
|
return 'never[]';
|
|
145
152
|
}
|
|
146
|
-
return '[' + value.map((v) => DumpHelpers.dumpType(this.dumpValueToType(v, transform, d + 1), d)).join(', ') + ']';
|
|
153
|
+
return '[' + value.map((v) => DumpHelpers.dumpType(this.dumpValueToType(v, transform, singleLine, d + 1), singleLine, d)).join(', ') + ']';
|
|
147
154
|
}
|
|
148
155
|
else {
|
|
149
156
|
const obj = {};
|
|
@@ -158,7 +165,7 @@ class DumpHelpers {
|
|
|
158
165
|
obj[key] = transform[key](value);
|
|
159
166
|
}
|
|
160
167
|
else {
|
|
161
|
-
obj[key] = this.dumpValueToType(value, transform[key], d + 1);
|
|
168
|
+
obj[key] = this.dumpValueToType(value, transform[key], singleLine, d + 1);
|
|
162
169
|
}
|
|
163
170
|
});
|
|
164
171
|
return obj;
|
|
@@ -271,6 +271,9 @@ class TypeScriptCompiler {
|
|
|
271
271
|
// string: A specific key
|
|
272
272
|
const parseObj = (node, path, nested = false) => {
|
|
273
273
|
return node.properties.map(prop => {
|
|
274
|
+
if (ts.isSpreadAssignment(prop)) {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
274
277
|
if (!ts.isPropertyAssignment(prop)) {
|
|
275
278
|
throw new Error('A nesoi builder object property must be an assignment');
|
|
276
279
|
}
|
|
@@ -141,7 +141,7 @@ export declare abstract class BucketAdapter<Obj extends NesoiObj> {
|
|
|
141
141
|
}): Promise<NQL_Result<MetadataOnly extends true ? {
|
|
142
142
|
id: Obj['id'];
|
|
143
143
|
[x: string]: any;
|
|
144
|
-
}
|
|
144
|
+
} : Obj>>;
|
|
145
145
|
/**
|
|
146
146
|
* Return the epoch of the last update of an object
|
|
147
147
|
* @param {Obj} obj An object of this bucket
|
|
@@ -6,6 +6,13 @@ import { BucketCacheSync } from '../cache/bucket_cache';
|
|
|
6
6
|
/**
|
|
7
7
|
* @category Adapters
|
|
8
8
|
* @subcategory Entity
|
|
9
|
+
*
|
|
10
|
+
* > Every method that alters data makes a `Deep.copy` of the input
|
|
11
|
+
* > before processing it, to avoid side-effects to the input data
|
|
12
|
+
* > by modifying the external data on the adapter.
|
|
13
|
+
* > It also makes a `Deep.copy` of the data before outputting it,
|
|
14
|
+
* > to avoid side-effects on the adapter data by modifying the returned
|
|
15
|
+
* > object externally.
|
|
9
16
|
* */
|
|
10
17
|
export declare class MemoryBucketAdapter<B extends $Bucket, Obj extends B['#data']> extends BucketAdapter<Obj> {
|
|
11
18
|
schema: B;
|
|
@@ -4,9 +4,17 @@ exports.MemoryBucketAdapter = void 0;
|
|
|
4
4
|
const bucket_adapter_1 = require("./bucket_adapter");
|
|
5
5
|
const crypto_1 = require("crypto");
|
|
6
6
|
const memory_nql_1 = require("./memory.nql");
|
|
7
|
+
const bucket_model_schema_1 = require("../model/bucket_model.schema");
|
|
7
8
|
/**
|
|
8
9
|
* @category Adapters
|
|
9
10
|
* @subcategory Entity
|
|
11
|
+
*
|
|
12
|
+
* > Every method that alters data makes a `Deep.copy` of the input
|
|
13
|
+
* > before processing it, to avoid side-effects to the input data
|
|
14
|
+
* > by modifying the external data on the adapter.
|
|
15
|
+
* > It also makes a `Deep.copy` of the data before outputting it,
|
|
16
|
+
* > to avoid side-effects on the adapter data by modifying the returned
|
|
17
|
+
* > object externally.
|
|
10
18
|
* */
|
|
11
19
|
class MemoryBucketAdapter extends bucket_adapter_1.BucketAdapter {
|
|
12
20
|
constructor(schema, data = {}, config) {
|
|
@@ -37,12 +45,14 @@ class MemoryBucketAdapter extends bucket_adapter_1.BucketAdapter {
|
|
|
37
45
|
}
|
|
38
46
|
/* Write Operations */
|
|
39
47
|
async create(trx, obj) {
|
|
48
|
+
const input = bucket_model_schema_1.$BucketModel.copy(this.schema.model, obj, this.config.meta);
|
|
40
49
|
const lastId = (await this.index(trx))
|
|
41
|
-
.map((
|
|
50
|
+
.map((_obj) => parseInt(_obj.id))
|
|
42
51
|
.sort((a, b) => b - a)[0] || 0;
|
|
43
|
-
|
|
44
|
-
this.data[
|
|
45
|
-
|
|
52
|
+
input.id = lastId + 1;
|
|
53
|
+
this.data[input.id] = input;
|
|
54
|
+
const output = bucket_model_schema_1.$BucketModel.copy(this.schema.model, input, this.config.meta);
|
|
55
|
+
return Promise.resolve(output);
|
|
46
56
|
}
|
|
47
57
|
async createMany(trx, objs) {
|
|
48
58
|
const out = [];
|
|
@@ -55,17 +65,16 @@ class MemoryBucketAdapter extends bucket_adapter_1.BucketAdapter {
|
|
|
55
65
|
if (!obj.id || !this.data[obj.id]) {
|
|
56
66
|
throw new Error(`Object with id ${obj.id} not found for replace`);
|
|
57
67
|
}
|
|
58
|
-
this.
|
|
59
|
-
|
|
68
|
+
const input = bucket_model_schema_1.$BucketModel.copy(this.schema.model, obj, this.config.meta);
|
|
69
|
+
this.data[input.id] = input;
|
|
70
|
+
const output = bucket_model_schema_1.$BucketModel.copy(this.schema.model, input, this.config.meta);
|
|
71
|
+
return Promise.resolve(output);
|
|
60
72
|
}
|
|
61
|
-
replaceMany(trx, objs) {
|
|
73
|
+
async replaceMany(trx, objs) {
|
|
62
74
|
const out = [];
|
|
63
75
|
for (const obj of objs) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
this.data[obj.id] = obj;
|
|
68
|
-
out.push(obj);
|
|
76
|
+
const output = await this.replace(trx, obj);
|
|
77
|
+
out.push(output);
|
|
69
78
|
}
|
|
70
79
|
return Promise.resolve(out);
|
|
71
80
|
}
|
|
@@ -73,39 +82,38 @@ class MemoryBucketAdapter extends bucket_adapter_1.BucketAdapter {
|
|
|
73
82
|
if (!obj.id || !this.data[obj.id]) {
|
|
74
83
|
throw new Error(`Object with id ${obj.id} not found for patch`);
|
|
75
84
|
}
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
for (const key in
|
|
79
|
-
if (
|
|
80
|
-
delete
|
|
85
|
+
const data = this.data[obj.id];
|
|
86
|
+
const input = bucket_model_schema_1.$BucketModel.copy(this.schema.model, obj, this.config.meta);
|
|
87
|
+
for (const key in input) {
|
|
88
|
+
if (input[key] === null) {
|
|
89
|
+
delete data[key];
|
|
81
90
|
}
|
|
82
|
-
else if (
|
|
83
|
-
|
|
91
|
+
else if (input[key] !== undefined) {
|
|
92
|
+
data[key] = input[key];
|
|
84
93
|
}
|
|
85
94
|
}
|
|
86
|
-
|
|
95
|
+
const output = bucket_model_schema_1.$BucketModel.copy(this.schema.model, data, this.config.meta);
|
|
96
|
+
return Promise.resolve(output);
|
|
87
97
|
}
|
|
88
|
-
patchMany(trx, objs) {
|
|
98
|
+
async patchMany(trx, objs) {
|
|
89
99
|
const out = [];
|
|
90
100
|
for (const obj of objs) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
// TODO: Implement patch
|
|
95
|
-
this.data[obj.id] = obj;
|
|
96
|
-
out.push(obj);
|
|
101
|
+
const output = await this.patch(trx, obj);
|
|
102
|
+
out.push(output);
|
|
97
103
|
}
|
|
98
104
|
return Promise.resolve(out);
|
|
99
105
|
}
|
|
100
106
|
async put(trx, obj) {
|
|
101
|
-
|
|
107
|
+
const input = bucket_model_schema_1.$BucketModel.copy(this.schema.model, obj, this.config.meta);
|
|
108
|
+
if (!input.id) {
|
|
102
109
|
const lastId = (await this.index(trx))
|
|
103
|
-
.map((
|
|
110
|
+
.map((_obj) => parseInt(_obj.id))
|
|
104
111
|
.sort((a, b) => b - a)[0] || 0;
|
|
105
|
-
|
|
112
|
+
input.id = lastId + 1;
|
|
106
113
|
}
|
|
107
|
-
this.data[
|
|
108
|
-
|
|
114
|
+
this.data[input.id] = input;
|
|
115
|
+
const output = bucket_model_schema_1.$BucketModel.copy(this.schema.model, input, this.config.meta);
|
|
116
|
+
return Promise.resolve(output);
|
|
109
117
|
}
|
|
110
118
|
async putMany(trx, objs) {
|
|
111
119
|
const lastId = (await this.index(trx))
|
|
@@ -114,11 +122,13 @@ class MemoryBucketAdapter extends bucket_adapter_1.BucketAdapter {
|
|
|
114
122
|
let id = lastId + 1;
|
|
115
123
|
const out = [];
|
|
116
124
|
for (const obj of objs) {
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
const input = bucket_model_schema_1.$BucketModel.copy(this.schema.model, obj, this.config.meta);
|
|
126
|
+
if (!input.id) {
|
|
127
|
+
input.id = id;
|
|
119
128
|
}
|
|
120
|
-
this.data[
|
|
121
|
-
|
|
129
|
+
this.data[input.id] = input;
|
|
130
|
+
const output = bucket_model_schema_1.$BucketModel.copy(this.schema.model, input, this.config.meta);
|
|
131
|
+
out.push(output);
|
|
122
132
|
id++;
|
|
123
133
|
}
|
|
124
134
|
return Promise.resolve(out);
|
|
@@ -425,11 +425,13 @@ class Bucket {
|
|
|
425
425
|
continue;
|
|
426
426
|
const linkObj = composition[link.name];
|
|
427
427
|
if (!linkObj) {
|
|
428
|
-
|
|
428
|
+
if (mode === 'patch')
|
|
429
|
+
continue;
|
|
430
|
+
throw error_1.NesoiError.Bucket.MissingComposition({ method: 'replace', bucket: this.schema.name, link: link.name });
|
|
429
431
|
}
|
|
430
432
|
if (link.many) {
|
|
431
433
|
if (!Array.isArray(linkObj)) {
|
|
432
|
-
throw error_1.NesoiError.Bucket.CompositionValueShouldBeArray({ method: '
|
|
434
|
+
throw error_1.NesoiError.Bucket.CompositionValueShouldBeArray({ method: 'replace', bucket: this.schema.name, link: link.name });
|
|
433
435
|
}
|
|
434
436
|
for (const linkObjItem of linkObj) {
|
|
435
437
|
await trx.bucket(link.bucket.refName)[mode](linkObjItem);
|
|
@@ -525,20 +527,44 @@ class Bucket {
|
|
|
525
527
|
}
|
|
526
528
|
}
|
|
527
529
|
// Delete compositions (with other key)
|
|
530
|
+
// Currently there's only 'self' key
|
|
531
|
+
//
|
|
532
|
+
// for(const link of Object.values(this.schema.graph.links)) {
|
|
533
|
+
// if (link.rel !== 'composition') continue;
|
|
534
|
+
// if (link.keyOwner !== 'other') continue;
|
|
535
|
+
// const linked = await this.graph.readLink(trx, id, link.name, {
|
|
536
|
+
// silent: true
|
|
537
|
+
// }) as any;
|
|
538
|
+
// if (!linked) continue;
|
|
539
|
+
// if (link.many) {
|
|
540
|
+
// for (const linkedItem of linked) {
|
|
541
|
+
// await trx.bucket(link.bucket.refName).delete(linkedItem.id);
|
|
542
|
+
// }
|
|
543
|
+
// }
|
|
544
|
+
// else {
|
|
545
|
+
// await trx.bucket(link.bucket.refName).delete(linked.id);
|
|
546
|
+
// }
|
|
547
|
+
// }
|
|
548
|
+
// Composition (with self key)
|
|
528
549
|
for (const link of Object.values(this.schema.graph.links)) {
|
|
529
550
|
if (link.rel !== 'composition')
|
|
530
551
|
continue;
|
|
531
|
-
if (link.keyOwner !== '
|
|
552
|
+
if (link.keyOwner !== 'self')
|
|
532
553
|
continue;
|
|
533
|
-
const linked =
|
|
534
|
-
|
|
535
|
-
|
|
554
|
+
const linked = result
|
|
555
|
+
// If safe, avoid reading the object again inside readLink.
|
|
556
|
+
// Instead, use graph's readLink which takes the object.
|
|
557
|
+
? await this.graph.readLink(trx, result.data[0], link.name, {
|
|
558
|
+
silent: true
|
|
559
|
+
})
|
|
560
|
+
// If unsafe, read the link base by id.
|
|
561
|
+
: await this.readLink(trx, id, link.name, {
|
|
562
|
+
silent: true
|
|
563
|
+
});
|
|
536
564
|
if (!linked)
|
|
537
565
|
continue;
|
|
538
566
|
if (link.many) {
|
|
539
|
-
|
|
540
|
-
await trx.bucket(link.bucket.refName).delete(linkedItem.id);
|
|
541
|
-
}
|
|
567
|
+
await trx.bucket(link.bucket.refName).unsafe.deleteMany(linked.map((l) => l.id));
|
|
542
568
|
}
|
|
543
569
|
else {
|
|
544
570
|
await trx.bucket(link.bucket.refName).delete(linked.id);
|
|
@@ -550,24 +576,6 @@ class Bucket {
|
|
|
550
576
|
await trash_1.Trash.add(trx, this.module, this.schema.name, obj);
|
|
551
577
|
}
|
|
552
578
|
await this.adapter.delete(trx, id);
|
|
553
|
-
// Composition (with self key)
|
|
554
|
-
for (const link of Object.values(this.schema.graph.links)) {
|
|
555
|
-
if (link.rel !== 'composition')
|
|
556
|
-
continue;
|
|
557
|
-
if (link.keyOwner !== 'self')
|
|
558
|
-
continue;
|
|
559
|
-
const linked = await this.readLink(trx, id, link.name, {
|
|
560
|
-
silent: true
|
|
561
|
-
});
|
|
562
|
-
if (!linked)
|
|
563
|
-
continue;
|
|
564
|
-
if (link.many) {
|
|
565
|
-
await trx.bucket(link.bucket.refName).unsafe.deleteMany(linked.map((l) => l.id));
|
|
566
|
-
}
|
|
567
|
-
else {
|
|
568
|
-
await trx.bucket(link.bucket.refName).delete(linked.id);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
579
|
}
|
|
572
580
|
/**
|
|
573
581
|
* Delete many entities
|
|
@@ -35,10 +35,7 @@ export declare class BucketCache<Obj extends NesoiObj> {
|
|
|
35
35
|
constructor(bucketName: string, outerAdapter: AnyBucketAdapter, config: NonNullable<BucketConfig<any, any, any>['cache']>);
|
|
36
36
|
get(trx: AnyTrxNode, id: NesoiObj['id']): Promise<any>;
|
|
37
37
|
index(trx: AnyTrxNode): Promise<any[]>;
|
|
38
|
-
query(trx: AnyTrxNode, view: $BucketView, query: NQL_AnyQuery, pagination?: NQL_Pagination): Promise<NQL_Result<any
|
|
39
|
-
[x: string]: any;
|
|
40
|
-
id: any;
|
|
41
|
-
}[]> | Obj[]>;
|
|
38
|
+
query(trx: AnyTrxNode, view: $BucketView, query: NQL_AnyQuery, pagination?: NQL_Pagination): Promise<NQL_Result<any> | Obj[]>;
|
|
42
39
|
private syncOne;
|
|
43
40
|
private syncOneAndPast;
|
|
44
41
|
private syncAll;
|
|
@@ -18,14 +18,10 @@ export type BucketModelpathObjInfer<Builders extends BucketModelFieldBuilders<an
|
|
|
18
18
|
};
|
|
19
19
|
}[keyof Builders]>;
|
|
20
20
|
export type BucketModelpathListInfer<Builder extends AnyBucketModelFieldBuilder> = {
|
|
21
|
-
[J in keyof Builder['#modelpath'] as `.$${number}${J & string}` | `.${number}${J & string}`]: Builder['#modelpath'][J];
|
|
22
|
-
} & {
|
|
23
|
-
[J in keyof Builder['#modelpath'] as `.${'*'}${J & string}`]: Builder['#modelpath'][J][];
|
|
21
|
+
[J in keyof Builder['#modelpath'] as `.*${J & string}` | `.$${number}${J & string}` | `.${number}${J & string}`]: Builder['#modelpath'][J];
|
|
24
22
|
};
|
|
25
23
|
export type BucketModelpathDictInfer<Builder extends AnyBucketModelFieldBuilder> = {
|
|
26
|
-
[J in keyof Builder['#modelpath'] as `.$${number}${J & string}` | `.${string}${J & string}`]: Builder['#modelpath'][J];
|
|
27
|
-
} & {
|
|
28
|
-
[J in keyof Builder['#modelpath'] as `.${'*'}${J & string}`]: Record<string, Builder['#modelpath'][J]>;
|
|
24
|
+
[J in keyof Builder['#modelpath'] as `.*${J & string}` | `.$${number}${J & string}` | `.${string}${J & string}`]: Builder['#modelpath'][J];
|
|
29
25
|
};
|
|
30
26
|
export type BucketModelpathUnionInfer<Builders extends AnyBucketModelFieldBuilder[]> = Builders[0]['#modelpath'] | Builders[1]['#modelpath'];
|
|
31
27
|
export type BucketModelpathInfer<Def extends BucketModelDef<any, any>> = BucketModelpathRawInfer<ReturnType<Def>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { $Dependency } from "../../../../engine/dependency";
|
|
2
|
+
import { BucketAdapterConfig } from '../adapters/bucket_adapter';
|
|
2
3
|
export type $BucketModelFieldType = 'boolean' | 'date' | 'datetime' | 'duration' | 'decimal' | 'enum' | 'file' | 'float' | 'int' | 'string' | 'obj' | 'unknown' | 'dict' | 'list' | 'union';
|
|
3
4
|
export type $BucketModelFieldCrypto = {
|
|
4
5
|
algorithm: string;
|
|
@@ -67,5 +68,7 @@ export declare class $BucketModel {
|
|
|
67
68
|
}, defaults?: Record<string, any>, hasFileField?: boolean, hasEncryptedField?: boolean);
|
|
68
69
|
static getField(model: $BucketModel, modelpath: string): $BucketModelField[];
|
|
69
70
|
static fieldsOfType(model: $BucketModel, type: $BucketModelFieldType): $BucketModelField[];
|
|
70
|
-
static forEachField(
|
|
71
|
+
static forEachField(model: $BucketModel, predicate: (field: $BucketModelField, path: string) => void): void;
|
|
72
|
+
static copy<T extends Record<string, any>>(model: $BucketModel, obj: T, meta?: BucketAdapterConfig['meta']): T;
|
|
73
|
+
static getModelpaths(model: $BucketModel): Record<string, $BucketModelField[]>;
|
|
71
74
|
}
|