nesoi 3.4.1 → 3.4.3

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.
Files changed (40) hide show
  1. package/lib/compiler/typescript/bridge/extract.js +1 -1
  2. package/lib/compiler/typescript/bridge/organize.js +3 -3
  3. package/lib/elements/blocks/job/internal/resource_job.schema.d.ts +1 -0
  4. package/lib/elements/blocks/resource/resource.builder.js +2 -2
  5. package/lib/elements/blocks/resource/resource_query.builder.d.ts +3 -0
  6. package/lib/elements/blocks/resource/resource_query.builder.js +7 -1
  7. package/lib/elements/entities/bucket/adapters/bucket_adapter.d.ts +5 -3
  8. package/lib/elements/entities/bucket/adapters/bucket_adapter.js +3 -3
  9. package/lib/elements/entities/bucket/adapters/memory.bucket_adapter.d.ts +2 -2
  10. package/lib/elements/entities/bucket/adapters/memory.bucket_adapter.js +5 -5
  11. package/lib/elements/entities/bucket/adapters/memory.nql.d.ts +3 -1
  12. package/lib/elements/entities/bucket/adapters/memory.nql.js +14 -5
  13. package/lib/elements/entities/bucket/adapters/rest.nql.d.ts +1 -1
  14. package/lib/elements/entities/bucket/adapters/rest.nql.js +1 -1
  15. package/lib/elements/entities/bucket/bucket.d.ts +12 -0
  16. package/lib/elements/entities/bucket/bucket.js +23 -4
  17. package/lib/elements/entities/bucket/cache/bucket_cache.d.ts +4 -2
  18. package/lib/elements/entities/bucket/cache/bucket_cache.js +7 -3
  19. package/lib/elements/entities/bucket/graph/bucket_graph.d.ts +10 -1
  20. package/lib/elements/entities/bucket/graph/bucket_graph.js +50 -4
  21. package/lib/elements/entities/bucket/model/bucket_model.d.ts +8 -2
  22. package/lib/elements/entities/bucket/model/bucket_model.js +276 -275
  23. package/lib/elements/entities/bucket/query/nql_engine.d.ts +2 -2
  24. package/lib/elements/entities/bucket/query/nql_engine.js +2 -2
  25. package/lib/elements/entities/bucket/view/bucket_view.js +47 -8
  26. package/lib/elements/entities/bucket/view/bucket_view_field.builder.d.ts +1 -0
  27. package/lib/elements/entities/bucket/view/bucket_view_field.builder.js +8 -0
  28. package/lib/engine/data/error.d.ts +4 -0
  29. package/lib/engine/data/error.js +4 -0
  30. package/lib/engine/transaction/nodes/bucket.trx_node.d.ts +5 -1
  31. package/lib/engine/transaction/nodes/bucket.trx_node.js +8 -0
  32. package/lib/engine/transaction/nodes/bucket_query.trx_node.d.ts +4 -0
  33. package/lib/engine/transaction/nodes/bucket_query.trx_node.js +22 -0
  34. package/lib/engine/transaction/trx_engine.d.ts +2 -2
  35. package/lib/engine/transaction/trx_engine.js +14 -13
  36. package/lib/engine/util/parse.d.ts +0 -7
  37. package/package.json +1 -1
  38. package/tools/joaquin/bucket.d.ts +4 -0
  39. package/tools/joaquin/bucket.js +13 -0
  40. package/tsconfig.build.tsbuildinfo +1 -1
@@ -6,6 +6,8 @@ const date_1 = require("../../../../engine/data/date");
6
6
  const datetime_1 = require("../../../../engine/data/datetime");
7
7
  const decimal_1 = require("../../../../engine/data/decimal");
8
8
  const duration_1 = require("../../../../engine/data/duration");
