nesoi 3.0.0 → 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/lib/adapters/postgres/src/migrator/bucket.d.ts +20 -0
- package/lib/adapters/postgres/src/migrator/bucket.js +184 -0
- package/lib/adapters/postgres/src/migrator/csv.d.ts +7 -0
- package/lib/adapters/postgres/src/migrator/csv.js +72 -0
- package/lib/adapters/postgres/src/migrator/migration.d.ts +2 -18
- package/lib/adapters/postgres/src/migrator/migration.js +10 -158
- package/lib/adapters/postgres/src/migrator/migrator.js +8 -5
- package/lib/adapters/postgres/src/migrator/runner.d.ts +16 -6
- package/lib/adapters/postgres/src/migrator/runner.js +103 -34
- package/lib/adapters/postgres/src/postgres.bucket_adapter.d.ts +19 -22
- package/lib/adapters/postgres/src/postgres.bucket_adapter.js +116 -100
- package/lib/adapters/postgres/src/postgres.cli.d.ts +23 -3
- package/lib/adapters/postgres/src/postgres.cli.js +70 -10
- package/lib/adapters/postgres/src/postgres.config.d.ts +5 -0
- package/lib/adapters/postgres/src/postgres.config.js +2 -0
- package/lib/adapters/postgres/src/postgres.nql.d.ts +7 -3
- package/lib/adapters/postgres/src/postgres.nql.js +86 -32
- package/lib/adapters/postgres/src/postgres.provider.d.ts +18 -0
- package/lib/adapters/postgres/src/postgres.provider.js +77 -0
- package/lib/adapters/postgres/test/postgres.bucket_adapter.test.js +76 -39
- package/lib/compiler/apps/monolyth/monolyth_compiler.d.ts +3 -0
- package/lib/compiler/apps/monolyth/monolyth_compiler.js +24 -0
- package/lib/compiler/apps/monolyth/stages/2_build_typescript_stage.js +2 -1
- package/lib/compiler/apps/monolyth/stages/5_dump_cli_stage.js +1 -1
- package/lib/compiler/apps/monolyth/stages/6_dump_package_json_stage.js +1 -1
- package/lib/compiler/elements/bucket.element.js +26 -11
- package/lib/compiler/elements/constants.element.js +1 -1
- package/lib/compiler/elements/element.d.ts +2 -0
- package/lib/compiler/elements/message.element.js +4 -4
- package/lib/compiler/helpers/dump_helpers.js +5 -2
- package/lib/compiler/stages/7_dump_stage.js +2 -0
- package/lib/compiler/treeshake.js +9 -37
- package/lib/compiler/typescript/bridge/extract.js +12 -0
- package/lib/compiler/typescript/bridge/inject.js +3 -0
- package/lib/compiler/typescript/bridge/organize.js +3 -3
- package/lib/elements/blocks/block.builder.js +4 -2
- package/lib/elements/blocks/job/internal/resource_job.builder.d.ts +22 -20
- package/lib/elements/blocks/job/internal/resource_job.d.ts +2 -1
- package/lib/elements/blocks/job/internal/resource_job.js +17 -4
- package/lib/elements/blocks/job/job.js +3 -0
- package/lib/elements/blocks/job/job.types.d.ts +7 -0
- package/lib/elements/blocks/job/job.types.js +2 -0
- package/lib/elements/blocks/machine/machine.js +3 -2
- package/lib/elements/blocks/resource/resource.builder.js +2 -4
- package/lib/elements/blocks/resource/resource.d.ts +5 -3
- package/lib/elements/blocks/resource/resource.js +26 -17
- package/lib/elements/edge/controller/adapters/controller_adapter.d.ts +2 -1
- package/lib/elements/edge/controller/adapters/controller_adapter.js +11 -2
- package/lib/elements/edge/controller/controller.builder.d.ts +4 -5
- package/lib/elements/edge/controller/controller.builder.js +7 -7
- package/lib/elements/edge/controller/controller.d.ts +2 -1
- package/lib/elements/edge/controller/controller.js +8 -6
- package/lib/elements/entities/bucket/adapters/bucket_adapter.d.ts +61 -23
- package/lib/elements/entities/bucket/adapters/bucket_adapter.js +22 -13
- package/lib/elements/entities/bucket/adapters/memory.bucket_adapter.d.ts +21 -22
- package/lib/elements/entities/bucket/adapters/memory.bucket_adapter.js +68 -2
- package/lib/elements/entities/bucket/adapters/memory.nql.d.ts +10 -6
- package/lib/elements/entities/bucket/adapters/memory.nql.js +38 -3
- package/lib/elements/entities/bucket/adapters/slow_memory.bucket_adapter.d.ts +0 -20
- package/lib/elements/entities/bucket/adapters/slow_memory.bucket_adapter.js +46 -30
- package/lib/elements/entities/bucket/bucket.builder.d.ts +8 -2
- package/lib/elements/entities/bucket/bucket.builder.js +13 -19
- package/lib/elements/entities/bucket/bucket.config.d.ts +5 -1
- package/lib/elements/entities/bucket/bucket.d.ts +180 -19
- package/lib/elements/entities/bucket/bucket.js +662 -48
- package/lib/elements/entities/bucket/bucket.schema.d.ts +7 -1
- package/lib/elements/entities/bucket/bucket.schema.js +2 -1
- package/lib/elements/entities/bucket/bucket.types.d.ts +2 -7
- package/lib/elements/entities/bucket/cache/bucket_cache.d.ts +6 -2
- package/lib/elements/entities/bucket/cache/bucket_cache.js +12 -12
- package/lib/elements/entities/bucket/graph/bucket_graph.d.ts +32 -5
- package/lib/elements/entities/bucket/graph/bucket_graph.js +80 -111
- package/lib/elements/entities/bucket/graph/bucket_graph.schema.d.ts +3 -6
- package/lib/elements/entities/bucket/graph/bucket_graph.schema.js +1 -4
- package/lib/elements/entities/bucket/graph/bucket_graph_link.builder.d.ts +3 -7
- package/lib/elements/entities/bucket/graph/bucket_graph_link.builder.js +6 -2
- package/lib/elements/entities/bucket/model/bucket_model.builder.js +1 -1
- package/lib/elements/entities/bucket/model/bucket_model.convert.js +3 -3
- package/lib/elements/entities/bucket/model/bucket_model.schema.d.ts +37 -8
- package/lib/elements/entities/bucket/model/bucket_model.schema.js +25 -4
- package/lib/elements/entities/bucket/model/bucket_model_field.builder.d.ts +33 -14
- package/lib/elements/entities/bucket/model/bucket_model_field.builder.js +56 -13
- package/lib/elements/entities/bucket/query/nql.schema.d.ts +1 -0
- package/lib/elements/entities/bucket/query/nql_compiler.js +13 -2
- package/lib/elements/entities/bucket/query/nql_engine.d.ts +11 -4
- package/lib/elements/entities/bucket/query/nql_engine.js +20 -11
- package/lib/elements/entities/bucket/view/bucket_view.js +63 -35
- package/lib/elements/entities/bucket/view/bucket_view.schema.d.ts +5 -2
- package/lib/elements/entities/bucket/view/bucket_view_field.builder.d.ts +6 -2
- package/lib/elements/entities/bucket/view/bucket_view_field.builder.js +22 -16
- package/lib/elements/entities/constants/constants.schema.d.ts +1 -1
- package/lib/elements/entities/drive/drive_adapter.d.ts +44 -0
- package/lib/elements/entities/drive/drive_adapter.js +10 -0
- package/lib/elements/entities/drive/local.drive_adapter.d.ts +10 -0
- package/lib/elements/entities/drive/local.drive_adapter.js +34 -0
- package/lib/elements/entities/message/message.schema.d.ts +1 -0
- package/lib/elements/entities/message/message.schema.js +33 -0
- package/lib/elements/entities/message/message_parser.d.ts +5 -1
- package/lib/elements/entities/message/message_parser.js +56 -35
- package/lib/elements/entities/message/template/message_template.schema.d.ts +10 -8
- package/lib/elements/entities/message/template/message_template_field.builder.d.ts +16 -6
- package/lib/elements/entities/message/template/message_template_field.builder.js +25 -0
- package/lib/elements/entities/message/template/message_template_parser.js +2 -1
- package/lib/engine/apps/app.config.d.ts +32 -11
- package/lib/engine/apps/app.config.js +12 -0
- package/lib/engine/apps/app.d.ts +2 -0
- package/lib/engine/apps/app.js +3 -0
- package/lib/engine/apps/inline.app.d.ts +5 -3
- package/lib/engine/apps/inline.app.js +27 -12
- package/lib/engine/apps/monolyth/monolyth.app.d.ts +4 -2
- package/lib/engine/apps/monolyth/monolyth.app.js +22 -10
- package/lib/engine/auth/authn.d.ts +5 -1
- package/lib/engine/auth/zero.authn_provider.d.ts +4 -2
- package/lib/engine/auth/zero.authn_provider.js +2 -2
- package/lib/engine/cli/cli.d.ts +3 -1
- package/lib/engine/cli/cli.js +22 -3
- package/lib/engine/cli/cli_adapter.d.ts +2 -1
- package/lib/engine/cli/cli_adapter.js +2 -1
- package/lib/engine/cli/cli_input.d.ts +19 -0
- package/lib/engine/cli/cli_input.js +207 -0
- package/lib/engine/cli/ui.d.ts +1 -1
- package/lib/engine/cli/ui.js +2 -2
- package/lib/engine/daemon.d.ts +3 -2
- package/lib/engine/daemon.js +14 -2
- package/lib/engine/data/date.js +2 -2
- package/lib/engine/data/datetime.d.ts +40 -4
- package/lib/engine/data/datetime.js +70 -11
- package/lib/engine/data/decimal.d.ts +1 -1
- package/lib/engine/data/decimal.js +3 -3
- package/lib/engine/data/error.d.ts +21 -4
- package/lib/engine/data/error.js +23 -7
- package/lib/engine/data/file.d.ts +38 -0
- package/lib/engine/data/file.js +54 -0
- package/lib/engine/data/json.d.ts +6 -0
- package/lib/engine/data/json.js +26 -0
- package/lib/engine/data/obj.d.ts +1 -1
- package/lib/engine/data/trash.d.ts +14 -0
- package/lib/engine/data/trash.js +2 -0
- package/lib/engine/data/tree.d.ts +7 -12
- package/lib/engine/data/tree.js +101 -49
- package/lib/engine/module.d.ts +2 -1
- package/lib/engine/module.js +2 -5
- package/lib/engine/space.d.ts +1 -0
- package/lib/engine/space.js +6 -0
- package/lib/engine/transaction/nodes/bucket.trx_node.d.ts +184 -24
- package/lib/engine/transaction/nodes/bucket.trx_node.js +346 -451
- package/lib/engine/transaction/nodes/bucket_query.trx_node.d.ts +4 -2
- package/lib/engine/transaction/nodes/bucket_query.trx_node.js +27 -15
- package/lib/engine/transaction/nodes/job.trx_node.d.ts +2 -1
- package/lib/engine/transaction/nodes/job.trx_node.js +6 -0
- package/lib/engine/transaction/trx.d.ts +5 -2
- package/lib/engine/transaction/trx.js +2 -2
- package/lib/engine/transaction/trx_engine.config.d.ts +1 -3
- package/lib/engine/transaction/trx_engine.d.ts +2 -2
- package/lib/engine/transaction/trx_engine.js +14 -11
- package/lib/engine/transaction/trx_node.d.ts +14 -4
- package/lib/engine/transaction/trx_node.js +50 -8
- package/lib/engine/tree.d.ts +1 -1
- package/lib/engine/util/crypto.d.ts +50 -0
- package/lib/engine/util/crypto.js +89 -0
- package/lib/engine/util/deep.d.ts +5 -0
- package/lib/engine/util/deep.js +46 -0
- package/lib/engine/util/dotenv.d.ts +2 -8
- package/lib/engine/util/dotenv.js +14 -36
- package/lib/engine/util/hash.d.ts +3 -0
- package/lib/engine/util/hash.js +23 -0
- package/lib/engine/util/log.js +1 -1
- package/lib/engine/util/mime.d.ts +10 -0
- package/lib/engine/util/mime.js +389 -0
- package/lib/engine/util/parse.d.ts +6 -5
- package/lib/engine/util/parse.js +16 -15
- package/lib/engine/util/path.d.ts +3 -0
- package/lib/engine/util/path.js +92 -0
- package/lib/engine/util/rules.d.ts +4 -0
- package/lib/engine/util/rules.js +12 -0
- package/package.json +2 -2
- package/tools/compile.js +2 -2
- package/tools/dotenv.d.ts +1 -0
- package/tools/dotenv.js +4 -0
- package/tools/joaquin/job.d.ts +5 -5
- package/tools/joaquin/mock.d.ts +23 -2
- package/tools/joaquin/mock.js +127 -21
- package/tsconfig.build.tsbuildinfo +1 -1
- package/lib/adapters/postgres/test/postgres.bucket_query.test.d.ts +0 -0
- package/lib/adapters/postgres/test/postgres.bucket_query.test.js +0 -136
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Bucket = void 0;
|
|
3
|
+
exports.Bucket = exports.$id = void 0;
|
|
4
|
+
const trx_node_1 = require("../../../engine/transaction/trx_node");
|
|
4
5
|
const error_1 = require("../../../engine/data/error");
|
|
5
6
|
const bucket_view_1 = require("./view/bucket_view");
|
|
6
7
|
const memory_bucket_adapter_1 = require("./adapters/memory.bucket_adapter");
|
|
7
8
|
const bucket_cache_1 = require("./cache/bucket_cache");
|
|
8
9
|
const log_1 = require("../../../engine/util/log");
|
|
9
10
|
const bucket_graph_1 = require("./graph/bucket_graph");
|
|
11
|
+
const datetime_1 = require("../../../engine/data/datetime");
|
|
12
|
+
const tree_1 = require("../../../engine/data/tree");
|
|
13
|
+
const crypto_1 = require("../../../engine/util/crypto");
|
|
14
|
+
const bucket_model_schema_1 = require("./model/bucket_model.schema");
|
|
15
|
+
/**
|
|
16
|
+
* **This should only be used inside a `#composition` of a bucket `create`** to refer to the parent id, which doesn't exist yet.
|
|
17
|
+
*
|
|
18
|
+
* This property has no useful value outside the engine. If you try to `console.log` it, you'll find a Symbol.
|
|
19
|
+
* It's replaced by the bucket after creating the parent, before creating the composition.
|
|
20
|
+
*/
|
|
21
|
+
exports.$id = Symbol('FUTURE ID OF CREATE');
|
|
10
22
|
class Bucket {
|
|
11
23
|
constructor(schema, config, providers = {}) {
|
|
12
24
|
this.schema = schema;
|
|
@@ -26,100 +38,702 @@ class Bucket {
|
|
|
26
38
|
if (this.config?.cache) {
|
|
27
39
|
this.cache = new bucket_cache_1.BucketCache(this.schema.name, this.adapter, this.config.cache);
|
|
28
40
|
}
|
|
41
|
+
// Drive
|
|
42
|
+
if (this.config?.drive) {
|
|
43
|
+
this.drive = this.config.drive(schema, providers);
|
|
44
|
+
}
|
|
29
45
|
}
|
|
30
|
-
//
|
|
31
|
-
|
|
46
|
+
// Getters
|
|
47
|
+
getQueryMeta() {
|
|
48
|
+
return {
|
|
49
|
+
...this.adapter.getQueryMeta(),
|
|
50
|
+
bucket: this.schema
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/* CRUD */
|
|
54
|
+
/**
|
|
55
|
+
* Read one raw entity by `id`
|
|
56
|
+
*
|
|
57
|
+
* - Options:
|
|
58
|
+
* - `silent`: If not found, return `undefined` instead of throwing an exception
|
|
59
|
+
* - `no_tenancy`: Don't apply tenancy rules.
|
|
60
|
+
*/
|
|
61
|
+
async readOne(trx, id, options) {
|
|
62
|
+
log_1.Log.debug('bucket', this.schema.name, `Read id=${id}`);
|
|
63
|
+
// Validate ID
|
|
32
64
|
if (typeof id !== 'string' && typeof id !== 'number') {
|
|
33
65
|
throw error_1.NesoiError.Bucket.InvalidId({ bucket: this.schema.alias, id });
|
|
34
66
|
}
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
?
|
|
38
|
-
:
|
|
39
|
-
|
|
40
|
-
|
|
67
|
+
// Make tenancy query
|
|
68
|
+
const tenancy = (options?.no_tenancy)
|
|
69
|
+
? undefined
|
|
70
|
+
: this.getTenancyQuery(trx);
|
|
71
|
+
let raw;
|
|
72
|
+
// With Tenancy
|
|
73
|
+
if (tenancy) {
|
|
74
|
+
const result = await this.adapter.query(trx, {
|
|
75
|
+
id,
|
|
76
|
+
'#and': tenancy
|
|
77
|
+
}, { perPage: 1 });
|
|
78
|
+
raw = result.data[0];
|
|
79
|
+
}
|
|
80
|
+
// Without Tenancy
|
|
81
|
+
else {
|
|
82
|
+
raw = this.cache
|
|
83
|
+
? await this.cache.get(trx, id)
|
|
84
|
+
: await this.adapter.get(trx, id);
|
|
85
|
+
}
|
|
86
|
+
// Empty result
|
|
87
|
+
if (!raw) {
|
|
88
|
+
if (options?.silent)
|
|
89
|
+
return undefined;
|
|
90
|
+
else
|
|
91
|
+
throw error_1.NesoiError.Bucket.ObjNotFound({ bucket: this.schema.alias, id: id });
|
|
92
|
+
}
|
|
93
|
+
// Encryption
|
|
94
|
+
if (this.schema.model.hasEncryptedField) {
|
|
95
|
+
this.decrypt(trx, raw);
|
|
96
|
+
}
|
|
41
97
|
return raw;
|
|
42
98
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Read all raw entities
|
|
101
|
+
*
|
|
102
|
+
* - Options:
|
|
103
|
+
* - `no_tenancy`: Don't apply tenancy rules.
|
|
104
|
+
*/
|
|
105
|
+
async readAll(trx, options) {
|
|
106
|
+
log_1.Log.debug('bucket', this.schema.name, 'Read All');
|
|
107
|
+
// Make tenancy query
|
|
108
|
+
const tenancy = (options?.no_tenancy)
|
|
109
|
+
? undefined
|
|
110
|
+
: this.getTenancyQuery(trx);
|
|
111
|
+
let raws;
|
|
112
|
+
// With Tenancy
|
|
113
|
+
if (tenancy) {
|
|
114
|
+
const result = await this.adapter.query(trx, tenancy);
|
|
115
|
+
raws = result.data;
|
|
116
|
+
}
|
|
117
|
+
// Without Tenancy
|
|
118
|
+
else {
|
|
119
|
+
raws = this.cache
|
|
120
|
+
? await this.cache.index(trx)
|
|
121
|
+
: await this.adapter.index(trx);
|
|
122
|
+
}
|
|
123
|
+
// Encryption
|
|
124
|
+
if (this.schema.model.hasEncryptedField) {
|
|
125
|
+
for (const raw of raws) {
|
|
126
|
+
this.decrypt(trx, raw);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
48
129
|
return raws;
|
|
49
130
|
}
|
|
50
|
-
|
|
131
|
+
/**
|
|
132
|
+
* Read an entity's view by `id`
|
|
133
|
+
*
|
|
134
|
+
* - Options:
|
|
135
|
+
* - `silent`: If not found, return `undefined` instead of throwing an exception
|
|
136
|
+
* - `no_tenancy`: Don't apply tenancy rules.
|
|
137
|
+
*/
|
|
138
|
+
async viewOne(trx, id, view, options) {
|
|
139
|
+
log_1.Log.debug('bucket', this.schema.name, `View id=${id}, v=${view}`);
|
|
140
|
+
// Read
|
|
141
|
+
const raw = await this.readOne(trx, id, options);
|
|
142
|
+
if (!raw) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
// Build
|
|
146
|
+
return this.buildOne(trx, raw, view);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Read a view of all entities
|
|
150
|
+
*
|
|
151
|
+
* - Options:
|
|
152
|
+
* - `no_tenancy`: Don't apply tenancy rules.
|
|
153
|
+
*/
|
|
154
|
+
async viewAll(trx, view, options) {
|
|
155
|
+
log_1.Log.debug('bucket', this.schema.name, `View all, v=${view}`);
|
|
156
|
+
// Read
|
|
157
|
+
const raws = await this.readAll(trx, options);
|
|
158
|
+
// Build
|
|
159
|
+
return this.buildMany(trx, raws, view);
|
|
160
|
+
}
|
|
161
|
+
// Graph
|
|
162
|
+
/**
|
|
163
|
+
* Read raw entity of a graph link
|
|
164
|
+
*
|
|
165
|
+
* - Options:
|
|
166
|
+
* - `silent`: If not found, return `undefined` instead of throwing an exception
|
|
167
|
+
* - `no_tenancy`: Don't apply tenancy rules.
|
|
168
|
+
*/
|
|
169
|
+
async readLink(trx, id, link, options) {
|
|
170
|
+
log_1.Log.debug('bucket', this.schema.name, `Read Link, id=${id} l=${link}`);
|
|
171
|
+
// Validate ID
|
|
51
172
|
if (typeof id !== 'string' && typeof id !== 'number') {
|
|
52
173
|
throw error_1.NesoiError.Bucket.InvalidId({ bucket: this.schema.alias, id });
|
|
53
174
|
}
|
|
54
|
-
|
|
175
|
+
// Read object
|
|
55
176
|
const obj = await this.readOne(trx, id);
|
|
177
|
+
// Empty response
|
|
56
178
|
if (!obj) {
|
|
57
|
-
|
|
179
|
+
const schema = this.schema.graph.links[link];
|
|
180
|
+
if (schema.many) {
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
return undefined;
|
|
58
184
|
}
|
|
59
|
-
|
|
185
|
+
// Read link
|
|
186
|
+
const linkObj = await this.graph.readLink(trx, obj, link, options);
|
|
187
|
+
// Encryption
|
|
188
|
+
if (linkObj) {
|
|
189
|
+
if (this.schema.model.hasEncryptedField) {
|
|
190
|
+
this.decrypt(trx, linkObj);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return linkObj;
|
|
60
194
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Read the view of an entity of a graph link
|
|
197
|
+
*
|
|
198
|
+
* - Options:
|
|
199
|
+
* - `silent`: If not found, return `undefined` instead of throwing an exception
|
|
200
|
+
* - `no_tenancy`: Don't apply tenancy rules.
|
|
201
|
+
*/
|
|
202
|
+
async viewLink(trx, id, link, view, options) {
|
|
203
|
+
log_1.Log.debug('bucket', this.schema.name, `View Link, id=${id} l=${link}`);
|
|
204
|
+
// Validate ID
|
|
205
|
+
if (typeof id !== 'string' && typeof id !== 'number') {
|
|
206
|
+
throw error_1.NesoiError.Bucket.InvalidId({ bucket: this.schema.alias, id });
|
|
207
|
+
}
|
|
208
|
+
// Read object
|
|
209
|
+
const obj = await this.readOne(trx, id);
|
|
210
|
+
// Empty response
|
|
211
|
+
if (!obj) {
|
|
212
|
+
const schema = this.schema.graph.links[link];
|
|
213
|
+
if (schema.many) {
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
// View link
|
|
219
|
+
const linkObj = await this.graph.viewLink(trx, obj, link, view, options);
|
|
220
|
+
// Encryption
|
|
221
|
+
if (linkObj && this.schema.model.hasEncryptedField) {
|
|
222
|
+
if (Array.isArray(linkObj)) {
|
|
223
|
+
for (const obj of linkObj)
|
|
224
|
+
this.decrypt(trx, obj);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
this.decrypt(trx, linkObj);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return linkObj;
|
|
65
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Return true if the graph link refers to at least one object
|
|
234
|
+
*
|
|
235
|
+
* - Options:
|
|
236
|
+
* - `no_tenancy`: Don't apply tenancy rules.
|
|
237
|
+
*/
|
|
238
|
+
async hasLink(trx, id, link, options) {
|
|
239
|
+
log_1.Log.debug('bucket', this.schema.name, `Has Link, id=${id} l=${link}`);
|
|
240
|
+
// Read Object
|
|
241
|
+
const obj = await this.readOne(trx, id);
|
|
242
|
+
if (!obj) {
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
// Check Link
|
|
246
|
+
return this.graph.hasLink(trx, link, obj, options);
|
|
247
|
+
}
|
|
248
|
+
// Build
|
|
249
|
+
/**
|
|
250
|
+
* Build one object with a view
|
|
251
|
+
*/
|
|
66
252
|
async buildOne(trx, obj, view) {
|
|
67
253
|
if (!(view in this.views)) {
|
|
68
254
|
throw error_1.NesoiError.Bucket.ViewNotFound({ bucket: this.schema.alias, view: view });
|
|
69
255
|
}
|
|
70
256
|
return this.views[view].parse(trx, obj);
|
|
71
257
|
}
|
|
72
|
-
|
|
258
|
+
/**
|
|
259
|
+
* Build a list ob objects with a view
|
|
260
|
+
*/
|
|
261
|
+
async buildMany(trx, objs, view) {
|
|
73
262
|
return Promise.all(objs.map(obj => this.buildOne(trx, obj, view)));
|
|
74
263
|
}
|
|
75
|
-
//
|
|
264
|
+
// Create
|
|
265
|
+
/**
|
|
266
|
+
* Create an entity
|
|
267
|
+
*/
|
|
268
|
+
async create(trx, obj) {
|
|
269
|
+
var _a, _b;
|
|
270
|
+
log_1.Log.debug('bucket', this.schema.name, `Create id=${obj['id'] || 'new'}`, obj);
|
|
271
|
+
// Separate composition
|
|
272
|
+
let composition = obj['#composition'];
|
|
273
|
+
delete obj['#composition'];
|
|
274
|
+
// Add meta (created_by/created_at/updated_by/updated_at)
|
|
275
|
+
this.addMeta(trx, obj, 'create');
|
|
276
|
+
// Encryption
|
|
277
|
+
if (this.schema.model.hasEncryptedField) {
|
|
278
|
+
this.encrypt(trx, obj);
|
|
279
|
+
}
|
|
280
|
+
// Drive
|
|
281
|
+
if (this.schema.model.hasFileField) {
|
|
282
|
+
await this.copyFilesToDrive(obj);
|
|
283
|
+
}
|
|
284
|
+
// Create
|
|
285
|
+
const input = Object.assign({}, this.schema.model.defaults, obj);
|
|
286
|
+
const _obj = await this.adapter.create(trx, input);
|
|
287
|
+
// Composition
|
|
288
|
+
if (composition) {
|
|
289
|
+
this.replaceFutureId(composition, _obj.id);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
composition = {};
|
|
293
|
+
}
|
|
294
|
+
// Create composition
|
|
295
|
+
for (const link of Object.values(this.schema.graph.links)) {
|
|
296
|
+
if (link.rel !== 'composition')
|
|
297
|
+
continue;
|
|
298
|
+
const linkObj = composition[link.name];
|
|
299
|
+
if (!linkObj) {
|
|
300
|
+
throw error_1.NesoiError.Bucket.MissingComposition({ method: 'create', bucket: this.schema.name, link: link.name });
|
|
301
|
+
}
|
|
302
|
+
if (link.many) {
|
|
303
|
+
if (!Array.isArray(linkObj)) {
|
|
304
|
+
throw error_1.NesoiError.Bucket.CompositionValueShouldBeArray({ method: 'create', bucket: this.schema.name, link: link.name });
|
|
305
|
+
}
|
|
306
|
+
_obj['#composition'] ?? (_obj['#composition'] = {});
|
|
307
|
+
(_a = _obj['#composition'])[_b = link.name] ?? (_a[_b] = []);
|
|
308
|
+
for (const linkObjItem of linkObj) {
|
|
309
|
+
const child = await trx.bucket(link.bucket.refName).create(linkObjItem);
|
|
310
|
+
_obj['#composition'][link.name].push(child);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
const child = await trx.bucket(link.bucket.refName).create(linkObj);
|
|
315
|
+
_obj['#composition'] ?? (_obj['#composition'] = {});
|
|
316
|
+
_obj['#composition'][link.name] = child;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return _obj;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Replace the `$id` symbol on an object with the proper ID value.
|
|
323
|
+
* This is used on composition, to access the ID of the parent.
|
|
324
|
+
*/
|
|
325
|
+
replaceFutureId(composition, value) {
|
|
326
|
+
let poll = [composition];
|
|
327
|
+
while (poll.length) {
|
|
328
|
+
const next = [];
|
|
329
|
+
for (const obj of poll) {
|
|
330
|
+
if (Array.isArray(obj)) {
|
|
331
|
+
for (let i = 0; i < obj.length; i++) {
|
|
332
|
+
if (typeof obj[i] === 'symbol' && obj[i] == exports.$id) {
|
|
333
|
+
obj[i] = value;
|
|
334
|
+
}
|
|
335
|
+
else if (typeof obj[i] === 'object') {
|
|
336
|
+
next.push(obj[i]);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
for (const key in obj) {
|
|
342
|
+
if (typeof obj[key] === 'symbol' && obj[key] == exports.$id) {
|
|
343
|
+
obj[key] = value;
|
|
344
|
+
}
|
|
345
|
+
else if (typeof obj[key] === 'object') {
|
|
346
|
+
next.push(obj[key]);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
poll = next;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// Update
|
|
355
|
+
/**
|
|
356
|
+
* Update an entity
|
|
357
|
+
*
|
|
358
|
+
* - Options:
|
|
359
|
+
* - `mode`: Type of update to perform (default: `patch`)
|
|
360
|
+
* - `patch`: Only modifies properties that changed
|
|
361
|
+
* - `replace`: Replace the whole object
|
|
362
|
+
* - `no_tenancy`: Don't apply tenancy rules (default: `false`)
|
|
363
|
+
* - `unsafe`:
|
|
364
|
+
* - Don't attempt to read the object before updating. This option is faster, but can throw exceptions directly from the adapter (default: `false`)
|
|
365
|
+
* - **WARNING** Unsafe currently avoids the tenancy check
|
|
366
|
+
*/
|
|
367
|
+
async update(trx, obj, options) {
|
|
368
|
+
log_1.Log.debug('bucket', this.schema.name, `Update id=${obj['id']}`, obj);
|
|
369
|
+
// Separate composition
|
|
370
|
+
const composition = obj['#composition'] || {};
|
|
371
|
+
delete obj['#composition'];
|
|
372
|
+
// Tenancy
|
|
373
|
+
const tenancy = (options?.no_tenancy)
|
|
374
|
+
? undefined
|
|
375
|
+
: this.getTenancyQuery(trx);
|
|
376
|
+
// Read old object, if safe, to check if it exists
|
|
377
|
+
let oldObj;
|
|
378
|
+
if (!options?.unsafe) {
|
|
379
|
+
// With Tenancy
|
|
380
|
+
if (tenancy) {
|
|
381
|
+
const result = await this.adapter.query(trx, {
|
|
382
|
+
id: obj.id,
|
|
383
|
+
'#and': tenancy
|
|
384
|
+
}, { perPage: 1 }, undefined, {
|
|
385
|
+
metadataOnly: true
|
|
386
|
+
});
|
|
387
|
+
oldObj = result.data[0];
|
|
388
|
+
}
|
|
389
|
+
// Without Tenancy
|
|
390
|
+
else {
|
|
391
|
+
oldObj = this.cache
|
|
392
|
+
? await this.cache.get(trx, obj['id'])
|
|
393
|
+
: await this.adapter.get(trx, obj['id']);
|
|
394
|
+
}
|
|
395
|
+
// Empty response
|
|
396
|
+
if (!oldObj) {
|
|
397
|
+
throw error_1.NesoiError.Bucket.ObjNotFound({ bucket: this.schema.alias, id: obj['id'] });
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// Add meta (updated_by/updated_at)
|
|
401
|
+
this.addMeta(trx, obj, 'update');
|
|
402
|
+
// Encryption
|
|
403
|
+
if (this.schema.model.hasEncryptedField) {
|
|
404
|
+
this.encrypt(trx, obj);
|
|
405
|
+
}
|
|
406
|
+
// Drive
|
|
407
|
+
if (this.schema.model.hasFileField) {
|
|
408
|
+
await this.copyFilesToDrive(obj);
|
|
409
|
+
}
|
|
410
|
+
// Patch/Replace
|
|
411
|
+
const mode = options?.mode || 'patch';
|
|
412
|
+
const _obj = await this.adapter[mode](trx, obj);
|
|
413
|
+
// Composition
|
|
414
|
+
for (const link of Object.values(this.schema.graph.links)) {
|
|
415
|
+
if (link.rel !== 'composition')
|
|
416
|
+
continue;
|
|
417
|
+
const linkObj = composition[link.name];
|
|
418
|
+
if (!linkObj) {
|
|
419
|
+
throw error_1.NesoiError.Bucket.MissingComposition({ method: 'patch', bucket: this.schema.name, link: link.name });
|
|
420
|
+
}
|
|
421
|
+
if (link.many) {
|
|
422
|
+
if (!Array.isArray(linkObj)) {
|
|
423
|
+
throw error_1.NesoiError.Bucket.CompositionValueShouldBeArray({ method: 'patch', bucket: this.schema.name, link: link.name });
|
|
424
|
+
}
|
|
425
|
+
for (const linkObjItem of linkObj) {
|
|
426
|
+
await trx.bucket(link.bucket.refName)[mode](linkObjItem);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
await trx.bucket(link.bucket.refName)[mode](linkObj);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return _obj;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Create or Replace an entity
|
|
437
|
+
*
|
|
438
|
+
* **WARNING** Tenancy not checked
|
|
439
|
+
*/
|
|
76
440
|
async put(trx, obj) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
441
|
+
var _a, _b;
|
|
442
|
+
log_1.Log.debug('bucket', this.schema.name, `Put id=${obj['id']}`, obj);
|
|
443
|
+
// Separate composition
|
|
444
|
+
const composition = obj['#composition'] || {};
|
|
445
|
+
delete obj['#composition'];
|
|
446
|
+
// Add meta (updated_by/updated_at)
|
|
447
|
+
this.addMeta(trx, obj, 'update');
|
|
448
|
+
// Encryption
|
|
449
|
+
if (this.schema.model.hasEncryptedField) {
|
|
450
|
+
this.encrypt(trx, obj);
|
|
451
|
+
}
|
|
452
|
+
// Drive
|
|
453
|
+
if (this.schema.model.hasFileField) {
|
|
454
|
+
await this.copyFilesToDrive(obj);
|
|
455
|
+
}
|
|
456
|
+
// Put
|
|
457
|
+
const _obj = await this.adapter.put(trx, obj);
|
|
458
|
+
// Composition
|
|
459
|
+
for (const link of Object.values(this.schema.graph.links)) {
|
|
460
|
+
if (link.rel !== 'composition')
|
|
461
|
+
continue;
|
|
462
|
+
const linkObj = composition[link.name];
|
|
463
|
+
if (!linkObj) {
|
|
464
|
+
throw error_1.NesoiError.Bucket.MissingComposition({ method: 'replace', bucket: this.schema.name, link: link.name });
|
|
465
|
+
}
|
|
466
|
+
if (link.many) {
|
|
467
|
+
if (!Array.isArray(linkObj)) {
|
|
468
|
+
throw error_1.NesoiError.Bucket.CompositionValueShouldBeArray({ method: 'replace', bucket: this.schema.name, link: link.name });
|
|
469
|
+
}
|
|
470
|
+
_obj['#composition'] ?? (_obj['#composition'] = {});
|
|
471
|
+
(_a = _obj['#composition'])[_b = link.name] ?? (_a[_b] = []);
|
|
472
|
+
for (const linkObjItem of linkObj) {
|
|
473
|
+
const child = await trx.bucket(link.bucket.refName).put(linkObjItem);
|
|
474
|
+
_obj['#composition'][link.name].push(child);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
const child = await trx.bucket(link.bucket.refName).put(linkObj);
|
|
479
|
+
_obj['#composition'] ?? (_obj['#composition'] = {});
|
|
480
|
+
_obj['#composition'][link.name] = child;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return _obj;
|
|
80
484
|
}
|
|
81
485
|
// Delete
|
|
82
|
-
|
|
486
|
+
/**
|
|
487
|
+
* Delete an entity
|
|
488
|
+
*
|
|
489
|
+
* - Options:
|
|
490
|
+
* - `no_tenancy`: Don't apply tenancy rules (default: `false`)
|
|
491
|
+
* - `unsafe`
|
|
492
|
+
* - Don't attempt to read the object before updating. This option is faster, but can throw exceptions directly from the adapter (default: `false`)
|
|
493
|
+
* - **WARNING** Unsafe currently avoids the tenancy check
|
|
494
|
+
*/
|
|
495
|
+
async delete(trx, id, options) {
|
|
496
|
+
log_1.Log.debug('bucket', this.schema.name, `Delete id=${id}`);
|
|
497
|
+
// Validate ID
|
|
83
498
|
if (typeof id !== 'string' && typeof id !== 'number') {
|
|
84
499
|
throw error_1.NesoiError.Bucket.InvalidId({ bucket: this.schema.alias, id });
|
|
85
500
|
}
|
|
86
|
-
|
|
501
|
+
// Read object, if safe, to check if it exists
|
|
502
|
+
if (!options?.unsafe) {
|
|
503
|
+
// Tenancy
|
|
504
|
+
const tenancy = (options?.no_tenancy)
|
|
505
|
+
? undefined
|
|
506
|
+
: this.getTenancyQuery(trx);
|
|
507
|
+
// Check if object exists
|
|
508
|
+
const result = await this.adapter.query(trx, {
|
|
509
|
+
id, '#and': tenancy
|
|
510
|
+
}, { perPage: 1 }, undefined, {
|
|
511
|
+
metadataOnly: true
|
|
512
|
+
});
|
|
513
|
+
if (!result.data.length) {
|
|
514
|
+
throw error_1.NesoiError.Bucket.ObjNotFound({ bucket: this.schema.alias, id });
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
// Delete compositions (with other key)
|
|
518
|
+
for (const link of Object.values(this.schema.graph.links)) {
|
|
519
|
+
if (link.rel !== 'composition')
|
|
520
|
+
continue;
|
|
521
|
+
if (link.keyOwner !== 'other')
|
|
522
|
+
continue;
|
|
523
|
+
const linked = await this.readLink(trx, id, link.name, {
|
|
524
|
+
silent: true
|
|
525
|
+
});
|
|
526
|
+
if (!linked)
|
|
527
|
+
continue;
|
|
528
|
+
if (link.many) {
|
|
529
|
+
for (const linkedItem of linked) {
|
|
530
|
+
await trx.bucket(link.bucket.refName).delete(linkedItem.id);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
await trx.bucket(link.bucket.refName).delete(linked.id);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
// Delete the object itself
|
|
87
538
|
await this.adapter.delete(trx, id);
|
|
539
|
+
// Composition (with self key)
|
|
540
|
+
for (const link of Object.values(this.schema.graph.links)) {
|
|
541
|
+
if (link.rel !== 'composition')
|
|
542
|
+
continue;
|
|
543
|
+
if (link.keyOwner !== 'self')
|
|
544
|
+
continue;
|
|
545
|
+
const linked = await this.readLink(trx, id, link.name, {
|
|
546
|
+
silent: true
|
|
547
|
+
});
|
|
548
|
+
if (!linked)
|
|
549
|
+
continue;
|
|
550
|
+
if (link.many) {
|
|
551
|
+
await trx.bucket(link.bucket.refName).unsafe.deleteMany(linked.map((l) => l.id));
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
await trx.bucket(link.bucket.refName).delete(linked.id);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
88
557
|
}
|
|
89
|
-
|
|
558
|
+
/**
|
|
559
|
+
* Delete many entities
|
|
560
|
+
*
|
|
561
|
+
* - Options:
|
|
562
|
+
* - `no_tenancy`: Don't apply tenancy rules (default: `false`)
|
|
563
|
+
* - `unsafe`
|
|
564
|
+
* - Don't attempt to read the object before updating. This option is faster, but can throw exceptions directly from the adapter (default: `false`)
|
|
565
|
+
* - **WARNING** Unsafe currently avoids the tenancy check
|
|
566
|
+
*/
|
|
567
|
+
async deleteMany(trx, ids, options) {
|
|
90
568
|
log_1.Log.debug('bucket', this.schema.name, `Delete Many ids=${ids}`);
|
|
569
|
+
// Filter ids, if safe, to check if it exists
|
|
570
|
+
if (!options?.unsafe) {
|
|
571
|
+
// Tenancy
|
|
572
|
+
const tenancy = (options?.no_tenancy)
|
|
573
|
+
? undefined
|
|
574
|
+
: this.getTenancyQuery(trx);
|
|
575
|
+
// Filter ids
|
|
576
|
+
const result = await this.adapter.query(trx, {
|
|
577
|
+
'id in': ids,
|
|
578
|
+
'#and': tenancy
|
|
579
|
+
}, undefined, undefined, {
|
|
580
|
+
metadataOnly: true
|
|
581
|
+
});
|
|
582
|
+
ids = result.data.map(obj => obj.id);
|
|
583
|
+
}
|
|
584
|
+
// Composition (with other key)
|
|
585
|
+
for (const link of Object.values(this.schema.graph.links)) {
|
|
586
|
+
if (link.rel !== 'composition')
|
|
587
|
+
continue;
|
|
588
|
+
if (link.keyOwner !== 'other')
|
|
589
|
+
continue;
|
|
590
|
+
for (const id of ids) {
|
|
591
|
+
const linked = await this.readLink(trx, id, link.name, { silent: true });
|
|
592
|
+
if (!linked)
|
|
593
|
+
continue;
|
|
594
|
+
if (link.many) {
|
|
595
|
+
await trx.bucket(link.bucket.refName).unsafe.deleteMany(linked.map((l) => l.id));
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
await trx.bucket(link.bucket.refName).unsafe.delete(linked.id);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
91
602
|
await this.adapter.deleteMany(trx, ids);
|
|
603
|
+
// Composition (with self key)
|
|
604
|
+
for (const link of Object.values(this.schema.graph.links)) {
|
|
605
|
+
if (link.rel !== 'composition')
|
|
606
|
+
continue;
|
|
607
|
+
if (link.keyOwner !== 'self')
|
|
608
|
+
continue;
|
|
609
|
+
for (const id of ids) {
|
|
610
|
+
const linked = await this.readLink(trx, id, link.name, { silent: true });
|
|
611
|
+
if (!linked)
|
|
612
|
+
continue;
|
|
613
|
+
if (link.many) {
|
|
614
|
+
await trx.bucket(link.bucket.refName).unsafe.deleteMany(linked.map((l) => l.id));
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
await trx.bucket(link.bucket.refName).unsafe.delete(linked.id);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
92
621
|
}
|
|
93
622
|
// Query
|
|
94
|
-
|
|
623
|
+
/**
|
|
624
|
+
* Query entities using NQL
|
|
625
|
+
*
|
|
626
|
+
* - Options:
|
|
627
|
+
* - `no_tenancy`: Don't apply tenancy rules (default: `false`)
|
|
628
|
+
* - `params`: NQL parameters
|
|
629
|
+
*/
|
|
630
|
+
async query(trx, query, pagination, view, options) {
|
|
95
631
|
log_1.Log.trace('bucket', this.schema.name, 'Query', query);
|
|
96
632
|
const v = (view ? this.views[view] : null) || this.views['default'];
|
|
97
633
|
if (!v) {
|
|
98
634
|
throw error_1.NesoiError.Bucket.Query.ViewNotFound(this.schema.name, view || 'default');
|
|
99
635
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
636
|
+
// Tenancy
|
|
637
|
+
const tenancy = (options?.no_tenancy)
|
|
638
|
+
? undefined
|
|
639
|
+
: this.getTenancyQuery(trx);
|
|
640
|
+
query = {
|
|
641
|
+
...query,
|
|
642
|
+
'#and': tenancy
|
|
643
|
+
};
|
|
644
|
+
// Query
|
|
645
|
+
const result = await this.adapter.query(trx, query, pagination, options?.params);
|
|
646
|
+
if (!result.data.length)
|
|
647
|
+
return {
|
|
648
|
+
data: []
|
|
649
|
+
};
|
|
650
|
+
// Encryption
|
|
651
|
+
if (this.schema.model.hasEncryptedField) {
|
|
652
|
+
for (const obj of result.data) {
|
|
653
|
+
this.decrypt(trx, obj);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
// Build
|
|
105
657
|
if (view) {
|
|
106
|
-
|
|
658
|
+
result.data = await this.buildMany(trx, result.data, view);
|
|
107
659
|
}
|
|
108
|
-
|
|
109
|
-
|
|
660
|
+
return result;
|
|
661
|
+
}
|
|
662
|
+
// Metadata
|
|
663
|
+
/**
|
|
664
|
+
* Add `created_by`, `created_at`, `updated_by` and `updated_at` fields to object
|
|
665
|
+
*/
|
|
666
|
+
addMeta(trx, obj, operation) {
|
|
667
|
+
const match = trx_node_1.TrxNode.getFirstUserMatch(trx, this.schema.tenancy);
|
|
668
|
+
if (operation === 'create') {
|
|
669
|
+
obj[this.adapter.config.meta.created_at] = datetime_1.NesoiDatetime.now();
|
|
670
|
+
if (match) {
|
|
671
|
+
obj[this.adapter.config.meta.created_by] = match.user.id;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
obj[this.adapter.config.meta.updated_at] = datetime_1.NesoiDatetime.now();
|
|
675
|
+
if (match) {
|
|
676
|
+
obj[this.adapter.config.meta.updated_by] = match.user.id;
|
|
110
677
|
}
|
|
111
678
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
679
|
+
// Tenancy
|
|
680
|
+
getTenancyQuery(trx) {
|
|
681
|
+
if (!this.schema.tenancy)
|
|
682
|
+
return;
|
|
683
|
+
const match = trx_node_1.TrxNode.getFirstUserMatch(trx, this.schema.tenancy);
|
|
684
|
+
return this.schema.tenancy[match.provider]?.(match.user);
|
|
117
685
|
}
|
|
118
|
-
|
|
119
|
-
|
|
686
|
+
// Encryption
|
|
687
|
+
encrypt(trx, obj, fields = this.schema.model.fields) {
|
|
688
|
+
for (const key in fields) {
|
|
689
|
+
const field = fields[key];
|
|
690
|
+
if (field.crypto) {
|
|
691
|
+
const key = trx.value(field.crypto.key);
|
|
692
|
+
tree_1.Tree.set(obj, field.path, val => crypto_1.Crypto.encrypt(val, key));
|
|
693
|
+
}
|
|
694
|
+
if (field.children) {
|
|
695
|
+
this.encrypt(trx, obj, field.children);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
120
698
|
}
|
|
121
|
-
|
|
122
|
-
|
|
699
|
+
decrypt(trx, obj, fields = this.schema.model.fields) {
|
|
700
|
+
for (const key in fields) {
|
|
701
|
+
const field = fields[key];
|
|
702
|
+
if (field.crypto) {
|
|
703
|
+
const key = trx.value(field.crypto.key);
|
|
704
|
+
tree_1.Tree.set(obj, field.path, val => crypto_1.Crypto.decrypt(val, key));
|
|
705
|
+
}
|
|
706
|
+
if (field.children) {
|
|
707
|
+
this.decrypt(trx, obj, field.children);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
// Drive (Files)
|
|
712
|
+
/**
|
|
713
|
+
* Copy all files from the object to the bucket's Drive
|
|
714
|
+
* - Call `drive.copy` to send the files preserving the local copy
|
|
715
|
+
* - Replace the file on the object with a new one representing the remote
|
|
716
|
+
*/
|
|
717
|
+
async copyFilesToDrive(obj) {
|
|
718
|
+
if (!this.drive) {
|
|
719
|
+
throw error_1.NesoiError.Bucket.Drive.NoAdapter({ bucket: this.schema.alias });
|
|
720
|
+
}
|
|
721
|
+
const fields = bucket_model_schema_1.$BucketModel.fieldsOfType(this.schema.model, 'file');
|
|
722
|
+
for (const field of fields) {
|
|
723
|
+
if (field.array) {
|
|
724
|
+
const files = tree_1.Tree.get(obj, field.path);
|
|
725
|
+
const remoteFiles = [];
|
|
726
|
+
for (const file of files) {
|
|
727
|
+
remoteFiles.push(await this.drive.copy(file, this.drive.dirpath));
|
|
728
|
+
}
|
|
729
|
+
tree_1.Tree.set(obj, field.path, () => remoteFiles);
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
const file = tree_1.Tree.get(obj, field.path);
|
|
733
|
+
const remoteFile = await this.drive.copy(file, this.drive.dirpath);
|
|
734
|
+
tree_1.Tree.set(obj, field.path, () => remoteFile);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
123
737
|
}
|
|
124
738
|
}
|
|
125
739
|
exports.Bucket = Bucket;
|