nesoi 3.0.20 → 3.1.0
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/4_dump_modules_stage.js +8 -0
- package/lib/compiler/compiler.js +1 -1
- package/lib/compiler/elements/bucket.element.d.ts +2 -1
- package/lib/compiler/elements/bucket.element.js +68 -122
- package/lib/compiler/elements/element.js +2 -1
- package/lib/compiler/elements/externals.element.js +3 -0
- package/lib/compiler/elements/message.element.js +34 -57
- package/lib/compiler/elements/queue.element.js +1 -1
- package/lib/compiler/helpers/dump_helpers.d.ts +2 -0
- package/lib/compiler/helpers/dump_helpers.js +12 -2
- 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/memory.nql.js +1 -1
- package/lib/elements/entities/bucket/bucket.builder.d.ts +6 -4
- package/lib/elements/entities/bucket/bucket.js +7 -16
- package/lib/elements/entities/bucket/bucket.schema.d.ts +2 -1
- 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 +45 -9
- package/lib/elements/entities/bucket/model/bucket_model.schema.d.ts +5 -6
- package/lib/elements/entities/bucket/model/bucket_model.schema.js +64 -21
- package/lib/elements/entities/bucket/model/bucket_model_field.builder.d.ts +88 -55
- 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.builder.js +2 -2
- 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/message_parser.d.ts +0 -1
- package/lib/elements/entities/message/message_parser.js +1 -68
- package/lib/elements/entities/message/template/message_template.builder.js +1 -1
- package/lib/elements/entities/message/template/message_template.schema.d.ts +11 -6
- package/lib/elements/entities/message/template/message_template.schema.js +29 -6
- package/lib/elements/entities/message/template/message_template_field.builder.d.ts +50 -203
- package/lib/elements/entities/message/template/message_template_field.builder.js +74 -74
- package/lib/elements/entities/message/template/message_template_parser.d.ts +2 -2
- package/lib/elements/entities/message/template/message_template_parser.js +137 -71
- package/lib/engine/apps/inline.app.js +1 -0
- package/lib/engine/data/error.d.ts +12 -11
- package/lib/engine/data/error.js +7 -7
- 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/util/parse.d.ts +36 -28
- package/lib/engine/util/parse.js +53 -43
- 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,9 +12,13 @@ class MessageTemplateFieldFactory {
|
|
|
12
12
|
constructor(module) {
|
|
13
13
|
this.module = module;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Specifies an alias for the field.
|
|
17
|
+
*/
|
|
15
18
|
as(alias) {
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
const chain = new MessageTemplateFieldFactory(this.module);
|
|
20
|
+
chain.alias = alias;
|
|
21
|
+
return chain;
|
|
18
22
|
}
|
|
19
23
|
get any() {
|
|
20
24
|
return new MessageTemplateFieldBuilder('unknown', {}, this.alias);
|
|
@@ -74,10 +78,15 @@ class MessageTemplateFieldFactory {
|
|
|
74
78
|
return new MessageTemplateFieldBuilder('obj', {}, this.alias, children);
|
|
75
79
|
}
|
|
76
80
|
dict(item) {
|
|
77
|
-
item = item.optional;
|
|
78
81
|
return new MessageTemplateFieldBuilder('dict', {}, this.alias, { __dict: item });
|
|
79
82
|
}
|
|
80
|
-
|
|
83
|
+
list(item) {
|
|
84
|
+
return new MessageTemplateFieldBuilder('list', {}, this.alias, { '#': item });
|
|
85
|
+
}
|
|
86
|
+
union(...children) {
|
|
87
|
+
return new MessageTemplateFieldBuilder('union', {}, this.alias, Object.fromEntries(children.map((c, i) => [i, c])));
|
|
88
|
+
}
|
|
89
|
+
msg(msg, extra = {}) {
|
|
81
90
|
// Module and tag are updated on build
|
|
82
91
|
const ref = new dependency_1.$Dependency(this.module, 'message', msg);
|
|
83
92
|
return new MessageTemplateFieldBuilder('msg', { msg: ref }, this.alias, extra);
|
|
@@ -101,10 +110,9 @@ class MessageTemplateFieldBuilder {
|
|
|
101
110
|
this.value = value;
|
|
102
111
|
this.alias = alias;
|
|
103
112
|
this.children = children;
|
|
104
|
-
this._array = false;
|
|
105
113
|
this._required = true;
|
|
106
114
|
this._defaultValue = undefined;
|
|
107
|
-
this._nullable =
|
|
115
|
+
this._nullable = false;
|
|
108
116
|
this._rules = [];
|
|
109
117
|
}
|
|
110
118
|
as(alias) {
|
|
@@ -113,99 +121,91 @@ class MessageTemplateFieldBuilder {
|
|
|
113
121
|
}
|
|
114
122
|
get optional() {
|
|
115
123
|
this._required = false;
|
|
116
|
-
if (this._or) {
|
|
117
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
118
|
-
this._or.optional;
|
|
119
|
-
}
|
|
120
124
|
return this;
|
|
121
125
|
}
|
|
122
126
|
default(value) {
|
|
123
127
|
this._required = false;
|
|
124
128
|
this._defaultValue = value;
|
|
125
|
-
if (this._or) {
|
|
126
|
-
this._or.default(value);
|
|
127
|
-
}
|
|
128
129
|
return this;
|
|
129
130
|
}
|
|
130
131
|
get nullable() {
|
|
131
132
|
this._nullable = true;
|
|
132
|
-
if (this._or) {
|
|
133
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
134
|
-
this._or.nullable;
|
|
135
|
-
}
|
|
136
133
|
return this;
|
|
137
134
|
}
|
|
138
135
|
rule(rule) {
|
|
139
136
|
this._rules.push(rule);
|
|
140
137
|
return this;
|
|
141
138
|
}
|
|
142
|
-
get array() {
|
|
143
|
-
this._array = true;
|
|
144
|
-
if (this._or) {
|
|
145
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
146
|
-
this._or.array;
|
|
147
|
-
}
|
|
148
|
-
return this;
|
|
149
|
-
}
|
|
150
|
-
or(def) {
|
|
151
|
-
this._or = def;
|
|
152
|
-
this._or._array = this._array;
|
|
153
|
-
this._or._defaultValue = this._defaultValue;
|
|
154
|
-
this._or._nullable = this._nullable;
|
|
155
|
-
this._or._required = this._required;
|
|
156
|
-
this._or._rules = this._rules;
|
|
157
|
-
return this;
|
|
158
|
-
}
|
|
159
139
|
// Build
|
|
160
140
|
static build(builder, name, tree, module, basePathRaw, basePathParsed) {
|
|
161
|
-
const
|
|
162
|
-
? this.build(builder._or, name, tree, module, basePathRaw, basePathParsed)
|
|
163
|
-
: undefined;
|
|
141
|
+
const pathRaw = basePathRaw + (builder.type === 'id' ? `${name}_id` : name);
|
|
164
142
|
const pathParsed = basePathParsed + name;
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (builder.value.id) {
|
|
143
|
+
const childrenBasePathRaw = pathRaw + '.';
|
|
144
|
+
const childrenBasePathParsed = pathParsed + '.';
|
|
145
|
+
let type = builder.type;
|
|
146
|
+
let children;
|
|
147
|
+
if (builder.type === 'id') {
|
|
171
148
|
const bucket = tree.getSchema(builder.value.id.bucket);
|
|
172
149
|
builder.value.id.type = bucket.model.fields.id.type;
|
|
173
150
|
}
|
|
174
|
-
|
|
151
|
+
// A .msg() parameter is an obj which takes fields from
|
|
152
|
+
// another message
|
|
153
|
+
else if (builder.type === 'msg') {
|
|
154
|
+
const dep = builder.value.msg;
|
|
155
|
+
if (dep.type !== 'message') {
|
|
156
|
+
throw error_1.NesoiError.Builder.Message.UnknownModuleMessage(dep.tag);
|
|
157
|
+
}
|
|
158
|
+
const $msg = tree.getSchema(dep);
|
|
159
|
+
if (!$msg) {
|
|
160
|
+
throw error_1.NesoiError.Builder.Message.UnknownModuleMessage(dep.tag);
|
|
161
|
+
}
|
|
162
|
+
if (dep.module !== module.name) {
|
|
163
|
+
if (!(dep.refName in module.externals.messages)) {
|
|
164
|
+
throw error_1.NesoiError.Builder.Message.UnknownModuleMessage(dep.tag);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const injectFields = (target, fields) => {
|
|
168
|
+
for (const key in fields) {
|
|
169
|
+
target[key] = message_template_schema_1.$MessageTemplateField.clone(fields[key]);
|
|
170
|
+
target[key].pathRaw = childrenBasePathRaw + target[key].pathRaw;
|
|
171
|
+
target[key].pathParsed = childrenBasePathParsed + target[key].pathParsed;
|
|
172
|
+
if (fields[key].children) {
|
|
173
|
+
target[key].children = {};
|
|
174
|
+
injectFields(target[key].children, fields[key].children);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
type = 'obj';
|
|
179
|
+
children = {};
|
|
180
|
+
injectFields(children, $msg.template.fields);
|
|
181
|
+
}
|
|
182
|
+
else if (builder.type === 'list') {
|
|
183
|
+
children = MessageTemplateFieldBuilder.buildMany(builder.children, tree, module, childrenBasePathRaw, childrenBasePathParsed, '#', '#');
|
|
184
|
+
}
|
|
185
|
+
else if (builder.type === 'dict') {
|
|
186
|
+
children = MessageTemplateFieldBuilder.buildMany(builder.children, tree, module, childrenBasePathRaw, childrenBasePathParsed, '#', '#');
|
|
187
|
+
}
|
|
188
|
+
else if (builder.type === 'union') {
|
|
189
|
+
children = MessageTemplateFieldBuilder.buildMany(builder.children, tree, module, basePathRaw, basePathParsed, name, undefined);
|
|
190
|
+
}
|
|
191
|
+
// All other fields build their children directly
|
|
192
|
+
else if (builder.children) {
|
|
193
|
+
children = MessageTemplateFieldBuilder.buildMany(builder.children, tree, module, childrenBasePathRaw, childrenBasePathParsed);
|
|
194
|
+
}
|
|
195
|
+
return new message_template_schema_1.$MessageTemplateField(type, name, builder.alias || name, pathRaw, pathParsed, builder._required, builder._defaultValue, builder._nullable, builder._rules, builder.value, children);
|
|
175
196
|
}
|
|
176
|
-
static
|
|
197
|
+
static buildMany(fields, tree, module, basePathRaw = '', basePathParsed = '', name, key) {
|
|
177
198
|
const schema = {};
|
|
178
199
|
for (const c in fields) {
|
|
179
|
-
|
|
180
|
-
// Extended fields inherit from other messages
|
|
181
|
-
if (child.__ext) {
|
|
182
|
-
const ext = tree.getSchema(child.__ext);
|
|
183
|
-
schema[c].children = Object.assign({}, ext.template.fields, schema[c].children || {});
|
|
184
|
-
continue;
|
|
185
|
-
}
|
|
186
|
-
const param = c;
|
|
187
|
-
// A .msg() parameter is an obj which takes fields from
|
|
188
|
-
// another message
|
|
189
|
-
if (child.type === 'msg') {
|
|
190
|
-
const name = child.value.msg.name;
|
|
191
|
-
const $msg = module.messages[name];
|
|
192
|
-
if (!$msg) {
|
|
193
|
-
throw error_1.NesoiError.Builder.Message.UnknownModuleMessage(name);
|
|
194
|
-
}
|
|
195
|
-
const builder = new MessageTemplateFieldFactory(module.name).obj({});
|
|
196
|
-
builder.alias = child.alias;
|
|
197
|
-
builder._required = child._required;
|
|
198
|
-
builder._defaultValue = child._defaultValue;
|
|
199
|
-
builder._nullable = child._nullable;
|
|
200
|
-
builder._rules = child._rules.slice(0, -1);
|
|
201
|
-
builder.children = child.children;
|
|
202
|
-
schema[param] = MessageTemplateFieldBuilder.build(builder, c, tree, module, basePathRaw, basePathParsed);
|
|
203
|
-
schema[param].children = schema[param].children || {};
|
|
204
|
-
Object.assign(schema[param].children, $msg.template.fields);
|
|
200
|
+
if (c === '__ext')
|
|
205
201
|
continue;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
202
|
+
const child = fields[c];
|
|
203
|
+
schema[key || c] = MessageTemplateFieldBuilder.build(child, name || c, tree, module, basePathRaw, basePathParsed);
|
|
204
|
+
}
|
|
205
|
+
// Extended field groups inherit from other messages
|
|
206
|
+
if ('__ext' in fields) {
|
|
207
|
+
const ext = tree.getSchema(fields.__ext);
|
|
208
|
+
Object.assign(schema, ext.template.fields);
|
|
209
209
|
}
|
|
210
210
|
return schema;
|
|
211
211
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $
|
|
1
|
+
import { $MessageTemplateFields } from './message_template.schema';
|
|
2
2
|
import { AnyTrxNode } from "../../../../engine/transaction/trx_node";
|
|
3
|
-
export declare function MessageTemplateFieldParser(
|
|
3
|
+
export declare function MessageTemplateFieldParser(trx: AnyTrxNode, fields: $MessageTemplateFields, raw: Record<string, any>): Promise<Record<string, any>>;
|
|
4
4
|
/**
|
|
5
5
|
* Empty values: `{}`, `[]`, `''`, `null`, `undefined`
|
|
6
6
|
*/
|
|
@@ -4,19 +4,34 @@ exports.MessageTemplateFieldParser = MessageTemplateFieldParser;
|
|
|
4
4
|
exports.isEmpty = isEmpty;
|
|
5
5
|
const parse_1 = require("../../../../engine/util/parse");
|
|
6
6
|
const error_1 = require("../../../../engine/data/error");
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// TODO: OPTIMIZATION
|
|
8
|
+
// Parse everything that's static first, then move on to
|
|
9
|
+
// parsing ids etc.
|
|
10
|
+
async function MessageTemplateFieldParser(trx, fields, raw) {
|
|
11
|
+
const parsed = {};
|
|
12
|
+
const inject = {};
|
|
13
|
+
for (const k in fields) {
|
|
14
|
+
const field = fields[k];
|
|
15
|
+
const key_raw = field.pathRaw.split('.')[0];
|
|
16
|
+
const key_parsed = field.pathParsed.split('.')[0];
|
|
17
|
+
const value = raw[key_raw];
|
|
18
|
+
parsed[key_parsed] = await parseFieldValue(trx, field, [field.name], raw, value, inject);
|
|
19
|
+
}
|
|
20
|
+
Object.assign(parsed, inject);
|
|
21
|
+
return parsed;
|
|
9
22
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
23
|
+
/**
|
|
24
|
+
* [Parser Step 1]
|
|
25
|
+
*
|
|
26
|
+
* - Check for empty fields ({}, [], '', null, undefined)
|
|
27
|
+
* - If it's array, run step 2 for each value (with this field and path+i)
|
|
28
|
+
* - If not, run step 2 for the original value (with this field and path)
|
|
29
|
+
*/
|
|
30
|
+
async function parseFieldValue(trx, field, path, raw, value, inject) {
|
|
31
|
+
sanitize(field, path, value);
|
|
17
32
|
if (isEmpty(value)) {
|
|
18
33
|
if (field.required) {
|
|
19
|
-
throw error_1.NesoiError.Message.FieldIsRequired({
|
|
34
|
+
throw error_1.NesoiError.Message.FieldIsRequired({ alias: field.alias, path: path.join('.'), value });
|
|
20
35
|
}
|
|
21
36
|
else if (field.defaultValue !== undefined) {
|
|
22
37
|
return field.defaultValue;
|
|
@@ -25,100 +40,133 @@ async function parseFieldValue(trx, field, raw, value, path_idx) {
|
|
|
25
40
|
return undefined;
|
|
26
41
|
}
|
|
27
42
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
if (field.required && !value.length) {
|
|
33
|
-
throw error_1.NesoiError.Message.FieldIsRequired({ field: field.alias, path: field.path_raw, value });
|
|
34
|
-
}
|
|
35
|
-
const parsedValue = [];
|
|
36
|
-
for (let i = 0; i < value.length; i++) {
|
|
37
|
-
const v = value[i];
|
|
38
|
-
const parsed = await _attemptUnion(trx, field, raw, v, path_idx + 1);
|
|
39
|
-
parsedValue.push(parsed);
|
|
40
|
-
}
|
|
41
|
-
return parsedValue;
|
|
42
|
-
}
|
|
43
|
-
return _attemptUnion(trx, field, raw, value, path_idx);
|
|
43
|
+
let output = await _attemptUnion(trx, field, path, raw, value, inject);
|
|
44
|
+
output = await applyFieldRules(field, path, raw, output, inject);
|
|
45
|
+
return output;
|
|
44
46
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
/**
|
|
48
|
+
* [Parser Step 2]
|
|
49
|
+
*
|
|
50
|
+
* - Attempt to run parse method (step 3) for field.
|
|
51
|
+
* - If it fails, attempt other union options (step 2) (if available), with same path
|
|
52
|
+
* - If it works, apply field rules.
|
|
53
|
+
*/
|
|
54
|
+
async function _attemptUnion(trx, field, path, raw, value, inject) {
|
|
55
|
+
if (field.type !== 'union') {
|
|
56
|
+
return _runParseMethod(trx, field, path, raw, value, inject);
|
|
48
57
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
const unionErrors = [];
|
|
59
|
+
let output = undefined;
|
|
60
|
+
for (const k in field.children) {
|
|
61
|
+
const option = field.children[k];
|
|
62
|
+
try {
|
|
63
|
+
output = await _runParseMethod(trx, option, path, raw, value, inject);
|
|
64
|
+
break;
|
|
53
65
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
catch (e) {
|
|
67
|
+
unionErrors.push({
|
|
68
|
+
option: option.alias,
|
|
69
|
+
name: e.name,
|
|
70
|
+
status: e.status,
|
|
71
|
+
message: e.message,
|
|
72
|
+
data: e.data,
|
|
73
|
+
});
|
|
59
74
|
}
|
|
60
|
-
throw e;
|
|
61
75
|
}
|
|
76
|
+
if (unionErrors.length === Object.keys(field.children).length) {
|
|
77
|
+
throw error_1.NesoiError.Message.ValueDoesntMatchUnion({ alias: field.alias, path: path.join('.'), value, unionErrors });
|
|
78
|
+
}
|
|
79
|
+
return output;
|
|
62
80
|
}
|
|
63
|
-
|
|
81
|
+
/**
|
|
82
|
+
* [Parser Step 3]
|
|
83
|
+
*
|
|
84
|
+
* - Run a specific parsing method based on the field type
|
|
85
|
+
*/
|
|
86
|
+
async function _runParseMethod(trx, field, path, raw, value, inject) {
|
|
64
87
|
switch (field.type) {
|
|
65
88
|
case 'obj':
|
|
66
89
|
case 'dict':
|
|
67
|
-
|
|
90
|
+
case 'list':
|
|
91
|
+
return parseParentField(trx, field, path, raw, value, inject);
|
|
68
92
|
case 'unknown':
|
|
69
93
|
return value;
|
|
70
94
|
case 'boolean':
|
|
71
|
-
return (0, parse_1.parseBoolean)(field, value);
|
|
95
|
+
return (0, parse_1.parseBoolean)(field, path, value);
|
|
72
96
|
case 'date':
|
|
73
|
-
return (0, parse_1.parseDate)(field, value);
|
|
97
|
+
return (0, parse_1.parseDate)(field, path, value);
|
|
74
98
|
case 'datetime':
|
|
75
|
-
return (0, parse_1.parseDatetime)(field, value);
|
|
99
|
+
return (0, parse_1.parseDatetime)(field, path, value);
|
|
76
100
|
case 'duration':
|
|
77
|
-
return (0, parse_1.parseDuration)(field, value);
|
|
101
|
+
return (0, parse_1.parseDuration)(field, path, value);
|
|
78
102
|
case 'decimal':
|
|
79
|
-
return (0, parse_1.parseDecimal)(field, value);
|
|
103
|
+
return (0, parse_1.parseDecimal)(field, path, value);
|
|
80
104
|
case 'enum':
|
|
81
|
-
return (0, parse_1.parseEnum)(raw, field, value, field.meta.enum.options, trx);
|
|
105
|
+
return (0, parse_1.parseEnum)(raw, field, path, value, field.meta.enum.options, trx);
|
|
82
106
|
case 'file':
|
|
83
|
-
return (0, parse_1.parseFile)(field, value, field.meta.file);
|
|
107
|
+
return (0, parse_1.parseFile)(field, path, value, field.meta.file);
|
|
84
108
|
case 'float':
|
|
85
|
-
return (0, parse_1.parseFloat_)(field, value);
|
|
109
|
+
return (0, parse_1.parseFloat_)(field, path, value);
|
|
86
110
|
case 'int':
|
|
87
|
-
return (0, parse_1.parseInt_)(field, value);
|
|
111
|
+
return (0, parse_1.parseInt_)(field, path, value);
|
|
88
112
|
case 'string':
|
|
89
|
-
return (0, parse_1.parseString)(field, value);
|
|
113
|
+
return (0, parse_1.parseString)(field, path, value);
|
|
90
114
|
case 'string_or_number':
|
|
91
|
-
return (0, parse_1.parseStringOrNumber)(field, value);
|
|
115
|
+
return (0, parse_1.parseStringOrNumber)(field, path, value);
|
|
92
116
|
case 'id':
|
|
93
|
-
return
|
|
117
|
+
return parseIdField(trx, field, path, value);
|
|
94
118
|
}
|
|
95
119
|
throw error_1.NesoiError.Builder.Message.UnknownTemplateFieldType(field.type);
|
|
96
120
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
121
|
+
/**
|
|
122
|
+
* [Parser Step 3-b]: 'obj' or 'dict' or 'list'
|
|
123
|
+
*
|
|
124
|
+
* - The parser methods only return a tuple of field and value, to be parsed again by (step 1)
|
|
125
|
+
* - When calling step 1, the child property name is appended to the path
|
|
126
|
+
*/
|
|
127
|
+
async function parseParentField(trx, field, path, raw, value, inject) {
|
|
128
|
+
if (field.type === 'list') {
|
|
129
|
+
const children = (0, parse_1.parseList)(field, path, value);
|
|
130
|
+
const parsedParent = [];
|
|
131
|
+
for (const key in children) {
|
|
132
|
+
const child = children[key];
|
|
133
|
+
parsedParent.push(await parseFieldValue(trx, child.field, [...path, key], raw, child.value, inject));
|
|
134
|
+
}
|
|
135
|
+
return parsedParent;
|
|
101
136
|
}
|
|
102
137
|
else {
|
|
103
|
-
children
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
138
|
+
let children;
|
|
139
|
+
if (field.type === 'obj') {
|
|
140
|
+
children = (0, parse_1.parseObj)(field, path, value);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
children = (0, parse_1.parseDict)(field, path, value);
|
|
144
|
+
}
|
|
145
|
+
const parsedParent = {};
|
|
146
|
+
for (const key in children) {
|
|
147
|
+
const child = children[key];
|
|
148
|
+
parsedParent[key] = await parseFieldValue(trx, child.field, [...path, key], raw, child.value, inject);
|
|
149
|
+
}
|
|
150
|
+
return parsedParent;
|
|
109
151
|
}
|
|
110
|
-
return parsed;
|
|
111
152
|
}
|
|
112
|
-
|
|
153
|
+
/**
|
|
154
|
+
* [Parser Step 3-b]: 'id'
|
|
155
|
+
*
|
|
156
|
+
* - Gathers the data for parsing a id
|
|
157
|
+
*/
|
|
158
|
+
async function parseIdField(trx, field, path, value) {
|
|
113
159
|
const bucket = field.meta.id.bucket;
|
|
114
160
|
const type = field.meta.id.type;
|
|
115
161
|
const view = field.meta.id.view;
|
|
116
|
-
const parsed = await (0, parse_1.parseId)(field, value, trx, bucket.refName, type, view);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
162
|
+
const parsed = await (0, parse_1.parseId)(field, path, value, trx, bucket.refName, type, view);
|
|
163
|
+
return parsed.obj;
|
|
164
|
+
}
|
|
165
|
+
function sanitize(field, path, value) {
|
|
166
|
+
if (typeof value === 'function') {
|
|
167
|
+
throw error_1.NesoiError.Message.UnsanitaryValue({
|
|
168
|
+
alias: field.alias, path: path.join('.'), details: 'Functions not allowed as message inputs.'
|
|
169
|
+
});
|
|
122
170
|
}
|
|
123
171
|
}
|
|
124
172
|
/**
|
|
@@ -139,3 +187,21 @@ function isEmpty(value) {
|
|
|
139
187
|
}
|
|
140
188
|
return false;
|
|
141
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Rules
|
|
192
|
+
*/
|
|
193
|
+
async function applyFieldRules(field, path, raw, value, inject) {
|
|
194
|
+
let output = value;
|
|
195
|
+
const rules = field.rules;
|
|
196
|
+
for (const r in rules) {
|
|
197
|
+
const rule = rules[r];
|
|
198
|
+
const res = await rule({ field, value, path: path.join('.'), msg: raw, inject });
|
|
199
|
+
if (typeof res === 'object') {
|
|
200
|
+
output = res.set;
|
|
201
|
+
}
|
|
202
|
+
else if (res !== true) {
|
|
203
|
+
throw error_1.NesoiError.Message.RuleFailed({ alias: field.alias, path: path.join('.'), rule, error: res });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return output;
|
|
207
|
+
}
|
|
@@ -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
|
});
|
|
@@ -169,53 +169,54 @@ export declare namespace NesoiError {
|
|
|
169
169
|
module: string;
|
|
170
170
|
}): BaseError;
|
|
171
171
|
function InvalidEnumScope($: {
|
|
172
|
+
alias: string;
|
|
172
173
|
path: string;
|
|
173
|
-
name: string;
|
|
174
|
-
alias?: string;
|
|
175
174
|
value: any;
|
|
176
175
|
fieldpath: string;
|
|
177
176
|
}): BaseError;
|
|
178
177
|
function InvalidFieldEnumValue($: {
|
|
179
|
-
|
|
178
|
+
alias: string;
|
|
180
179
|
path: string;
|
|
181
180
|
value: any;
|
|
182
181
|
type: string;
|
|
183
182
|
options: string[];
|
|
184
183
|
}): BaseError;
|
|
185
184
|
function InvalidFieldType($: {
|
|
186
|
-
|
|
185
|
+
alias: string;
|
|
187
186
|
path: string;
|
|
188
187
|
value: any;
|
|
189
188
|
type: string;
|
|
190
189
|
}): BaseError;
|
|
191
190
|
function ValueDoesntMatchUnion($: {
|
|
192
|
-
|
|
191
|
+
alias: string;
|
|
193
192
|
path: string;
|
|
194
193
|
value: any;
|
|
195
|
-
unionErrors: string[];
|
|
194
|
+
unionErrors: Record<string, any>[];
|
|
196
195
|
}): BaseError;
|
|
197
196
|
function UnsanitaryValue($: {
|
|
197
|
+
alias: string;
|
|
198
|
+
path: string;
|
|
198
199
|
details: string;
|
|
199
200
|
}): BaseError;
|
|
200
201
|
function FieldIsRequired($: {
|
|
201
|
-
|
|
202
|
+
alias: string;
|
|
202
203
|
path: string;
|
|
203
204
|
value: any;
|
|
204
205
|
}): BaseError;
|
|
205
206
|
function RuleFailed($: {
|
|
207
|
+
alias: string;
|
|
208
|
+
path: string;
|
|
206
209
|
rule: $MessageTemplateRule;
|
|
207
210
|
error: string;
|
|
208
211
|
}): BaseError;
|
|
209
212
|
function FileTooBig($: {
|
|
213
|
+
alias: string;
|
|
210
214
|
path: string;
|
|
211
|
-
name: string;
|
|
212
|
-
alias?: string;
|
|
213
215
|
maxsize: number;
|
|
214
216
|
}): BaseError;
|
|
215
217
|
function FileExtNotAllowed($: {
|
|
218
|
+
alias: string;
|
|
216
219
|
path: string;
|
|
217
|
-
name: string;
|
|
218
|
-
alias?: string;
|
|
219
220
|
options: string[];
|
|
220
221
|
}): BaseError;
|
|
221
222
|
}
|
package/lib/engine/data/error.js
CHANGED
|
@@ -302,19 +302,19 @@ var NesoiError;
|
|
|
302
302
|
}
|
|
303
303
|
Message.NotSupportedByModule = NotSupportedByModule;
|
|
304
304
|
function InvalidEnumScope($) {
|
|
305
|
-
return new BaseError('Message.InvalidEnumScope', `${$.alias
|
|
305
|
+
return new BaseError('Message.InvalidEnumScope', `${$.alias} is an enum with dynamic scope, and the path '${$.fieldpath}' of the message has an invalid value '${$.value}'`, Status.BAD_REQUEST, $);
|
|
306
306
|
}
|
|
307
307
|
Message.InvalidEnumScope = InvalidEnumScope;
|
|
308
308
|
function InvalidFieldEnumValue($) {
|
|
309
|
-
return new BaseError('Message.InvalidFieldEnumValue', `Message field '${$.
|
|
309
|
+
return new BaseError('Message.InvalidFieldEnumValue', `Message field '${$.alias}' value '${$.value}' should be one of the following: ${$.options?.join(',')}`, Status.BAD_REQUEST, $);
|
|
310
310
|
}
|
|
311
311
|
Message.InvalidFieldEnumValue = InvalidFieldEnumValue;
|
|
312
312
|
function InvalidFieldType($) {
|
|
313
|
-
return new BaseError('Message.InvalidFieldType', `Message field '${$.
|
|
313
|
+
return new BaseError('Message.InvalidFieldType', `Message field '${$.alias}' value '${$.value}' is not of type '${$.type}'`, Status.BAD_REQUEST, $);
|
|
314
314
|
}
|
|
315
315
|
Message.InvalidFieldType = InvalidFieldType;
|
|
316
316
|
function ValueDoesntMatchUnion($) {
|
|
317
|
-
return new BaseError('Message.ValueDoesntMatchUnion', `Message field '${$.
|
|
317
|
+
return new BaseError('Message.ValueDoesntMatchUnion', `Message field '${$.alias}' (${$.path}) value '${$.value}' doesn't match any of the union options'`, Status.BAD_REQUEST, $);
|
|
318
318
|
}
|
|
319
319
|
Message.ValueDoesntMatchUnion = ValueDoesntMatchUnion;
|
|
320
320
|
function UnsanitaryValue($) {
|
|
@@ -322,7 +322,7 @@ var NesoiError;
|
|
|
322
322
|
}
|
|
323
323
|
Message.UnsanitaryValue = UnsanitaryValue;
|
|
324
324
|
function FieldIsRequired($) {
|
|
325
|
-
return new BaseError('Message.FieldIsRequired', `Field ${$.
|
|
325
|
+
return new BaseError('Message.FieldIsRequired', `Field ${$.alias} (${$.path}) is required`, Status.BAD_REQUEST, $);
|
|
326
326
|
}
|
|
327
327
|
Message.FieldIsRequired = FieldIsRequired;
|
|
328
328
|
function RuleFailed($) {
|
|
@@ -330,11 +330,11 @@ var NesoiError;
|
|
|
330
330
|
}
|
|
331
331
|
Message.RuleFailed = RuleFailed;
|
|
332
332
|
function FileTooBig($) {
|
|
333
|
-
return new BaseError('Message.FileTooBig', `${$.alias
|
|
333
|
+
return new BaseError('Message.FileTooBig', `${$.alias} size exceeds max (${$.maxsize})`, Status.BAD_REQUEST, $);
|
|
334
334
|
}
|
|
335
335
|
Message.FileTooBig = FileTooBig;
|
|
336
336
|
function FileExtNotAllowed($) {
|
|
337
|
-
return new BaseError('Message.FileExtNotAllowed', `${$.alias
|
|
337
|
+
return new BaseError('Message.FileExtNotAllowed', `${$.alias} extension not allowed. Options: ${$.options}`, Status.BAD_REQUEST, $);
|
|
338
338
|
}
|
|
339
339
|
Message.FileExtNotAllowed = FileExtNotAllowed;
|
|
340
340
|
})(Message = NesoiError.Message || (NesoiError.Message = {}));
|
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
|
}
|