9
+ const log_1 = require("../../../../engine/util/log");
10
+ const parse_1 = require("../../../../engine/util/parse");
9
11
  /**
10
12
  * @category Elements
11
13
  * @subcategory Entity
@@ -19,7 +21,7 @@ class BucketModel {
19
21
  this.alias = bucket.alias;
20
22
  this.schema = bucket.model;
21
23
  }
22
- copy(obj, op, serialize, modelpath) {
24
+ copy(obj, op, serialize, modelpath_or_roots) {
23
25
  const meta = this.config?.meta || {
24
26
  created_at: 'created_at',
25
27
  created_by: 'created_by',
@@ -28,11 +30,12 @@ class BucketModel {
28
30
  };
29
31
  const copy = {};
30
32
  const modelpath_results = [];
31
- const paths = modelpath?.split('.');
32
- let poll = paths
33
+ const roots = Array.isArray(modelpath_or_roots) ? modelpath_or_roots : undefined;
34
+ const paths = Array.isArray(modelpath_or_roots) ? undefined : modelpath_or_roots?.split('.');
35
+ const poll = paths
33
36
  // Specific modelpath requested, start with root field only
34
37
  ? [{
35
- path: paths[0],
38
+ key: paths[0],
36
39
  obj,
37
40
  copy,
38
41
  field: this.schema.fields[paths[0]],
@@ -40,300 +43,298 @@ class BucketModel {
40
43
  modelpath: { i: 0, asterisk_values: [] }
41
44
  }]
42
45
  // No modelpath, use all fields
43
- : Object.entries(this.schema.fields).map(([path, field]) => ({
44
- path, obj, copy, field, depth: 0
46
+ : Object.entries(this.schema.fields)
47
+ .filter(([_, field]) => !roots || roots.includes(field.path))
48
+ .map(([path, field]) => ({
49
+ key: path,
50
+ obj,
51
+ copy,
52
+ field,
53
+ depth: 0
45
54
  }));
55
+ modelpath_results.push(...this.runCopyCmdPoll(op, poll, paths, serialize));
56
+ copy[meta.created_by] = obj[meta.created_by];
57
+ copy[meta.updated_by] = obj[meta.updated_by];
58
+ const meta_as_json = serialize?.();
59
+ const created_at = obj[meta.created_at];
60
+ if (typeof created_at === 'string') {
61
+ copy[meta.created_at] = meta_as_json ? created_at : datetime_1.NesoiDatetime.fromISO(obj[created_at]);
62
+ }
63
+ else if (created_at instanceof datetime_1.NesoiDatetime) {
64
+ copy[meta.created_at] = meta_as_json ? created_at.toISO() : created_at;
65
+ }
66
+ const updated_at = obj[meta.updated_at];
67
+ if (typeof updated_at === 'string') {
68
+ copy[meta.updated_at] = meta_as_json ? updated_at : datetime_1.NesoiDatetime.fromISO(obj[updated_at]);
69
+ }
70
+ else if (updated_at instanceof datetime_1.NesoiDatetime) {
71
+ copy[meta.updated_at] = meta_as_json ? updated_at.toISO() : updated_at;
72
+ }
73
+ if (paths)
74
+ return modelpath_results;
75
+ return copy;
76
+ }
77
+ runCopyCmdPoll(op, poll, modelpath, serialize) {
78
+ const modelpath_results = [];
46
79
  while (poll.length) {
47
80
  const next = [];
48
- for (const entry of poll) {
49
- if (entry.is_union_option) {
50
- const alreadyParsed = entry.copy[entry.path] !== undefined;
51
- if (alreadyParsed)
52
- continue;
53
- }
54
- const val = entry.obj[entry.path];
55
- if (val === undefined) {
56
- delete entry.copy[entry.path];
57
- continue;
58
- }
59
- if (val === null) {
60
- delete entry.copy[entry.path];
61
- continue;
62
- }
63
- const isLeafPath = entry.modelpath
64
- ? entry.modelpath.i === (paths?.length ?? 0) - 1
81
+ for (const cmd of poll) {
82
+ const isLeafPath = cmd.modelpath
83
+ ? cmd.modelpath.i === (modelpath?.length ?? 0) - 1
65
84
  : false;
66
- const nextPath = (!entry.modelpath || isLeafPath)
67
- ? undefined
68
- : paths[entry.modelpath.i + 1];
69
- const addChildrenToQueue = !entry.modelpath
70
- || entry.modelpath.i >= (paths.length - 1)
71
- || nextPath === '*';
72
- if (entry.field.type === 'list') {
73
- if (!Array.isArray(val))
74
- continue;
75
- entry.copy[entry.path] = [];
76
- // Leaf path or no modelpath = add entire list to queue
77
- if (addChildrenToQueue) {
78
- next.push(...val.map((_, i) => ({
79
- path: i.toString(),
80
- obj: val,
81
- copy: entry.copy[entry.path],
82
- field: entry.field.children['#'],
83
- depth: entry.depth + 1,
84
- modelpath: entry.modelpath ? {
85
- i: entry.modelpath.i + 1,
86
- asterisk_values: [...entry.modelpath.asterisk_values, ...(nextPath === '*' ? [i.toString()] : [])]
87
- } : undefined
88
- })));
89
- }
90
- // Branch path = add next path to queue
91
- else {
92
- next.push({
93
- path: nextPath,
94
- obj: val,
95
- copy: entry.copy[entry.path],
96
- field: entry.field.children['#'],
97
- depth: entry.depth + 1,
98
- modelpath: entry.modelpath ? {
99
- i: entry.modelpath.i + 1,
100
- asterisk_values: entry.modelpath.asterisk_values
101
- } : undefined
102
- });
103
- }
104
- }
105
- else if (entry.field.type === 'dict') {
106
- if (typeof val !== 'object' || Array.isArray(val))
107
- continue;
108
- entry.copy[entry.path] = {};
109
- // Leaf path or no modelpath = add entire dict to queue
110
- if (addChildrenToQueue) {
111
- next.push(...Object.keys(val).map((path) => ({
112
- path,
113
- obj: val,
114
- copy: entry.copy[entry.path],
115
- field: entry.field.children['#'],
116
- depth: entry.depth + 1,
117
- modelpath: entry.modelpath ? {
118
- i: entry.modelpath.i + 1,
119
- asterisk_values: [...entry.modelpath.asterisk_values, ...(nextPath === '*' ? [path] : [])]
120
- } : undefined
121
- })));
122
- }
123
- // Branch path = add next path to queue
124
- else {
125
- next.push({
126
- path: nextPath,
127
- obj: val,
128
- copy: entry.copy[entry.path],
129
- field: entry.field.children['#'],
130
- depth: entry.depth + 1,
131
- modelpath: entry.modelpath ? {
132
- i: entry.modelpath.i + 1,
133
- asterisk_values: entry.modelpath.asterisk_values
134
- } : undefined
135
- });
136
- }
137
- }
138
- else if (entry.field.type === 'obj') {
139
- if (typeof val !== 'object' || Array.isArray(val))
140
- continue;
141
- // disambiguate between dict and obj when obj comes first
142
- // on a union
143
- const objectHasValidFields = Object.keys(val).some(key => key in entry.field.children);
144
- if (!objectHasValidFields)
145
- continue;
146
- entry.copy[entry.path] = {};
147
- // Leaf path or no modelpath = add entire dict to queue
148
- if (addChildrenToQueue) {
149
- next.push(...Object.keys(entry.field.children).map(path => ({
150
- path: path,
151
- obj: val,
152
- copy: entry.copy[entry.path],
153
- field: entry.field.children[path],
154
- depth: entry.depth + 1,
155
- modelpath: entry.modelpath ? {
156
- i: entry.modelpath.i + 1,
157
- asterisk_values: [...entry.modelpath.asterisk_values, ...(nextPath === '*' ? [path] : [])]
158
- } : undefined
159
- })));
160
- }
161
- // Branch path = add next path to queue
162
- else {
163
- next.push({
164
- path: nextPath,
165
- obj: val,
166
- copy: entry.copy[entry.path],
167
- field: entry.field.children[nextPath],
168
- depth: entry.depth + 1,
169
- modelpath: entry.modelpath ? {
170
- i: entry.modelpath.i + 1,
171
- asterisk_values: entry.modelpath.asterisk_values
172
- } : undefined
173
- });
174
- }
175
- }
176
- else if (entry.field.type === 'union') {
177
- const options = Object.entries(entry.field.children);
178
- // Add union options to queue with flag
179
- // This flag avoids reparsing a value if an earlier option already did it
180
- next.push(...options.map(([_, option], i) => ({
181
- ...entry,
182
- field: option,
183
- is_union_option: i === options.length - 1 ? 'last' : true
184
- })));
185
- continue;
186
- }
187
- else if (entry.field.type === 'enum') {
188
- const v = entry.obj[entry.path];
189
- const options = entry.field.meta.enum.options;
190
- if (!(v in options)) {
191
- if (entry.is_union_option !== true) {
192
- throw error_1.NesoiError.Bucket.Model.InvalidEnum({ bucket: this.alias, value: v, options: Object.keys(options) });
193
- }
194
- }
195
- entry.copy[entry.path] = entry.obj[entry.path];
196
- }
197
- else if (entry.field.type === 'date') {
198
- const v = entry.obj[entry.path];
199
- if (serialize?.(entry)) {
200
- if (op === 'load') {
201
- try {
202
- entry.copy[entry.path] = date_1.NesoiDate.fromISO(v);
203
- }
204
- catch {
205
- if (entry.is_union_option !== true) {
206
- throw error_1.NesoiError.Bucket.Model.InvalidISODate({ bucket: this.alias, value: v });
207
- }
208
- continue;
209
- }
85
+ if (cmd.field.type === 'union') {
86
+ const options = Object.values(cmd.field.children);
87
+ let unionErrors = [];
88
+ for (const option of options) {
89
+ try {
90
+ // Clean field for next attempt
91
+ delete cmd.copy[cmd.key];
92
+ // Attempt union option
93
+ modelpath_results.push(...this.runCopyCmdPoll(op, [{
94
+ ...cmd,
95
+ field: option
96
+ }], modelpath, serialize));
97
+ // Success, clear errors and proceed
98
+ unionErrors = [];
99
+ break;
210
100
  }
211
- else if (op === 'save') {
212
- try {
213
- entry.copy[entry.path] = v.toISO();
214
- }
215
- catch {
216
- if (entry.is_union_option !== true) {
217
- throw error_1.NesoiError.Bucket.Model.InvalidNesoiDate({ bucket: this.alias, value: v });
218
- }
219
- continue;
220
- }
101
+ catch (e) {
102
+ unionErrors.push(e);
221
103
  }
222
104
  }
223
- else {
224
- entry.copy[entry.path] = entry.obj[entry.path];
225
- }
226
- }
227
- else if (entry.field.type === 'datetime') {
228
- const v = entry.obj[entry.path];
229
- if (serialize?.(entry)) {
230
- if (op === 'load') {
231
- try {
232
- entry.copy[entry.path] = datetime_1.NesoiDatetime.fromISO(v);
233
- }
234
- catch {
235
- if (entry.is_union_option !== true) {
236
- throw error_1.NesoiError.Bucket.Model.InvalidISODatetime({ bucket: this.alias, value: v });
237
- }
238
- continue;
239
- }
240
- }
241
- else if (op === 'save') {
242
- try {
243
- entry.copy[entry.path] = v.toISO();
244
- }
245
- catch {
246
- if (entry.is_union_option !== true) {
247
- throw error_1.NesoiError.Bucket.Model.InvalidNesoiDatetime({ bucket: this.alias, value: v });
248
- }
249
- continue;
250
- }
251
- }
252
- }
253
- else {
254
- entry.copy[entry.path] = entry.obj[entry.path];
255
- }
256
- }
257
- else if (entry.field.type === 'decimal') {
258
- const meta = entry.field.meta.decimal;
259
- const v = entry.obj[entry.path];
260
- if (serialize?.(entry)) {
261
- if ((op === 'load' && typeof v !== 'string') || (op === 'save' && !(v instanceof decimal_1.NesoiDecimal))) {
262
- if (entry.is_union_option !== true) {
263
- throw error_1.NesoiError.Bucket.Model.InvalidNesoiDecimal({ bucket: this.alias, value: v });
264
- }
265
- continue;
266
- }
267
- if (op === 'load')
268
- entry.copy[entry.path] = new decimal_1.NesoiDecimal(v, meta?.left, meta?.right);
269
- if (op === 'save')
270
- entry.copy[entry.path] = v.toString();
271
- }
272
- else {
273
- if (!(v instanceof decimal_1.NesoiDecimal)) {
274
- if (entry.is_union_option !== true) {
275
- throw error_1.NesoiError.Bucket.Model.InvalidNesoiDecimal({ bucket: this.alias, value: v });
276
- }
277
- continue;
278
- }
279
- entry.copy[entry.path] = v;
280
- }
281
- }
282
- else if (entry.field.type === 'duration') {
283
- const v = entry.obj[entry.path];
284
- if (serialize?.(entry)) {
285
- if ((op === 'load' && typeof v !== 'string') || (op === 'save' && !(v instanceof duration_1.NesoiDuration))) {
286
- if (entry.is_union_option !== true) {
287
- throw error_1.NesoiError.Bucket.Model.InvalidNesoiDuration({ bucket: this.alias, value: v });
288
- }
289
- continue;
290
- }
291
- if (op === 'load')
292
- entry.copy[entry.path] = duration_1.NesoiDuration.fromString(v);
293
- if (op === 'save')
294
- entry.copy[entry.path] = v.toString();
295
- }
296
- else {
297
- if (!(v instanceof duration_1.NesoiDuration)) {
298
- if (entry.is_union_option !== true) {
299
- throw error_1.NesoiError.Bucket.Model.InvalidNesoiDuration({ bucket: this.alias, value: v });
300
- }
301
- continue;
302
- }
303
- entry.copy[entry.path] = v;
105
+ if (unionErrors.length) {
106
+ throw error_1.NesoiError.Message.ValueDoesntMatchUnion({ alias: cmd.field.alias, path: '', value: cmd.obj[cmd.key], unionErrors });
304
107
  }
305
108
  }
306
109
  else {
307
- entry.copy[entry.path] = entry.obj[entry.path];
110
+ const as_json = serialize?.(cmd);
111
+ next.push(...this.runCopyCmd(op, cmd, modelpath, as_json));
308
112
  }
309
113
  if (isLeafPath) {
310
114
  modelpath_results.push({
311
- value: entry.copy[entry.path],
312
- index: entry.modelpath.asterisk_values
115
+ value: cmd.copy[cmd.key],
116
+ index: cmd.modelpath.asterisk_values
313
117
  });
314
118
  }
315
119
  }
316
120
  poll = next;
317
121
  }
318
- copy[meta.created_by] = obj[meta.created_by];
319
- copy[meta.updated_by] = obj[meta.updated_by];
320
- if (serialize?.()) {
321
- if (op === 'load') {
322
- copy[meta.created_at] = obj[meta.created_at] ? datetime_1.NesoiDatetime.fromISO(obj[meta.created_at]) : undefined;
323
- copy[meta.updated_at] = obj[meta.updated_at] ? datetime_1.NesoiDatetime.fromISO(obj[meta.updated_at]) : undefined;
122
+ return modelpath_results;
123
+ }
124
+ runCopyCmd(op, cmd, modelpath, as_json = false) {
125
+ const next = [];
126
+ const value = cmd.obj[cmd.key];
127
+ if (value === undefined || value === null) {
128
+ if (cmd.field.path !== 'id' && cmd.field.required) {
129
+ if (op === 'load') {
130
+ log_1.Log.warn('bucket.model', this.alias, `Object with id ${cmd.obj.id} missing required field '${cmd.field.path}' during read`);
131
+ }
132
+ else {
133
+ throw error_1.NesoiError.Bucket.Model.FieldRequired({ bucket: this.alias, field: cmd.field.alias });
134
+ }
135
+ }
136
+ delete cmd.copy[cmd.key];
137
+ return [];
138
+ }
139
+ const isLeafPath = cmd.modelpath
140
+ ? cmd.modelpath.i === (modelpath?.length ?? 0) - 1
141
+ : false;
142
+ const nextPath = (!cmd.modelpath || isLeafPath)
143
+ ? undefined
144
+ : modelpath[cmd.modelpath.i + 1];
145
+ const addChildrenToQueue = !cmd.modelpath
146
+ || cmd.modelpath.i >= (modelpath.length - 1) // is leaf or inner field
147
+ || nextPath === '*';
148
+ if (cmd.field.type === 'list') {
149
+ if (!Array.isArray(value)) {
150
+ throw error_1.NesoiError.Message.InvalidFieldType({ alias: cmd.field.alias, path: '', value, type: 'list' });
151
+ }
152
+ cmd.copy[cmd.key] = [];
153
+ // Leaf path or no modelpath = add entire list to queue
154
+ if (addChildrenToQueue) {
155
+ next.push(...value.map((_, i) => ({
156
+ key: i.toString(),
157
+ obj: value,
158
+ copy: cmd.copy[cmd.key],
159
+ field: cmd.field.children['#'],
160
+ depth: cmd.depth + 1,
161
+ modelpath: cmd.modelpath ? {
162
+ i: cmd.modelpath.i + 1,
163
+ asterisk_values: [...cmd.modelpath.asterisk_values, ...(nextPath === '*' ? [i.toString()] : [])]
164
+ } : undefined
165
+ })));
166
+ }
167
+ // Branch path = add next path to queue
168
+ else {
169
+ next.push({
170
+ key: nextPath,
171
+ obj: value,
172
+ copy: cmd.copy[cmd.key],
173
+ field: cmd.field.children['#'],
174
+ depth: cmd.depth + 1,
175
+ modelpath: cmd.modelpath ? {
176
+ i: cmd.modelpath.i + 1,
177
+ asterisk_values: cmd.modelpath.asterisk_values
178
+ } : undefined
179
+ });
180
+ }
181
+ return next;
182
+ }
183
+ else if (cmd.field.type === 'dict') {
184
+ if (typeof value !== 'object' || Array.isArray(value)) {
185
+ throw error_1.NesoiError.Message.InvalidFieldType({ alias: cmd.field.alias, path: '', value, type: 'dict' });
186
+ }
187
+ cmd.copy[cmd.key] = {};
188
+ // Leaf path or no modelpath = add entire dict to queue
189
+ if (addChildrenToQueue) {
190
+ next.push(...Object.keys(value).map((key) => ({
191
+ key,
192
+ obj: value,
193
+ copy: cmd.copy[cmd.key],
194
+ field: cmd.field.children['#'],
195
+ depth: cmd.depth + 1,
196
+ modelpath: cmd.modelpath ? {
197
+ i: cmd.modelpath.i + 1,
198
+ asterisk_values: [...cmd.modelpath.asterisk_values, ...(nextPath === '*' ? [key] : [])]
199
+ } : undefined
200
+ })));
201
+ }
202
+ // Branch path = add next path to queue
203
+ else if (nextPath in value) {
204
+ next.push({
205
+ key: nextPath,
206
+ obj: value,
207
+ copy: cmd.copy[cmd.key],
208
+ field: cmd.field.children['#'],
209
+ depth: cmd.depth + 1,
210
+ modelpath: cmd.modelpath ? {
211
+ i: cmd.modelpath.i + 1,
212
+ asterisk_values: cmd.modelpath.asterisk_values
213
+ } : undefined
214
+ });
215
+ }
216
+ return next;
217
+ }
218
+ else if (cmd.field.type === 'obj') {
219
+ if (typeof value !== 'object' || Array.isArray(value)) {
220
+ throw error_1.NesoiError.Message.InvalidFieldType({ alias: cmd.field.alias, path: '', value, type: 'obj' });
221
+ }
222
+ const missingKeys = Object.entries(cmd.field.children)
223
+ .filter(([_, child]) => child.required)
224
+ .some(([key]) => key !== 'id' && !(key in cmd.obj[cmd.key]));
225
+ if (missingKeys) {
226
+ throw new Error('Object missing keys');
227
+ }
228
+ cmd.copy[cmd.key] = {};
229
+ // Leaf path or no modelpath = add entire dict to queue
230
+ if (addChildrenToQueue) {
231
+ next.push(...Object.keys(cmd.field.children).map(path => ({
232
+ key: path,
233
+ obj: value,
234
+ copy: cmd.copy[cmd.key],
235
+ field: cmd.field.children[path],
236
+ depth: cmd.depth + 1,
237
+ modelpath: cmd.modelpath ? {
238
+ i: cmd.modelpath.i + 1,
239
+ asterisk_values: [...cmd.modelpath.asterisk_values, ...(nextPath === '*' ? [path] : [])]
240
+ } : undefined
241
+ })));
242
+ }
243
+ // Branch path = add next path to queue
244
+ else {
245
+ next.push({
246
+ key: nextPath,
247
+ obj: value,
248
+ copy: cmd.copy[cmd.key],
249
+ field: cmd.field.children[nextPath],
250
+ depth: cmd.depth + 1,
251
+ modelpath: cmd.modelpath ? {
252
+ i: cmd.modelpath.i + 1,
253
+ asterisk_values: cmd.modelpath.asterisk_values
254
+ } : undefined
255
+ });
256
+ }
257
+ return next;
258
+ }
259
+ else if (cmd.field.type === 'enum') {
260
+ if (typeof value !== 'string') {
261
+ throw error_1.NesoiError.Message.InvalidFieldType({ alias: cmd.field.alias, path: '', value, type: 'obj' });
262
+ }
263
+ const options = cmd.field.meta.enum.options;
264
+ if (!(value in options)) {
265
+ throw error_1.NesoiError.Bucket.Model.InvalidEnum({ bucket: this.alias, value, options: Object.keys(options) });
266
+ }
267
+ cmd.copy[cmd.key] = cmd.obj[cmd.key];
268
+ return [];
269
+ }
270
+ else if (cmd.field.type === 'date') {
271
+ if (value instanceof date_1.NesoiDate) {
272
+ cmd.copy[cmd.key] = as_json ? value.toISO() : value;
273
+ }
274
+ else if (typeof value === 'string') {
275
+ const date = date_1.NesoiDate.fromISO(value);
276
+ cmd.copy[cmd.key] = as_json ? date.toISO() : date;
277
+ }
278
+ else {
279
+ throw error_1.NesoiError.Message.InvalidFieldType({ alias: cmd.field.alias, path: '', value, type: 'date' });
280
+ }
281
+ }
282
+ else if (cmd.field.type === 'datetime') {
283
+ if (value instanceof datetime_1.NesoiDatetime) {
284
+ cmd.copy[cmd.key] = as_json ? value.toISO() : value;
285
+ }
286
+ else if (typeof value === 'string') {
287
+ const datetime = datetime_1.NesoiDatetime.fromISO(value);
288
+ cmd.copy[cmd.key] = as_json ? datetime.toISO() : datetime;
324
289
  }
325
- else if (op === 'save') {
326
- copy[meta.created_at] = obj[meta.created_at]?.toISO?.();
327
- copy[meta.updated_at] = obj[meta.updated_at]?.toISO?.();
290
+ else {
291
+ throw error_1.NesoiError.Message.InvalidFieldType({ alias: cmd.field.alias, path: '', value, type: 'datetime' });
328
292
  }
329
293
  }
294
+ else if (cmd.field.type === 'decimal') {
295
+ if (value instanceof decimal_1.NesoiDecimal) {
296
+ cmd.copy[cmd.key] = as_json ? value.toString() : value;
297
+ }
298
+ else if (typeof value === 'string') {
299
+ const meta = cmd.field.meta.decimal;
300
+ const decimal = new decimal_1.NesoiDecimal(value, meta?.left, meta?.right);
301
+ cmd.copy[cmd.key] = as_json ? decimal.toString() : decimal;
302
+ }
303
+ else {
304
+ throw error_1.NesoiError.Message.InvalidFieldType({ alias: cmd.field.alias, path: '', value, type: 'decimal' });
305
+ }
306
+ }
307
+ else if (cmd.field.type === 'duration') {
308
+ if (value instanceof duration_1.NesoiDuration) {
309
+ cmd.copy[cmd.key] = as_json ? value.toString() : value;
310
+ }
311
+ else if (typeof value === 'string') {
312
+ const duration = duration_1.NesoiDuration.fromString(value);
313
+ cmd.copy[cmd.key] = as_json ? duration.toString() : duration;
314
+ }
315
+ else {
316
+ throw error_1.NesoiError.Message.InvalidFieldType({ alias: cmd.field.alias, path: '', value, type: 'decimal' });
317
+ }
318
+ }
319
+ else if (cmd.field.type === 'int') {
320
+ cmd.copy[cmd.key] = (0, parse_1.parseInt_)({ alias: cmd.field.alias }, [], cmd.obj[cmd.key]);
321
+ }
322
+ else if (cmd.field.type === 'float') {
323
+ cmd.copy[cmd.key] = (0, parse_1.parseFloat_)({ alias: cmd.field.alias }, [], cmd.obj[cmd.key]);
324
+ }
325
+ else if (cmd.field.type === 'string') {
326
+ cmd.copy[cmd.key] = (0, parse_1.parseString)({ alias: cmd.field.alias }, [], cmd.obj[cmd.key]);
327
+ }
328
+ else if (cmd.field.type === 'literal') {
329
+ cmd.copy[cmd.key] = (0, parse_1.parseLiteral)({ alias: cmd.field.alias }, [], cmd.obj[cmd.key], cmd.field.meta.literal.template);
330
+ }
331
+ else if (cmd.field.type === 'boolean') {
332
+ cmd.copy[cmd.key] = (0, parse_1.parseBoolean)({ alias: cmd.field.alias }, [], cmd.obj[cmd.key]);
333
+ }
330
334
  else {
331
- copy[meta.created_at] = obj[meta.created_at];
332
- copy[meta.updated_at] = obj[meta.updated_at];
335
+ cmd.copy[cmd.key] = cmd.obj[cmd.key];
333
336
  }
334
- if (modelpath)
335
- return modelpath_results;
336
- return copy;
337
+ return next;
337
338
  }
338
339
  }
339
340
  exports.BucketModel = BucketModel;
@@ -15,7 +15,7 @@ export type NQL_Result<T = Obj> = {
15
15
  * @category NQL
16
16
  * */
