nesoi 3.4.21 → 3.4.24
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/bundler/browser/browser.bundler.js +1 -1
- package/lib/bundler/monolyth/monolyth.bundler.d.ts +2 -2
- package/lib/bundler/monolyth/monolyth.bundler.js +9 -6
- package/lib/bundler/monolyth/stages/2_build_typescript_stage.js +5 -6
- package/lib/bundler/monolyth/stages/3_copy_types_stage.js +2 -3
- package/lib/compiler/compiler.d.ts +10 -1
- package/lib/compiler/compiler.js +54 -5
- package/lib/compiler/elements/controller.element.d.ts +1 -1
- package/lib/compiler/elements/controller.element.js +8 -0
- package/lib/compiler/progressive.js +2 -2
- package/lib/compiler/stages/4_build_schemas_stage.js +1 -1
- package/lib/compiler/stages/5_inject_ts_stage.js +2 -0
- package/lib/compiler/stages/6_build_elements_stage.js +2 -0
- package/lib/compiler/stages/7_dump_stage.js +4 -2
- package/lib/elements/edge/controller/adapters/cli.controller_adapter.d.ts +3 -6
- package/lib/elements/edge/controller/adapters/cli.controller_adapter.js +4 -4
- package/lib/elements/edge/controller/adapters/controller_adapter.d.ts +16 -6
- package/lib/elements/edge/controller/adapters/controller_adapter.js +20 -23
- package/lib/elements/edge/controller/adapters/fetch.controller_adapter.d.ts +27 -0
- package/lib/elements/edge/controller/adapters/fetch.controller_adapter.js +83 -0
- package/lib/elements/edge/controller/controller.schema.d.ts +9 -0
- package/lib/elements/edge/controller/controller.schema.js +41 -0
- package/lib/elements/entities/bucket/adapters/memory.bucket_adapter.js +2 -2
- package/lib/elements/entities/bucket/adapters/memory.nql.js +33 -2
- package/lib/elements/entities/bucket/bucket.js +2 -2
- package/lib/elements/entities/bucket/model/bucket_model.js +1 -1
- package/lib/elements/entities/bucket/query/nql_compiler.js +10 -0
- package/lib/elements/entities/constants/constants.d.ts +1 -1
- package/lib/elements/entities/constants/constants.js +1 -1
- package/lib/elements/entities/message/template/message_template_parser.js +1 -1
- package/lib/engine/app/app.config.d.ts +5 -1
- package/lib/engine/app/app.d.ts +11 -0
- package/lib/engine/app/app.js +30 -0
- package/lib/engine/app/inline.app.js +2 -1
- package/lib/engine/builder.d.ts +4 -2
- package/lib/engine/builder.js +65 -9
- package/lib/engine/data/error.d.ts +8 -0
- package/lib/engine/data/error.js +8 -0
- package/lib/engine/data/tree.js +4 -1
- package/lib/engine/dependency.d.ts +1 -0
- package/lib/engine/transaction/nodes/controller.trx_node.d.ts +17 -0
- package/lib/engine/transaction/nodes/controller.trx_node.js +60 -0
- package/lib/engine/transaction/trx_node.d.ts +2 -0
- package/lib/engine/transaction/trx_node.js +5 -0
- package/lib/engine/treeshake.js +1 -1
- package/lib/engine/util/deep.js +2 -2
- package/package.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -107,6 +107,7 @@ class $Controller {
|
|
|
107
107
|
$t = 'controller';
|
|
108
108
|
'#authn';
|
|
109
109
|
'#input';
|
|
110
|
+
'#path';
|
|
110
111
|
constructor(module, name, alias, auth, input, domains = {}, topics = {}) {
|
|
111
112
|
this.module = module;
|
|
112
113
|
this.name = name;
|
|
@@ -116,5 +117,45 @@ class $Controller {
|
|
|
116
117
|
this.domains = domains;
|
|
117
118
|
this.topics = topics;
|
|
118
119
|
}
|
|
120
|
+
static endpoints(schema) {
|
|
121
|
+
const endpoints = {};
|
|
122
|
+
const _endpoint = (endpoint, path) => {
|
|
123
|
+
const path_str = this.makePath(schema, path, endpoint);
|
|
124
|
+
endpoints[path_str] = {
|
|
125
|
+
path,
|
|
126
|
+
endpoint
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
const _group = (group, path) => {
|
|
130
|
+
for (const g in group.groups) {
|
|
131
|
+
_group(group.groups[g], [...path, group]);
|
|
132
|
+
}
|
|
133
|
+
for (const e in group.endpoints) {
|
|
134
|
+
_endpoint(group.endpoints[e], [...path, group]);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const _domain = (domain) => {
|
|
138
|
+
for (const g in domain.groups) {
|
|
139
|
+
_group(domain.groups[g], [domain]);
|
|
140
|
+
}
|
|
141
|
+
for (const e in domain.endpoints) {
|
|
142
|
+
_endpoint(domain.endpoints[e], [domain]);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
for (const d in schema.domains) {
|
|
146
|
+
_domain(schema.domains[d]);
|
|
147
|
+
}
|
|
148
|
+
return endpoints;
|
|
149
|
+
}
|
|
150
|
+
static makePath(schema, path, endpoint) {
|
|
151
|
+
const domain = path[0];
|
|
152
|
+
const root = `${domain.name ?? schema.name}@${domain.version}`;
|
|
153
|
+
const list = [
|
|
154
|
+
root,
|
|
155
|
+
...path.slice(1).map(node => node.name),
|
|
156
|
+
endpoint.name
|
|
157
|
+
];
|
|
158
|
+
return list.join('/');
|
|
159
|
+
}
|
|
119
160
|
}
|
|
120
161
|
exports.$Controller = $Controller;
|
|
@@ -92,13 +92,13 @@ class MemoryBucketAdapter extends bucket_adapter_1.BucketAdapter {
|
|
|
92
92
|
throw new Error(`Object with id ${obj.id} not found for patch`);
|
|
93
93
|
}
|
|
94
94
|
const data = this.data[obj.id];
|
|
95
|
-
const keys = Object.entries(obj).filter(([_, val]) => val
|
|
95
|
+
const keys = Object.entries(obj).filter(([_, val]) => val != null).map(([key]) => key);
|
|
96
96
|
const input = this.model.copy(obj, 'save', undefined, keys);
|
|
97
97
|
for (const key in input) {
|
|
98
98
|
if (input[key] === null) {
|
|
99
99
|
delete data[key];
|
|
100
100
|
}
|
|
101
|
-
else if (input[key]
|
|
101
|
+
else if (input[key] != null) {
|
|
102
102
|
data[key] = input[key];
|
|
103
103
|
}
|
|
104
104
|
}
|
|
@@ -5,6 +5,7 @@ const nql_engine_1 = require("../query/nql_engine");
|
|
|
5
5
|
const tree_1 = require("../../../../engine/data/tree");
|
|
6
6
|
const datetime_1 = require("../../../../engine/data/datetime");
|
|
7
7
|
const bucket_model_1 = require("../model/bucket_model");
|
|
8
|
+
const date_1 = require("../../../../engine/data/date");
|
|
8
9
|
/**
|
|
9
10
|
* @category NQL
|
|
10
11
|
* */
|
|
@@ -114,7 +115,7 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
|
|
|
114
115
|
if (pagination.returnTotal) {
|
|
115
116
|
totalItems = output.length;
|
|
116
117
|
}
|
|
117
|
-
if (pagination.page
|
|
118
|
+
if (pagination.page != null || pagination.perPage != null) {
|
|
118
119
|
const a = ((pagination.page || 1) - 1) * (pagination.perPage ?? 10);
|
|
119
120
|
const b = a + (pagination.perPage ?? 10);
|
|
120
121
|
output = output.slice(a, b);
|
|
@@ -278,7 +279,7 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
|
|
|
278
279
|
? tree_1.Tree.get(obj, rule.fieldpath)
|
|
279
280
|
: obj[rule.fieldpath];
|
|
280
281
|
// Value is undefined, only 'present' rule applies
|
|
281
|
-
if (fieldValue
|
|
282
|
+
if (fieldValue == null) {
|
|
282
283
|
if (rule.op === 'present') {
|
|
283
284
|
return false;
|
|
284
285
|
}
|
|
@@ -296,12 +297,30 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
|
|
|
296
297
|
// Check each operation
|
|
297
298
|
// (Compatible operations and types have already been validated)
|
|
298
299
|
if (rule.op === '<') {
|
|
300
|
+
if (fieldValue instanceof date_1.NesoiDate) {
|
|
301
|
+
return fieldValue.compare(date_1.NesoiDate.from(queryValue)) < 0;
|
|
302
|
+
}
|
|
303
|
+
if (fieldValue instanceof datetime_1.NesoiDatetime) {
|
|
304
|
+
return fieldValue.epoch < datetime_1.NesoiDatetime.parse(queryValue).epoch;
|
|
305
|
+
}
|
|
299
306
|
return fieldValue < queryValue;
|
|
300
307
|
}
|
|
301
308
|
if (rule.op === '<=') {
|
|
309
|
+
if (fieldValue instanceof date_1.NesoiDate) {
|
|
310
|
+
return fieldValue.compare(date_1.NesoiDate.from(queryValue)) <= 0;
|
|
311
|
+
}
|
|
312
|
+
if (fieldValue instanceof datetime_1.NesoiDatetime) {
|
|
313
|
+
return fieldValue.epoch <= datetime_1.NesoiDatetime.parse(queryValue).epoch;
|
|
314
|
+
}
|
|
302
315
|
return fieldValue <= queryValue;
|
|
303
316
|
}
|
|
304
317
|
if (rule.op === '==') {
|
|
318
|
+
if (fieldValue instanceof date_1.NesoiDate) {
|
|
319
|
+
return fieldValue.compare(date_1.NesoiDate.from(queryValue)) == 0;
|
|
320
|
+
}
|
|
321
|
+
if (fieldValue instanceof datetime_1.NesoiDatetime) {
|
|
322
|
+
return fieldValue.epoch == datetime_1.NesoiDatetime.parse(queryValue).epoch;
|
|
323
|
+
}
|
|
305
324
|
if (rule.case_i) {
|
|
306
325
|
return fieldValue?.toLowerCase() === queryValue?.toLowerCase();
|
|
307
326
|
}
|
|
@@ -310,9 +329,21 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
|
|
|
310
329
|
}
|
|
311
330
|
}
|
|
312
331
|
if (rule.op === '>') {
|
|
332
|
+
if (fieldValue instanceof date_1.NesoiDate) {
|
|
333
|
+
return fieldValue.compare(date_1.NesoiDate.from(queryValue)) > 0;
|
|
334
|
+
}
|
|
335
|
+
if (fieldValue instanceof datetime_1.NesoiDatetime) {
|
|
336
|
+
return fieldValue.epoch > datetime_1.NesoiDatetime.parse(queryValue).epoch;
|
|
337
|
+
}
|
|
313
338
|
return fieldValue > queryValue;
|
|
314
339
|
}
|
|
315
340
|
if (rule.op === '>=') {
|
|
341
|
+
if (fieldValue instanceof date_1.NesoiDate) {
|
|
342
|
+
return fieldValue.compare(date_1.NesoiDate.from(queryValue)) >= 0;
|
|
343
|
+
}
|
|
344
|
+
if (fieldValue instanceof datetime_1.NesoiDatetime) {
|
|
345
|
+
return fieldValue.epoch >= datetime_1.NesoiDatetime.parse(queryValue).epoch;
|
|
346
|
+
}
|
|
316
347
|
return fieldValue >= queryValue;
|
|
317
348
|
}
|
|
318
349
|
if (rule.op === 'in') {
|
|
@@ -804,7 +804,7 @@ class Bucket {
|
|
|
804
804
|
if (field.crypto) {
|
|
805
805
|
const key = trx.value(field.crypto.value.short);
|
|
806
806
|
const val = tree_1.Tree.get(obj, field.path);
|
|
807
|
-
if (val
|
|
807
|
+
if (val != null) {
|
|
808
808
|
const encrypted = await crypto_1.NesoiCrypto.encrypt(val, key);
|
|
809
809
|
tree_1.Tree.set(obj, field.path, () => encrypted);
|
|
810
810
|
}
|
|
@@ -820,7 +820,7 @@ class Bucket {
|
|
|
820
820
|
if (field.crypto) {
|
|
821
821
|
const key = trx.value(field.crypto.value.short);
|
|
822
822
|
const val = tree_1.Tree.get(obj, field.path);
|
|
823
|
-
if (val
|
|
823
|
+
if (val != null) {
|
|
824
824
|
const encrypted = await crypto_1.NesoiCrypto.decrypt(val, key);
|
|
825
825
|
tree_1.Tree.set(obj, field.path, () => encrypted);
|
|
826
826
|
}
|
|
@@ -123,7 +123,7 @@ class BucketModel {
|
|
|
123
123
|
runCopyCmd(op, cmd, modelpath, as_json = false) {
|
|
124
124
|
const next = [];
|
|
125
125
|
const value = cmd.obj[cmd.key];
|
|
126
|
-
if (value
|
|
126
|
+
if (value == null) {
|
|
127
127
|
if (cmd.field.path !== 'id' && cmd.field.required) {
|
|
128
128
|
throw error_1.NesoiError.Bucket.Model.FieldRequired({ bucket: this.alias, field: cmd.field.path, indexes: cmd.modelpath?.asterisk_values });
|
|
129
129
|
}
|
|
@@ -5,6 +5,8 @@ const bucket_model_schema_1 = require("../model/bucket_model.schema");
|
|
|
5
5
|
const string_1 = require("../../../../engine/util/string");
|
|
6
6
|
const daemon_1 = require("../../../../engine/daemon");
|
|
7
7
|
const dependency_1 = require("../../../../engine/dependency");
|
|
8
|
+
const date_1 = require("../../../../engine/data/date");
|
|
9
|
+
const datetime_1 = require("../../../../engine/data/datetime");
|
|
8
10
|
/**
|
|
9
11
|
* @category NQL
|
|
10
12
|
* */
|
|
@@ -70,6 +72,8 @@ class NQL_RuleTree {
|
|
|
70
72
|
for (const key in query) {
|
|
71
73
|
const value = query[key];
|
|
72
74
|
const parsedKey = await this.parseKey(meta, key);
|
|
75
|
+
if (value == null)
|
|
76
|
+
continue;
|
|
73
77
|
// Fieldpath term -> Condition
|
|
74
78
|
if (parsedKey.type === 'fieldpath') {
|
|
75
79
|
const parsed = await this.parseValue(value, parsedKey, meta, select);
|
|
@@ -268,6 +272,12 @@ class NQL_RuleTree {
|
|
|
268
272
|
}
|
|
269
273
|
}
|
|
270
274
|
else {
|
|
275
|
+
if (value instanceof date_1.NesoiDate) {
|
|
276
|
+
return { static: value.toISO() };
|
|
277
|
+
}
|
|
278
|
+
if (value instanceof datetime_1.NesoiDatetime) {
|
|
279
|
+
return { static: value.toISO() };
|
|
280
|
+
}
|
|
271
281
|
// Parameter
|
|
272
282
|
if ('.' in value) {
|
|
273
283
|
return { param: value['.'], param_is_deep: value['.'].includes('.') };
|
|
@@ -7,5 +7,5 @@ export declare class Enum<$ extends $ConstantEnum> {
|
|
|
7
7
|
private schema;
|
|
8
8
|
constructor(schema: $);
|
|
9
9
|
keys<K extends keyof $['options']>(): K[];
|
|
10
|
-
get<K extends keyof $['options']>(key: K): $['options'][K]['value'];
|
|
10
|
+
get<K extends keyof $['options']>(key: K): $['options'][K]['value'] | undefined;
|
|
11
11
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { $Space, ModuleName } from "../../schema";
|
|
1
|
+
import type { $Module, $Space, ModuleName } from "../../schema";
|
|
2
2
|
import type { BucketConfig } from "../../elements/entities/bucket/bucket.config";
|
|
3
3
|
import type { AuthnProvider } from '../auth/authn';
|
|
4
4
|
import type { ControllerConfig } from "../../elements/edge/controller/controller.config";
|
|
@@ -14,11 +14,14 @@ import type { Overlay } from '../util/type';
|
|
|
14
14
|
import type { TrxStatus } from '../transaction/trx';
|
|
15
15
|
import type { NesoiObj } from '../data/obj';
|
|
16
16
|
import type { MessageTemplateDef } from "../../elements/entities/message/template/message_template.builder";
|
|
17
|
+
type ModuleElementTag<M extends $Module> = `message:${keyof M['messages'] & string}` | `bucket:${keyof M['buckets'] & string}` | `job:${keyof M['jobs'] & string}` | `resource:${keyof M['resources'] & string}` | `machine:${keyof M['machines'] & string}` | `controller:${keyof M['controllers'] & string}` | `queue:${keyof M['queues'] & string}` | `topic:${keyof M['topics'] & string}`;
|
|
17
18
|
export type AppModuleConfig<S extends $Space, M extends ModuleName<S>, Services extends Record<string, IService>> = {
|
|
18
19
|
buckets?: AppBucketConfig<S, M, Services>;
|
|
19
20
|
trash?: AppTrashConfig<Services>;
|
|
20
21
|
controllers?: AppControllerConfig<S, M, Services>;
|
|
21
22
|
trx?: TrxEngineConfig<S, S['modules'][M], any, Services>;
|
|
23
|
+
include?: ModuleElementTag<S['modules'][M]>[];
|
|
24
|
+
exclude?: ModuleElementTag<S['modules'][M]>[];
|
|
22
25
|
};
|
|
23
26
|
export type AppConfig<S extends $Space, Modules extends ModuleName<S>, Services extends Record<string, IService>> = {
|
|
24
27
|
env?: $Message;
|
|
@@ -80,3 +83,4 @@ export declare class AppConfigBuilder<S extends $Space, Modules extends string =
|
|
|
80
83
|
cli(config: CLIConfig<Services>): _App;
|
|
81
84
|
compiler(config: CompilerConfig): _App;
|
|
82
85
|
}
|
|
86
|
+
export {};
|
package/lib/engine/app/app.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { AnyAppConfig } from './app.config';
|
|
|
5
5
|
import type { IService } from './service';
|
|
6
6
|
import { Space } from '../space';
|
|
7
7
|
import { AppConfigBuilder } from './app.config';
|
|
8
|
+
import { Tag } from '../dependency';
|
|
8
9
|
/**
|
|
9
10
|
* @category App
|
|
10
11
|
*/
|
|
@@ -66,5 +67,15 @@ export declare abstract class App<S extends $Space, Modules extends string = Mod
|
|
|
66
67
|
config: AnyAppConfig;
|
|
67
68
|
nesoiNpmPkg: string;
|
|
68
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* Get a list of included/excluded tags per module, used by the builder
|
|
72
|
+
* to avoid including specific tags on the app.
|
|
73
|
+
*/
|
|
74
|
+
static getIncludeExcludeTags(app: AnyApp): {
|
|
75
|
+
[module: string]: {
|
|
76
|
+
include?: Tag[];
|
|
77
|
+
exclude?: Tag[];
|
|
78
|
+
};
|
|
79
|
+
};
|
|
69
80
|
}
|
|
70
81
|
export type AnyApp = App<any, any>;
|
package/lib/engine/app/app.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.App = void 0;
|
|
|
4
4
|
const module_1 = require("../module");
|
|
5
5
|
const space_1 = require("../space");
|
|
6
6
|
const app_config_1 = require("./app.config");
|
|
7
|
+
const dependency_1 = require("../dependency");
|
|
7
8
|
/*
|
|
8
9
|
App
|
|
9
10
|
*/
|
|
@@ -112,5 +113,34 @@ class App {
|
|
|
112
113
|
nesoiNpmPkg: app._nesoiNpmPkg,
|
|
113
114
|
};
|
|
114
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Get a list of included/excluded tags per module, used by the builder
|
|
118
|
+
* to avoid including specific tags on the app.
|
|
119
|
+
*/
|
|
120
|
+
static getIncludeExcludeTags(app) {
|
|
121
|
+
if (!app._config.modules)
|
|
122
|
+
return {};
|
|
123
|
+
const tags = {};
|
|
124
|
+
for (const m in app._config.modules) {
|
|
125
|
+
const module = app._config.modules[m];
|
|
126
|
+
if (module.include) {
|
|
127
|
+
tags[m] ??= {};
|
|
128
|
+
tags[m].include ??= [];
|
|
129
|
+
for (const ref of module.include) {
|
|
130
|
+
const [type, name] = ref.split(':');
|
|
131
|
+
tags[m].include.push(new dependency_1.Tag(m, type, name));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (module.exclude) {
|
|
135
|
+
tags[m] ??= {};
|
|
136
|
+
tags[m].exclude ??= [];
|
|
137
|
+
for (const ref of module.exclude) {
|
|
138
|
+
const [type, name] = ref.split(':');
|
|
139
|
+
tags[m].exclude.push(new dependency_1.Tag(m, type, name));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return tags;
|
|
144
|
+
}
|
|
115
145
|
}
|
|
116
146
|
exports.App = App;
|
|
@@ -45,6 +45,7 @@ class InlineApp extends app_1.App {
|
|
|
45
45
|
const tree = new tree_1.ModuleTree(this._modules, {
|
|
46
46
|
exclude: ['*.test.ts']
|
|
47
47
|
});
|
|
48
|
+
const tags = app_1.App.getIncludeExcludeTags(this);
|
|
48
49
|
await tree.resolve();
|
|
49
50
|
await tree.traverse('Building', async (node) => {
|
|
50
51
|
// Inline nodes are built by their root builder
|
|
@@ -52,7 +53,7 @@ class InlineApp extends app_1.App {
|
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
55
|
const module = this._modules[node.tag.module];
|
|
55
|
-
await builder_1.Builder.buildNode(module, node, tree);
|
|
56
|
+
await builder_1.Builder.buildNode(module, node, tree, tags);
|
|
56
57
|
});
|
|
57
58
|
}
|
|
58
59
|
/**
|
package/lib/engine/builder.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ResolvedBuilderNode } from './dependency';
|
|
2
2
|
import type { ModuleTree } from './tree';
|
|
3
3
|
import type { AnyModule } from './module';
|
|
4
|
+
import type { Compiler } from "../compiler";
|
|
4
5
|
export declare class Builder {
|
|
5
6
|
/**
|
|
6
7
|
* Build a resolved builder node, then merge the
|
|
@@ -10,7 +11,8 @@ export declare class Builder {
|
|
|
10
11
|
* @param node A resolved builder node
|
|
11
12
|
* @param tree A module tree
|
|
12
13
|
*/
|
|
13
|
-
static buildNode(module: AnyModule, node: ResolvedBuilderNode, tree: ModuleTree): void;
|
|
14
|
+
static buildNode(module: AnyModule, node: ResolvedBuilderNode, tree: ModuleTree, tags?: Compiler['tags']): void;
|
|
15
|
+
static filterNode(module: string, node: ResolvedBuilderNode, tags?: Compiler['tags']): boolean;
|
|
14
16
|
/**
|
|
15
17
|
* Merge inline message schemas into the module.
|
|
16
18
|
*
|
package/lib/engine/builder.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Builder = void 0;
|
|
4
|
+
const dependency_1 = require("./dependency");
|
|
4
5
|
const log_1 = require("./util/log");
|
|
5
6
|
const error_1 = require("./data/error");
|
|
6
7
|
const message_builder_1 = require("../elements/entities/message/message.builder");
|
|
@@ -23,8 +24,9 @@ class Builder {
|
|
|
23
24
|
* @param node A resolved builder node
|
|
24
25
|
* @param tree A module tree
|
|
25
26
|
*/
|
|
26
|
-
static buildNode(module, node, tree) {
|
|
27
|
+
static buildNode(module, node, tree, tags) {
|
|
27
28
|
log_1.Log.trace('builder', 'module', `Building ${module.name}::${(0, log_1.scopeTag)(node.builder.$b, node.builder.name)}`);
|
|
29
|
+
const add_root = this.filterNode(module.name, node, tags);
|
|
28
30
|
if (node.builder.$b === 'constants') {
|
|
29
31
|
module.schema.constants = constants_builder_1.ConstantsBuilder.build(node);
|
|
30
32
|
}
|
|
@@ -32,45 +34,99 @@ class Builder {
|
|
|
32
34
|
module.schema.externals = externals_builder_1.ExternalsBuilder.build(node, tree);
|
|
33
35
|
}
|
|
34
36
|
else if (node.builder.$b === 'bucket') {
|
|
35
|
-
|
|
37
|
+
if (add_root) {
|
|
38
|
+
module.schema.buckets[node.tag.name] = bucket_builder_1.BucketBuilder.build(node, tree);
|
|
39
|
+
}
|
|
36
40
|
}
|
|
37
41
|
else if (node.builder.$b === 'message') {
|
|
38
|
-
|
|
42
|
+
if (add_root) {
|
|
43
|
+
module.schema.messages[node.tag.name] = message_builder_1.MessageBuilder.build(node, tree, module.schema);
|
|
44
|
+
}
|
|
39
45
|
}
|
|
40
46
|
else if (node.builder.$b === 'job') {
|
|
41
47
|
const { schema, inlineMessages } = job_builder_1.JobBuilder.build(node, tree, module.schema);
|
|
42
|
-
|
|
48
|
+
if (add_root) {
|
|
49
|
+
module.schema.jobs[node.tag.name] = schema;
|
|
50
|
+
}
|
|
43
51
|
this.mergeInlineMessages(module, inlineMessages);
|
|
44
52
|
}
|
|
45
53
|
else if (node.builder.$b === 'resource') {
|
|
46
54
|
const { schema, inlineMessages, inlineJobs } = resource_builder_1.ResourceBuilder.build(node, tree, module.schema);
|
|
47
|
-
|
|
55
|
+
if (add_root) {
|
|
56
|
+
module.schema.resources[schema.name] = schema;
|
|
57
|
+
}
|
|
48
58
|
this.mergeInlineMessages(module, inlineMessages);
|
|
49
59
|
this.mergeInlineJobs(module, inlineJobs);
|
|
50
60
|
}
|
|
51
61
|
else if (node.builder.$b === 'machine') {
|
|
52
62
|
const { schema, inlineMessages, inlineJobs } = machine_builder_1.MachineBuilder.build(node, tree, module.schema);
|
|
53
|
-
|
|
63
|
+
if (add_root) {
|
|
64
|
+
module.schema.machines[schema.name] = schema;
|
|
65
|
+
}
|
|
54
66
|
this.mergeInlineMessages(module, inlineMessages);
|
|
55
67
|
this.mergeInlineJobs(module, inlineJobs);
|
|
56
68
|
}
|
|
57
69
|
else if (node.builder.$b === 'controller') {
|
|
58
|
-
|
|
70
|
+
if (add_root) {
|
|
71
|
+
module.schema.controllers[node.tag.name] = controller_builder_1.ControllerBuilder.build(node);
|
|
72
|
+
}
|
|
59
73
|
}
|
|
60
74
|
else if (node.builder.$b === 'queue') {
|
|
61
75
|
const { schema, inlineMessages } = queue_builder_1.QueueBuilder.build(node, tree, module.schema);
|
|
62
|
-
|
|
76
|
+
if (add_root) {
|
|
77
|
+
module.schema.queues[node.tag.name] = schema;
|
|
78
|
+
}
|
|
63
79
|
this.mergeInlineMessages(module, inlineMessages);
|
|
64
80
|
}
|
|
65
81
|
else if (node.builder.$b === 'topic') {
|
|
66
82
|
const { schema, inlineMessages } = topic_builder_1.TopicBuilder.build(node, tree, module.schema);
|
|
67
|
-
|
|
83
|
+
if (add_root) {
|
|
84
|
+
module.schema.topics[node.tag.name] = schema;
|
|
85
|
+
}
|
|
68
86
|
this.mergeInlineMessages(module, inlineMessages);
|
|
69
87
|
}
|
|
70
88
|
else {
|
|
71
89
|
throw error_1.NesoiError.Module.UnknownBuilderType(module, node.filepath.toString(), node.tag.name, node.builder.$b);
|
|
72
90
|
}
|
|
73
91
|
}
|
|
92
|
+
static filterNode(module, node, tags) {
|
|
93
|
+
let add_root = true;
|
|
94
|
+
// Filter elements with include/exclude
|
|
95
|
+
const module_tags = tags?.[module];
|
|
96
|
+
if (module_tags?.include) {
|
|
97
|
+
if (!module_tags.include.some(t => dependency_1.Tag.matches(t, node.tag))) {
|
|
98
|
+
node.filtered = true;
|
|
99
|
+
add_root = false;
|
|
100
|
+
}
|
|
101
|
+
for (const type of ['message', 'job']) {
|
|
102
|
+
if (node.inlines[type]) {
|
|
103
|
+
for (const name in node.inlines[type]) {
|
|
104
|
+
if (!module_tags.include.some(t => dependency_1.Tag.matches(t, node.inlines[type][name].tag))) {
|
|
105
|
+
node.inlines[type][name].filtered = true;
|
|
106
|
+
delete node.inlines[type][name];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (module_tags?.exclude) {
|
|
113
|
+
if (module_tags.exclude.some(t => dependency_1.Tag.matches(t, node.tag))) {
|
|
114
|
+
node.filtered = true;
|
|
115
|
+
add_root = false;
|
|
116
|
+
}
|
|
117
|
+
for (const type of ['message', 'job']) {
|
|
118
|
+
if (node.inlines[type]) {
|
|
119
|
+
for (const name in node.inlines[type]) {
|
|
120
|
+
if (module_tags.exclude.some(t => dependency_1.Tag.matches(t, node.inlines[type][name].tag))) {
|
|
121
|
+
node.inlines[type][name].filtered = true;
|
|
122
|
+
delete node.inlines[type][name];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return add_root;
|
|
129
|
+
}
|
|
74
130
|
/**
|
|
75
131
|
* Merge inline message schemas into the module.
|
|
76
132
|
*
|
|
@@ -337,6 +337,14 @@ export declare namespace NesoiError {
|
|
|
337
337
|
function UnmetCondition(alias: string, msg: string): BaseError;
|
|
338
338
|
}
|
|
339
339
|
namespace Controller {
|
|
340
|
+
function DomainNotFound($: {
|
|
341
|
+
domain: string;
|
|
342
|
+
controller: string;
|
|
343
|
+
}): BaseError;
|
|
344
|
+
function EndpointNotFound($: {
|
|
345
|
+
endpoint: string;
|
|
346
|
+
controller: string;
|
|
347
|
+
}): BaseError;
|
|
340
348
|
function SubscribeFailed($: {
|
|
341
349
|
topic: string;
|
|
342
350
|
}): BaseError;
|
package/lib/engine/data/error.js
CHANGED
|
@@ -507,6 +507,14 @@ var NesoiError;
|
|
|
507
507
|
*/
|
|
508
508
|
let Controller;
|
|
509
509
|
(function (Controller) {
|
|
510
|
+
function DomainNotFound($) {
|
|
511
|
+
return new BaseError('Controller.DomainNotFound', `Domain '${$.domain}' not found on controller '${$.controller}'`, Status.BAD_REQUEST, $);
|
|
512
|
+
}
|
|
513
|
+
Controller.DomainNotFound = DomainNotFound;
|
|
514
|
+
function EndpointNotFound($) {
|
|
515
|
+
return new BaseError('Controller.DomainNotFound', `Endpoint '${$.endpoint}' not found on controller '${$.controller}'`, Status.BAD_REQUEST, $);
|
|
516
|
+
}
|
|
517
|
+
Controller.EndpointNotFound = EndpointNotFound;
|
|
510
518
|
function SubscribeFailed($) {
|
|
511
519
|
return new BaseError('Controller.SubscribeFailed', `Failed to subscribe to topic '${$.topic}'`, Status.BAD_REQUEST, $);
|
|
512
520
|
}
|
package/lib/engine/data/tree.js
CHANGED
|
@@ -30,6 +30,9 @@ class Tree {
|
|
|
30
30
|
if (ref === undefined) {
|
|
31
31
|
return undefined;
|
|
32
32
|
}
|
|
33
|
+
if (ref === null) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
33
36
|
}
|
|
34
37
|
// When reading from a TypeAsObj,
|
|
35
38
|
// advance on unions
|
|
@@ -103,7 +106,7 @@ class Tree {
|
|
|
103
106
|
else {
|
|
104
107
|
ref.walk(path);
|
|
105
108
|
}
|
|
106
|
-
if (ref.get()
|
|
109
|
+
if (ref.get() == null) {
|
|
107
110
|
ref.replace(replacer, __index);
|
|
108
111
|
return;
|
|
109
112
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { $Module, $Space } from "../../../schema";
|
|
2
|
+
import type { $Controller } from "../../../elements/edge/controller/controller.schema";
|
|
3
|
+
import { TrxNode } from '../trx_node';
|
|
4
|
+
import { Tag } from "../../dependency";
|
|
5
|
+
/**
|
|
6
|
+
* @category Engine
|
|
7
|
+
* @subcategory Transaction
|
|
8
|
+
*/
|
|
9
|
+
export declare class ControllerTrxNode<S extends $Space, M extends $Module, $ extends $Controller> {
|
|
10
|
+
private trx;
|
|
11
|
+
private tag;
|
|
12
|
+
private external;
|
|
13
|
+
private controller?;
|
|
14
|
+
constructor(trx: TrxNode<any, M, any>, tag: Tag);
|
|
15
|
+
private wrap;
|
|
16
|
+
invoke<Path extends keyof $['#path']>(path: Path, raw: $['#path'][Path]['#raw']): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ControllerTrxNode = void 0;
|
|
4
|
+
const trx_node_1 = require("../trx_node");
|
|
5
|
+
const external_trx_node_1 = require("./external.trx_node");
|
|
6
|
+
const dependency_1 = require("../../dependency");
|
|
7
|
+
const error_1 = require("../../data/error");
|
|
8
|
+
/**
|
|
9
|
+
* @category Engine
|
|
10
|
+
* @subcategory Transaction
|
|
11
|
+
*/
|
|
12
|
+
class ControllerTrxNode {
|
|
13
|
+
trx;
|
|
14
|
+
tag;
|
|
15
|
+
external;
|
|
16
|
+
controller;
|
|
17
|
+
constructor(trx, tag) {
|
|
18
|
+
this.trx = trx;
|
|
19
|
+
this.tag = tag;
|
|
20
|
+
const module = trx_node_1.TrxNode.getModule(trx);
|
|
21
|
+
this.external = tag.module !== module.name;
|
|
22
|
+
if (!this.external) {
|
|
23
|
+
this.controller = dependency_1.Tag.element(tag, trx);
|
|
24
|
+
if (!this.controller) {
|
|
25
|
+
throw error_1.NesoiError.Trx.NodeNotFound(this.tag.full, trx.globalId);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/*
|
|
30
|
+
Wrap
|
|
31
|
+
*/
|
|
32
|
+
async wrap(action, input, fn, fmtTrxOut) {
|
|
33
|
+
const wrapped = async (parentTrx, controller) => {
|
|
34
|
+
const trx = trx_node_1.TrxNode.makeChildNode(parentTrx, controller.schema.module, 'controller', controller.schema.name);
|
|
35
|
+
trx_node_1.TrxNode.open(trx, action, input);
|
|
36
|
+
let out;
|
|
37
|
+
try {
|
|
38
|
+
out = await fn(trx, controller);
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
throw trx_node_1.TrxNode.error(trx, e);
|
|
42
|
+
}
|
|
43
|
+
trx_node_1.TrxNode.ok(trx, fmtTrxOut ? fmtTrxOut(out) : out);
|
|
44
|
+
return out;
|
|
45
|
+
};
|
|
46
|
+
if (this.external) {
|
|
47
|
+
const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag);
|
|
48
|
+
return ext.run_and_hold(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return wrapped(this.trx, this.controller);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async invoke(path, raw) {
|
|
55
|
+
return this.wrap('invoke', raw, (_, controller) => {
|
|
56
|
+
return controller.adapter.invoke(path, raw);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.ControllerTrxNode = ControllerTrxNode;
|
|
@@ -14,6 +14,7 @@ import { ResourceTrxNode } from './nodes/resource.trx_node';
|
|
|
14
14
|
import { MachineTrxNode } from './nodes/machine.trx_node';
|
|
15
15
|
import { Enum } from "../../elements/entities/constants/constants";
|
|
16
16
|
import { TopicTrxNode } from './nodes/topic.trx_node';
|
|
17
|
+
import { ControllerTrxNode } from './nodes/controller.trx_node';
|
|
17
18
|
export type TrxNodeBlock = 'bucket' | 'message' | 'job' | 'resource' | 'machine' | 'queue' | 'topic' | 'controller' | 'externals';
|
|
18
19
|
export type TrxNodeState = 'open' | 'hold' | 'ok' | 'error';
|
|
19
20
|
export type TrxNodeStatus = {
|
|
@@ -70,6 +71,7 @@ export declare class TrxNode<Space extends $Space, M extends $Module, AuthUsers
|
|
|
70
71
|
static jobWithCustomCtx<M extends $Module, JobName extends keyof M['jobs'], Job extends M['jobs'][JobName]>(node: AnyTrxNode, name: string, ctx?: Record<string, any>): JobTrxNode<M, Job>;
|
|
71
72
|
resource<Name extends keyof M['resources'], Resource extends M['resources'][Name]>(name: Name): ResourceTrxNode<M, Resource>;
|
|
72
73
|
machine<Name extends keyof M['machines'], Machine extends M['machines'][Name]>(name: Name): MachineTrxNode<M, Machine>;
|
|
74
|
+
controller<Name extends keyof M['controllers'], Controller extends M['controllers'][Name]>(name: Name): ControllerTrxNode<Space, M, Controller>;
|
|
73
75
|
queue<Name extends keyof M['queues'], Queue extends M['queues'][Name]>(name: Name): QueueTrxNode<M, Queue>;
|
|
74
76
|
topic<Name extends keyof M['topics'], topic extends M['topics'][Name]>(name: Name): TopicTrxNode<Space, M, topic>;
|
|
75
77
|
authenticate(tokens: AuthRequest<keyof AuthUsers>): Promise<TrxNode<$Space, $Module, AuthUsers>>;
|