gingersnap 0.23.10 → 0.23.12

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.
@@ -73,14 +73,9 @@ class Optional {
73
73
  * A Data de/serializer class that manages and validates data as JavaScript Objects
74
74
  */
75
75
  class Model {
76
- /**
77
- * Converts arraybuffer to a model
78
- * @param data arraybuffer
79
- * @param format data format
80
- * @param options configurations for deserializing the data
81
- * @returns new model or an array of models
82
- */
83
- static fromBuffer(data, format = types.DataFormat.JSON, options) {
76
+ static fromBuffer(data, options) {
77
+ var _a;
78
+ const format = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : types.DataFormat.JSON;
84
79
  switch (format) {
85
80
  case types.DataFormat.MESSAGE_PACK: {
86
81
  const decoder = msgpack.decode;
@@ -89,27 +84,18 @@ class Model {
89
84
  throw new ParsingError.ParsingError([], "expected an array of models");
90
85
  if ((!(options === null || options === void 0 ? void 0 : options.array) && result instanceof Array) || Array.isArray(result))
91
86
  throw new ParsingError.ParsingError([], "expected only one model");
92
- if (result instanceof Array || Array.isArray(result))
93
- return result.map((v) => this.fromJSON(v));
94
- return this.fromJSON(result);
87
+ return this.fromJSON(result, { array: options === null || options === void 0 ? void 0 : options.array, maybeArray: options === null || options === void 0 ? void 0 : options.maybeArray });
95
88
  }
96
89
  case types.DataFormat.CSV: {
97
90
  const text = data instanceof Uint8Array ? new TextDecoder().decode(data.buffer) : data.toString();
98
- return this.fromString(text, format, options);
91
+ return this.fromString(text, options);
99
92
  }
100
93
  case types.DataFormat.XML:
101
94
  case types.DataFormat.JSON:
102
- return this.fromString(data instanceof Uint8Array ? new TextDecoder().decode(data) : data.toString(), format, options);
95
+ return this.fromString(data instanceof Uint8Array ? new TextDecoder().decode(data) : data.toString(), options);
103
96
  }
104
97
  }
105
- /**
106
- * Downloads data from the given source and deserializes the data to one or more models
107
- * @param source URL source to fetch the data
108
- * @param format data format
109
- * @param options configurations for deserializing and/or retrieving the data
110
- * @returns one or more models
111
- */
112
- static fromURL(source, format = types.DataFormat.JSON, options) {
98
+ static fromURL(source, options) {
113
99
  return _tslib.__awaiter(this, void 0, void 0, function* () {
114
100
  const fetcher = fetch;
115
101
  const resp = yield fetcher(source, {
@@ -119,48 +105,37 @@ class Model {
119
105
  });
120
106
  if (!resp.ok)
121
107
  throw new NetworkError.NetworkError(resp.status);
122
- return yield this.fromBlob(yield resp.blob(), format, options);
108
+ return yield this.fromBlob(yield resp.blob(), options);
123
109
  });
124
110
  }
125
- /**
126
- * Deserializes one or more models from a Blob
127
- * @param data blob data
128
- * @param format data format
129
- * @param options configurations for deserializing the data
130
- * @returns one or more models
131
- */
132
- static fromBlob(data, format = types.DataFormat.JSON, options) {
111
+ static fromBlob(data, options) {
133
112
  return _tslib.__awaiter(this, void 0, void 0, function* () {
134
- return this.fromBuffer(new Uint8Array(yield data.arrayBuffer()), format);
113
+ return this.fromBuffer(new Uint8Array(yield data.arrayBuffer()), options);
135
114
  });
136
115
  }
137
- /**
138
- * Deserializes one or more models from given string
139
- *
140
- * @remarks
141
- * If the data format is a binary one, the provided string should be a hexadecimal string.
142
- * @param data string data source
143
- * @param format data format
144
- * @param options
145
- */
146
- static fromString(data, format = types.DataFormat.JSON, options) {
147
- var _a, _b, _c, _d, _e, _f;
116
+ static fromString(data, options) {
117
+ var _a, _b, _c, _d, _e, _f, _g;
118
+ const format = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : types.DataFormat.JSON;
148
119
  switch (format) {
149
120
  case types.DataFormat.JSON:
150
121
  try {
151
122
  data = JSON.parse(data);
152
123
  }
153
124
  catch (e) {
154
- throw new ParsingError.ParsingError((_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : String(e));
125
+ throw new ParsingError.ParsingError((_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e));
155
126
  }
156
- return this.fromJSON(data);
127
+ return this.fromJSON(data, { maybeArray: options === null || options === void 0 ? void 0 : options.maybeArray, array: options === null || options === void 0 ? void 0 : options.array });
157
128
  case types.DataFormat.XML:
158
- return this.fromObject(this.__xmlParser__.xml2js(data), format);
129
+ return this.fromObject(this.__xmlParser__.xml2js(data), {
130
+ format,
131
+ maybeArray: options === null || options === void 0 ? void 0 : options.maybeArray,
132
+ array: options === null || options === void 0 ? void 0 : options.array,
133
+ });
159
134
  case types.DataFormat.CSV: {
160
135
  let result;
161
136
  let text = data;
162
137
  if (options === null || options === void 0 ? void 0 : options.headers)
163
- text = options.headers.join((_b = options === null || options === void 0 ? void 0 : options.delimiter) !== null && _b !== void 0 ? _b : ",") + ((_c = options.newline) !== null && _c !== void 0 ? _c : "\n") + text;
138
+ text = options.headers.join((_c = options === null || options === void 0 ? void 0 : options.delimiter) !== null && _c !== void 0 ? _c : ",") + ((_d = options.newline) !== null && _d !== void 0 ? _d : "\n") + text;
164
139
  try {
165
140
  result = Papa.parse(text, {
166
141
  header: true,
@@ -168,27 +143,24 @@ class Model {
168
143
  });
169
144
  }
170
145
  catch (e) {
171
- throw new ParsingError.ParsingError([], (_d = e === null || e === void 0 ? void 0 : e.message) !== null && _d !== void 0 ? _d : String(e));
146
+ throw new ParsingError.ParsingError([], (_e = e === null || e === void 0 ? void 0 : e.message) !== null && _e !== void 0 ? _e : String(e));
172
147
  }
173
148
  if (!(options === null || options === void 0 ? void 0 : options.ignoreErrors) && result.errors.length > 0)
174
149
  throw new ParsingError.ParsingError(result.errors);
175
150
  if (!(options === null || options === void 0 ? void 0 : options.array) && result.data.length > 0)
176
151
  throw new ParsingError.ParsingError([], "Too many records found");
177
- if (options === null || options === void 0 ? void 0 : options.array)
178
- return result.data.map((v) => this.fromObject(v));
179
- return this.fromObject(result.data[0]);
152
+ if ((options === null || options === void 0 ? void 0 : options.array) || (options === null || options === void 0 ? void 0 : options.maybeArray))
153
+ return this.fromObject(result.data, { array: true });
154
+ if (!(options === null || options === void 0 ? void 0 : options.maybeArray) || (options.maybeArray && result.data.length === 1))
155
+ return this.fromObject(result.data[0]);
156
+ break;
180
157
  }
181
158
  default:
182
- return this.fromBuffer(new Uint8Array((_f = (_e = data.match(/../g)) === null || _e === void 0 ? void 0 : _e.map((h) => parseInt(h, 16))) !== null && _f !== void 0 ? _f : []), format, options);
159
+ return this.fromBuffer(new Uint8Array((_g = (_f = data.match(/../g)) === null || _f === void 0 ? void 0 : _f.map((h) => parseInt(h, 16))) !== null && _g !== void 0 ? _g : []), options);
183
160
  }
184
161
  }
185
- /**
186
- * Converts a JSON object to a model
187
- * @param data JSON Object
188
- * @returns new model
189
- */
190
- static fromJSON(data) {
191
- return this.fromObject(data, types.DataFormat.JSON);
162
+ static fromJSON(data, options) {
163
+ return this.fromObject(data, options);
192
164
  }
193
165
  /**
194
166
  * Converts the current model to a JSON object
@@ -231,6 +203,7 @@ class Model {
231
203
  return acc;
232
204
  }, {}, Array.from(((_b = (_a = Model.buildPropTree(Object.getPrototypeOf(this))) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : new Map()).entries()));
233
205
  }
206
+ // TODO add support for union fields in serialization and deserialization, and later date include schema generation
234
207
  /**
235
208
  * Converts the current model to a JSON string
236
209
  */
@@ -421,15 +394,17 @@ class Model {
421
394
  }
422
395
  return tree;
423
396
  }
424
- /**
425
- * Constructs a model from a JSON object
426
- * @param data JSON object
427
- * @param format
428
- * @private
429
- */
430
- static fromObject(data, format = types.DataFormat.JSON) {
431
- if (data instanceof Array || Array.isArray(data) || typeof data !== "object") {
432
- throw new ParsingError.ParsingError([], "Invalid data provided. Must be an object");
397
+ static fromObject(data, options) {
398
+ var _a;
399
+ const format = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : types.DataFormat.JSON;
400
+ if (Array.isArray(data)) {
401
+ if (!(options === null || options === void 0 ? void 0 : options.array) || !(options === null || options === void 0 ? void 0 : options.maybeArray))
402
+ throw new ParsingError.ParsingError([], "Invalid data provided. Must be an object");
403
+ else
404
+ return data.map((item) => this.fromObject(item, { format }));
405
+ }
406
+ else if (options === null || options === void 0 ? void 0 : options.array) {
407
+ throw new ParsingError.ParsingError([], "Invalid data provided. Must be an array of objects");
433
408
  }
434
409
  const processValue = (fieldProps, value) => {
435
410
  var _a, _b;
@@ -23,10 +23,12 @@ export interface FieldProps {
23
23
  Type: any;
24
24
  KeyType?: any;
25
25
  ValueType?: any;
26
+ isUnion?: boolean;
26
27
  isArray?: boolean;
27
28
  isMap?: boolean;
28
29
  readonly?: boolean;
29
30
  aliases?: string[];
31
+ unionTypes?: any[];
30
32
  schema?: {
31
33
  description: string;
32
34
  dataType: DataType;
@@ -78,6 +80,22 @@ export declare class Optional<T> {
78
80
  */
79
81
  get(): T;
80
82
  }
83
+ export interface ModelConversionOptions {
84
+ array?: boolean;
85
+ maybeArray?: boolean;
86
+ format?: DataFormat;
87
+ }
88
+ export interface ModelAdvanceConversionOptions extends ModelConversionOptions {
89
+ headers?: string[];
90
+ ignoreErrors?: boolean;
91
+ delimiter?: string;
92
+ newline?: string;
93
+ }
94
+ export interface ModelURLConversionOptions extends ModelAdvanceConversionOptions {
95
+ requestHeaders?: any;
96
+ mode?: any;
97
+ }
98
+ export type ModelJSONConversionOptions = Omit<ModelConversionOptions, "format">;
81
99
  /**
82
100
  * A Data de/serializer class that manages and validates data as JavaScript Objects
83
101
  */
@@ -87,46 +105,42 @@ export declare class Model {
87
105
  /**
88
106
  * Converts arraybuffer to a model
89
107
  * @param data arraybuffer
90
- * @param format data format
91
108
  * @param options configurations for deserializing the data
92
109
  * @returns new model or an array of models
93
110
  */
94
- static fromBuffer<T extends Model>(this: ModelConstructor<T>, data: Uint8Array | Buffer, format?: DataFormat, options?: {
95
- headers?: string[];
96
- ignoreErrors?: boolean;
97
- array?: boolean;
98
- delimiter?: string;
99
- newline?: string;
111
+ static fromBuffer<T extends Model>(this: ModelConstructor<T>, data: Uint8Array | Buffer, options?: Omit<ModelAdvanceConversionOptions, "array" | "maybeArray">): T;
112
+ static fromBuffer<T extends Model>(this: ModelConstructor<T>, data: Uint8Array | Buffer, options: Omit<ModelAdvanceConversionOptions, "array" | "maybeArray"> & {
113
+ array: true;
114
+ }): T[];
115
+ static fromBuffer<T extends Model>(this: ModelConstructor<T>, data: Uint8Array | Buffer, options: Omit<ModelAdvanceConversionOptions, "array" | "maybeArray"> & {
116
+ maybeArray: true;
100
117
  }): T | T[];
118
+ static fromBuffer<T extends Model>(this: ModelConstructor<T>, data: Uint8Array | Buffer, options?: ModelAdvanceConversionOptions): T | T[];
101
119
  /**
102
120
  * Downloads data from the given source and deserializes the data to one or more models
103
121
  * @param source URL source to fetch the data
104
- * @param format data format
105
122
  * @param options configurations for deserializing and/or retrieving the data
106
123
  * @returns one or more models
107
124
  */
108
- static fromURL<T extends Model>(this: ModelConstructor<T>, source: string, format?: DataFormat, options?: {
109
- headers?: string[];
110
- ignoreErrors?: boolean;
111
- array?: boolean;
112
- delimiter?: string;
113
- newline?: string;
114
- requestHeaders?: any;
115
- mode?: any;
125
+ static fromURL<T extends Model>(this: ModelConstructor<T>, source: string, options?: Omit<ModelURLConversionOptions, "array" | "maybeArray">): Promise<T>;
126
+ static fromURL<T extends Model>(this: ModelConstructor<T>, source: string, options: Omit<ModelURLConversionOptions, "array" | "maybeArray"> & {
127
+ array: true;
128
+ }): Promise<T[]>;
129
+ static fromURL<T extends Model>(this: ModelConstructor<T>, source: string, options: Omit<ModelURLConversionOptions, "array" | "maybeArray"> & {
130
+ maybeArray: true;
116
131
  }): Promise<T | T[]>;
117
132
  /**
118
133
  * Deserializes one or more models from a Blob
119
134
  * @param data blob data
120
- * @param format data format
121
135
  * @param options configurations for deserializing the data
122
136
  * @returns one or more models
123
137
  */
124
- static fromBlob<T extends Model>(this: ModelConstructor<T>, data: Blob, format?: DataFormat, options?: {
125
- headers?: string[];
126
- ignoreErrors?: boolean;
127
- array?: boolean;
128
- delimiter?: string;
129
- newline?: string;
138
+ static fromBlob<T extends Model>(this: ModelConstructor<T>, data: Blob, options?: Omit<ModelAdvanceConversionOptions, "array" | "maybeArray">): Promise<T>;
139
+ static fromBlob<T extends Model>(this: ModelConstructor<T>, data: Blob, options: Omit<ModelAdvanceConversionOptions, "array" | "maybeArray"> & {
140
+ array: true;
141
+ }): Promise<T[]>;
142
+ static fromBlob<T extends Model>(this: ModelConstructor<T>, data: Blob, options: Omit<ModelAdvanceConversionOptions, "array" | "maybeArray"> & {
143
+ maybeArray: true;
130
144
  }): Promise<T | T[]>;
131
145
  /**
132
146
  * Deserializes one or more models from given string
@@ -137,12 +151,12 @@ export declare class Model {
137
151
  * @param format data format
138
152
  * @param options
139
153
  */
140
- static fromString<T extends Model>(this: ModelConstructor<T>, data: string, format?: DataFormat, options?: {
141
- headers?: string[];
142
- ignoreErrors?: boolean;
143
- array?: boolean;
144
- delimiter?: string;
145
- newline?: string;
154
+ static fromString<T extends Model>(this: ModelConstructor<T>, data: string, options?: Omit<ModelAdvanceConversionOptions, "array" | "maybeArray">): T;
155
+ static fromString<T extends Model>(this: ModelConstructor<T>, data: string, options: Omit<ModelAdvanceConversionOptions, "array" | "maybeArray"> & {
156
+ array: true;
157
+ }): T[];
158
+ static fromString<T extends Model>(this: ModelConstructor<T>, data: string, options: Omit<ModelAdvanceConversionOptions, "maybeArray"> & {
159
+ maybeArray: true;
146
160
  }): T | T[];
147
161
  /**
148
162
  * Converts a JSON object to a model
@@ -150,6 +164,10 @@ export declare class Model {
150
164
  * @returns new model
151
165
  */
152
166
  static fromJSON<T extends Model>(this: ModelConstructor<T>, data: object): T;
167
+ static fromJSON<T extends Model>(this: ModelConstructor<T>, data: object, options: {
168
+ array: true;
169
+ }): T[];
170
+ static fromJSON<T extends Model>(this: ModelConstructor<T>, data: object, options: ModelJSONConversionOptions): T | T[];
153
171
  /**
154
172
  * Converts the current model to a JSON object
155
173
  */
@@ -201,9 +219,9 @@ export declare class Model {
201
219
  */
202
220
  private static buildPropTree;
203
221
  /**
204
- * Constructs a model from a JSON object
205
- * @param data JSON object
206
- * @param format
222
+ * Constructs a model from JSON objects
223
+ * @param data JSON object or array of JSON object
224
+ * @param options
207
225
  * @private
208
226
  */
209
227
  private static fromObject;
@@ -52,14 +52,9 @@ class Optional {
52
52
  * A Data de/serializer class that manages and validates data as JavaScript Objects
53
53
  */
54
54
  class Model {
55
- /**
56
- * Converts arraybuffer to a model
57
- * @param data arraybuffer
58
- * @param format data format
59
- * @param options configurations for deserializing the data
60
- * @returns new model or an array of models
61
- */
62
- static fromBuffer(data, format = DataFormat.JSON, options) {
55
+ static fromBuffer(data, options) {
56
+ var _a;
57
+ const format = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : DataFormat.JSON;
63
58
  switch (format) {
64
59
  case DataFormat.MESSAGE_PACK: {
65
60
  const decoder = decode;
@@ -68,27 +63,18 @@ class Model {
68
63
  throw new ParsingError([], "expected an array of models");
69
64
  if ((!(options === null || options === void 0 ? void 0 : options.array) && result instanceof Array) || Array.isArray(result))
70
65
  throw new ParsingError([], "expected only one model");
71
- if (result instanceof Array || Array.isArray(result))
72
- return result.map((v) => this.fromJSON(v));
73
- return this.fromJSON(result);
66
+ return this.fromJSON(result, { array: options === null || options === void 0 ? void 0 : options.array, maybeArray: options === null || options === void 0 ? void 0 : options.maybeArray });
74
67
  }
75
68
  case DataFormat.CSV: {
76
69
  const text = data instanceof Uint8Array ? new TextDecoder().decode(data.buffer) : data.toString();
77
- return this.fromString(text, format, options);
70
+ return this.fromString(text, options);
78
71
  }
79
72
  case DataFormat.XML:
80
73
  case DataFormat.JSON:
81
- return this.fromString(data instanceof Uint8Array ? new TextDecoder().decode(data) : data.toString(), format, options);
74
+ return this.fromString(data instanceof Uint8Array ? new TextDecoder().decode(data) : data.toString(), options);
82
75
  }
83
76
  }
84
- /**
85
- * Downloads data from the given source and deserializes the data to one or more models
86
- * @param source URL source to fetch the data
87
- * @param format data format
88
- * @param options configurations for deserializing and/or retrieving the data
89
- * @returns one or more models
90
- */
91
- static fromURL(source, format = DataFormat.JSON, options) {
77
+ static fromURL(source, options) {
92
78
  return __awaiter(this, void 0, void 0, function* () {
93
79
  const fetcher = fetch;
94
80
  const resp = yield fetcher(source, {
@@ -98,48 +84,37 @@ class Model {
98
84
  });
99
85
  if (!resp.ok)
100
86
  throw new NetworkError(resp.status);
101
- return yield this.fromBlob(yield resp.blob(), format, options);
87
+ return yield this.fromBlob(yield resp.blob(), options);
102
88
  });
103
89
  }
104
- /**
105
- * Deserializes one or more models from a Blob
106
- * @param data blob data
107
- * @param format data format
108
- * @param options configurations for deserializing the data
109
- * @returns one or more models
110
- */
111
- static fromBlob(data, format = DataFormat.JSON, options) {
90
+ static fromBlob(data, options) {
112
91
  return __awaiter(this, void 0, void 0, function* () {
113
- return this.fromBuffer(new Uint8Array(yield data.arrayBuffer()), format);
92
+ return this.fromBuffer(new Uint8Array(yield data.arrayBuffer()), options);
114
93
  });
115
94
  }
116
- /**
117
- * Deserializes one or more models from given string
118
- *
119
- * @remarks
120
- * If the data format is a binary one, the provided string should be a hexadecimal string.
121
- * @param data string data source
122
- * @param format data format
123
- * @param options
124
- */
125
- static fromString(data, format = DataFormat.JSON, options) {
126
- var _a, _b, _c, _d, _e, _f;
95
+ static fromString(data, options) {
96
+ var _a, _b, _c, _d, _e, _f, _g;
97
+ const format = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : DataFormat.JSON;
127
98
  switch (format) {
128
99
  case DataFormat.JSON:
129
100
  try {
130
101
  data = JSON.parse(data);
131
102
  }
132
103
  catch (e) {
133
- throw new ParsingError((_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : String(e));
104
+ throw new ParsingError((_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e));
134
105
  }
135
- return this.fromJSON(data);
106
+ return this.fromJSON(data, { maybeArray: options === null || options === void 0 ? void 0 : options.maybeArray, array: options === null || options === void 0 ? void 0 : options.array });
136
107
  case DataFormat.XML:
137
- return this.fromObject(this.__xmlParser__.xml2js(data), format);
108
+ return this.fromObject(this.__xmlParser__.xml2js(data), {
109
+ format,
110
+ maybeArray: options === null || options === void 0 ? void 0 : options.maybeArray,
111
+ array: options === null || options === void 0 ? void 0 : options.array,
112
+ });
138
113
  case DataFormat.CSV: {
139
114
  let result;
140
115
  let text = data;
141
116
  if (options === null || options === void 0 ? void 0 : options.headers)
142
- text = options.headers.join((_b = options === null || options === void 0 ? void 0 : options.delimiter) !== null && _b !== void 0 ? _b : ",") + ((_c = options.newline) !== null && _c !== void 0 ? _c : "\n") + text;
117
+ text = options.headers.join((_c = options === null || options === void 0 ? void 0 : options.delimiter) !== null && _c !== void 0 ? _c : ",") + ((_d = options.newline) !== null && _d !== void 0 ? _d : "\n") + text;
143
118
  try {
144
119
  result = Papa.parse(text, {
145
120
  header: true,
@@ -147,27 +122,24 @@ class Model {
147
122
  });
148
123
  }
149
124
  catch (e) {
150
- throw new ParsingError([], (_d = e === null || e === void 0 ? void 0 : e.message) !== null && _d !== void 0 ? _d : String(e));
125
+ throw new ParsingError([], (_e = e === null || e === void 0 ? void 0 : e.message) !== null && _e !== void 0 ? _e : String(e));
151
126
  }
152
127
  if (!(options === null || options === void 0 ? void 0 : options.ignoreErrors) && result.errors.length > 0)
153
128
  throw new ParsingError(result.errors);
154
129
  if (!(options === null || options === void 0 ? void 0 : options.array) && result.data.length > 0)
155
130
  throw new ParsingError([], "Too many records found");
156
- if (options === null || options === void 0 ? void 0 : options.array)
157
- return result.data.map((v) => this.fromObject(v));
158
- return this.fromObject(result.data[0]);
131
+ if ((options === null || options === void 0 ? void 0 : options.array) || (options === null || options === void 0 ? void 0 : options.maybeArray))
132
+ return this.fromObject(result.data, { array: true });
133
+ if (!(options === null || options === void 0 ? void 0 : options.maybeArray) || (options.maybeArray && result.data.length === 1))
134
+ return this.fromObject(result.data[0]);
135
+ break;
159
136
  }
160
137
  default:
161
- return this.fromBuffer(new Uint8Array((_f = (_e = data.match(/../g)) === null || _e === void 0 ? void 0 : _e.map((h) => parseInt(h, 16))) !== null && _f !== void 0 ? _f : []), format, options);
138
+ return this.fromBuffer(new Uint8Array((_g = (_f = data.match(/../g)) === null || _f === void 0 ? void 0 : _f.map((h) => parseInt(h, 16))) !== null && _g !== void 0 ? _g : []), options);
162
139
  }
163
140
  }
164
- /**
165
- * Converts a JSON object to a model
166
- * @param data JSON Object
167
- * @returns new model
168
- */
169
- static fromJSON(data) {
170
- return this.fromObject(data, DataFormat.JSON);
141
+ static fromJSON(data, options) {
142
+ return this.fromObject(data, options);
171
143
  }
172
144
  /**
173
145
  * Converts the current model to a JSON object
@@ -210,6 +182,7 @@ class Model {
210
182
  return acc;
211
183
  }, {}, Array.from(((_b = (_a = Model.buildPropTree(Object.getPrototypeOf(this))) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : new Map()).entries()));
212
184
  }
185
+ // TODO add support for union fields in serialization and deserialization, and later date include schema generation
213
186
  /**
214
187
  * Converts the current model to a JSON string
215
188
  */
@@ -400,15 +373,17 @@ class Model {
400
373
  }
401
374
  return tree;
402
375
  }
403
- /**
404
- * Constructs a model from a JSON object
405
- * @param data JSON object
406
- * @param format
407
- * @private
408
- */
409
- static fromObject(data, format = DataFormat.JSON) {
410
- if (data instanceof Array || Array.isArray(data) || typeof data !== "object") {
411
- throw new ParsingError([], "Invalid data provided. Must be an object");
376
+ static fromObject(data, options) {
377
+ var _a;
378
+ const format = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : DataFormat.JSON;
379
+ if (Array.isArray(data)) {
380
+ if (!(options === null || options === void 0 ? void 0 : options.array) || !(options === null || options === void 0 ? void 0 : options.maybeArray))
381
+ throw new ParsingError([], "Invalid data provided. Must be an object");
382
+ else
383
+ return data.map((item) => this.fromObject(item, { format }));
384
+ }
385
+ else if (options === null || options === void 0 ? void 0 : options.array) {
386
+ throw new ParsingError([], "Invalid data provided. Must be an array of objects");
412
387
  }
413
388
  const processValue = (fieldProps, value) => {
414
389
  var _a, _b;
@@ -129,6 +129,30 @@ const Field = (name, type = undefined) => (target, key) => {
129
129
  props.parent = Object.getPrototypeOf(target).constructor.name;
130
130
  model.namespacedModelInternalProps.set(target.constructor.name, props);
131
131
  };
132
+ const UnionField = (types, name) => (target, key) => {
133
+ var _a, _b, _c;
134
+ const schema = {};
135
+ const props = (_a = model.namespacedModelInternalProps.get(target.constructor.name)) !== null && _a !== void 0 ? _a : {
136
+ fields: new Map(),
137
+ };
138
+ schema.description = (_b = name === null || name === void 0 ? void 0 : name.description) !== null && _b !== void 0 ? _b : "";
139
+ const fieldProp = (_c = props.fields.get(key)) !== null && _c !== void 0 ? _c : {};
140
+ fieldProp.name = typeof name === "string" ? name : typeof name === "object" ? name.name : key;
141
+ fieldProp.isUnion = true;
142
+ fieldProp.schema = schema;
143
+ fieldProp.unionTypes = types;
144
+ props.fields.set(key, fieldProp);
145
+ if (typeof name === "string" && name) {
146
+ if (fieldProp.aliases) {
147
+ fieldProp.aliases.push(name);
148
+ }
149
+ else {
150
+ fieldProp.aliases = [name];
151
+ }
152
+ }
153
+ props.parent = Object.getPrototypeOf(target).constructor.name;
154
+ model.namespacedModelInternalProps.set(target.constructor.name, props);
155
+ };
132
156
  /**
133
157
  * A property that exists on the incoming data, that contains an array of same data types
134
158
  * @param type Type of data in the array
@@ -310,5 +334,6 @@ exports.RaiseError = RaiseError;
310
334
  exports.Range = Range;
311
335
  exports.Readonly = Readonly;
312
336
  exports.SchemaType = SchemaType;
337
+ exports.UnionField = UnionField;
313
338
  exports.UpperBound = UpperBound;
314
339
  exports.Validator = Validator;
@@ -1,4 +1,4 @@
1
- import { IgnoreProps } from "./model";
1
+ import { IgnoreProps, Model } from "./model";
2
2
  import { DataType } from "./types";
3
3
  /**
4
4
  * A property that exist in the incoming data
@@ -11,6 +11,10 @@ export declare const Field: (name?: string | {
11
11
  name: string;
12
12
  description: string;
13
13
  }, type?: any) => (target: any, key: string) => void;
14
+ export declare const UnionField: <T extends new (...args: any[]) => Model>(types: T[], name?: string | {
15
+ name: string;
16
+ description: string;
17
+ }) => (target: any, key: string) => void;
14
18
  /**
15
19
  * A property that exists on the incoming data, that contains an array of same data types
16
20
  * @param type Type of data in the array
@@ -108,6 +108,30 @@ const Field = (name, type = undefined) => (target, key) => {
108
108
  props.parent = Object.getPrototypeOf(target).constructor.name;
109
109
  namespacedModelInternalProps.set(target.constructor.name, props);
110
110
  };
111
+ const UnionField = (types, name) => (target, key) => {
112
+ var _a, _b, _c;
113
+ const schema = {};
114
+ const props = (_a = namespacedModelInternalProps.get(target.constructor.name)) !== null && _a !== void 0 ? _a : {
115
+ fields: new Map(),
116
+ };
117
+ schema.description = (_b = name === null || name === void 0 ? void 0 : name.description) !== null && _b !== void 0 ? _b : "";
118
+ const fieldProp = (_c = props.fields.get(key)) !== null && _c !== void 0 ? _c : {};
119
+ fieldProp.name = typeof name === "string" ? name : typeof name === "object" ? name.name : key;
120
+ fieldProp.isUnion = true;
121
+ fieldProp.schema = schema;
122
+ fieldProp.unionTypes = types;
123
+ props.fields.set(key, fieldProp);
124
+ if (typeof name === "string" && name) {
125
+ if (fieldProp.aliases) {
126
+ fieldProp.aliases.push(name);
127
+ }
128
+ else {
129
+ fieldProp.aliases = [name];
130
+ }
131
+ }
132
+ props.parent = Object.getPrototypeOf(target).constructor.name;
133
+ namespacedModelInternalProps.set(target.constructor.name, props);
134
+ };
111
135
  /**
112
136
  * A property that exists on the incoming data, that contains an array of same data types
113
137
  * @param type Type of data in the array
@@ -279,4 +303,4 @@ const UpperBound = (value, inclusive = false) => createValidator(inclusive ? (v)
279
303
  */
280
304
  const Range = (lower, upper, inclusive = false) => createValidator(inclusive ? (v) => lower <= v && v <= upper : (v) => lower <= v && v < upper, new InvalidValue(`value is not within the range of ${lower} <= v ` + (inclusive ? `<= ${upper}` : `< ${upper}`)));
281
305
 
282
- export { Alias, ArrayField, Field, Ignore, LowerBound, MapField, RaiseError, Range, Readonly, SchemaType, UpperBound, Validator };
306
+ export { Alias, ArrayField, Field, Ignore, LowerBound, MapField, RaiseError, Range, Readonly, SchemaType, UnionField, UpperBound, Validator };
package/data/model.cjs CHANGED
@@ -21,6 +21,7 @@ exports.RaiseError = property.RaiseError;
21
21
  exports.Range = property.Range;
22
22
  exports.Readonly = property.Readonly;
23
23
  exports.SchemaType = property.SchemaType;
24
+ exports.UnionField = property.UnionField;
24
25
  exports.UpperBound = property.UpperBound;
25
26
  exports.Validator = property.Validator;
26
27
  Object.defineProperty(exports, 'DataFormat', {
package/data/model.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Model, Optional } from './model/model.mjs';
2
- export { Alias, ArrayField, Field, Ignore, LowerBound, MapField, RaiseError, Range, Readonly, SchemaType, UpperBound, Validator } from './model/property.mjs';
2
+ export { Alias, ArrayField, Field, Ignore, LowerBound, MapField, RaiseError, Range, Readonly, SchemaType, UnionField, UpperBound, Validator } from './model/property.mjs';
3
3
  export { DataFormat, DataType } from './model/types.mjs';
4
4
  export { APIKeyCredentials, BasicCredentials, BearerCredentials, Credentials } from './model/credentials.mjs';
5
5
  export { createModelClassAnnotationTag, createModelFieldAnnotationTag, getModelClassAnnotationTagProperties, getModelFieldAnnotationTagProperties } from './model/plugin.mjs';
@@ -10,7 +10,7 @@ require('uuid');
10
10
  var Pair = require('../../data-structures/array/Pair.cjs');
11
11
  var model = require('../model/model.cjs');
12
12
  var property = require('../model/property.cjs');
13
- var types = require('../model/types.cjs');
13
+ require('../model/types.cjs');
14
14
  require('../model/credentials.cjs');
15
15
 
16
16
  class PersistedCachedRecord extends model.Model {
@@ -65,7 +65,7 @@ class Cache {
65
65
  .get(transformedKey)
66
66
  .thenApply(({ value }) => {
67
67
  if (value) {
68
- const val = PersistedCachedRecord.fromString(value, types.DataFormat.JSON);
68
+ const val = PersistedCachedRecord.fromString(value);
69
69
  val.value = this.decode(val.value);
70
70
  return val;
71
71
  }
@@ -109,7 +109,7 @@ class Cache {
109
109
  }
110
110
  values() {
111
111
  var _a, _b;
112
- return ((_b = (_a = this.persistStore) === null || _a === void 0 ? void 0 : _a.values().map((v) => PersistedCachedRecord.fromString(v, types.DataFormat.JSON)).map((v) => v.value)) !== null && _b !== void 0 ? _b : stream.Stream.of(this.valuesSync()));
112
+ return ((_b = (_a = this.persistStore) === null || _a === void 0 ? void 0 : _a.values().map((v) => PersistedCachedRecord.fromString(v)).map((v) => v.value)) !== null && _b !== void 0 ? _b : stream.Stream.of(this.valuesSync()));
113
113
  }
114
114
  valuesSync() {
115
115
  return this.memStore.values(true);
@@ -8,7 +8,7 @@ import 'uuid';
8
8
  import { pair } from '../../data-structures/array/Pair.mjs';
9
9
  import { Model } from '../model/model.mjs';
10
10
  import { Field } from '../model/property.mjs';
11
- import { DataFormat } from '../model/types.mjs';
11
+ import '../model/types.mjs';
12
12
  import '../model/credentials.mjs';
13
13
 
14
14
  class PersistedCachedRecord extends Model {
@@ -63,7 +63,7 @@ class Cache {
63
63
  .get(transformedKey)
64
64
  .thenApply(({ value }) => {
65
65
  if (value) {
66
- const val = PersistedCachedRecord.fromString(value, DataFormat.JSON);
66
+ const val = PersistedCachedRecord.fromString(value);
67
67
  val.value = this.decode(val.value);
68
68
  return val;
69
69
  }
@@ -107,7 +107,7 @@ class Cache {
107
107
  }
108
108
  values() {
109
109
  var _a, _b;
110
- return ((_b = (_a = this.persistStore) === null || _a === void 0 ? void 0 : _a.values().map((v) => PersistedCachedRecord.fromString(v, DataFormat.JSON)).map((v) => v.value)) !== null && _b !== void 0 ? _b : Stream.of(this.valuesSync()));
110
+ return ((_b = (_a = this.persistStore) === null || _a === void 0 ? void 0 : _a.values().map((v) => PersistedCachedRecord.fromString(v)).map((v) => v.value)) !== null && _b !== void 0 ? _b : Stream.of(this.valuesSync()));
111
111
  }
112
112
  valuesSync() {
113
113
  return this.memStore.values(true);
@@ -77,7 +77,7 @@ class EventSourceService extends NetworkService.NetworkService {
77
77
  .map((data) => {
78
78
  if (config.responseClass.prototype instanceof model.Model) {
79
79
  const ModelClass = config.responseClass;
80
- return ModelClass.fromString(data, config.dataFormat);
80
+ return ModelClass.fromString(data, { format: config.dataFormat });
81
81
  }
82
82
  return config.responseClass(data, config.dataFormat);
83
83
  })
@@ -56,7 +56,7 @@ class EventSourceService extends NetworkService {
56
56
  .map((data) => {
57
57
  if (config.responseClass.prototype instanceof Model) {
58
58
  const ModelClass = config.responseClass;
59
- return ModelClass.fromString(data, config.dataFormat);
59
+ return ModelClass.fromString(data, { format: config.dataFormat });
60
60
  }
61
61
  return config.responseClass(data, config.dataFormat);
62
62
  })
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"gingersnap","version":"0.23.10","description":"A general purpose library built with the aim of filling the gaps of javascript shortcomings","dependencies":{"@msgpack/msgpack":"^3.0.0-beta2","browser-or-node":"^3.0.0-pre.0","modern-isomorphic-ws":"^1.0.5","object-hash":"^3.0.0","papaparse":"^5.4.1","protobufjs":"^7.2.6","ramda":"^0.30.1","reflect-metadata":"^0.2.2","tslib":"^2.6.3","uuid":"^9.0.1","ws":"^8.16.0","x2js":"^3.4.4"},"author":"CookieNerds LLC","exports":{"./synchronize":{"import":{"types":"./synchronize.d.ts","default":"./synchronize.mjs"},"require":{"types":"./synchronize.d.ts","default":"./synchronize.cjs"}},"./mocks":{"import":{"types":"./mocks.d.ts","default":"./mocks.mjs"},"require":{"types":"./mocks.d.ts","default":"./mocks.cjs"}},"./socket":{"import":{"types":"./socket.d.ts","default":"./socket.mjs"},"require":{"types":"./socket.d.ts","default":"./socket.cjs"}},"./typing":{"import":{"types":"./typing.d.ts","default":"./typing.mjs"},"require":{"types":"./typing.d.ts","default":"./typing.cjs"}},"./stream":{"import":{"types":"./stream/index.d.ts","default":"./stream.mjs"},"require":{"types":"./stream/index.d.ts","default":"./stream.cjs"}},"./reflection/injector":{"import":{"types":"./reflection/injector.d.ts","default":"./reflection/injector.mjs"},"require":{"types":"./reflection/injector.d.ts","default":"./reflection/injector.cjs"}},"./stream/call":{"import":{"types":"./stream/call.d.ts","default":"./stream/call.mjs"},"require":{"types":"./stream/call.d.ts","default":"./stream/call.cjs"}},"./stream/state":{"import":{"types":"./stream/state.d.ts","default":"./stream/state.mjs"},"require":{"types":"./stream/state.d.ts","default":"./stream/state.cjs"}},"./stream/collector":{"import":{"types":"./stream/collector.d.ts","default":"./stream/collector.mjs"},"require":{"types":"./stream/collector.d.ts","default":"./stream/collector.cjs"}},"./stream/observable":{"import":{"types":"./stream/observable.d.ts","default":"./stream/observable.mjs"},"require":{"types":"./stream/observable.d.ts","default":"./stream/observable.cjs"}},"./networking":{"import":{"types":"./networking/index.d.ts","default":"./networking.mjs"},"require":{"types":"./networking/index.d.ts","default":"./networking.cjs"}},"./managers":{"import":{"types":"./managers/index.d.ts","default":"./managers.mjs"},"require":{"types":"./managers/index.d.ts","default":"./managers.cjs"}},"./future":{"import":{"types":"./future/index.d.ts","default":"./future.mjs"},"require":{"types":"./future/index.d.ts","default":"./future.cjs"}},"./errors":{"import":{"types":"./errors/index.d.ts","default":"./errors.mjs"},"require":{"types":"./errors/index.d.ts","default":"./errors.cjs"}},"./data-structures/array":{"import":{"types":"./data-structures/array/index.d.ts","default":"./data-structures/array.mjs"},"require":{"types":"./data-structures/array/index.d.ts","default":"./data-structures/array.cjs"}},"./data-structures/object":{"import":{"types":"./data-structures/object/index.d.ts","default":"./data-structures/object.mjs"},"require":{"types":"./data-structures/object/index.d.ts","default":"./data-structures/object.cjs"}},"./data/decoders":{"import":{"types":"./data/decoders/index.d.ts","default":"./data/decoders.mjs"},"require":{"types":"./data/decoders/index.d.ts","default":"./data/decoders.cjs"}},"./data/model":{"import":{"types":"./data/model/index.d.ts","default":"./data/model.mjs"},"require":{"types":"./data/model/index.d.ts","default":"./data/model.cjs"}},"./data/bus":{"import":{"types":"./data/bus.d.ts","default":"./data/bus.mjs"},"require":{"types":"./data/bus.d.ts","default":"./data/bus.cjs"}},"./data/AtomicValue":{"import":{"types":"./data/AtomicValue.d.ts","default":"./data/AtomicValue.mjs"},"require":{"types":"./data/AtomicValue.d.ts","default":"./data/AtomicValue.cjs"}},"./data/store":{"import":{"types":"./data/store/index.d.ts","default":"./data/store.mjs"},"require":{"types":"./data/store/index.d.ts","default":"./data/store.cjs"}},"./functools":{"import":{"types":"./functools/index.d.ts","default":"./functools.mjs"},"require":{"types":"./functools/index.d.ts","default":"./functools.cjs"}}}}
1
+ {"name":"gingersnap","version":"0.23.12","description":"A general purpose library built with the aim of filling the gaps of javascript shortcomings","dependencies":{"@msgpack/msgpack":"^3.0.0-beta2","browser-or-node":"^3.0.0-pre.0","modern-isomorphic-ws":"^1.0.5","object-hash":"^3.0.0","papaparse":"^5.4.1","protobufjs":"^7.2.6","ramda":"^0.30.1","reflect-metadata":"^0.2.2","tslib":"^2.6.3","uuid":"^9.0.1","ws":"^8.16.0","x2js":"^3.4.4"},"author":"CookieNerds LLC","exports":{"./synchronize":{"import":{"types":"./synchronize.d.ts","default":"./synchronize.mjs"},"require":{"types":"./synchronize.d.ts","default":"./synchronize.cjs"}},"./mocks":{"import":{"types":"./mocks.d.ts","default":"./mocks.mjs"},"require":{"types":"./mocks.d.ts","default":"./mocks.cjs"}},"./socket":{"import":{"types":"./socket.d.ts","default":"./socket.mjs"},"require":{"types":"./socket.d.ts","default":"./socket.cjs"}},"./typing":{"import":{"types":"./typing.d.ts","default":"./typing.mjs"},"require":{"types":"./typing.d.ts","default":"./typing.cjs"}},"./stream":{"import":{"types":"./stream/index.d.ts","default":"./stream.mjs"},"require":{"types":"./stream/index.d.ts","default":"./stream.cjs"}},"./reflection/injector":{"import":{"types":"./reflection/injector.d.ts","default":"./reflection/injector.mjs"},"require":{"types":"./reflection/injector.d.ts","default":"./reflection/injector.cjs"}},"./stream/call":{"import":{"types":"./stream/call.d.ts","default":"./stream/call.mjs"},"require":{"types":"./stream/call.d.ts","default":"./stream/call.cjs"}},"./stream/state":{"import":{"types":"./stream/state.d.ts","default":"./stream/state.mjs"},"require":{"types":"./stream/state.d.ts","default":"./stream/state.cjs"}},"./stream/collector":{"import":{"types":"./stream/collector.d.ts","default":"./stream/collector.mjs"},"require":{"types":"./stream/collector.d.ts","default":"./stream/collector.cjs"}},"./stream/observable":{"import":{"types":"./stream/observable.d.ts","default":"./stream/observable.mjs"},"require":{"types":"./stream/observable.d.ts","default":"./stream/observable.cjs"}},"./networking":{"import":{"types":"./networking/index.d.ts","default":"./networking.mjs"},"require":{"types":"./networking/index.d.ts","default":"./networking.cjs"}},"./managers":{"import":{"types":"./managers/index.d.ts","default":"./managers.mjs"},"require":{"types":"./managers/index.d.ts","default":"./managers.cjs"}},"./future":{"import":{"types":"./future/index.d.ts","default":"./future.mjs"},"require":{"types":"./future/index.d.ts","default":"./future.cjs"}},"./errors":{"import":{"types":"./errors/index.d.ts","default":"./errors.mjs"},"require":{"types":"./errors/index.d.ts","default":"./errors.cjs"}},"./data-structures/array":{"import":{"types":"./data-structures/array/index.d.ts","default":"./data-structures/array.mjs"},"require":{"types":"./data-structures/array/index.d.ts","default":"./data-structures/array.cjs"}},"./data-structures/object":{"import":{"types":"./data-structures/object/index.d.ts","default":"./data-structures/object.mjs"},"require":{"types":"./data-structures/object/index.d.ts","default":"./data-structures/object.cjs"}},"./data/decoders":{"import":{"types":"./data/decoders/index.d.ts","default":"./data/decoders.mjs"},"require":{"types":"./data/decoders/index.d.ts","default":"./data/decoders.cjs"}},"./data/model":{"import":{"types":"./data/model/index.d.ts","default":"./data/model.mjs"},"require":{"types":"./data/model/index.d.ts","default":"./data/model.cjs"}},"./data/bus":{"import":{"types":"./data/bus.d.ts","default":"./data/bus.mjs"},"require":{"types":"./data/bus.d.ts","default":"./data/bus.cjs"}},"./data/AtomicValue":{"import":{"types":"./data/AtomicValue.d.ts","default":"./data/AtomicValue.mjs"},"require":{"types":"./data/AtomicValue.d.ts","default":"./data/AtomicValue.cjs"}},"./data/store":{"import":{"types":"./data/store/index.d.ts","default":"./data/store.mjs"},"require":{"types":"./data/store/index.d.ts","default":"./data/store.cjs"}},"./functools":{"import":{"types":"./functools/index.d.ts","default":"./functools.mjs"},"require":{"types":"./functools/index.d.ts","default":"./functools.cjs"}}}}
package/stream/index.d.ts CHANGED
@@ -144,6 +144,7 @@ export declare class Stream<T> implements AsyncGenerator<T> {
144
144
  * @param callback
145
145
  */
146
146
  filter(callback: (v: T) => boolean | Promise<boolean> | Future<boolean>): Stream<T>;
147
+ filterNotNull(): Stream<NonNullable<T>>;
147
148
  reduce<K, V>(initialData: K, functor: (v: T, prev: K | V) => V, exhaustive?: boolean): Stream<V>;
148
149
  reduceWhile<K, V>(predicate: (v: T) => boolean, initialData: K, functor: (v: T, prev: K | V) => V, exhaustive?: boolean): Stream<V>;
149
150
  /**
package/stream.cjs CHANGED
@@ -396,6 +396,9 @@ class Stream {
396
396
  });
397
397
  return this;
398
398
  }
399
+ filterNotNull() {
400
+ return this.filter((it) => it !== null || it !== undefined);
401
+ }
399
402
  reduce(initialData, functor, exhaustive = true) {
400
403
  if (!this.canAlterStream)
401
404
  throw new IllegalOperationError.IllegalOperationError("Cannot alter the stream as it is frozen");
package/stream.mjs CHANGED
@@ -375,6 +375,9 @@ class Stream {
375
375
  });
376
376
  return this;
377
377
  }
378
+ filterNotNull() {
379
+ return this.filter((it) => it !== null || it !== undefined);
380
+ }
378
381
  reduce(initialData, functor, exhaustive = true) {
379
382
  if (!this.canAlterStream)
380
383
  throw new IllegalOperationError("Cannot alter the stream as it is frozen");