@chubbyts/chubbyts-decode-encode 1.2.0 → 1.3.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/README.md +5 -5
- package/dist/decoder/index.d.ts +1 -1
- package/dist/decoder/index.mjs +19 -0
- package/dist/decoder/{json-type-decoder.js → json-type-decoder.cjs} +2 -2
- package/dist/decoder/json-type-decoder.d.ts +1 -1
- package/dist/decoder/json-type-decoder.mjs +16 -0
- package/dist/decoder/{jsonx-type-decoder.js → jsonx-type-decoder.cjs} +3 -3
- package/dist/decoder/jsonx-type-decoder.d.ts +1 -1
- package/dist/decoder/jsonx-type-decoder.mjs +91 -0
- package/dist/decoder/{url-encoded-type-decoder.js → url-encoded-type-decoder.cjs} +3 -3
- package/dist/decoder/url-encoded-type-decoder.d.ts +1 -1
- package/dist/decoder/url-encoded-type-decoder.mjs +34 -0
- package/dist/decoder/{yaml-type-decoder.js → yaml-type-decoder.cjs} +2 -2
- package/dist/decoder/yaml-type-decoder.d.ts +1 -1
- package/dist/decoder/yaml-type-decoder.mjs +17 -0
- package/dist/encoder/index.d.ts +1 -1
- package/dist/encoder/index.mjs +19 -0
- package/dist/encoder/json-type-encoder.d.ts +1 -1
- package/dist/encoder/json-type-encoder.mjs +6 -0
- package/dist/encoder/{jsonx-type-encoder.js → jsonx-type-encoder.cjs} +10 -10
- package/dist/encoder/jsonx-type-encoder.d.ts +1 -1
- package/dist/encoder/jsonx-type-encoder.mjs +173 -0
- package/dist/encoder/{url-encoded-type-encoder.js → url-encoded-type-encoder.cjs} +6 -6
- package/dist/encoder/url-encoded-type-encoder.d.ts +1 -1
- package/dist/encoder/url-encoded-type-encoder.mjs +26 -0
- package/dist/encoder/yaml-type-encoder.d.ts +1 -1
- package/dist/encoder/yaml-type-encoder.mjs +7 -0
- package/dist/index.mjs +6 -0
- package/dist/jsonx-datatypes.mjs +6 -0
- package/package.json +29 -19
- /package/dist/decoder/{index.js → index.cjs} +0 -0
- /package/dist/encoder/{index.js → index.cjs} +0 -0
- /package/dist/encoder/{json-type-encoder.js → json-type-encoder.cjs} +0 -0
- /package/dist/encoder/{yaml-type-encoder.js → yaml-type-encoder.cjs} +0 -0
- /package/dist/{index.js → index.cjs} +0 -0
- /package/dist/{jsonx-datatypes.js → jsonx-datatypes.cjs} +0 -0
package/README.md
CHANGED
|
@@ -24,17 +24,17 @@ A simple decode/encode solution for json / jsonx / url-encoded / xml / yaml.
|
|
|
24
24
|
## Requirements
|
|
25
25
|
|
|
26
26
|
* node: 16
|
|
27
|
-
* [@chubbyts/chubbyts-throwable-to-error][2]: ^1.1
|
|
28
|
-
* [fast-xml-parser][3]: ^4.2.
|
|
29
|
-
* [qs][4]: ^6.11.
|
|
30
|
-
* [yaml][5]: ^2.
|
|
27
|
+
* [@chubbyts/chubbyts-throwable-to-error][2]: ^1.2.1
|
|
28
|
+
* [fast-xml-parser][3]: ^4.2.6
|
|
29
|
+
* [qs][4]: ^6.11.2
|
|
30
|
+
* [yaml][5]: ^2.3.1
|
|
31
31
|
|
|
32
32
|
## Installation
|
|
33
33
|
|
|
34
34
|
Through [NPM](https://www.npmjs.com) as [@chubbyts/chubbyts-decode-encode][1].
|
|
35
35
|
|
|
36
36
|
```ts
|
|
37
|
-
npm i @chubbyts/chubbyts-decode-encode@^1.
|
|
37
|
+
npm i @chubbyts/chubbyts-decode-encode@^1.3.0
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
## Usage
|
package/dist/decoder/index.d.ts
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class DecodeError extends Error {
|
|
2
|
+
constructor(message, stack) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.stack = stack;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export const createDecoder = (decoderTypes) => {
|
|
8
|
+
const decoderTypeMap = new Map(decoderTypes.map((DecoderType) => [DecoderType.contentType, DecoderType]));
|
|
9
|
+
const contentTypes = Array.from(decoderTypeMap.keys());
|
|
10
|
+
return {
|
|
11
|
+
decode: (encodedData, contentType) => {
|
|
12
|
+
if (decoderTypeMap.has(contentType)) {
|
|
13
|
+
return decoderTypeMap.get(contentType).decode(encodedData);
|
|
14
|
+
}
|
|
15
|
+
throw new Error(`Unsupported contentType "${contentType}", supported contentTypes are "${contentTypes.join('", "')}".`);
|
|
16
|
+
},
|
|
17
|
+
contentTypes,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createJsonTypeDecoder = void 0;
|
|
4
4
|
const throwable_to_error_1 = require("@chubbyts/chubbyts-throwable-to-error/dist/throwable-to-error");
|
|
5
|
-
const
|
|
5
|
+
const index_1 = require("./index.cjs");
|
|
6
6
|
const createJsonTypeDecoder = () => {
|
|
7
7
|
return {
|
|
8
8
|
decode: (encodedData) => {
|
|
@@ -11,7 +11,7 @@ const createJsonTypeDecoder = () => {
|
|
|
11
11
|
}
|
|
12
12
|
catch (e) {
|
|
13
13
|
const error = (0, throwable_to_error_1.throwableToError)(e);
|
|
14
|
-
throw new
|
|
14
|
+
throw new index_1.DecodeError(error.message, error.stack);
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
contentType: 'application/json',
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { TypeDecoder } from '
|
|
1
|
+
import type { TypeDecoder } from './index';
|
|
2
2
|
export declare const createJsonTypeDecoder: () => TypeDecoder;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { throwableToError } from '@chubbyts/chubbyts-throwable-to-error/dist/throwable-to-error';
|
|
2
|
+
import { DecodeError } from './index.mjs';
|
|
3
|
+
export const createJsonTypeDecoder = () => {
|
|
4
|
+
return {
|
|
5
|
+
decode: (encodedData) => {
|
|
6
|
+
try {
|
|
7
|
+
return JSON.parse(encodedData);
|
|
8
|
+
}
|
|
9
|
+
catch (e) {
|
|
10
|
+
const error = throwableToError(e);
|
|
11
|
+
throw new DecodeError(error.message, error.stack);
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
contentType: 'application/json',
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createJsonxTypeDecoder = void 0;
|
|
4
4
|
const fast_xml_parser_1 = require("fast-xml-parser");
|
|
5
5
|
const throwable_to_error_1 = require("@chubbyts/chubbyts-throwable-to-error/dist/throwable-to-error");
|
|
6
|
-
const jsonx_datatypes_1 = require("../jsonx-datatypes");
|
|
7
|
-
const
|
|
6
|
+
const jsonx_datatypes_1 = require("../jsonx-datatypes.cjs");
|
|
7
|
+
const index_1 = require("./index.cjs");
|
|
8
8
|
const decodeHtmlEntities = (string) => string.replace(/&#\d+;/gm, (code) => String.fromCharCode(code.match(/\d+/)[0]));
|
|
9
9
|
const isWithName = (node) => typeof node === 'object' &&
|
|
10
10
|
null !== node &&
|
|
@@ -86,7 +86,7 @@ const createJsonxTypeDecoder = () => {
|
|
|
86
86
|
}
|
|
87
87
|
catch (e) {
|
|
88
88
|
const error = (0, throwable_to_error_1.throwableToError)(e);
|
|
89
|
-
throw new
|
|
89
|
+
throw new index_1.DecodeError(error.message, error.stack);
|
|
90
90
|
}
|
|
91
91
|
},
|
|
92
92
|
contentType: 'application/jsonx+xml',
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { TypeDecoder } from '
|
|
1
|
+
import type { TypeDecoder } from './index';
|
|
2
2
|
export declare const createJsonxTypeDecoder: () => TypeDecoder;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { XMLParser } from 'fast-xml-parser';
|
|
2
|
+
import { throwableToError } from '@chubbyts/chubbyts-throwable-to-error/dist/throwable-to-error';
|
|
3
|
+
import { DATATYPE_ARRAY, DATATYPE_BOOLEAN, DATATYPE_NULL, DATATYPE_NUMBER, DATATYPE_OBJECT, DATATYPE_STRING, } from '../jsonx-datatypes.mjs';
|
|
4
|
+
import { DecodeError } from './index.mjs';
|
|
5
|
+
const decodeHtmlEntities = (string) => string.replace(/&#\d+;/gm, (code) => String.fromCharCode(code.match(/\d+/)[0]));
|
|
6
|
+
const isWithName = (node) => typeof node === 'object' &&
|
|
7
|
+
null !== node &&
|
|
8
|
+
typeof node[':@'] === 'object' &&
|
|
9
|
+
node[':@'] !== null &&
|
|
10
|
+
typeof node[':@']['@_name'] === 'string';
|
|
11
|
+
const isObjectNode = (node) => Object.keys(node)[0] === DATATYPE_OBJECT && Array.isArray(node[DATATYPE_OBJECT]);
|
|
12
|
+
const isArrayNode = (node) => Object.keys(node)[0] === DATATYPE_ARRAY && Array.isArray(node[DATATYPE_ARRAY]);
|
|
13
|
+
const isStringNode = (node) => Object.keys(node)[0] === DATATYPE_STRING && Array.isArray(node[DATATYPE_STRING]);
|
|
14
|
+
const isNumberNode = (node) => Object.keys(node)[0] === DATATYPE_NUMBER && Array.isArray(node[DATATYPE_NUMBER]);
|
|
15
|
+
const isBooleanNode = (node) => Object.keys(node)[0] === DATATYPE_BOOLEAN && Array.isArray(node[DATATYPE_BOOLEAN]);
|
|
16
|
+
const isNullNode = (node) => Object.keys(node)[0] === DATATYPE_NULL && Array.isArray(node[DATATYPE_NULL]);
|
|
17
|
+
const convertNullNode = () => {
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
const convertBooleanNode = (node) => {
|
|
21
|
+
return node['json:boolean'][0]['#text'];
|
|
22
|
+
};
|
|
23
|
+
const convertNumberNode = (node) => {
|
|
24
|
+
return node['json:number'][0]['#text'];
|
|
25
|
+
};
|
|
26
|
+
const convertStringNode = (node) => {
|
|
27
|
+
return decodeHtmlEntities(node['json:string'][0]['#text']);
|
|
28
|
+
};
|
|
29
|
+
const convertNode = (node) => {
|
|
30
|
+
if (isObjectNode(node)) {
|
|
31
|
+
return convertObjectNode(node);
|
|
32
|
+
}
|
|
33
|
+
else if (isArrayNode(node)) {
|
|
34
|
+
return convertArrayNode(node);
|
|
35
|
+
}
|
|
36
|
+
else if (isStringNode(node)) {
|
|
37
|
+
return convertStringNode(node);
|
|
38
|
+
}
|
|
39
|
+
else if (isNumberNode(node)) {
|
|
40
|
+
return convertNumberNode(node);
|
|
41
|
+
}
|
|
42
|
+
else if (isBooleanNode(node)) {
|
|
43
|
+
return convertBooleanNode(node);
|
|
44
|
+
}
|
|
45
|
+
else if (isNullNode(node)) {
|
|
46
|
+
return convertNullNode();
|
|
47
|
+
}
|
|
48
|
+
throw new Error(`Unsupported node: ${JSON.stringify(node)}`);
|
|
49
|
+
};
|
|
50
|
+
const convertArrayNode = (node) => {
|
|
51
|
+
return node['json:array'].map(convertNode);
|
|
52
|
+
};
|
|
53
|
+
const convertNodeWithName = (node) => {
|
|
54
|
+
if (isObjectNode(node) && isWithName(node)) {
|
|
55
|
+
return [node[':@']['@_name'], convertObjectNode(node)];
|
|
56
|
+
}
|
|
57
|
+
else if (isArrayNode(node) && isWithName(node)) {
|
|
58
|
+
return [node[':@']['@_name'], convertArrayNode(node)];
|
|
59
|
+
}
|
|
60
|
+
else if (isStringNode(node) && isWithName(node)) {
|
|
61
|
+
return [node[':@']['@_name'], convertStringNode(node)];
|
|
62
|
+
}
|
|
63
|
+
else if (isNumberNode(node) && isWithName(node)) {
|
|
64
|
+
return [node[':@']['@_name'], convertNumberNode(node)];
|
|
65
|
+
}
|
|
66
|
+
else if (isBooleanNode(node) && isWithName(node)) {
|
|
67
|
+
return [node[':@']['@_name'], convertBooleanNode(node)];
|
|
68
|
+
}
|
|
69
|
+
else if (isNullNode(node) && isWithName(node)) {
|
|
70
|
+
return [node[':@']['@_name'], convertNullNode()];
|
|
71
|
+
}
|
|
72
|
+
throw new Error(`Unsupported node: ${JSON.stringify(node)}`);
|
|
73
|
+
};
|
|
74
|
+
const convertObjectNode = (node) => {
|
|
75
|
+
return Object.fromEntries(node['json:object'].map(convertNodeWithName));
|
|
76
|
+
};
|
|
77
|
+
export const createJsonxTypeDecoder = () => {
|
|
78
|
+
return {
|
|
79
|
+
decode: (encodedData) => {
|
|
80
|
+
try {
|
|
81
|
+
const parser = new XMLParser({ preserveOrder: true, ignoreAttributes: false, htmlEntities: false });
|
|
82
|
+
return convertNode(parser.parse(encodedData)[1]);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
const error = throwableToError(e);
|
|
86
|
+
throw new DecodeError(error.message, error.stack);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
contentType: 'application/jsonx+xml',
|
|
90
|
+
};
|
|
91
|
+
};
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createUrlEncodedTypeDecoder = void 0;
|
|
4
4
|
const qs_1 = require("qs");
|
|
5
|
-
const
|
|
5
|
+
const index_1 = require("../index.cjs");
|
|
6
6
|
const decodeValue = (value) => {
|
|
7
|
-
if ((0,
|
|
7
|
+
if ((0, index_1.isObject)(value)) {
|
|
8
8
|
return Object.fromEntries(Object.entries(value).map(([subKey, subValue]) => [subKey, decodeValue(subValue)]));
|
|
9
9
|
}
|
|
10
|
-
if ((0,
|
|
10
|
+
if ((0, index_1.isArray)(value)) {
|
|
11
11
|
return value.map(decodeValue);
|
|
12
12
|
}
|
|
13
13
|
if (value === 'null') {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { TypeDecoder } from '
|
|
1
|
+
import type { TypeDecoder } from './index';
|
|
2
2
|
export declare const createUrlEncodedTypeDecoder: () => TypeDecoder;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { parse } from 'qs';
|
|
2
|
+
import { isArray, isObject } from '../index.mjs';
|
|
3
|
+
const decodeValue = (value) => {
|
|
4
|
+
if (isObject(value)) {
|
|
5
|
+
return Object.fromEntries(Object.entries(value).map(([subKey, subValue]) => [subKey, decodeValue(subValue)]));
|
|
6
|
+
}
|
|
7
|
+
if (isArray(value)) {
|
|
8
|
+
return value.map(decodeValue);
|
|
9
|
+
}
|
|
10
|
+
if (value === 'null') {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
if (value === 'true') {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
if (value === 'false') {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const integer = parseInt(value, 10);
|
|
20
|
+
if (!isNaN(integer) && integer.toString() === value) {
|
|
21
|
+
return integer;
|
|
22
|
+
}
|
|
23
|
+
const float = parseFloat(value);
|
|
24
|
+
if (!isNaN(float) && float.toString() === value) {
|
|
25
|
+
return float;
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
};
|
|
29
|
+
export const createUrlEncodedTypeDecoder = () => {
|
|
30
|
+
return {
|
|
31
|
+
decode: (encodedData) => decodeValue(parse(encodedData, { depth: 100 })),
|
|
32
|
+
contentType: 'application/x-www-form-urlencoded',
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createYamlTypeDecoder = void 0;
|
|
4
4
|
const yaml_1 = require("yaml");
|
|
5
5
|
const throwable_to_error_1 = require("@chubbyts/chubbyts-throwable-to-error/dist/throwable-to-error");
|
|
6
|
-
const
|
|
6
|
+
const index_1 = require("./index.cjs");
|
|
7
7
|
const createYamlTypeDecoder = () => {
|
|
8
8
|
return {
|
|
9
9
|
decode: (encodedData) => {
|
|
@@ -12,7 +12,7 @@ const createYamlTypeDecoder = () => {
|
|
|
12
12
|
}
|
|
13
13
|
catch (e) {
|
|
14
14
|
const error = (0, throwable_to_error_1.throwableToError)(e);
|
|
15
|
-
throw new
|
|
15
|
+
throw new index_1.DecodeError(error.message, error.stack);
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
contentType: 'application/x-yaml',
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { TypeDecoder } from '
|
|
1
|
+
import type { TypeDecoder } from './index';
|
|
2
2
|
export declare const createYamlTypeDecoder: () => TypeDecoder;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { parse } from 'yaml';
|
|
2
|
+
import { throwableToError } from '@chubbyts/chubbyts-throwable-to-error/dist/throwable-to-error';
|
|
3
|
+
import { DecodeError } from './index.mjs';
|
|
4
|
+
export const createYamlTypeDecoder = () => {
|
|
5
|
+
return {
|
|
6
|
+
decode: (encodedData) => {
|
|
7
|
+
try {
|
|
8
|
+
return parse(encodedData);
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
const error = throwableToError(e);
|
|
12
|
+
throw new DecodeError(error.message, error.stack);
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
contentType: 'application/x-yaml',
|
|
16
|
+
};
|
|
17
|
+
};
|
package/dist/encoder/index.d.ts
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class EncodeError extends Error {
|
|
2
|
+
constructor(message, stack) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.stack = stack;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export const createEncoder = (encoderTypes) => {
|
|
8
|
+
const encoderTypeMap = new Map(encoderTypes.map((encoderType) => [encoderType.contentType, encoderType]));
|
|
9
|
+
const contentTypes = Array.from(encoderTypeMap.keys());
|
|
10
|
+
return {
|
|
11
|
+
encode: (data, contentType) => {
|
|
12
|
+
if (encoderTypeMap.has(contentType)) {
|
|
13
|
+
return encoderTypeMap.get(contentType).encode(data);
|
|
14
|
+
}
|
|
15
|
+
throw new Error(`Unsupported contentType "${contentType}", supported contentTypes are "${contentTypes.join('", "')}".`);
|
|
16
|
+
},
|
|
17
|
+
contentTypes,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { TypeEncoder } from '
|
|
1
|
+
import type { TypeEncoder } from './index';
|
|
2
2
|
export declare const createJsonTypeEncoder: (prettyPrint?: boolean) => TypeEncoder;
|
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createJsonxTypeEncoder = void 0;
|
|
4
4
|
const fast_xml_parser_1 = require("fast-xml-parser");
|
|
5
5
|
const throwable_to_error_1 = require("@chubbyts/chubbyts-throwable-to-error/dist/throwable-to-error");
|
|
6
|
-
const
|
|
7
|
-
const jsonx_datatypes_1 = require("../jsonx-datatypes");
|
|
8
|
-
const
|
|
6
|
+
const index_1 = require("../index.cjs");
|
|
7
|
+
const jsonx_datatypes_1 = require("../jsonx-datatypes.cjs");
|
|
8
|
+
const index_2 = require("./index.cjs");
|
|
9
9
|
const encodeHtmlEntities = (string) => string.replace(/[\u00A0-\u9999<>&]/g, (i) => '&#' + i.charCodeAt(0) + ';');
|
|
10
10
|
const createXmlNode = () => {
|
|
11
11
|
return {
|
|
@@ -98,22 +98,22 @@ const createStringNode = (value, key = undefined) => {
|
|
|
98
98
|
};
|
|
99
99
|
};
|
|
100
100
|
const createNode = (value, key = undefined) => {
|
|
101
|
-
if ((0,
|
|
101
|
+
if ((0, index_1.isObject)(value)) {
|
|
102
102
|
return createObjectNode(value, key);
|
|
103
103
|
}
|
|
104
|
-
else if ((0,
|
|
104
|
+
else if ((0, index_1.isArray)(value)) {
|
|
105
105
|
return createArrayNode(value, key);
|
|
106
106
|
}
|
|
107
|
-
else if ((0,
|
|
107
|
+
else if ((0, index_1.isString)(value)) {
|
|
108
108
|
return createStringNode(value, key);
|
|
109
109
|
}
|
|
110
|
-
else if ((0,
|
|
110
|
+
else if ((0, index_1.isNumber)(value)) {
|
|
111
111
|
return createNumberNode(value, key);
|
|
112
112
|
}
|
|
113
|
-
else if ((0,
|
|
113
|
+
else if ((0, index_1.isBoolean)(value)) {
|
|
114
114
|
return createBooleanNode(value, key);
|
|
115
115
|
}
|
|
116
|
-
else if ((0,
|
|
116
|
+
else if ((0, index_1.isNull)(value)) {
|
|
117
117
|
return createNullNode(key);
|
|
118
118
|
}
|
|
119
119
|
throw new Error(`Unsupported value: ${JSON.stringify(value)}`);
|
|
@@ -168,7 +168,7 @@ const createJsonxTypeEncoder = (prettyPrint = false) => {
|
|
|
168
168
|
}
|
|
169
169
|
catch (e) {
|
|
170
170
|
const error = (0, throwable_to_error_1.throwableToError)(e);
|
|
171
|
-
throw new
|
|
171
|
+
throw new index_2.EncodeError(error.message, error.stack);
|
|
172
172
|
}
|
|
173
173
|
},
|
|
174
174
|
contentType: 'application/jsonx+xml',
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { TypeEncoder } from '
|
|
1
|
+
import type { TypeEncoder } from './index';
|
|
2
2
|
export declare const createJsonxTypeEncoder: (prettyPrint?: boolean) => TypeEncoder;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { XMLBuilder } from 'fast-xml-parser';
|
|
2
|
+
import { throwableToError } from '@chubbyts/chubbyts-throwable-to-error/dist/throwable-to-error';
|
|
3
|
+
import { isArray, isBoolean, isNumber, isObject, isString, isNull } from '../index.mjs';
|
|
4
|
+
import { DATATYPE_ARRAY, DATATYPE_BOOLEAN, DATATYPE_NULL, DATATYPE_NUMBER, DATATYPE_OBJECT, DATATYPE_STRING, } from '../jsonx-datatypes.mjs';
|
|
5
|
+
import { EncodeError } from './index.mjs';
|
|
6
|
+
const encodeHtmlEntities = (string) => string.replace(/[\u00A0-\u9999<>&]/g, (i) => '&#' + i.charCodeAt(0) + ';');
|
|
7
|
+
const createXmlNode = () => {
|
|
8
|
+
return {
|
|
9
|
+
'?xml': [
|
|
10
|
+
{
|
|
11
|
+
'#text': '',
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
':@': {
|
|
15
|
+
'@_version': '1.0',
|
|
16
|
+
'@_encoding': 'UTF-8',
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const createJsonxAttributes = () => {
|
|
21
|
+
return {
|
|
22
|
+
':@': {
|
|
23
|
+
'@_xsi:schemaLocation': 'http://www.datapower.com/schemas/json jsonx.xsd',
|
|
24
|
+
'@_xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
|
25
|
+
'@_xmlns:json': 'http://www.ibm.com/xmlns/prod/2009/jsonx',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
const createNullNode = (key = undefined) => {
|
|
30
|
+
const node = {
|
|
31
|
+
[DATATYPE_NULL]: [],
|
|
32
|
+
};
|
|
33
|
+
if (key === undefined) {
|
|
34
|
+
return node;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
...node,
|
|
38
|
+
':@': {
|
|
39
|
+
'@_name': key,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const createBooleanNode = (value, key = undefined) => {
|
|
44
|
+
const node = {
|
|
45
|
+
[DATATYPE_BOOLEAN]: [
|
|
46
|
+
{
|
|
47
|
+
'#text': value,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
if (key === undefined) {
|
|
52
|
+
return node;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
...node,
|
|
56
|
+
':@': {
|
|
57
|
+
'@_name': key,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
const createNumberNode = (value, key = undefined) => {
|
|
62
|
+
const node = {
|
|
63
|
+
[DATATYPE_NUMBER]: [
|
|
64
|
+
{
|
|
65
|
+
'#text': value,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
};
|
|
69
|
+
if (key === undefined) {
|
|
70
|
+
return node;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
...node,
|
|
74
|
+
':@': {
|
|
75
|
+
'@_name': key,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
const createStringNode = (value, key = undefined) => {
|
|
80
|
+
const node = {
|
|
81
|
+
[DATATYPE_STRING]: [
|
|
82
|
+
{
|
|
83
|
+
'#text': value === value.trim() ? encodeHtmlEntities(value) : `<![CDATA[${encodeHtmlEntities(value)}]]>`,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
if (key === undefined) {
|
|
88
|
+
return node;
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
...node,
|
|
92
|
+
':@': {
|
|
93
|
+
'@_name': key,
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
const createNode = (value, key = undefined) => {
|
|
98
|
+
if (isObject(value)) {
|
|
99
|
+
return createObjectNode(value, key);
|
|
100
|
+
}
|
|
101
|
+
else if (isArray(value)) {
|
|
102
|
+
return createArrayNode(value, key);
|
|
103
|
+
}
|
|
104
|
+
else if (isString(value)) {
|
|
105
|
+
return createStringNode(value, key);
|
|
106
|
+
}
|
|
107
|
+
else if (isNumber(value)) {
|
|
108
|
+
return createNumberNode(value, key);
|
|
109
|
+
}
|
|
110
|
+
else if (isBoolean(value)) {
|
|
111
|
+
return createBooleanNode(value, key);
|
|
112
|
+
}
|
|
113
|
+
else if (isNull(value)) {
|
|
114
|
+
return createNullNode(key);
|
|
115
|
+
}
|
|
116
|
+
throw new Error(`Unsupported value: ${JSON.stringify(value)}`);
|
|
117
|
+
};
|
|
118
|
+
const createArrayNode = (value, key = undefined) => {
|
|
119
|
+
const elements = value.map((subValue) => createNode(subValue));
|
|
120
|
+
const node = {
|
|
121
|
+
[DATATYPE_ARRAY]: elements,
|
|
122
|
+
};
|
|
123
|
+
if (key === undefined) {
|
|
124
|
+
return node;
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
...node,
|
|
128
|
+
':@': {
|
|
129
|
+
'@_name': key,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
const createObjectNode = (value, key = undefined) => {
|
|
134
|
+
const elements = Object.entries(value).map(([subKey, subValue]) => createNode(subValue, subKey));
|
|
135
|
+
const node = {
|
|
136
|
+
[DATATYPE_OBJECT]: elements,
|
|
137
|
+
};
|
|
138
|
+
if (key === undefined) {
|
|
139
|
+
return node;
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
...node,
|
|
143
|
+
':@': {
|
|
144
|
+
'@_name': key,
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
export const createJsonxTypeEncoder = (prettyPrint = false) => {
|
|
149
|
+
const builder = new XMLBuilder({
|
|
150
|
+
preserveOrder: true,
|
|
151
|
+
ignoreAttributes: false,
|
|
152
|
+
processEntities: false,
|
|
153
|
+
format: prettyPrint,
|
|
154
|
+
});
|
|
155
|
+
return {
|
|
156
|
+
encode: (data) => {
|
|
157
|
+
try {
|
|
158
|
+
return builder.build([
|
|
159
|
+
createXmlNode(),
|
|
160
|
+
{
|
|
161
|
+
...createNode(data),
|
|
162
|
+
...createJsonxAttributes(),
|
|
163
|
+
},
|
|
164
|
+
]);
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
const error = throwableToError(e);
|
|
168
|
+
throw new EncodeError(error.message, error.stack);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
contentType: 'application/jsonx+xml',
|
|
172
|
+
};
|
|
173
|
+
};
|
|
@@ -2,21 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createUrlEncodedTypeEncoder = void 0;
|
|
4
4
|
const qs_1 = require("qs");
|
|
5
|
-
const
|
|
5
|
+
const index_1 = require("../index.cjs");
|
|
6
6
|
const encodeValue = (value) => {
|
|
7
|
-
if ((0,
|
|
7
|
+
if ((0, index_1.isObject)(value)) {
|
|
8
8
|
return Object.fromEntries(Object.entries(value).map(([subKey, subValue]) => [subKey, encodeValue(subValue)]));
|
|
9
9
|
}
|
|
10
|
-
if ((0,
|
|
10
|
+
if ((0, index_1.isArray)(value)) {
|
|
11
11
|
return value.map(encodeValue);
|
|
12
12
|
}
|
|
13
|
-
if ((0,
|
|
13
|
+
if ((0, index_1.isNumber)(value)) {
|
|
14
14
|
return value.toString();
|
|
15
15
|
}
|
|
16
|
-
if ((0,
|
|
16
|
+
if ((0, index_1.isBoolean)(value)) {
|
|
17
17
|
return value ? 'true' : 'false';
|
|
18
18
|
}
|
|
19
|
-
if ((0,
|
|
19
|
+
if ((0, index_1.isNull)(value)) {
|
|
20
20
|
return 'null';
|
|
21
21
|
}
|
|
22
22
|
return value;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { TypeEncoder } from '
|
|
1
|
+
import type { TypeEncoder } from './index';
|
|
2
2
|
export declare const createUrlEncodedTypeEncoder: () => TypeEncoder;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { stringify } from 'qs';
|
|
2
|
+
import { isArray, isBoolean, isNull, isNumber, isObject } from '../index.mjs';
|
|
3
|
+
const encodeValue = (value) => {
|
|
4
|
+
if (isObject(value)) {
|
|
5
|
+
return Object.fromEntries(Object.entries(value).map(([subKey, subValue]) => [subKey, encodeValue(subValue)]));
|
|
6
|
+
}
|
|
7
|
+
if (isArray(value)) {
|
|
8
|
+
return value.map(encodeValue);
|
|
9
|
+
}
|
|
10
|
+
if (isNumber(value)) {
|
|
11
|
+
return value.toString();
|
|
12
|
+
}
|
|
13
|
+
if (isBoolean(value)) {
|
|
14
|
+
return value ? 'true' : 'false';
|
|
15
|
+
}
|
|
16
|
+
if (isNull(value)) {
|
|
17
|
+
return 'null';
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
};
|
|
21
|
+
export const createUrlEncodedTypeEncoder = () => {
|
|
22
|
+
return {
|
|
23
|
+
encode: (data) => stringify(encodeValue(data), { encodeValuesOnly: true }),
|
|
24
|
+
contentType: 'application/x-www-form-urlencoded',
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { TypeEncoder } from '
|
|
1
|
+
import type { TypeEncoder } from './index';
|
|
2
2
|
export declare const createYamlTypeEncoder: () => TypeEncoder;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const isNull = (value) => value === null;
|
|
2
|
+
export const isBoolean = (value) => typeof value === 'boolean';
|
|
3
|
+
export const isNumber = (value) => typeof value === 'number';
|
|
4
|
+
export const isString = (value) => typeof value === 'string';
|
|
5
|
+
export const isArray = (value) => Array.isArray(value);
|
|
6
|
+
export const isObject = (value) => value !== null && typeof value === 'object' && value.constructor.name == 'Object';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const DATATYPE_OBJECT = 'json:object';
|
|
2
|
+
export const DATATYPE_ARRAY = 'json:array';
|
|
3
|
+
export const DATATYPE_BOOLEAN = 'json:boolean';
|
|
4
|
+
export const DATATYPE_STRING = 'json:string';
|
|
5
|
+
export const DATATYPE_NUMBER = 'json:number';
|
|
6
|
+
export const DATATYPE_NULL = 'json:null';
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chubbyts/chubbyts-decode-encode",
|
|
3
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "1.3.0",
|
|
4
5
|
"description": "A simple decode/encode solution for json / jsonx / url-encoded / xml / yaml.",
|
|
5
6
|
"keywords": [
|
|
6
7
|
"chubbyts",
|
|
@@ -16,14 +17,14 @@
|
|
|
16
17
|
"license": "MIT",
|
|
17
18
|
"repository": "chubbyts/chubbyts-decode-encode",
|
|
18
19
|
"scripts": {
|
|
20
|
+
"build": "node ./build.js",
|
|
19
21
|
"cs-fix": "prettier --write src tests",
|
|
20
22
|
"cs": "prettier --check src tests",
|
|
23
|
+
"infection": "stryker run",
|
|
21
24
|
"lint-fix": "eslint src tests --fix",
|
|
22
25
|
"lint": "eslint src tests",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"build": "rm -Rf dist && tsc",
|
|
26
|
-
"prepare": "npm run build"
|
|
26
|
+
"prepare": "npm run build",
|
|
27
|
+
"test": "jest"
|
|
27
28
|
},
|
|
28
29
|
"jest": {
|
|
29
30
|
"preset": "ts-jest",
|
|
@@ -46,27 +47,36 @@
|
|
|
46
47
|
"files": [
|
|
47
48
|
"dist"
|
|
48
49
|
],
|
|
50
|
+
"exports": {
|
|
51
|
+
"./*": {
|
|
52
|
+
"types": "./*.d.ts",
|
|
53
|
+
"require": "./*.cjs",
|
|
54
|
+
"import": "./*.mjs",
|
|
55
|
+
"default": "./*.mjs"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
49
58
|
"engines": {
|
|
50
59
|
"node": ">=16"
|
|
51
60
|
},
|
|
52
61
|
"dependencies": {
|
|
53
|
-
"@chubbyts/chubbyts-throwable-to-error": "^1.1
|
|
54
|
-
"fast-xml-parser": "^4.2.
|
|
55
|
-
"qs": "^6.11.
|
|
56
|
-
"yaml": "^2.
|
|
62
|
+
"@chubbyts/chubbyts-throwable-to-error": "^1.2.1",
|
|
63
|
+
"fast-xml-parser": "^4.2.6",
|
|
64
|
+
"qs": "^6.11.2",
|
|
65
|
+
"yaml": "^2.3.1"
|
|
57
66
|
},
|
|
58
67
|
"devDependencies": {
|
|
59
|
-
"@chubbyts/chubbyts-eslint": "^
|
|
60
|
-
"@chubbyts/chubbyts-function-mock": "^1.
|
|
61
|
-
"@
|
|
62
|
-
"@stryker-mutator/
|
|
63
|
-
"@
|
|
64
|
-
"@types/
|
|
68
|
+
"@chubbyts/chubbyts-eslint": "^2.0.3",
|
|
69
|
+
"@chubbyts/chubbyts-function-mock": "^1.4.1",
|
|
70
|
+
"@chubbyts/chubbyts-packaging": "^2.0.4",
|
|
71
|
+
"@stryker-mutator/core": "^7.1.0",
|
|
72
|
+
"@stryker-mutator/jest-runner": "^7.1.0",
|
|
73
|
+
"@types/jest": "^29.5.3",
|
|
74
|
+
"@types/node": "^20.4.1",
|
|
65
75
|
"@types/qs": "^6.9.7",
|
|
66
|
-
"jest": "^29.
|
|
67
|
-
"prettier": "^
|
|
68
|
-
"ts-jest": "^29.1.
|
|
69
|
-
"typescript": "^5.
|
|
76
|
+
"jest": "^29.6.1",
|
|
77
|
+
"prettier": "^3.0.0",
|
|
78
|
+
"ts-jest": "^29.1.1",
|
|
79
|
+
"typescript": "^5.1.6"
|
|
70
80
|
},
|
|
71
81
|
"publishConfig": {
|
|
72
82
|
"access": "public"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|