@schukai/monster 3.3.0 → 3.4.1

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 CHANGED
@@ -73,7 +73,7 @@ We do try to work around some browser bugs, but on the whole we don't use polyfi
73
73
  However, many functions can be mapped via [polyfill.io](https://polyfill.io/) and thus the compatibility can be increased.
74
74
 
75
75
  ```html
76
- <script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet"
76
+ <script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,Blob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet"
77
77
  crossorigin="anonymous"
78
78
  referrerpolicy="no-referrer"></script>
79
79
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schukai/monster",
3
- "version": "3.3.0",
3
+ "version": "3.4.1",
4
4
  "description": "Monster is a simple library for creating fast, robust and lightweight websites.",
5
5
  "keywords": [
6
6
  "framework",
@@ -4,9 +4,9 @@
4
4
  */
5
5
 
6
6
  /**
7
- * Namespace for storages
7
+ * Namespace for server
8
8
  *
9
- * @namespace Monster.Data.Datasource.RestAPI
9
+ * @namespace Monster.Data.Datasource.Server
10
10
  * @memberOf Monster.Data.Datasource
11
11
  * @author schukai GmbH
12
12
  */
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright 2022 schukai GmbH
3
+ * SPDX-License-Identifier: AGPL-3.0
4
+ */
5
+
6
+ /**
7
+ * Namespace for storages
8
+ *
9
+ * @namespace Monster.Data.Datasource.Server.RestAPI
10
+ * @memberOf Monster.Data.Datasource.Server
11
+ * @author schukai GmbH
12
+ */
13
+ const ns = {};
@@ -5,7 +5,7 @@
5
5
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
6
  */
7
7
 
8
- import {internalSymbol,instanceSymbol} from "../../../constants.mjs";
8
+ import {internalSymbol,instanceSymbol} from "../../../../constants.mjs";
9
9
 
10
10
  export {WriteError}
11
11
 
@@ -15,7 +15,7 @@ export {WriteError}
15
15
  * @license AGPLv3
16
16
  * @since 1.24.0
17
17
  * @copyright schukai GmbH
18
- * @memberOf Monster.Data.Datasource.RestAPI
18
+ * @memberOf Monster.Data.Datasource.Server.RestAPI
19
19
  * @summary the error is thrown by the rest api in case of error
20
20
  */
21
21
  class WriteError extends Error {
@@ -38,7 +38,7 @@ class WriteError extends Error {
38
38
  * @since 2.1.0
39
39
  */
40
40
  static get [instanceSymbol]() {
41
- return Symbol.for("@schukai/monster/data/datasource/restapi/writeerror");
41
+ return Symbol.for("@schukai/monster/data/datasource/server/restapi/writeerror");
42
42
  }
43
43
 
44
44
  /**
@@ -5,11 +5,11 @@
5
5
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
6
  */
7
7
 
8
- import {internalSymbol,instanceSymbol} from "../../constants.mjs";
9
- import {isObject} from "../../types/is.mjs";
10
- import {Datasource} from "../datasource.mjs";
11
- import {Pathfinder} from "../pathfinder.mjs";
12
- import {Pipe} from "../pipe.mjs";
8
+ import {internalSymbol, instanceSymbol} from "../../../constants.mjs";
9
+ import {isObject} from "../../../types/is.mjs";
10
+ import {Server} from "../server.mjs";
11
+ import {Pathfinder} from "../../pathfinder.mjs";
12
+ import {Pipe} from "../../pipe.mjs";
13
13
  import {WriteError} from "./restapi/writeerror.mjs";
14
14
 
15
15
  export {RestAPI}
@@ -17,29 +17,25 @@ export {RestAPI}
17
17
  /**
18
18
  * The RestAPI is a class that enables a REST API server.
19
19
  *
20
- * @externalExample ../../../example/data/storage/restapi.mjs
20
+ * @externalExample ../../../example/data/storage/restapi.mjs
21
21
  * @license AGPLv3
22
22
  * @since 1.22.0
23
23
  * @copyright schukai GmbH
24
- * @memberOf Monster.Data.Datasource
24
+ * @memberOf Monster.Data.Datasource.Server
25
25
  * @summary The RestAPI is a class that binds a REST API server.
26
26
  */
27
- class RestAPI extends Datasource {
27
+ class RestAPI extends Server {
28
28
 
29
29
  /**
30
30
  *
31
- * @param {Object} [readDefinition] An options object containing any custom settings that you want to apply to the read request.
32
- * @param {Object} [writeDefinition] An options object containing any custom settings that you want to apply to the write request.
31
+ * @param {Object} [options] options contains definitions for the datasource.
33
32
  */
34
- constructor(readDefinition, writeDefinition) {
33
+ constructor(options) {
35
34
  super();
36
35
 
37
- const options = {}
38
-
39
- if (isObject(readDefinition)) options.read = readDefinition;
40
- if (isObject(writeDefinition)) options.write = writeDefinition;
41
-
42
- this.setOptions(options);
36
+ if (isObject(options)) {
37
+ this.setOptions(options);
38
+ }
43
39
 
44
40
  }
45
41
 
@@ -49,9 +45,9 @@ class RestAPI extends Datasource {
49
45
  * @since 2.1.0
50
46
  */
51
47
  static get [instanceSymbol]() {
52
- return Symbol.for("@schukai/monster/data/datasource/restapi");
53
- }
54
-
48
+ return Symbol.for("@schukai/monster/data/datasource/server/restapi");
49
+ }
50
+
55
51
  /**
56
52
  * @property {Object} write={} Options
57
53
  * @property {Object} write.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor}
@@ -64,9 +60,9 @@ class RestAPI extends Datasource {
64
60
  * @property {Monster.Data.Datasource~exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing.
65
61
  * @property {Object} write.report
66
62
  * @property {String} write.report.path Path to validations
67
- * @property {Object} write.sheathing
63
+ * @property {Object} write.sheathing
68
64
  * @property {Object} write.sheathing.object Object to be wrapped
69
- * @property {string} write.sheathing.path Path to the data
65
+ * @property {string} write.sheathing.path Path to the data
70
66
  * @property {Object} read={} Options
71
67
  * @property {Object} read.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor}
72
68
  * @property {string} read.init.method=GET
@@ -124,45 +120,37 @@ class RestAPI extends Datasource {
124
120
  let init = self.getOption('read.init');
125
121
  if (!isObject(init)) init = {};
126
122
 
127
- return fetch(self.getOption('read.url'), init).then(resp => {
128
- response = resp;
123
+ return new Promise((resolve, reject) => {
124
+ fetch(self.getOption('read.url'), init).then(resp => {
125
+ response = resp;
129
126
 
130
- const acceptedStatus = self.getOption('read.acceptedStatus', [200]);
127
+ const acceptedStatus = self.getOption('read.acceptedStatus', [200]);
131
128
 
132
- if (acceptedStatus.indexOf(resp.status) === -1) {
133
- throw Error('the data cannot be read (response ' + resp.status + ')')
134
- }
129
+ if (acceptedStatus.indexOf(resp.status) === -1) {
130
+ throw Error('the data cannot be read (response ' + resp.status + ')')
131
+ }
135
132
 
136
- return resp.text()
137
- }).then(body => {
133
+ return resp.text()
134
+ }).then(body => {
138
135
 
139
- let obj;
136
+ let obj;
140
137
 
141
- try {
142
- obj = JSON.parse(body);
138
+ try {
139
+ obj = JSON.parse(body);
143
140
 
144
- } catch (e) {
141
+ } catch (e) {
145
142
 
146
- if (body.length > 100) {
147
- body = body.substring(0, 97) + '...';
148
- }
143
+ if (body.length > 100) {
144
+ body = body.substring(0, 97) + '...';
145
+ }
149
146
 
150
- throw new Error('the response does not contain a valid json (actual: ' + body + ').');
151
- }
147
+ throw new Error('the response does not contain a valid json (actual: ' + body + ').');
148
+ }
152
149
 
153
- let transformation = self.getOption('read.mapping.transformer');
154
- if (transformation !== undefined) {
155
- const pipe = new Pipe(transformation);
150
+ self.set(self.transformServerPayload.call(self, obj));
151
+ resolve(response);
152
+ }).catch(reject);
156
153
 
157
- for (const callback of self.getOption('read.mapping.callbacks')) {
158
- pipe.setCallback(callback.constructor.name, callback);
159
- }
160
-
161
- obj = pipe.run(obj);
162
- }
163
-
164
- self.set(obj);
165
- return response;
166
154
  })
167
155
  }
168
156
 
@@ -173,7 +161,6 @@ class RestAPI extends Datasource {
173
161
  write() {
174
162
  const self = this;
175
163
 
176
-
177
164
  let init = self.getOption('write.init');
178
165
  if (!isObject(init)) init = {};
179
166
  if (typeof init['headers'] !== 'object') {
@@ -182,42 +169,28 @@ class RestAPI extends Datasource {
182
169
  }
183
170
  }
184
171
 
185
- let obj = self.get();
186
- let transformation = self.getOption('write.mapping.transformer');
187
- if (transformation !== undefined) {
188
- const pipe = new Pipe(transformation);
189
-
190
- for (const callback of self.getOption('write.mapping.callbacks')) {
191
- pipe.setCallback(callback.constructor.name, callback);
192
- }
193
-
194
- obj = pipe.run(obj);
195
- }
196
-
197
- let sheathingObject = self.getOption('write.sheathing.object');
198
- let sheathingPath = self.getOption('write.sheathing.path');
199
- let reportPath = self.getOption('write.report.path');
200
-
201
- if (sheathingObject && sheathingPath) {
202
- const sub = obj;
203
- obj = sheathingObject;
204
- (new Pathfinder(obj)).setVia(sheathingPath, sub);
205
- }
206
-
172
+ let obj = self.prepareServerPayload(self.get());
207
173
  init['body'] = JSON.stringify(obj);
208
174
 
209
- return fetch(self.getOption('write.url'), init).then(response => {
175
+ return new Promise((resolve, reject) => {
176
+ fetch(self.getOption('write.url'), init).then(response => {
177
+ const acceptedStatus = self.getOption('write.acceptedStatus', [200, 201]);
210
178
 
211
- const acceptedStatus = self.getOption('write.acceptedStatus', [200, 2001]);
212
-
213
- if (acceptedStatus.indexOf(response.status) === -1) {
179
+ if (acceptedStatus.indexOf(response.status) > -1) {
180
+ reject(response);
181
+ return;
182
+ }
214
183
 
215
- return response.text().then((body) => {
184
+ response.text().then((body) => {
216
185
 
217
- let obj, validation;
186
+ let obj = {}, validation = {};
218
187
  try {
219
188
  obj = JSON.parse(body);
220
- validation = new Pathfinder(obj).getVia(reportPath)
189
+
190
+ if (reportPath) {
191
+ validation = (new Pathfinder(obj)).getVia(reportPath);
192
+ }
193
+
221
194
 
222
195
  } catch (e) {
223
196
 
@@ -225,18 +198,20 @@ class RestAPI extends Datasource {
225
198
  body = body.substring(0, 97) + '...';
226
199
  }
227
200
 
228
- throw new Error('the response does not contain a valid json (actual: ' + body + ').');
201
+ reject(new Error('the response does not contain a valid json (actual: ' + body + ').'));
202
+ return;
229
203
  }
230
204
 
231
- throw new WriteError('the data cannot be written (response ' + response.status + ')', response, validation)
205
+ reject(new WriteError('the data cannot be written (response ' + response.status + ')', response, validation))
206
+ return;
232
207
 
233
- })
208
+ }).catch(reject);
234
209
 
235
210
 
236
- }
211
+ }).catch(reject);
212
+
213
+ })
237
214
 
238
- return response;
239
- });
240
215
  }
241
216
 
242
217
 
@@ -5,16 +5,13 @@
5
5
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
6
  */
7
7
 
8
- import {internalSymbol, instanceSymbol} from "../../constants.mjs";
9
- import {isString, isObject} from "../../types/is.mjs";
10
- import {WebConnect} from "../../net/webconnect.mjs";
11
- import {Message} from "../../net/webconnect/message.mjs";
12
- import {Datasource} from "../datasource.mjs";
13
- import {Pathfinder} from "../pathfinder.mjs";
14
- import {Pipe} from "../pipe.mjs";
15
-
16
- export {WebSocketDatasource}
8
+ import {internalSymbol, instanceSymbol} from "../../../constants.mjs";
9
+ import {isString, isObject} from "../../../types/is.mjs";
10
+ import {WebConnect as NetWebConnect} from "../../../net/webconnect.mjs";
11
+ import {Message} from "../../../net/webconnect/message.mjs";
12
+ import {Server} from "../server.mjs";
17
13
 
14
+ export {WebConnect}
18
15
 
19
16
  /**
20
17
  * @private
@@ -24,32 +21,7 @@ export {WebSocketDatasource}
24
21
  */
25
22
  const webConnectSymbol = Symbol("connection");
26
23
 
27
- /**
28
- *
29
- * @param self
30
- * @param obj
31
- * @returns {*}
32
- */
33
- function doTransform(type, obj) {
34
- const self = this;
35
- let transformation = self.getOption(type + '.mapping.transformer');
36
- if (transformation !== undefined) {
37
- const pipe = new Pipe(transformation);
38
- const callbacks = self.getOption(type + '.mapping.callbacks')
39
24
 
40
- if (isObject(callbacks)) {
41
- for (const key in callbacks) {
42
- if (callbacks.hasOwnProperty(key) && typeof callbacks[key] === 'function') {
43
- pipe.setCallback(key, callbacks[key]);
44
- }
45
- }
46
- }
47
-
48
- obj = pipe.run(obj);
49
- }
50
-
51
- return obj;
52
- }
53
25
 
54
26
  /**
55
27
  * The RestAPI is a class that enables a REST API server.
@@ -58,10 +30,10 @@ function doTransform(type, obj) {
58
30
  * @license AGPLv3
59
31
  * @since 3.1.0
60
32
  * @copyright schukai GmbH
61
- * @memberOf Monster.Data.Datasource
33
+ * @memberOf Monster.Data.Datasource.Server
62
34
  * @summary The LocalStorage class encapsulates the access to data objects.
63
35
  */
64
- class WebSocketDatasource extends Datasource {
36
+ class WebConnect extends Server {
65
37
 
66
38
  /**
67
39
  *
@@ -78,7 +50,7 @@ class WebSocketDatasource extends Datasource {
78
50
 
79
51
  if (!isObject(options)) options = {};
80
52
  this.setOptions(options);
81
- this[webConnectSymbol] = new WebConnect({
53
+ this[webConnectSymbol] = new NetWebConnect({
82
54
  url: self.getOption('url'),
83
55
  connection: {
84
56
  timeout: self.getOption('connection.timeout'),
@@ -111,7 +83,7 @@ class WebSocketDatasource extends Datasource {
111
83
  * @returns {symbol}
112
84
  */
113
85
  static get [instanceSymbol]() {
114
- return Symbol.for("@schukai/monster/data/datasource/websocket");
86
+ return Symbol.for("@schukai/monster/data/datasource/server/webconnect");
115
87
  }
116
88
 
117
89
  /**
@@ -195,7 +167,6 @@ class WebSocketDatasource extends Datasource {
195
167
  }
196
168
 
197
169
  obj = obj.getData();
198
-
199
170
  obj = self.transformServerPayload.call(self, obj);
200
171
  self.set( obj);
201
172
  }
@@ -206,95 +177,6 @@ class WebSocketDatasource extends Datasource {
206
177
 
207
178
  };
208
179
 
209
- // const self = this;
210
- // let response;
211
- //
212
- // if (self[webConnectSymbol]?.socket?.readyState !== 1) {
213
- // return Promise.reject('The connection is not established.');
214
- // }
215
- //
216
- // return new Promise((resolve, reject) => {
217
- // if (self[receiveQueueSymbol].isEmpty()) {
218
- // resolve();
219
- // }
220
- //
221
- // while (!self[receiveQueueSymbol].isEmpty()) {
222
- //
223
- // const event = self[receiveQueueSymbol].poll();
224
- // const body = event?.data;
225
- // if (!body) continue;
226
- //
227
- // let obj;
228
- // try {
229
- // obj = JSON.parse(body);
230
- // } catch (e) {
231
- //
232
- // let msg = 'the response does not contain a valid json (actual: ';
233
- //
234
- // if (body.length > 100) {
235
- // msg += body.substring(0, 97) + '...';
236
- // } else {
237
- // msg += body;
238
- // }
239
- //
240
- // msg += "; " + e.message + ')';
241
- //
242
- // reject(msg);
243
- // return;
244
- // }
245
- //
246
- // obj = self.transformServerPayload.call(self, obj);
247
- //
248
- //
249
- // self.set(obj);
250
- // return response;
251
- // }
252
- // })
253
- //}
254
-
255
- /**
256
- * This prepares the data that comes from the server.
257
- * Should not be called directly.
258
- *
259
- * @private
260
- * @param {Object} payload
261
- * @returns {Object}
262
- */
263
- transformServerPayload(payload) {
264
- const self = this;
265
- payload = doTransform.call(self, 'read', payload);
266
-
267
- const dataPath = self.getOption('read.path');
268
- if (dataPath) {
269
- payload = (new Pathfinder(payload)).getVia(dataPath);
270
- }
271
-
272
- return payload;
273
- }
274
-
275
- /**
276
- * This prepares the data for writing and should not be called directly.
277
- *
278
- * @private
279
- * @param {Object} payload
280
- * @returns {Object}
281
- */
282
- prepareServerPayload(payload) {
283
- const self = this;
284
-
285
- payload = doTransform.call(self, 'write', payload);
286
-
287
- let sheathingObject = self.getOption('write.sheathing.object');
288
- let sheathingPath = self.getOption('write.sheathing.path');
289
-
290
- if (sheathingObject && sheathingPath) {
291
- const sub = payload;
292
- payload = sheathingObject;
293
- (new Pathfinder(payload)).setVia(sheathingPath, sub);
294
- }
295
-
296
- return payload;
297
- }
298
180
 
299
181
  /**
300
182
  * @return {Promise}
@@ -305,13 +187,12 @@ class WebSocketDatasource extends Datasource {
305
187
  return self[webConnectSymbol].send(obj)
306
188
  }
307
189
 
308
-
309
190
  /**
310
191
  * @return {RestAPI}
311
192
  */
312
193
  getClone() {
313
194
  const self = this;
314
- return new WebSocketDatasource(self[internalSymbol].getRealSubject()['options']);
195
+ return new WebConnect(self[internalSymbol].getRealSubject()['options']);
315
196
  }
316
197
 
317
198
  }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Copyright schukai GmbH and contributors 2022. All Rights Reserved.
3
+ * Node module: @schukai/monster
4
+ * This file is licensed under the AGPLv3 License.
5
+ * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
+ */
7
+
8
+ import {internalSymbol,instanceSymbol} from "../../constants.mjs";
9
+ import {isObject} from "../../types/is.mjs";
10
+ import {Datasource} from "../datasource.mjs";
11
+ import {Pathfinder} from "../pathfinder.mjs";
12
+ import {Pipe} from "../pipe.mjs";
13
+
14
+ export {Server}
15
+
16
+ /**
17
+ * Base class for all server datasources
18
+ *
19
+ * @license AGPLv3
20
+ * @since 3.4.0
21
+ * @copyright schukai GmbH
22
+ * @memberOf Monster.Data.Datasource
23
+ * @summary The Server class encapsulates the access to a server datasource
24
+ */
25
+ class Server extends Datasource {
26
+
27
+ /**
28
+ * This method is called by the `instanceof` operator.
29
+ * @returns {symbol}
30
+ */
31
+ static get [instanceSymbol]() {
32
+ return Symbol.for("@schukai/monster/data/datasource/server");
33
+ }
34
+
35
+
36
+ /**
37
+ * This prepares the data that comes from the server.
38
+ * Should not be called directly.
39
+ *
40
+ * @private
41
+ * @param {Object} payload
42
+ * @returns {Object}
43
+ */
44
+ transformServerPayload(payload) {
45
+ const self = this;
46
+ payload = doTransform.call(self, 'read', payload);
47
+
48
+ const dataPath = self.getOption('read.path');
49
+ if (dataPath) {
50
+ payload = (new Pathfinder(payload)).getVia(dataPath);
51
+ }
52
+
53
+ return payload;
54
+ }
55
+
56
+ /**
57
+ * This prepares the data for writing and should not be called directly.
58
+ *
59
+ * @private
60
+ * @param {Object} payload
61
+ * @returns {Object}
62
+ */
63
+ prepareServerPayload(payload) {
64
+ const self = this;
65
+
66
+ payload = doTransform.call(self, 'write', payload);
67
+
68
+ let sheathingObject = self.getOption('write.sheathing.object');
69
+ let sheathingPath = self.getOption('write.sheathing.path');
70
+
71
+ if (sheathingObject && sheathingPath) {
72
+ const sub = payload;
73
+ payload = sheathingObject;
74
+ (new Pathfinder(payload)).setVia(sheathingPath, sub);
75
+ }
76
+
77
+ return payload;
78
+ }
79
+
80
+ }
81
+
82
+
83
+ /**
84
+ *
85
+ * @param self
86
+ * @param obj
87
+ * @returns {*}
88
+ */
89
+ function doTransform(type, obj) {
90
+ const self = this;
91
+ let transformation = self.getOption(type + '.mapping.transformer');
92
+ if (transformation !== undefined) {
93
+ const pipe = new Pipe(transformation);
94
+ const callbacks = self.getOption(type + '.mapping.callbacks')
95
+
96
+ if (isObject(callbacks)) {
97
+ for (const key in callbacks) {
98
+ if (callbacks.hasOwnProperty(key) && typeof callbacks[key] === 'function') {
99
+ pipe.setCallback(key, callbacks[key]);
100
+ }
101
+ }
102
+ }
103
+
104
+ obj = pipe.run(obj);
105
+ }
106
+
107
+ return obj;
108
+ }
@@ -191,7 +191,7 @@ class Locale extends Base {
191
191
  *
192
192
  * ```
193
193
  * <script type="module">
194
- * import {Monster} from '@schukai/monster/source//monster.mjs';
194
+ * import {Monster} from '@schukai/monster/source/monster.mjs';
195
195
  * new Monster.I18n.createLocale()
196
196
  * </script>
197
197
  * ```