nesoi 3.0.21 → 3.1.1
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/apps/monolyth/stages/4_dump_modules_stage.js +8 -0
- package/lib/compiler/compiler.js +1 -1
- package/lib/compiler/elements/bucket.element.d.ts +3 -2
- package/lib/compiler/elements/bucket.element.js +86 -128
- package/lib/compiler/elements/element.js +4 -2
- package/lib/compiler/elements/externals.element.js +3 -0
- package/lib/compiler/elements/machine.element.js +2 -2
- package/lib/compiler/elements/message.element.js +35 -57
- package/lib/compiler/elements/queue.element.js +1 -1
- package/lib/compiler/helpers/dump_helpers.d.ts +5 -3
- package/lib/compiler/helpers/dump_helpers.js +43 -26
- package/lib/compiler/stages/4_build_schemas_stage.js +12 -0
- package/lib/compiler/stages/5_inject_ts_stage.js +4 -1
- package/lib/compiler/stages/7_dump_stage.js +7 -1
- package/lib/compiler/treeshake.js +4 -2
- package/lib/compiler/typescript/bridge/extract.js +37 -107
- package/lib/compiler/typescript/bridge/inject.d.ts +1 -1
- package/lib/compiler/typescript/bridge/inject.js +73 -45
- package/lib/compiler/typescript/bridge/organize.js +9 -5
- package/lib/compiler/typescript/typescript_compiler.d.ts +4 -6
- package/lib/compiler/typescript/typescript_compiler.js +139 -75
- package/lib/elements/blocks/block.builder.d.ts +1 -10
- package/lib/elements/blocks/block.builder.js +0 -32
- package/lib/elements/blocks/job/internal/resource_job.builder.d.ts +3 -21
- package/lib/elements/blocks/job/job.builder.d.ts +6 -20
- package/lib/elements/blocks/job/job.builder.js +0 -4
- package/lib/elements/blocks/machine/machine.builder.d.ts +5 -14
- package/lib/elements/blocks/machine/machine.builder.js +2 -2
- package/lib/elements/blocks/queue/queue.builder.d.ts +6 -15
- package/lib/elements/blocks/queue/queue.builder.js +2 -2
- package/lib/elements/edge/externals/externals.builder.d.ts +2 -0
- package/lib/elements/edge/externals/externals.builder.js +6 -1
- package/lib/elements/edge/externals/externals.schema.d.ts +2 -1
- package/lib/elements/edge/externals/externals.schema.js +3 -1
- 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/adapters/memory.nql.js +1 -1
- package/lib/elements/entities/bucket/bucket.builder.d.ts +6 -4
- package/lib/elements/entities/bucket/bucket.js +42 -43
- package/lib/elements/entities/bucket/bucket.schema.d.ts +2 -1
- package/lib/elements/entities/bucket/cache/bucket_cache.d.ts +1 -4
- package/lib/elements/entities/bucket/graph/bucket_graph.infer.d.ts +7 -5
- package/lib/elements/entities/bucket/graph/bucket_graph_link.builder.d.ts +2 -1
- package/lib/elements/entities/bucket/model/bucket_model.builder.d.ts +1 -1
- package/lib/elements/entities/bucket/model/bucket_model.convert.d.ts +1 -1
- package/lib/elements/entities/bucket/model/bucket_model.convert.js +4 -4
- package/lib/elements/entities/bucket/model/bucket_model.infer.d.ts +41 -9
- package/lib/elements/entities/bucket/model/bucket_model.schema.d.ts +8 -6
- package/lib/elements/entities/bucket/model/bucket_model.schema.js +184 -21
- package/lib/elements/entities/bucket/model/bucket_model_field.builder.d.ts +89 -56
- package/lib/elements/entities/bucket/model/bucket_model_field.builder.js +22 -30
- package/lib/elements/entities/bucket/query/nql.schema.d.ts +13 -10
- package/lib/elements/entities/bucket/query/nql_compiler.js +46 -21
- package/lib/elements/entities/bucket/view/bucket_view.builder.js +1 -1
- package/lib/elements/entities/bucket/view/bucket_view.d.ts +19 -0
- package/lib/elements/entities/bucket/view/bucket_view.js +230 -108
- package/lib/elements/entities/bucket/view/bucket_view.schema.d.ts +5 -10
- package/lib/elements/entities/bucket/view/bucket_view.schema.js +3 -5
- package/lib/elements/entities/bucket/view/bucket_view_field.builder.d.ts +16 -12
- package/lib/elements/entities/bucket/view/bucket_view_field.builder.js +55 -40
- package/lib/elements/entities/message/message.builder.d.ts +1 -11
- package/lib/elements/entities/message/message.infer.d.ts +6 -30
- package/lib/elements/entities/message/message.schema.js +2 -2
- package/lib/elements/entities/message/template/message_template.builder.js +1 -1
- package/lib/elements/entities/message/template/message_template.schema.d.ts +10 -15
- package/lib/elements/entities/message/template/message_template.schema.js +29 -12
- package/lib/elements/entities/message/template/message_template_field.builder.d.ts +45 -209
- package/lib/elements/entities/message/template/message_template_field.builder.js +69 -85
- package/lib/elements/entities/message/template/message_template_parser.js +52 -64
- package/lib/engine/apps/inline.app.js +1 -0
- package/lib/engine/data/trash.js +7 -7
- package/lib/engine/data/tree.d.ts +3 -0
- package/lib/engine/data/tree.js +36 -0
- package/lib/engine/space.js +1 -1
- 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.d.ts +22 -14
- package/lib/engine/util/parse.js +20 -5
- package/lib/engine/util/type.d.ts +3 -0
- package/package.json +1 -1
- package/tools/joaquin/bucket.d.ts +9 -0
- package/tools/joaquin/bucket.js +49 -0
- package/tools/joaquin/message.d.ts +2 -1
- package/tools/joaquin/message.js +9 -2
- package/tools/joaquin/mock.d.ts +1 -0
- package/tools/joaquin/mock.js +13 -5
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -12,8 +12,8 @@ async function MessageTemplateFieldParser(trx, fields, raw) {
|
|
|
12
12
|
const inject = {};
|
|
13
13
|
for (const k in fields) {
|
|
14
14
|
const field = fields[k];
|
|
15
|
-
const key_raw = field.
|
|
16
|
-
const key_parsed = field.
|
|
15
|
+
const key_raw = field.pathRaw.split('.')[0];
|
|
16
|
+
const key_parsed = field.pathParsed.split('.')[0];
|
|
17
17
|
const value = raw[key_raw];
|
|
18
18
|
parsed[key_parsed] = await parseFieldValue(trx, field, [field.name], raw, value, inject);
|
|
19
19
|
}
|
|
@@ -29,33 +29,22 @@ async function MessageTemplateFieldParser(trx, fields, raw) {
|
|
|
29
29
|
*/
|
|
30
30
|
async function parseFieldValue(trx, field, path, raw, value, inject) {
|
|
31
31
|
sanitize(field, path, value);
|
|
32
|
+
let output;
|
|
32
33
|
if (isEmpty(value)) {
|
|
33
34
|
if (field.required) {
|
|
34
35
|
throw error_1.NesoiError.Message.FieldIsRequired({ alias: field.alias, path: path.join('.'), value });
|
|
35
36
|
}
|
|
36
37
|
else if (field.defaultValue !== undefined) {
|
|
37
|
-
|
|
38
|
+
output = field.defaultValue;
|
|
38
39
|
}
|
|
39
40
|
else {
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
let output;
|
|
44
|
-
if (field.array) {
|
|
45
|
-
if (!Array.isArray(value)) {
|
|
46
|
-
throw error_1.NesoiError.Message.InvalidFieldType({ alias: field.alias, path: path.join('.'), value, type: 'list' });
|
|
47
|
-
}
|
|
48
|
-
output = [];
|
|
49
|
-
for (let i = 0; i < value.length; i++) {
|
|
50
|
-
const v = value[i];
|
|
51
|
-
const parsedValue = await _attemptUnion(trx, field, [...path, i.toString()], raw, v, inject);
|
|
52
|
-
output.push(parsedValue);
|
|
41
|
+
output = undefined;
|
|
53
42
|
}
|
|
54
|
-
output = await applyFieldRules('array', field, path, raw, output, inject);
|
|
55
43
|
}
|
|
56
44
|
else {
|
|
57
45
|
output = await _attemptUnion(trx, field, path, raw, value, inject);
|
|
58
46
|
}
|
|
47
|
+
output = await applyFieldRules(field, path, raw, output, inject);
|
|
59
48
|
return output;
|
|
60
49
|
}
|
|
61
50
|
/**
|
|
@@ -65,35 +54,31 @@ async function parseFieldValue(trx, field, path, raw, value, inject) {
|
|
|
65
54
|
* - If it fails, attempt other union options (step 2) (if available), with same path
|
|
66
55
|
* - If it works, apply field rules.
|
|
67
56
|
*/
|
|
68
|
-
async function _attemptUnion(trx, field, path, raw, value, inject
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
output = await _runParseMethod(trx, field, path, raw, value, inject);
|
|
57
|
+
async function _attemptUnion(trx, field, path, raw, value, inject) {
|
|
58
|
+
if (field.type !== 'union') {
|
|
59
|
+
return _runParseMethod(trx, field, path, raw, value, inject);
|
|
72
60
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
61
|
+
const unionErrors = [];
|
|
62
|
+
let output = undefined;
|
|
63
|
+
for (const k in field.children) {
|
|
64
|
+
const option = field.children[k];
|
|
65
|
+
try {
|
|
66
|
+
output = await _runParseMethod(trx, option, path, raw, value, inject);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
unionErrors.push({
|
|
71
|
+
option: option.alias,
|
|
78
72
|
name: e.name,
|
|
79
73
|
status: e.status,
|
|
80
74
|
message: e.message,
|
|
81
75
|
data: e.data,
|
|
82
|
-
}
|
|
83
|
-
];
|
|
84
|
-
// If failed and there's a second option, atempt it
|
|
85
|
-
if (field.or) {
|
|
86
|
-
return await _attemptUnion(trx, field.or, path, raw, value, inject, ue);
|
|
76
|
+
});
|
|
87
77
|
}
|
|
88
|
-
// If this error was not the first attempt, and we have no other option
|
|
89
|
-
// we throw a specific error
|
|
90
|
-
// This avoid confusion for the client when parsing unions
|
|
91
|
-
if (unionErrors.length) {
|
|
92
|
-
throw error_1.NesoiError.Message.ValueDoesntMatchUnion({ alias: field.preAlias, path: path.join('.'), value, unionErrors: ue });
|
|
93
|
-
}
|
|
94
|
-
throw e;
|
|
95
78
|
}
|
|
96
|
-
|
|
79
|
+
if (unionErrors.length === Object.keys(field.children).length) {
|
|
80
|
+
throw error_1.NesoiError.Message.ValueDoesntMatchUnion({ alias: field.alias, path: path.join('.'), value, unionErrors });
|
|
81
|
+
}
|
|
97
82
|
return output;
|
|
98
83
|
}
|
|
99
84
|
/**
|
|
@@ -105,7 +90,8 @@ async function _runParseMethod(trx, field, path, raw, value, inject) {
|
|
|
105
90
|
switch (field.type) {
|
|
106
91
|
case 'obj':
|
|
107
92
|
case 'dict':
|
|
108
|
-
|
|
93
|
+
case 'list':
|
|
94
|
+
return parseParentField(trx, field, path, raw, value, inject);
|
|
109
95
|
case 'unknown':
|
|
110
96
|
return value;
|
|
111
97
|
case 'boolean':
|
|
@@ -131,30 +117,41 @@ async function _runParseMethod(trx, field, path, raw, value, inject) {
|
|
|
131
117
|
case 'string_or_number':
|
|
132
118
|
return (0, parse_1.parseStringOrNumber)(field, path, value);
|
|
133
119
|
case 'id':
|
|
134
|
-
return
|
|
120
|
+
return parseIdField(trx, field, path, value);
|
|
135
121
|
}
|
|
136
122
|
throw error_1.NesoiError.Builder.Message.UnknownTemplateFieldType(field.type);
|
|
137
123
|
}
|
|
138
124
|
/**
|
|
139
|
-
* [Parser Step 3-b]: 'obj' or 'dict'
|
|
125
|
+
* [Parser Step 3-b]: 'obj' or 'dict' or 'list'
|
|
140
126
|
*
|
|
141
127
|
* - The parser methods only return a tuple of field and value, to be parsed again by (step 1)
|
|
142
128
|
* - When calling step 1, the child property name is appended to the path
|
|
143
129
|
*/
|
|
144
130
|
async function parseParentField(trx, field, path, raw, value, inject) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
131
|
+
if (field.type === 'list') {
|
|
132
|
+
const children = (0, parse_1.parseList)(field, path, value);
|
|
133
|
+
const parsedParent = [];
|
|
134
|
+
for (const key in children) {
|
|
135
|
+
const child = children[key];
|
|
136
|
+
parsedParent.push(await parseFieldValue(trx, child.field, [...path, key], raw, child.value, inject));
|
|
137
|
+
}
|
|
138
|
+
return parsedParent;
|
|
148
139
|
}
|
|
149
140
|
else {
|
|
150
|
-
children
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
141
|
+
let children;
|
|
142
|
+
if (field.type === 'obj') {
|
|
143
|
+
children = (0, parse_1.parseObj)(field, path, value);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
children = (0, parse_1.parseDict)(field, path, value);
|
|
147
|
+
}
|
|
148
|
+
const parsedParent = {};
|
|
149
|
+
for (const key in children) {
|
|
150
|
+
const child = children[key];
|
|
151
|
+
parsedParent[key] = await parseFieldValue(trx, child.field, [...path, key], raw, child.value, inject);
|
|
152
|
+
}
|
|
153
|
+
return parsedParent;
|
|
156
154
|
}
|
|
157
|
-
return parsedParent;
|
|
158
155
|
}
|
|
159
156
|
/**
|
|
160
157
|
* [Parser Step 3-b]: 'id'
|
|
@@ -166,12 +163,7 @@ async function parseIdField(trx, field, path, value) {
|
|
|
166
163
|
const type = field.meta.id.type;
|
|
167
164
|
const view = field.meta.id.view;
|
|
168
165
|
const parsed = await (0, parse_1.parseId)(field, path, value, trx, bucket.refName, type, view);
|
|
169
|
-
|
|
170
|
-
return parsed.map((p) => p.obj);
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
return parsed.obj;
|
|
174
|
-
}
|
|
166
|
+
return parsed.obj;
|
|
175
167
|
}
|
|
176
168
|
function sanitize(field, path, value) {
|
|
177
169
|
if (typeof value === 'function') {
|
|
@@ -201,13 +193,9 @@ function isEmpty(value) {
|
|
|
201
193
|
/**
|
|
202
194
|
* Rules
|
|
203
195
|
*/
|
|
204
|
-
async function applyFieldRules(
|
|
196
|
+
async function applyFieldRules(field, path, raw, value, inject) {
|
|
205
197
|
let output = value;
|
|
206
|
-
|
|
207
|
-
// - This comes from a .rule *before* .array
|
|
208
|
-
// If mode is array, the value received is an array
|
|
209
|
-
// - This comes from a .rule *after* .array
|
|
210
|
-
const rules = mode === 'item' ? field.rules : field.arrayRules;
|
|
198
|
+
const rules = field.rules;
|
|
211
199
|
for (const r in rules) {
|
|
212
200
|
const rule = rules[r];
|
|
213
201
|
const res = await rule({ field, value, path: path.join('.'), msg: raw, inject });
|
|
@@ -122,6 +122,7 @@ class InlineApp extends app_1.App {
|
|
|
122
122
|
Object.values(modules).forEach(module => {
|
|
123
123
|
module.injectDependencies(modules, {
|
|
124
124
|
buckets: Object.values(module.schema.externals.buckets),
|
|
125
|
+
messages: Object.values(module.schema.externals.messages),
|
|
125
126
|
jobs: Object.values(module.schema.externals.jobs),
|
|
126
127
|
machines: Object.values(module.schema.externals.machines),
|
|
127
128
|
});
|
package/lib/engine/data/trash.js
CHANGED
|
@@ -5,14 +5,14 @@ const bucket_schema_1 = require("../../elements/entities/bucket/bucket.schema");
|
|
|
5
5
|
const bucket_model_schema_1 = require("../../elements/entities/bucket/model/bucket_model.schema");
|
|
6
6
|
const bucket_graph_schema_1 = require("../../elements/entities/bucket/graph/bucket_graph.schema");
|
|
7
7
|
exports.$TrashBucket = new bucket_schema_1.$Bucket('__trash__', 'trash', 'Trash', new bucket_model_schema_1.$BucketModel({
|
|
8
|
-
id: new bucket_model_schema_1.$BucketModelField('id', 'id', 'int', 'id',
|
|
9
|
-
module: new bucket_model_schema_1.$BucketModelField('module', 'module', 'string', 'Module Name',
|
|
10
|
-
bucket: new bucket_model_schema_1.$BucketModelField('bucket', 'bucket', 'string', 'Bucket Name',
|
|
11
|
-
object_id: new bucket_model_schema_1.$BucketModelField('object_id', 'object_id', 'int', 'Object ID',
|
|
12
|
-
object: new bucket_model_schema_1.$BucketModelField('object', 'object', 'dict', 'Object',
|
|
13
|
-
|
|
8
|
+
id: new bucket_model_schema_1.$BucketModelField('id', 'id', 'int', 'id', true),
|
|
9
|
+
module: new bucket_model_schema_1.$BucketModelField('module', 'module', 'string', 'Module Name', true),
|
|
10
|
+
bucket: new bucket_model_schema_1.$BucketModelField('bucket', 'bucket', 'string', 'Bucket Name', true),
|
|
11
|
+
object_id: new bucket_model_schema_1.$BucketModelField('object_id', 'object_id', 'int', 'Object ID', true),
|
|
12
|
+
object: new bucket_model_schema_1.$BucketModelField('object', 'object', 'dict', 'Object', true, undefined, undefined, {
|
|
13
|
+
'#': new bucket_model_schema_1.$BucketModelField('', '', 'unknown', '', true, undefined, undefined)
|
|
14
14
|
}),
|
|
15
|
-
delete_trx_id: new bucket_model_schema_1.$BucketModelField('delete_trx_id', 'delete_trx_id', 'int', 'ID of Delete Transaction',
|
|
15
|
+
delete_trx_id: new bucket_model_schema_1.$BucketModelField('delete_trx_id', 'delete_trx_id', 'int', 'ID of Delete Transaction', true),
|
|
16
16
|
}), new bucket_graph_schema_1.$BucketGraph(), {});
|
|
17
17
|
class Trash {
|
|
18
18
|
static async add(trx, module, bucket, object) {
|
|
@@ -10,7 +10,10 @@ export declare class Tree {
|
|
|
10
10
|
* - `*`: Return all values of the matched array or dict
|
|
11
11
|
* - `0`: Return the first value of an array or dict (dict ordering is unstable)
|
|
12
12
|
* - `(number|string)[]`: Sequence of values to replace the `#`s on the fieldpath
|
|
13
|
+
*
|
|
14
|
+
* @deprecated Fieldpath was consolidated into Modelpath and Querypath.
|
|
13
15
|
*/
|
|
14
16
|
static get(obj: Record<string, any>, fieldpath: string, index?: '*' | 0 | (number | string)[]): any;
|
|
17
|
+
static getModelpath(obj: Record<string, any>, modelpath: string, index: (string | number)[]): any[];
|
|
15
18
|
static set(obj: Record<string, any>, fieldpath: string, replacer: (v: any, i: (number | string)[]) => any, __index?: (number | string)[]): void;
|
|
16
19
|
}
|
package/lib/engine/data/tree.js
CHANGED
|
@@ -17,6 +17,8 @@ class Tree {
|
|
|
17
17
|
* - `*`: Return all values of the matched array or dict
|
|
18
18
|
* - `0`: Return the first value of an array or dict (dict ordering is unstable)
|
|
19
19
|
* - `(number|string)[]`: Sequence of values to replace the `#`s on the fieldpath
|
|
20
|
+
*
|
|
21
|
+
* @deprecated Fieldpath was consolidated into Modelpath and Querypath.
|
|
20
22
|
*/
|
|
21
23
|
static get(obj, fieldpath, index = '*') {
|
|
22
24
|
index = (!Array.isArray(index)) ? index : [...index];
|
|
@@ -90,6 +92,40 @@ class Tree {
|
|
|
90
92
|
}
|
|
91
93
|
return ref;
|
|
92
94
|
}
|
|
95
|
+
static getModelpath(obj, modelpath, index) {
|
|
96
|
+
const paths = modelpath.split('.');
|
|
97
|
+
let poll = [obj];
|
|
98
|
+
while (poll.length) {
|
|
99
|
+
const next = [];
|
|
100
|
+
for (const item of poll) {
|
|
101
|
+
const path = paths[item.i];
|
|
102
|
+
// '*'
|
|
103
|
+
if (path === '*') {
|
|
104
|
+
if (typeof item !== 'object') {
|
|
105
|
+
throw new Error(`Can't read *, item is not object (${item})`);
|
|
106
|
+
}
|
|
107
|
+
next.push(...Object.values(item));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const idx_str = path.match(/^\$(\d+)/)?.[1];
|
|
111
|
+
let _path = path;
|
|
112
|
+
// $0, $1..
|
|
113
|
+
if (idx_str !== undefined) {
|
|
114
|
+
const idx = parseInt(idx_str);
|
|
115
|
+
if (idx >= index.length) {
|
|
116
|
+
throw new Error(`Can't read $${idx}, too few indexes (${index.length})`);
|
|
117
|
+
}
|
|
118
|
+
_path = index[idx];
|
|
119
|
+
}
|
|
120
|
+
const n = typeof item === 'object' ? item[_path] : undefined;
|
|
121
|
+
if (n)
|
|
122
|
+
next.push(n);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
poll = next;
|
|
126
|
+
}
|
|
127
|
+
return poll;
|
|
128
|
+
}
|
|
93
129
|
static set(obj, fieldpath, replacer, __index = []) {
|
|
94
130
|
const paths = fieldpath.split('.');
|
|
95
131
|
class Ptr {
|
package/lib/engine/space.js
CHANGED
|
@@ -301,7 +301,7 @@ class Space {
|
|
|
301
301
|
.filter(node => node.isDirectory());
|
|
302
302
|
for (const dir of dirs) {
|
|
303
303
|
const modulePath = path.join(dirpath, dir.name);
|
|
304
|
-
if (fs.existsSync(path.join(modulePath, '.
|
|
304
|
+
if (fs.existsSync(path.join(modulePath, '.subset'))) {
|
|
305
305
|
perform(modulePath, [...subdir, dir.name]);
|
|
306
306
|
}
|
|
307
307
|
else {
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { $Module, $Space } from "../../elements";
|
|
2
2
|
import { BucketAdapter } from "../../elements/entities/bucket/adapters/bucket_adapter";
|
|
3
|
-
import {
|
|
3
|
+
import { Trx } from './trx';
|
|
4
4
|
import { AnyUsers } from '../auth/authn';
|
|
5
5
|
import { TrxNode, TrxNodeStatus } from './trx_node';
|
|
6
|
+
import { TrxData } from './trx_engine';
|
|
6
7
|
export type TrxEngineWrapFn<S extends $Space, M extends $Module> = (trx: TrxNode<S, M, any>) => Promise<TrxNodeStatus>;
|
|
7
8
|
export type TrxEngineConfig<S extends $Space, M extends $Module, Authn extends AnyUsers, Services extends Record<string, any>> = {
|
|
8
9
|
/**
|
|
9
10
|
* Adapter used to store transactions of this module.
|
|
10
11
|
*/
|
|
11
|
-
adapter?: (schema: M) => BucketAdapter<
|
|
12
|
+
adapter?: (schema: M) => BucketAdapter<TrxData>;
|
|
12
13
|
wrap?: <T extends Trx<S, M, Authn>>(trx: T, fn: TrxEngineWrapFn<S, M>, services: Services) => Promise<any>;
|
|
13
14
|
};
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { $Module, $Space } from "../../schema";
|
|
2
2
|
import { Module } from '../module';
|
|
3
|
-
import { Trx } from './trx';
|
|
3
|
+
import { AnyTrx, Trx } from './trx';
|
|
4
4
|
import { TrxNode, TrxNodeStatus } from './trx_node';
|
|
5
5
|
import { AnyAuthnProviders, AuthnRequest } from '../auth/authn';
|
|
6
6
|
import { TrxEngineConfig } from './trx_engine.config';
|
|
7
7
|
import { IService } from '../apps/service';
|
|
8
8
|
export type TrxEngineOrigin = `app:${string}` | `plugin:${string}`;
|
|
9
|
+
export type TrxData = {
|
|
10
|
+
id: AnyTrx['id'];
|
|
11
|
+
origin: AnyTrx['origin'];
|
|
12
|
+
module: string;
|
|
13
|
+
start: AnyTrx['start'];
|
|
14
|
+
end: AnyTrx['end'];
|
|
15
|
+
};
|
|
9
16
|
/**
|
|
10
17
|
* @category Engine
|
|
11
18
|
* @subcategory Transaction
|
|
@@ -16,6 +23,7 @@ export declare class TrxEngine<S extends $Space, M extends $Module, Authn extend
|
|
|
16
23
|
private authnProviders?;
|
|
17
24
|
private config?;
|
|
18
25
|
private services;
|
|
26
|
+
private $TrxBucket;
|
|
19
27
|
/**
|
|
20
28
|
* Transaction used to read/write transactions on the adapter
|
|
21
29
|
*/
|
|
@@ -6,6 +6,9 @@ const trx_1 = require("./trx");
|
|
|
6
6
|
const trx_node_1 = require("./trx_node");
|
|
7
7
|
const error_1 = require("../data/error");
|
|
8
8
|
const memory_bucket_adapter_1 = require("../../elements/entities/bucket/adapters/memory.bucket_adapter");
|
|
9
|
+
const elements_1 = require("../../elements");
|
|
10
|
+
const bucket_model_schema_1 = require("../../elements/entities/bucket/model/bucket_model.schema");
|
|
11
|
+
const bucket_graph_schema_1 = require("../../elements/entities/bucket/graph/bucket_graph.schema");
|
|
9
12
|
/**
|
|
10
13
|
* @category Engine
|
|
11
14
|
* @subcategory Transaction
|
|
@@ -17,28 +20,56 @@ class TrxEngine {
|
|
|
17
20
|
this.authnProviders = authnProviders;
|
|
18
21
|
this.config = config;
|
|
19
22
|
this.services = services;
|
|
23
|
+
this.$TrxBucket = new elements_1.$Bucket(this.module.name, '__trx__', `Transaction of Module '${this.module.name}'`, new bucket_model_schema_1.$BucketModel({
|
|
24
|
+
id: new bucket_model_schema_1.$BucketModelField('id', 'id', 'string', 'ID', true),
|
|
25
|
+
origin: new bucket_model_schema_1.$BucketModelField('origin', 'origin', 'string', 'Origin', true),
|
|
26
|
+
module: new bucket_model_schema_1.$BucketModelField('module', 'module', 'string', 'Module', true),
|
|
27
|
+
start: new bucket_model_schema_1.$BucketModelField('start', 'start', 'datetime', 'Start', true),
|
|
28
|
+
end: new bucket_model_schema_1.$BucketModelField('end', 'end', 'datetime', 'Start', false),
|
|
29
|
+
}), new bucket_graph_schema_1.$BucketGraph(), {});
|
|
20
30
|
this.innerTrx = new trx_1.Trx(this, this.module, `trx:${origin}`);
|
|
21
|
-
this.adapter = config?.adapter?.(module.schema) || new memory_bucket_adapter_1.MemoryBucketAdapter(
|
|
31
|
+
this.adapter = config?.adapter?.(module.schema) || new memory_bucket_adapter_1.MemoryBucketAdapter(this.$TrxBucket, {});
|
|
22
32
|
}
|
|
23
33
|
getModule() {
|
|
24
34
|
return this.module;
|
|
25
35
|
}
|
|
26
36
|
async get(id) {
|
|
27
|
-
let trx
|
|
37
|
+
let trx;
|
|
28
38
|
if (!id) {
|
|
29
39
|
trx = new trx_1.Trx(this, this.module, this.origin);
|
|
30
40
|
log_1.Log.info('module', this.module.name, `Begin ${(0, log_1.scopeTag)('trx', trx.id)} @ ${(0, log_1.anyScopeTag)(this.origin)}`);
|
|
31
|
-
|
|
41
|
+
await this.adapter.create(this.innerTrx.root, {
|
|
42
|
+
id: trx.id,
|
|
43
|
+
origin: trx.origin,
|
|
44
|
+
start: trx.start,
|
|
45
|
+
end: trx.end,
|
|
46
|
+
module: this.module.name
|
|
47
|
+
});
|
|
48
|
+
return trx;
|
|
32
49
|
}
|
|
33
50
|
else {
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
log_1.Log.info('module', this.module.name, `Continue ${(0, log_1.scopeTag)('trx',
|
|
51
|
+
const trxData = await this.adapter.get(this.innerTrx.root, id);
|
|
52
|
+
if (trxData) {
|
|
53
|
+
log_1.Log.info('module', this.module.name, `Continue ${(0, log_1.scopeTag)('trx', trxData.id)} @ ${(0, log_1.anyScopeTag)(this.origin)}`);
|
|
54
|
+
// Objects read from adapters are not the proper JS class, so they don't
|
|
55
|
+
// carry methods. This must be used to recover the methods.
|
|
56
|
+
trx = Object.assign(new trx_1.Trx(this, this.module, this.origin), {
|
|
57
|
+
id: trxData.id,
|
|
58
|
+
origin: trxData.origin,
|
|
59
|
+
start: trxData.start,
|
|
60
|
+
end: trxData.end
|
|
61
|
+
});
|
|
37
62
|
}
|
|
38
63
|
else {
|
|
39
64
|
log_1.Log.info('module', this.module.name, `Chain ${(0, log_1.scopeTag)('trx', id)} @ ${(0, log_1.anyScopeTag)(this.origin)}`);
|
|
40
65
|
trx = new trx_1.Trx(this, this.module, this.origin, undefined, id);
|
|
41
|
-
|
|
66
|
+
await this.adapter.create(this.innerTrx.root, {
|
|
67
|
+
id: trx.id,
|
|
68
|
+
origin: this.origin,
|
|
69
|
+
start: trx.start,
|
|
70
|
+
end: trx.end,
|
|
71
|
+
module: this.module.name
|
|
72
|
+
});
|
|
42
73
|
}
|
|
43
74
|
}
|
|
44
75
|
return trx;
|
|
@@ -87,7 +118,13 @@ class TrxEngine {
|
|
|
87
118
|
log_1.Log.info('module', this.module.name, `Commit ${(0, log_1.scopeTag)('trx', trx.id)} @ ${(0, log_1.anyScopeTag)(this.origin)}`);
|
|
88
119
|
await trx_node_1.TrxNode.ok(trx.root, output);
|
|
89
120
|
trx_1.Trx.onFinish(trx);
|
|
90
|
-
await this.adapter.put(this.innerTrx.root,
|
|
121
|
+
await this.adapter.put(this.innerTrx.root, {
|
|
122
|
+
id: trx.id,
|
|
123
|
+
origin: this.origin,
|
|
124
|
+
start: trx.start,
|
|
125
|
+
end: trx.end,
|
|
126
|
+
module: this.module.name
|
|
127
|
+
});
|
|
91
128
|
return trx;
|
|
92
129
|
}
|
|
93
130
|
async rollback(trx, error) {
|
|
@@ -95,7 +132,13 @@ class TrxEngine {
|
|
|
95
132
|
log_1.Log.warn('module', this.module.name, `Rollback ${(0, log_1.scopeTag)('trx', trx.id)} @ ${(0, log_1.anyScopeTag)(this.origin)}`);
|
|
96
133
|
await trx_node_1.TrxNode.error(trx.root, error);
|
|
97
134
|
trx_1.Trx.onFinish(trx);
|
|
98
|
-
await this.adapter.put(this.innerTrx.root,
|
|
135
|
+
await this.adapter.put(this.innerTrx.root, {
|
|
136
|
+
id: trx.id,
|
|
137
|
+
origin: this.origin,
|
|
138
|
+
start: trx.start,
|
|
139
|
+
end: trx.end,
|
|
140
|
+
module: this.module.name
|
|
141
|
+
});
|
|
99
142
|
return trx;
|
|
100
143
|
}
|
|
101
144
|
}
|
package/lib/engine/util/deep.js
CHANGED
|
@@ -10,6 +10,8 @@ class Deep {
|
|
|
10
10
|
for (const [obj, copy] of poll) {
|
|
11
11
|
if (Array.isArray(obj)) {
|
|
12
12
|
for (const item of obj) {
|
|
13
|
+
if (typeof item === 'function')
|
|
14
|
+
continue;
|
|
13
15
|
if (item === null) {
|
|
14
16
|
copy.push(null);
|
|
15
17
|
}
|
|
@@ -26,6 +28,8 @@ class Deep {
|
|
|
26
28
|
else {
|
|
27
29
|
for (const key in obj) {
|
|
28
30
|
const item = obj[key];
|
|
31
|
+
if (typeof item === 'function')
|
|
32
|
+
continue;
|
|
29
33
|
if (item === null) {
|
|
30
34
|
copy[key] = null;
|
|
31
35
|
}
|
|
@@ -7,32 +7,32 @@ import { NesoiDatetime } from '../data/datetime';
|
|
|
7
7
|
import { NesoiFile } from '../data/file';
|
|
8
8
|
import { NesoiDuration } from '../data/duration';
|
|
9
9
|
export declare function parseBoolean(field: {
|
|
10
|
-
|
|
10
|
+
pathRaw: string;
|
|
11
11
|
alias: string;
|
|
12
12
|
}, path: string[], value: any): boolean;
|
|
13
13
|
export declare function parseDate(field: {
|
|
14
|
-
|
|
14
|
+
pathRaw: string;
|
|
15
15
|
alias: string;
|
|
16
16
|
}, path: string[], value: any): NesoiDate;
|
|
17
17
|
export declare function parseDatetime(field: {
|
|
18
|
-
|
|
18
|
+
pathRaw: string;
|
|
19
19
|
alias: string;
|
|
20
20
|
}, path: string[], value: any): NesoiDatetime;
|
|
21
21
|
export declare function parseDuration(field: {
|
|
22
|
-
|
|
22
|
+
pathRaw: string;
|
|
23
23
|
alias: string;
|
|
24
24
|
}, path: string[], value: any): NesoiDuration;
|
|
25
25
|
export declare function parseDecimal(field: {
|
|
26
|
-
|
|
26
|
+
pathRaw: string;
|
|
27
27
|
alias: string;
|
|
28
28
|
}, path: string[], value: any): NesoiDecimal;
|
|
29
29
|
export declare function parseEnum(raw: Record<string, any>, field: {
|
|
30
|
-
|
|
30
|
+
pathRaw: string;
|
|
31
31
|
name: string;
|
|
32
32
|
alias: string;
|
|
33
33
|
}, path: string[], value: any, options: string | readonly string[] | Record<string, any>, trx: AnyTrxNode): any;
|
|
34
34
|
export declare function parseFile(field: {
|
|
35
|
-
|
|
35
|
+
pathRaw: string;
|
|
36
36
|
name: string;
|
|
37
37
|
alias: string;
|
|
38
38
|
}, path: string[], value: any, options?: {
|
|
@@ -40,30 +40,38 @@ export declare function parseFile(field: {
|
|
|
40
40
|
extnames?: string[];
|
|
41
41
|
}): NesoiFile;
|
|
42
42
|
export declare function parseFloat_(field: {
|
|
43
|
-
|
|
43
|
+
pathRaw: string;
|
|
44
44
|
alias: string;
|
|
45
45
|
}, path: string[], value: any): number;
|
|
46
46
|
export declare function parseId<M extends $Module, Name extends BucketName<M>, View extends ViewName<M['buckets'][Name]> | undefined>(field: {
|
|
47
|
-
|
|
47
|
+
pathRaw: string;
|
|
48
48
|
alias: string;
|
|
49
49
|
}, path: string[], value: any, trx: AnyTrxNode, bucket: Name, type?: 'int' | 'string', view?: View): Promise<{
|
|
50
50
|
id: string | number;
|
|
51
51
|
obj: any;
|
|
52
52
|
}>;
|
|
53
53
|
export declare function parseInt_(field: {
|
|
54
|
-
|
|
54
|
+
pathRaw: string;
|
|
55
55
|
alias: string;
|
|
56
56
|
}, path: string[], value: any): number;
|
|
57
57
|
export declare function parseString(field: {
|
|
58
|
-
|
|
58
|
+
pathRaw: string;
|
|
59
59
|
alias: string;
|
|
60
60
|
}, path: string[], value: any): string;
|
|
61
61
|
export declare function parseStringOrNumber(field: {
|
|
62
|
-
|
|
62
|
+
pathRaw: string;
|
|
63
63
|
alias: string;
|
|
64
64
|
}, path: string[], value: any): string | number;
|
|
65
65
|
export declare function parseDict(field: {
|
|
66
|
-
|
|
66
|
+
pathRaw: string;
|
|
67
|
+
alias: string;
|
|
68
|
+
children?: $MessageTemplateFields;
|
|
69
|
+
}, path: string[], value: any): Record<string, {
|
|
70
|
+
field: $MessageTemplateField;
|
|
71
|
+
value?: any;
|
|
72
|
+
}>;
|
|
73
|
+
export declare function parseList(field: {
|
|
74
|
+
pathRaw: string;
|
|
67
75
|
alias: string;
|
|
68
76
|
children?: $MessageTemplateFields;
|
|
69
77
|
}, path: string[], value: any): Record<string, {
|
|
@@ -71,7 +79,7 @@ export declare function parseDict(field: {
|
|
|
71
79
|
value?: any;
|
|
72
80
|
}>;
|
|
73
81
|
export declare function parseObj(field: {
|
|
74
|
-
|
|
82
|
+
pathRaw: string;
|
|
75
83
|
alias: string;
|
|
76
84
|
children?: $MessageTemplateFields;
|
|
77
85
|
}, path: string[], value: any): Record<string, {
|
package/lib/engine/util/parse.js
CHANGED
|
@@ -13,6 +13,7 @@ exports.parseInt_ = parseInt_;
|
|
|
13
13
|
exports.parseString = parseString;
|
|
14
14
|
exports.parseStringOrNumber = parseStringOrNumber;
|
|
15
15
|
exports.parseDict = parseDict;
|
|
16
|
+
exports.parseList = parseList;
|
|
16
17
|
exports.parseObj = parseObj;
|
|
17
18
|
const date_1 = require("../data/date");
|
|
18
19
|
const error_1 = require("../data/error");
|
|
@@ -65,12 +66,12 @@ function parseEnum(raw, field, path, value, options, trx) {
|
|
|
65
66
|
const enumPath = enumName.match(/(.*)\.\{(.*)\}$/);
|
|
66
67
|
let _enum;
|
|
67
68
|
if (enumPath) {
|
|
68
|
-
|
|
69
|
+
const v = tree_1.Tree.get(raw, enumPath[2]);
|
|
70
|
+
enumName = enumPath[1] + '.' + v;
|
|
69
71
|
try {
|
|
70
72
|
_enum = trx.enum(enumName);
|
|
71
73
|
}
|
|
72
74
|
catch {
|
|
73
|
-
const v = tree_1.Tree.get(raw, enumPath[2]);
|
|
74
75
|
throw error_1.NesoiError.Message.InvalidEnumScope({ alias: field.alias, path: path.join('.'), value: v, fieldpath: enumPath[2] });
|
|
75
76
|
}
|
|
76
77
|
}
|
|
@@ -180,7 +181,7 @@ function parseDict(field, path, value) {
|
|
|
180
181
|
if (typeof value === 'object') {
|
|
181
182
|
const children = {};
|
|
182
183
|
for (const key in value) {
|
|
183
|
-
const _field = field.children['
|
|
184
|
+
const _field = field.children['#'];
|
|
184
185
|
children[key] = {
|
|
185
186
|
field: _field,
|
|
186
187
|
value: value[key]
|
|
@@ -190,6 +191,20 @@ function parseDict(field, path, value) {
|
|
|
190
191
|
}
|
|
191
192
|
throw error_1.NesoiError.Message.InvalidFieldType({ alias: field.alias, path: path.join('.'), value, type: 'dict' });
|
|
192
193
|
}
|
|
194
|
+
function parseList(field, path, value) {
|
|
195
|
+
if (!Array.isArray(value)) {
|
|
196
|
+
throw error_1.NesoiError.Message.InvalidFieldType({ alias: field.alias, path: path.join('.'), value, type: 'list' });
|
|
197
|
+
}
|
|
198
|
+
const children = {};
|
|
199
|
+
for (let i = 0; i < value.length; i++) {
|
|
200
|
+
const _field = field.children['#'];
|
|
201
|
+
children[i] = {
|
|
202
|
+
field: _field,
|
|
203
|
+
value: value[i]
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
return children;
|
|
207
|
+
}
|
|
193
208
|
function parseObj(field, path, value) {
|
|
194
209
|
if (typeof value === 'object') {
|
|
195
210
|
if (!field.children)
|
|
@@ -197,8 +212,8 @@ function parseObj(field, path, value) {
|
|
|
197
212
|
const children = {};
|
|
198
213
|
for (const key in field.children) {
|
|
199
214
|
const _field = field.children[key];
|
|
200
|
-
const key_raw = _field.
|
|
201
|
-
const key_parsed = _field.
|
|
215
|
+
const key_raw = _field.pathRaw.split('.')[path.length];
|
|
216
|
+
const key_parsed = _field.pathParsed.split('.')[path.length];
|
|
202
217
|
children[key_parsed] = {
|
|
203
218
|
field: _field,
|
|
204
219
|
value: value[key_raw]
|
package/package.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AnyBucketBuilder } from "../../src/elements/entities/bucket/bucket.builder";
|
|
2
|
+
import { NesoiError } from "../../src/engine/data/error";
|
|
3
|
+
import { AnyBuilder } from "../../src/engine/module";
|
|
4
|
+
export declare function expectBucket(def: (builder: AnyBucketBuilder) => any, inject?: AnyBuilder[]): {
|
|
5
|
+
toBuildOne(raw: Record<string, any>, view: string): {
|
|
6
|
+
as(parsed: Record<string, any>): Promise<void>;
|
|
7
|
+
butFail(error: (...args: any[]) => NesoiError.BaseError): Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
};
|