@lowdefy/helpers 6.0.0 → 6.2.0
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/dist/builtinMessages.js +1 -0
- package/dist/extractErrorProps.js +64 -58
- package/dist/index.js +3 -1
- package/dist/mapPlainValues.js +51 -0
- package/dist/projectCaughtError.js +84 -0
- package/dist/serializer.js +7 -20
- package/package.json +2 -2
package/dist/builtinMessages.js
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
'errorPage.name': 'Error',
|
|
25
25
|
'errorPage.message': 'An error has occurred.',
|
|
26
26
|
'errorPage.homeLink': 'Return to home page',
|
|
27
|
+
'server.genericError': 'Something went wrong.',
|
|
27
28
|
// Agent runtime — surfaces in browser as HTTP error responses / streamed errors
|
|
28
29
|
'agent.runtime.methodNotAllowed': 'Only POST requests are supported.',
|
|
29
30
|
'agent.runtime.invalidPath': 'Invalid agent path',
|
|
@@ -46,8 +46,22 @@ function symbolMarker(val) {
|
|
|
46
46
|
}
|
|
47
47
|
const MAX_CAUSE_DEPTH = 3;
|
|
48
48
|
const MAX_OBJECT_DEPTH = 5;
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
// Today's fields in today's order. The own `cause` key is skipped in the spread
|
|
50
|
+
// so an assigned (and therefore enumerable) cause is not listed twice.
|
|
51
|
+
function defaultProjection(err) {
|
|
52
|
+
const props = {
|
|
53
|
+
message: err.message,
|
|
54
|
+
name: err.name,
|
|
55
|
+
stack: err.stack,
|
|
56
|
+
cause: err.cause
|
|
57
|
+
};
|
|
58
|
+
for (const key of Object.keys(err)){
|
|
59
|
+
if (key === 'cause') continue;
|
|
60
|
+
props[key] = err[key];
|
|
61
|
+
}
|
|
62
|
+
return props;
|
|
63
|
+
}
|
|
64
|
+
function cleanValue(val, seen, objectDepth, causeDepth, project) {
|
|
51
65
|
if (objectDepth > MAX_OBJECT_DEPTH) return '[Truncated]';
|
|
52
66
|
if (typeof val === 'function') return functionMarker(val);
|
|
53
67
|
if (typeof val === 'bigint') return bigintMarker(val);
|
|
@@ -56,81 +70,73 @@ function cleanValue(val, seen, objectDepth, causeDepth, omit) {
|
|
|
56
70
|
if (seen.has(val)) return '[Circular]';
|
|
57
71
|
seen.add(val);
|
|
58
72
|
if (Array.isArray(val)) {
|
|
59
|
-
return val.map((item)=>cleanValue(item, seen, objectDepth + 1, causeDepth,
|
|
73
|
+
return val.map((item)=>cleanValue(item, seen, objectDepth + 1, causeDepth, project));
|
|
60
74
|
}
|
|
61
75
|
if (val instanceof Date) return val;
|
|
62
|
-
if (val instanceof Error) return _extractErrorProps(val, seen, objectDepth, causeDepth,
|
|
76
|
+
if (val instanceof Error) return _extractErrorProps(val, seen, objectDepth, causeDepth, project);
|
|
63
77
|
if (!isPlainObject(val)) return classInstanceMarker(val);
|
|
64
78
|
const cleaned = {};
|
|
65
79
|
for (const [k, v] of Object.entries(val)){
|
|
66
|
-
const cv = cleanValue(v, seen, objectDepth + 1, causeDepth,
|
|
80
|
+
const cv = cleanValue(v, seen, objectDepth + 1, causeDepth, project);
|
|
67
81
|
if (cv !== undefined) cleaned[k] = cv;
|
|
68
82
|
}
|
|
69
83
|
return cleaned;
|
|
70
84
|
}
|
|
71
|
-
function
|
|
85
|
+
function cleanCause(cause, seen, objectDepth, causeDepth, project) {
|
|
86
|
+
if (!(cause instanceof Error)) {
|
|
87
|
+
return cleanValue(cause, seen, objectDepth + 1, causeDepth, project);
|
|
88
|
+
}
|
|
89
|
+
if (seen.has(cause)) return '[Circular]';
|
|
90
|
+
if (causeDepth >= MAX_CAUSE_DEPTH) return '[Truncated]';
|
|
91
|
+
return _extractErrorProps(cause, seen, objectDepth, causeDepth + 1, project);
|
|
92
|
+
}
|
|
93
|
+
function cleanPropValue(value, seen, objectDepth, causeDepth, project) {
|
|
94
|
+
if (typeof value === 'function') return functionMarker(value);
|
|
95
|
+
if (typeof value === 'bigint') return bigintMarker(value);
|
|
96
|
+
if (typeof value === 'symbol') return symbolMarker(value);
|
|
97
|
+
if (value === null || typeof value !== 'object') return value;
|
|
98
|
+
if (value instanceof Date) return value;
|
|
99
|
+
if (Array.isArray(value)) return cleanValue(value, seen, objectDepth + 1, causeDepth, project);
|
|
100
|
+
if (value instanceof Error) {
|
|
101
|
+
if (seen.has(value)) return '[Circular]';
|
|
102
|
+
return _extractErrorProps(value, seen, objectDepth, causeDepth, project);
|
|
103
|
+
}
|
|
104
|
+
if (isPlainObject(value)) return cleanValue(value, seen, objectDepth + 1, causeDepth, project);
|
|
105
|
+
// A class instance (Socket, Agent, ClientRequest, ...). Its internals are never exposed —
|
|
106
|
+
// only the type name — but the key must not vanish: an absent key is indistinguishable
|
|
107
|
+
// from "no such field", and this output is now read by `get` as app-visible config data.
|
|
108
|
+
return classInstanceMarker(value);
|
|
109
|
+
}
|
|
110
|
+
function _extractErrorProps(err, seen, objectDepth, causeDepth, project) {
|
|
72
111
|
if (!err) return err;
|
|
73
112
|
seen.add(err);
|
|
74
113
|
// Called at every error node rather than once for the walk, so a caller's
|
|
75
114
|
// policy can key on the node itself - its class, or its own cause value.
|
|
76
115
|
// Which fields an audience may see is the caller's decision, never this
|
|
77
|
-
// walk's; this function only
|
|
78
|
-
//
|
|
79
|
-
// and never marked in `seen`.
|
|
80
|
-
const
|
|
116
|
+
// walk's; this function only cleans the entries it is handed. An entry the
|
|
117
|
+
// projection leaves out is never built, so a dropped cause is never
|
|
118
|
+
// deep-copied and never marked in `seen`.
|
|
119
|
+
const projected = (project ?? defaultProjection)(err);
|
|
81
120
|
const props = {};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (!(err.cause instanceof Error)) {
|
|
87
|
-
props.cause = cleanValue(err.cause, seen, objectDepth + 1, causeDepth, omit);
|
|
88
|
-
} else if (seen.has(err.cause)) {
|
|
89
|
-
props.cause = '[Circular]';
|
|
90
|
-
} else if (causeDepth >= MAX_CAUSE_DEPTH) {
|
|
91
|
-
props.cause = '[Truncated]';
|
|
92
|
-
} else {
|
|
93
|
-
props.cause = _extractErrorProps(err.cause, seen, objectDepth, causeDepth + 1, omit);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
for (const key of Object.keys(err)){
|
|
97
|
-
if (key === 'cause' || omitted.includes(key)) continue;
|
|
98
|
-
const value = err[key];
|
|
99
|
-
if (typeof value === 'function') {
|
|
100
|
-
props[key] = functionMarker(value);
|
|
101
|
-
} else if (typeof value === 'bigint') {
|
|
102
|
-
props[key] = bigintMarker(value);
|
|
103
|
-
} else if (typeof value === 'symbol') {
|
|
104
|
-
props[key] = symbolMarker(value);
|
|
105
|
-
} else if (value === null || typeof value !== 'object') {
|
|
106
|
-
props[key] = value;
|
|
107
|
-
} else if (value instanceof Date) {
|
|
108
|
-
props[key] = value;
|
|
109
|
-
} else if (Array.isArray(value)) {
|
|
110
|
-
props[key] = cleanValue(value, seen, objectDepth + 1, causeDepth, omit);
|
|
111
|
-
} else if (value instanceof Error) {
|
|
112
|
-
if (seen.has(value)) {
|
|
113
|
-
props[key] = '[Circular]';
|
|
114
|
-
} else {
|
|
115
|
-
props[key] = _extractErrorProps(value, seen, objectDepth, causeDepth, omit);
|
|
116
|
-
}
|
|
117
|
-
} else if (isPlainObject(value)) {
|
|
118
|
-
props[key] = cleanValue(value, seen, objectDepth + 1, causeDepth, omit);
|
|
121
|
+
for (const [key, value] of Object.entries(projected)){
|
|
122
|
+
if (value === undefined) continue;
|
|
123
|
+
if (key === 'cause') {
|
|
124
|
+
props.cause = cleanCause(value, seen, objectDepth, causeDepth, project);
|
|
119
125
|
} else {
|
|
120
|
-
|
|
121
|
-
// only the type name — but the key must not vanish: an absent key is indistinguishable
|
|
122
|
-
// from "no such field", and this output is now read by `get` as app-visible config data.
|
|
123
|
-
props[key] = classInstanceMarker(value);
|
|
126
|
+
props[key] = cleanPropValue(value, seen, objectDepth, causeDepth, project);
|
|
124
127
|
}
|
|
125
128
|
}
|
|
126
129
|
return props;
|
|
127
130
|
}
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
// project: (err) => object - the props to emit for THIS error node, called once
|
|
132
|
+
// per node. Entries are cleaned as own properties are: Errors recurse through
|
|
133
|
+
// the same `project`, the returned `cause` is walked in place of the original,
|
|
134
|
+
// and `undefined` entries are dropped. Returning neither `message` nor `name` is
|
|
135
|
+
// legal but degrades the wire format rather than just trimming it: serializer's
|
|
136
|
+
// propsToError revives a cause as an Error only when it has a `message`, and
|
|
137
|
+
// looks the Lowdefy error class up by `name`. Leave either out and a round-trip
|
|
138
|
+
// yields plain objects.
|
|
139
|
+
function extractErrorProps(err, { project } = {}) {
|
|
140
|
+
return _extractErrorProps(err, new Set(), 0, 0, project);
|
|
135
141
|
}
|
|
136
142
|
export default extractErrorProps;
|
package/dist/index.js
CHANGED
|
@@ -25,8 +25,10 @@ import getOperatorType from './getOperatorType.js';
|
|
|
25
25
|
import { isReserved, ReservedKeyError } from './ReservedKeyError.js';
|
|
26
26
|
import joinPath from './joinPath.js';
|
|
27
27
|
import LRUCache from './LRUCache.js';
|
|
28
|
+
import mapPlainValues from './mapPlainValues.js';
|
|
28
29
|
import mergeObjects from './mergeObjects.js';
|
|
29
30
|
import omit from './omit.js';
|
|
31
|
+
import projectCaughtError from './projectCaughtError.js';
|
|
30
32
|
import serializer from './serializer.js';
|
|
31
33
|
import set from './set.js';
|
|
32
34
|
import setKey from './setKey.js';
|
|
@@ -39,4 +41,4 @@ import unset from './unset.js';
|
|
|
39
41
|
import unsetKey from './unsetKey.js';
|
|
40
42
|
import urlQuery from './urlQuery.js';
|
|
41
43
|
import wait from './wait.js';
|
|
42
|
-
export { applyArrayIndices, builtinMessages, cachedPromises, extractErrorProps, get, getKey, getLocaleDateFormat, getLocaleDecimalSeparator, getLocaleGroupSeparator, getOperatorType, isReserved, joinPath, LRUCache, mergeObjects, omit, ReservedKeyError, serializer, set, setKey, splitPath, stableStringify, swap, translate, type, unset, unsetKey, urlQuery, wait };
|
|
44
|
+
export { applyArrayIndices, builtinMessages, cachedPromises, extractErrorProps, get, getKey, getLocaleDateFormat, getLocaleDecimalSeparator, getLocaleGroupSeparator, getOperatorType, isReserved, joinPath, LRUCache, mapPlainValues, mergeObjects, omit, projectCaughtError, ReservedKeyError, serializer, set, setKey, splitPath, stableStringify, swap, translate, type, unset, unsetKey, urlQuery, wait };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ // type.isObject also accepts class instances, whose internals a copy would expose.
|
|
16
|
+
function isPlainObject(value) {
|
|
17
|
+
if (value === null || typeof value !== 'object') return false;
|
|
18
|
+
const proto = Object.getPrototypeOf(value);
|
|
19
|
+
return proto === Object.prototype || proto === null;
|
|
20
|
+
}
|
|
21
|
+
function mapNode(value, key, visit, copies) {
|
|
22
|
+
const visited = visit(value, key);
|
|
23
|
+
if (visited !== value) return visited;
|
|
24
|
+
if (!Array.isArray(value) && !isPlainObject(value)) return value;
|
|
25
|
+
// Reusing the copy of an object already seen keeps shared references and cycles
|
|
26
|
+
// intact instead of recursing forever.
|
|
27
|
+
if (copies.has(value)) return copies.get(value);
|
|
28
|
+
if (Array.isArray(value)) {
|
|
29
|
+
const mappedArray = [];
|
|
30
|
+
copies.set(value, mappedArray);
|
|
31
|
+
value.forEach((item)=>{
|
|
32
|
+
mappedArray.push(mapNode(item, undefined, visit, copies));
|
|
33
|
+
});
|
|
34
|
+
return mappedArray;
|
|
35
|
+
}
|
|
36
|
+
const mappedObject = {};
|
|
37
|
+
copies.set(value, mappedObject);
|
|
38
|
+
Object.entries(value).forEach(([entryKey, item])=>{
|
|
39
|
+
mappedObject[entryKey] = mapNode(item, entryKey, visit, copies);
|
|
40
|
+
});
|
|
41
|
+
return mappedObject;
|
|
42
|
+
}
|
|
43
|
+
// Copies the plain objects and arrays in a value, calling visit(value, key) on every
|
|
44
|
+
// node first - key is the object key, undefined for the root and array items. A
|
|
45
|
+
// different return replaces the node; the same value is kept, and descended into
|
|
46
|
+
// when it is a plain object or array. Class instances, Dates and Errors are kept
|
|
47
|
+
// by reference. The input is never mutated.
|
|
48
|
+
function mapPlainValues(value, visit) {
|
|
49
|
+
return mapNode(value, undefined, visit, new Map());
|
|
50
|
+
}
|
|
51
|
+
export default mapPlainValues;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import { lowdefyErrorTypes, readErrorCodes } from '@lowdefy/errors';
|
|
16
|
+
import mapPlainValues from './mapPlainValues.js';
|
|
17
|
+
import type from './type.js';
|
|
18
|
+
function identity(value) {
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function scrubStrings(value, scrub) {
|
|
22
|
+
return mapPlainValues(value, (item)=>type.isString(item) ? scrub(item) : item);
|
|
23
|
+
}
|
|
24
|
+
// Own-key lookup: an error named after an Object.prototype member, such as
|
|
25
|
+
// 'constructor', must fall back to Error rather than pick up that member.
|
|
26
|
+
function prototypeFor(name) {
|
|
27
|
+
if (Object.hasOwn(lowdefyErrorTypes, name)) {
|
|
28
|
+
return lowdefyErrorTypes[name].prototype;
|
|
29
|
+
}
|
|
30
|
+
return Error.prototype;
|
|
31
|
+
}
|
|
32
|
+
function projectNode(error, scrub, seen) {
|
|
33
|
+
seen.add(error);
|
|
34
|
+
const projected = Object.create(prototypeFor(error.name));
|
|
35
|
+
// Non-enumerable, as on a constructed Error, so JSON.stringify skips it: an
|
|
36
|
+
// `_error` sent to a plugin as data (an HTTP body, a database insert) then
|
|
37
|
+
// carries no message. Assigning it would make it enumerable, which is also
|
|
38
|
+
// why this does not go through serializer.copy.
|
|
39
|
+
Object.defineProperty(projected, 'message', {
|
|
40
|
+
value: scrub(error.message),
|
|
41
|
+
enumerable: false,
|
|
42
|
+
writable: true,
|
|
43
|
+
configurable: true
|
|
44
|
+
});
|
|
45
|
+
const { code, statusCode } = readErrorCodes(error);
|
|
46
|
+
const fields = {
|
|
47
|
+
name: error.name,
|
|
48
|
+
code: type.isString(code) ? scrub(code) : code,
|
|
49
|
+
statusCode,
|
|
50
|
+
// The server's error sink sets `handled` once it has logged the error, and
|
|
51
|
+
// the client skips reporting a handled error back to the server. A rethrown
|
|
52
|
+
// `_error` without it would be logged a second time.
|
|
53
|
+
handled: error.handled
|
|
54
|
+
};
|
|
55
|
+
for (const [key, value] of Object.entries(fields)){
|
|
56
|
+
if (!type.isUndefined(value)) projected[key] = value;
|
|
57
|
+
}
|
|
58
|
+
const { cause } = error;
|
|
59
|
+
if (type.isError(cause)) {
|
|
60
|
+
if (!seen.has(cause)) projected.cause = projectNode(cause, scrub, seen);
|
|
61
|
+
} else if (error.name === 'UserError') {
|
|
62
|
+
// The author wrote a UserError's cause and metaData in config; any other
|
|
63
|
+
// class's non-Error cause is library data, such as a response body.
|
|
64
|
+
if (!type.isUndefined(cause)) projected.cause = scrubStrings(cause, scrub);
|
|
65
|
+
}
|
|
66
|
+
if (error.name === 'UserError' && !type.isUndefined(error.metaData)) {
|
|
67
|
+
projected.metaData = scrubStrings(error.metaData, scrub);
|
|
68
|
+
}
|
|
69
|
+
return projected;
|
|
70
|
+
}
|
|
71
|
+
// The value `_error` reads: the caught error rebuilt with only the fields a
|
|
72
|
+
// routine or catch list branches on. `received`, `configKey`, `location`,
|
|
73
|
+
// `source`, `config` and `stack` are left out - `received` can hold a token
|
|
74
|
+
// fetched at runtime that the scrub does not know. The result is an Error, so
|
|
75
|
+
// wherever config sends it on, the serializer's wire policy applies to it.
|
|
76
|
+
function projectCaughtError(error, { scrub = identity } = {}) {
|
|
77
|
+
if (!type.isError(error)) {
|
|
78
|
+
return projectCaughtError(new Error(String(error)), {
|
|
79
|
+
scrub
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return projectNode(error, scrub, new Set());
|
|
83
|
+
}
|
|
84
|
+
export default projectCaughtError;
|
package/dist/serializer.js
CHANGED
|
@@ -12,23 +12,10 @@
|
|
|
12
12
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
|
-
*/ import {
|
|
15
|
+
*/ import { lowdefyErrorTypes } from '@lowdefy/errors';
|
|
16
16
|
import extractErrorProps from './extractErrorProps.js';
|
|
17
17
|
import type from './type.js';
|
|
18
18
|
import stableStringify from './stableStringify.js';
|
|
19
|
-
const lowdefyErrorTypes = {
|
|
20
|
-
ActionError,
|
|
21
|
-
BlockError,
|
|
22
|
-
BuildError,
|
|
23
|
-
ConfigError,
|
|
24
|
-
ConfigWarning,
|
|
25
|
-
LowdefyInternalError,
|
|
26
|
-
OperatorError,
|
|
27
|
-
PluginError,
|
|
28
|
-
RequestError,
|
|
29
|
-
ServiceError,
|
|
30
|
-
UserError
|
|
31
|
-
};
|
|
32
19
|
function propsToError(data) {
|
|
33
20
|
const ErrorClass = lowdefyErrorTypes[data.name] || Error;
|
|
34
21
|
const error = Object.create(ErrorClass.prototype);
|
|
@@ -41,7 +28,7 @@ function propsToError(data) {
|
|
|
41
28
|
}
|
|
42
29
|
return error;
|
|
43
30
|
}
|
|
44
|
-
const makeReplacer = ({ replacer, isoStringDates, skipMarkers,
|
|
31
|
+
const makeReplacer = ({ replacer, isoStringDates, skipMarkers, projectError } = {})=>(key, value)=>{
|
|
45
32
|
let dateReplacer = (date)=>({
|
|
46
33
|
'~d': date.valueOf()
|
|
47
34
|
});
|
|
@@ -57,7 +44,7 @@ const makeReplacer = ({ replacer, isoStringDates, skipMarkers, omitErrorProps }
|
|
|
57
44
|
if (type.isError(newValue)) {
|
|
58
45
|
return {
|
|
59
46
|
'~e': extractErrorProps(newValue, {
|
|
60
|
-
|
|
47
|
+
project: projectError
|
|
61
48
|
})
|
|
62
49
|
};
|
|
63
50
|
}
|
|
@@ -224,7 +211,7 @@ const serialize = (json, options = {})=>{
|
|
|
224
211
|
return JSON.parse(JSON.stringify(json, makeReplacer({
|
|
225
212
|
replacer: options.replacer,
|
|
226
213
|
isoStringDates: options.isoStringDates,
|
|
227
|
-
|
|
214
|
+
projectError: options.projectError
|
|
228
215
|
})));
|
|
229
216
|
};
|
|
230
217
|
const serializeToString = (json, options = {})=>{
|
|
@@ -240,7 +227,7 @@ const serializeToString = (json, options = {})=>{
|
|
|
240
227
|
replacer: makeReplacer({
|
|
241
228
|
replacer: options.replacer,
|
|
242
229
|
skipMarkers: options.skipMarkers,
|
|
243
|
-
|
|
230
|
+
projectError: options.projectError
|
|
244
231
|
}),
|
|
245
232
|
space: options.space
|
|
246
233
|
});
|
|
@@ -249,7 +236,7 @@ const serializeToString = (json, options = {})=>{
|
|
|
249
236
|
replacer: options.replacer,
|
|
250
237
|
isoStringDates: options.isoStringDates,
|
|
251
238
|
skipMarkers: options.skipMarkers,
|
|
252
|
-
|
|
239
|
+
projectError: options.projectError
|
|
253
240
|
}), options.space);
|
|
254
241
|
};
|
|
255
242
|
const deserialize = (json, options = {})=>{
|
|
@@ -265,7 +252,7 @@ const copy = (json, options = {})=>{
|
|
|
265
252
|
if (type.isDate(json)) return new Date(json.valueOf());
|
|
266
253
|
return JSON.parse(JSON.stringify(json, makeReplacer({
|
|
267
254
|
replacer: options.replacer,
|
|
268
|
-
|
|
255
|
+
projectError: options.projectError
|
|
269
256
|
})), makeReviver(options.reviver));
|
|
270
257
|
};
|
|
271
258
|
const serializer = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lowdefy/helpers",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"homepage": "https://lowdefy.com",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"dist/*"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@lowdefy/errors": "6.
|
|
34
|
+
"@lowdefy/errors": "6.2.0",
|
|
35
35
|
"intl-messageformat": "11.2.7"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|