17
17
  export declare abstract class NQLRunner {
18
- abstract run(trx: AnyTrxNode, part: NQL_Part, params: Record<string, any>[], param_templates: Record<string, string>[], pagination?: NQL_Pagination, view?: $BucketView): Promise<NQL_Result>;
18
+ abstract run(trx: AnyTrxNode, part: NQL_Part, params: Record<string, any>[], param_templates: Record<string, string>[], pagination?: NQL_Pagination, view?: $BucketView, serialize?: boolean): Promise<NQL_Result>;
19
19
  }
20
20
  /**
21
21
  * @category NQL
@@ -27,7 +27,7 @@ export declare class NQL_Engine {
27
27
  run(trx: AnyTrxNode, query: NQL_CompiledQuery, pagination?: NQL_Pagination, params?: Record<string, any>[], param_templates?: Record<string, string>[], view?: $BucketView, customBuckets?: Record<string, {
28
28
  scope: string;
29
29
  nql: NQLRunner;
30
- }>): Promise<NQL_Result>;
30
+ }>, serialize?: boolean): Promise<NQL_Result>;
31
31
  linkExternal(bucket: AnyBucket): void;
32
32
  }
33
33
  export {};
@@ -23,7 +23,7 @@ class NQL_Engine {
23
23
  }
24
24
  }
25
25
  }
26
- async run(trx, query, pagination, params = [{}], param_templates = [], view, customBuckets) {
26
+ async run(trx, query, pagination, params = [{}], param_templates = [], view, customBuckets, serialize) {
27
27
  if (!params.length)
28
28
  params = [{}];
29
29
  let result = {
@@ -35,7 +35,7 @@ class NQL_Engine {
35
35
  // Run part
36
36
  const _runner = Object.values(customBuckets || {}).find(b => b.scope === part.union.meta.scope)?.nql
37
37
  || this.runners[part.union.meta.scope];
38
- const out = await _runner.run(trx, part, params, param_templates, pagination, view);
38
+ const out = await _runner.run(trx, part, params, param_templates, pagination, view, serialize);
39
39
  result = out;
40
40
  // Part failed, return
41
41
  // Failure here is only when a single value is expected,