nesoi 3.0.17 → 3.0.19

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.
@@ -1,89 +1,141 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MessageTemplateFieldParser = MessageTemplateFieldParser;
4
+ exports.isEmpty = isEmpty;
4
5
  const parse_1 = require("../../../../engine/util/parse");
5
6
  const error_1 = require("../../../../engine/data/error");
6
- async function MessageTemplateFieldParser(raw, trx, field, value, parseFields) {
7
- if (field.type === 'unknown') {
8
- return {
9
- '': value
10
- };
11
- }
12
- if (field.type === 'boolean') {
13
- return {
14
- '': await (0, parse_1.parseBoolean)(field, value, field.array)
15
- };
7
+ async function MessageTemplateFieldParser(raw, trx, field, value) {
8
+ return parseFieldValue(trx, field, field.path_raw, raw, value);
9
+ }
10
+ // Attempt to parse a field value
11
+ // - If field is an array, this method is run for each value, sequentially
12
+ // - If not, it's run for the original value, once
13
+ //
14
+ // - This method stacks with the .or options
15
+ //
16
+ async function parseFieldValue(trx, field, path, raw, value) {
17
+ if (isEmpty(value)) {
18
+ if (field.required) {
19
+ throw error_1.NesoiError.Message.FieldIsRequired({ field: field.alias, path, value });
20
+ }
21
+ else if (field.defaultValue !== undefined) {
22
+ return field.defaultValue;
23
+ }
24
+ else {
25
+ return undefined;
26
+ }
16
27
  }
17
- if (field.type === 'date') {
18
- return {
19
- '': await (0, parse_1.parseDate)(field, value, field.array)
20
- };
28
+ if (field.array) {
29
+ if (!Array.isArray(value)) {
30
+ throw error_1.NesoiError.Message.InvalidFieldType({ field: field.alias, path, value, type: 'list' });
31
+ }
32
+ if (field.required && !value.length) {
33
+ throw error_1.NesoiError.Message.FieldIsRequired({ field: field.alias, path, value });
34
+ }
35
+ const parsedValue = [];
36
+ for (let i = 0; i < value.length; i++) {
37
+ const v = value[i];
38
+ const parsed = await _attemptUnion(trx, field, `${path}.${i}`, raw, v);
39
+ parsedValue.push(parsed);
40
+ }
41
+ return parsedValue;
21
42
  }
22
- if (field.type === 'datetime') {
23
- return {
24
- '': await (0, parse_1.parseDatetime)(field, value, field.array)
25
- };
43
+ return _attemptUnion(trx, field, path, raw, value);
44
+ }
45
+ async function _attemptUnion(trx, field, path, raw, value, unionErrors = []) {
46
+ try {
47
+ return await _runParseMethod(trx, field, path, raw, value);
26
48
  }
27
- if (field.type === 'duration') {
28
- return {
29
- '': await (0, parse_1.parseDuration)(field, value, field.array)
30
- };
49
+ catch (e) {
50
+ // If failed and there's a second option, atempt it
51
+ if (field.or) {
52
+ return await _attemptUnion(trx, field.or, path, raw, value, [...unionErrors, e]);
53
+ }
54
+ // If this error was not the first attempt, and we have no other option
55
+ // we throw a specific error
56
+ // This avoid confusion for the client when parsing unions
57
+ if (unionErrors.length) {
58
+ throw error_1.NesoiError.Message.ValueDoesntMatchUnion({ field: field.alias, path, value, unionErrors: [...unionErrors, e] });
59
+ }
60
+ throw e;
31
61
  }
32
- if (field.type === 'decimal') {
33
- return {
34
- '': await (0, parse_1.parseDecimal)(field, value, field.array)
35
- };
62
+ }
63
+ async function _runParseMethod(trx, field, path, raw, value) {
64
+ switch (field.type) {
65
+ case 'obj':
66
+ case 'dict':
67
+ return await parseParentField(trx, field, path, raw, value);
68
+ case 'unknown':
69
+ return value;
70
+ case 'boolean':
71
+ return (0, parse_1.parseBoolean)(field, path, value);
72
+ case 'date':
73
+ return (0, parse_1.parseDate)(field, path, value);
74
+ case 'datetime':
75
+ return (0, parse_1.parseDatetime)(field, path, value);
76
+ case 'duration':
77
+ return (0, parse_1.parseDuration)(field, path, value);
78
+ case 'decimal':
79
+ return (0, parse_1.parseDecimal)(field, path, value);
80
+ case 'enum':
81
+ return (0, parse_1.parseEnum)(raw, field, path, value, field.meta.enum.options, trx);
82
+ case 'file':
83
+ return (0, parse_1.parseFile)(field, path, value, field.meta.file);
84
+ case 'float':
85
+ return (0, parse_1.parseFloat_)(field, path, value);
86
+ case 'int':
87
+ return (0, parse_1.parseInt_)(field, path, value);
88
+ case 'string':
89
+ return (0, parse_1.parseString)(field, path, value);
90
+ case 'string_or_number':
91
+ return (0, parse_1.parseStringOrNumber)(field, path, value);
92
+ case 'id':
93
+ return await parseIdField(trx, field, path, value);
36
94
  }
37
- if (field.type === 'enum') {
38
- const options = field.meta.enum.options;
39
- return {
40
- '': await (0, parse_1.parseEnum)(raw, field, value, field.array, options, trx)
41
- };
95
+ throw error_1.NesoiError.Builder.Message.UnknownTemplateFieldType(field.type);
96
+ }
97
+ async function parseParentField(trx, field, path, raw, value) {
98
+ let children;
99
+ if (field.type === 'obj') {
100
+ children = (0, parse_1.parseObj)(field, path, value);
42
101
  }
43
- if (field.type === 'file') {
44
- const config = field.meta.file;
45
- return {
46
- '': await (0, parse_1.parseFile)(field, value, field.array, config)
47
- };
102
+ else {
103
+ children = (0, parse_1.parseDict)(field, path, value);
48
104
  }
49
- if (field.type === 'float') {
50
- return {
51
- '': await (0, parse_1.parseFloat_)(field, value, field.array)
52
- };
105
+ const parsed = {};
106
+ for (const key in children) {
107
+ const child = children[key];
108
+ parsed[key] = await parseFieldValue(trx, child.field, `${path}.${key}`, raw, child.value);
53
109
  }
54
- if (field.type === 'id') {
55
- const bucket = field.meta.id.bucket;
56
- const type = field.meta.id.type;
57
- const view = field.meta.id.view;
58
- const parsed = await (0, parse_1.parseId)(field, value, field.array, trx, bucket.refName, type, view);
59
- return {
60
- '': parsed.obj
61
- };
110
+ return parsed;
111
+ }
112
+ async function parseIdField(trx, field, path, value) {
113
+ const bucket = field.meta.id.bucket;
114
+ const type = field.meta.id.type;
115
+ const view = field.meta.id.view;
116
+ const parsed = await (0, parse_1.parseId)(field, path, value, trx, bucket.refName, type, view);
117
+ if (field.array) {
118
+ return parsed.map((p) => p.obj);
62
119
  }
63
- if (field.type === 'int') {
64
- return {
65
- '': await (0, parse_1.parseInt_)(field, value, field.array)
66
- };
120
+ else {
121
+ return parsed.obj;
67
122
  }
68
- if (field.type === 'string') {
69
- return {
70
- '': await (0, parse_1.parseString)(field, value, field.array)
71
- };
123
+ }
124
+ /**
125
+ * Empty values: `{}`, `[]`, `''`, `null`, `undefined`
126
+ */
127
+ function isEmpty(value) {
128
+ if (value === null || value === undefined) {
129
+ return true;
72
130
  }
73
- if (field.type === 'string_or_number') {
74
- return {
75
- '': await (0, parse_1.parseStringOrNumber)(field, value, field.array)
76
- };
131
+ if (Array.isArray(value)) {
132
+ return value.length === 0;
77
133
  }
78
- if (field.type === 'obj') {
79
- return {
80
- '': await (0, parse_1.parseObj)(field, value, field.array, trx, parseFields)
81
- };
134
+ if (typeof value === 'object') {
135
+ return Object.keys(value).length === 0;
82
136
  }
83
- if (field.type === 'dict') {
84
- return {
85
- '': await (0, parse_1.parseDict)(field, value, field.array, trx, parseFields)
86
- };
137
+ if (typeof value === 'string') {
138
+ return value.length === 0;
87
139
  }
88
- throw error_1.NesoiError.Builder.Message.UnknownTemplateFieldType(field.type);
140
+ return false;
89
141
  }
@@ -169,6 +169,7 @@ export declare namespace NesoiError {
169
169
  module: string;
170
170
  }): BaseError;
171
171
  function InvalidEnumScope($: {
172
+ path: string;
172
173
  name: string;
173
174
  alias?: string;
174
175
  value: any;
@@ -176,15 +177,23 @@ export declare namespace NesoiError {
176
177
  }): BaseError;
177
178
  function InvalidFieldEnumValue($: {
178
179
  field: string;
180
+ path: string;
179
181
  value: any;
180
182
  type: string;
181
183
  options: string[];
182
184
  }): BaseError;
183
185
  function InvalidFieldType($: {
184
186
  field: string;
187
+ path: string;
185
188
  value: any;
186
189
  type: string;
187
190
  }): BaseError;
191
+ function ValueDoesntMatchUnion($: {
192
+ field: string;
193
+ path: string;
194
+ value: any;
195
+ unionErrors: string[];
196
+ }): BaseError;
188
197
  function UnsanitaryValue($: {
189
198
  details: string;
190
199
  }): BaseError;
@@ -198,11 +207,13 @@ export declare namespace NesoiError {
198
207
  error: string;
199
208
  }): BaseError;
200
209
  function FileTooBig($: {
210
+ path: string;
201
211
  name: string;
202
212
  alias?: string;
203
213
  maxsize: number;
204
214
  }): BaseError;
205
215
  function FileExtNotAllowed($: {
216
+ path: string;
206
217
  name: string;
207
218
  alias?: string;
208
219
  options: string[];
@@ -313,6 +313,10 @@ var NesoiError;
313
313
  return new BaseError('Message.InvalidFieldType', `Message field '${$.field}' value '${$.value}' is not of type '${$.type}'`, Status.BAD_REQUEST, $);
314
314
  }
315
315
  Message.InvalidFieldType = InvalidFieldType;
316
+ function ValueDoesntMatchUnion($) {
317
+ return new BaseError('Message.ValueDoesntMatchUnion', `Message field '${$.field}' (${$.path}) value '${$.value}' doesn't match any of the union options'`, Status.BAD_REQUEST, $);
318
+ }
319
+ Message.ValueDoesntMatchUnion = ValueDoesntMatchUnion;
316
320
  function UnsanitaryValue($) {
317
321
  return new BaseError('Message.UnsanitaryValue', $.details, Status.BAD_REQUEST, $);
318
322
  }
@@ -1,5 +1,5 @@
1
1
  import { NesoiDate } from '../data/date';
2
- import { $MessageTemplateFields } from '../../elements/entities/message/template/message_template.schema';
2
+ import { $MessageTemplateField, $MessageTemplateFields } from '../../elements/entities/message/template/message_template.schema';
3
3
  import { $Module, BucketName, ViewName } from "../../schema";
4
4
  import { AnyTrxNode } from '../transaction/trx_node';
5
5
  import { NesoiDecimal } from '../data/decimal';
@@ -7,63 +7,64 @@ import { NesoiDatetime } from '../data/datetime';
7
7
  import { NesoiFile } from '../data/file';
8
8
  import { NesoiDuration } from '../data/duration';
9
9
  export declare function parseBoolean(field: {
10
- name: string;
11
10
  alias: string;
12
- }, value: any, array: boolean): Promise<boolean | boolean[]>;
11
+ }, path: string, value: any): boolean;
13
12
  export declare function parseDate(field: {
14
- name: string;
15
13
  alias: string;
16
- }, value: any, array: boolean): Promise<NesoiDate | NesoiDate[]>;
14
+ }, path: string, value: any): NesoiDate;
17
15
  export declare function parseDatetime(field: {
18
- name: string;
19
16
  alias: string;
20
- }, value: any, array: boolean): Promise<NesoiDatetime | NesoiDatetime[]>;
17
+ }, path: string, value: any): NesoiDatetime;
21
18
  export declare function parseDuration(field: {
22
- name: string;
23
19
  alias: string;
24
- }, value: any, array: boolean): Promise<NesoiDuration | NesoiDuration[]>;
20
+ }, path: string, value: any): NesoiDuration;
25
21
  export declare function parseDecimal(field: {
26
- name: string;
27
22
  alias: string;
28
- }, value: any, array: boolean): Promise<NesoiDecimal | NesoiDecimal[]>;
23
+ }, path: string, value: any): NesoiDecimal;
29
24
  export declare function parseEnum(raw: Record<string, any>, field: {
30
25
  name: string;
31
26
  alias: string;
32
- }, value: any, array: boolean, options: string | readonly string[] | Record<string, any>, trx: AnyTrxNode): Promise<any>;
27
+ }, path: string, value: any, options: string | readonly string[] | Record<string, any>, trx: AnyTrxNode): any;
33
28
  export declare function parseFile(field: {
34
29
  name: string;
35
30
  alias: string;
36
- }, value: any, array: boolean, options?: {
31
+ }, path: string, value: any, options?: {
37
32
  maxsize?: number;
38
33
  extnames?: string[];
39
- }): Promise<NesoiFile | NesoiFile[]>;
34
+ }): NesoiFile;
40
35
  export declare function parseFloat_(field: {
41
- name: string;
42
36
  alias: string;
43
- }, value: any, array: boolean): Promise<number | number[]>;
37
+ }, path: string, value: any): number;
44
38
  export declare function parseId<M extends $Module, Name extends BucketName<M>, View extends ViewName<M['buckets'][Name]> | undefined>(field: {
45
- name: string;
46
39
  alias: string;
47
- }, value: any, array: boolean, trx: AnyTrxNode, bucket: Name, type?: 'int' | 'string', view?: View): Promise<unknown>;
40
+ }, path: string, value: any, trx: AnyTrxNode, bucket: Name, type?: 'int' | 'string', view?: View): Promise<{
41
+ value: {
42
+ id: string | number;
43
+ obj: any;
44
+ };
45
+ }>;
48
46
  export declare function parseInt_(field: {
49
- name: string;
50
47
  alias: string;
51
- }, value: any, array: boolean): Promise<number | number[]>;
48
+ }, path: string, value: any): number;
52
49
  export declare function parseString(field: {
53
- name: string;
54
50
  alias: string;
55
- }, value: any, array: boolean): Promise<string | string[]>;
51
+ }, path: string, value: any): string;
56
52
  export declare function parseStringOrNumber(field: {
57
- name: string;
58
53
  alias: string;
59
- }, value: any, array: boolean): Promise<string | number | (string | number)[]>;
54
+ }, path: string, value: any): string | number;
60
55
  export declare function parseDict(field: {
61
- name: string;
56
+ path_raw: string;
62
57
  alias: string;
63
58
  children?: $MessageTemplateFields;
64
- }, value: any, array: boolean, trx: AnyTrxNode, parseFields: (trx: AnyTrxNode, fields: $MessageTemplateFields, obj: Record<string, any>) => Promise<Record<string, any>>): Promise<unknown>;
59
+ }, path: string, value: any): Record<string, {
60
+ field: $MessageTemplateField;
61
+ value?: any;
62
+ }>;
65
63
  export declare function parseObj(field: {
66
- name: string;
64
+ path_raw: string;
67
65
  alias: string;
68
66
  children?: $MessageTemplateFields;
69
- }, value: any, array: boolean, trx: AnyTrxNode, parseFields: (trx: AnyTrxNode, fields: $MessageTemplateFields, obj: Record<string, any>) => Promise<Record<string, any>>): Promise<unknown>;
67
+ }, path: string, value: any): Record<string, {
68
+ field: $MessageTemplateField;
69
+ value?: any;
70
+ }>;