@chubbyts/chubbyts-decode-encode 2.1.1 → 2.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.
Files changed (33) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +7 -7
  3. package/dist/src/data.d.ts +11 -0
  4. package/dist/src/data.js +6 -0
  5. package/dist/src/decoder/decoder.d.ts +13 -0
  6. package/dist/src/decoder/decoder.js +19 -0
  7. package/dist/src/decoder/index.d.ts +5 -0
  8. package/dist/src/decoder/index.js +4 -0
  9. package/dist/src/decoder/json-type-decoder.d.ts +2 -0
  10. package/dist/src/decoder/json-type-decoder.js +16 -0
  11. package/dist/src/decoder/jsonx-type-decoder.d.ts +2 -0
  12. package/dist/src/decoder/jsonx-type-decoder.js +68 -0
  13. package/dist/src/decoder/url-encoded-type-decoder.d.ts +2 -0
  14. package/dist/src/decoder/url-encoded-type-decoder.js +30 -0
  15. package/dist/src/decoder/yaml-type-decoder.d.ts +2 -0
  16. package/dist/src/decoder/yaml-type-decoder.js +17 -0
  17. package/dist/src/encoder/encoder.d.ts +13 -0
  18. package/dist/src/encoder/encoder.js +19 -0
  19. package/dist/src/encoder/index.d.ts +5 -0
  20. package/dist/src/encoder/index.js +4 -0
  21. package/dist/src/encoder/json-type-encoder.d.ts +2 -0
  22. package/dist/src/encoder/json-type-encoder.js +6 -0
  23. package/dist/src/encoder/jsonx-type-encoder.d.ts +2 -0
  24. package/dist/src/encoder/jsonx-type-encoder.js +173 -0
  25. package/dist/src/encoder/url-encoded-type-encoder.d.ts +2 -0
  26. package/dist/src/encoder/url-encoded-type-encoder.js +20 -0
  27. package/dist/src/encoder/yaml-type-encoder.d.ts +2 -0
  28. package/dist/src/encoder/yaml-type-encoder.js +7 -0
  29. package/dist/src/index.d.ts +5 -0
  30. package/dist/src/index.js +4 -0
  31. package/dist/src/jsonx-datatypes.d.ts +36 -0
  32. package/dist/src/jsonx-datatypes.js +6 -0
  33. package/package.json +26 -27
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2025 Dominik Zogg
1
+ Copyright (c) 2026 Dominik Zogg
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -23,18 +23,18 @@ A simple decode/encode solution for json / jsonx / url-encoded / xml / yaml.
23
23
 
24
24
  ## Requirements
25
25
 
26
- * node: 18
27
- * [@chubbyts/chubbyts-throwable-to-error][2]: ^2.0.2
28
- * [fast-xml-parser][3]: ^5.3.1
29
- * [qs][4]: ^6.14.0
30
- * [yaml][5]: ^2.8.1
26
+ * node: 20
27
+ * [@chubbyts/chubbyts-throwable-to-error][2]: ^2.1.0
28
+ * [fast-xml-parser][3]: ^5.5.11
29
+ * [qs][4]: ^6.15.1
30
+ * [yaml][5]: ^2.8.3
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@^2.1.1
37
+ npm i @chubbyts/chubbyts-decode-encode@^2.2.0
38
38
  ```
39
39
 
40
40
  ## Usage
@@ -175,7 +175,7 @@ const contentType = yamlTypeEncoder.contentType;
175
175
 
176
176
  ## Copyright
177
177
 
178
- 2025 Dominik Zogg
178
+ 2026 Dominik Zogg
179
179
 
180
180
  [1]: https://www.npmjs.com/package/@chubbyts/chubbyts-decode-encode
181
181
  [2]: https://www.npmjs.com/package/@chubbyts/chubbyts-throwable-to-error
@@ -0,0 +1,11 @@
1
+ export type Data = {
2
+ [key: string]: Data;
3
+ } | Array<Data> | string | number | boolean | null;
4
+ export declare const isNull: (value: unknown) => value is null;
5
+ export declare const isBoolean: (value: unknown) => value is boolean;
6
+ export declare const isNumber: (value: unknown) => value is number;
7
+ export declare const isString: (value: unknown) => value is string;
8
+ export declare const isArray: (value: unknown) => value is Array<Data>;
9
+ export declare const isObject: (value: unknown) => value is {
10
+ [key: string]: Data;
11
+ };
@@ -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,13 @@
1
+ import type { Data } from '../data.js';
2
+ export declare class DecodeError extends Error {
3
+ constructor(message: string, stack?: string);
4
+ }
5
+ export type TypeDecoder = {
6
+ decode: (encodedData: string) => Data;
7
+ contentType: string;
8
+ };
9
+ export type Decoder = {
10
+ decode: (encodedData: string, contentType: string, context?: Record<string, unknown>) => Data;
11
+ contentTypes: Array<string>;
12
+ };
13
+ export declare const createDecoder: (decoderTypes: Array<TypeDecoder>) => Decoder;
@@ -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
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @deprecated This file re-exports the old API. Use './decoder.ts' directly instead.
3
+ */
4
+ export { DecodeError, createDecoder } from './decoder.js';
5
+ export type { TypeDecoder, Decoder } from './decoder.js';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @deprecated This file re-exports the old API. Use './decoder.ts' directly instead.
3
+ */
4
+ export { DecodeError, createDecoder } from './decoder.js';
@@ -0,0 +1,2 @@
1
+ import type { TypeDecoder } from './decoder.js';
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 './decoder.js';
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
+ };
@@ -0,0 +1,2 @@
1
+ import type { TypeDecoder } from './decoder.js';
2
+ export declare const createJsonxTypeDecoder: () => TypeDecoder;
@@ -0,0 +1,68 @@
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.js';
4
+ import { DecodeError } from './decoder.js';
5
+ const decodeHtmlEntities = (string) => string.replace(/&#\d+;/gm, (code) => String.fromCharCode(code.match(/\d+/)[0]));
6
+ const getNodeName = (node) => {
7
+ return node[':@']?.['@_name'];
8
+ };
9
+ const getNodeType = (node) => {
10
+ return Object.keys(node)[0];
11
+ };
12
+ const convertNullNode = () => {
13
+ return null;
14
+ };
15
+ const convertBooleanNode = (node) => {
16
+ return node['json:boolean'][0]['#text'];
17
+ };
18
+ const convertNumberNode = (node) => {
19
+ return node['json:number'][0]['#text'];
20
+ };
21
+ const convertStringNode = (node) => {
22
+ return decodeHtmlEntities(node['json:string'][0]['#text']);
23
+ };
24
+ const convertNode = (node) => {
25
+ switch (getNodeType(node)) {
26
+ case DATATYPE_OBJECT:
27
+ return convertObjectNode(node);
28
+ case DATATYPE_ARRAY:
29
+ return convertArrayNode(node);
30
+ case DATATYPE_STRING:
31
+ return convertStringNode(node);
32
+ case DATATYPE_NUMBER:
33
+ return convertNumberNode(node);
34
+ case DATATYPE_BOOLEAN:
35
+ return convertBooleanNode(node);
36
+ case DATATYPE_NULL:
37
+ return convertNullNode();
38
+ }
39
+ throw new Error(`Unsupported node: ${JSON.stringify(node)}`);
40
+ };
41
+ const convertArrayNode = (node) => {
42
+ return node['json:array'].map(convertNode);
43
+ };
44
+ const convertNodeWithName = (node) => {
45
+ const name = getNodeName(node);
46
+ if (undefined === name) {
47
+ throw new Error(`Unsupported node: ${JSON.stringify(node)}`);
48
+ }
49
+ return [name, convertNode(node)];
50
+ };
51
+ const convertObjectNode = (node) => {
52
+ return Object.fromEntries(node['json:object'].map(convertNodeWithName));
53
+ };
54
+ export const createJsonxTypeDecoder = () => {
55
+ return {
56
+ decode: (encodedData) => {
57
+ try {
58
+ const parser = new XMLParser({ preserveOrder: true, ignoreAttributes: false });
59
+ return convertNode(parser.parse(encodedData)[1]);
60
+ }
61
+ catch (e) {
62
+ const error = throwableToError(e);
63
+ throw new DecodeError(error.message, error.stack);
64
+ }
65
+ },
66
+ contentType: 'application/jsonx+xml',
67
+ };
68
+ };
@@ -0,0 +1,2 @@
1
+ import type { TypeDecoder } from './decoder.js';
2
+ export declare const createUrlEncodedTypeDecoder: () => TypeDecoder;
@@ -0,0 +1,30 @@
1
+ import { parse } from 'qs';
2
+ import { isArray, isObject } from '../data.js';
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 float = parseFloat(value); // handles integers as well
20
+ if (float.toString() === value) {
21
+ return float;
22
+ }
23
+ return value;
24
+ };
25
+ export const createUrlEncodedTypeDecoder = () => {
26
+ return {
27
+ decode: (encodedData) => decodeValue(parse(encodedData, { depth: 100 })),
28
+ contentType: 'application/x-www-form-urlencoded',
29
+ };
30
+ };
@@ -0,0 +1,2 @@
1
+ import type { TypeDecoder } from './decoder.js';
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 './decoder.js';
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
+ };
@@ -0,0 +1,13 @@
1
+ import type { Data } from '../data.js';
2
+ export declare class EncodeError extends Error {
3
+ constructor(message: string, stack?: string);
4
+ }
5
+ export type TypeEncoder = {
6
+ encode: (data: Data) => string;
7
+ contentType: string;
8
+ };
9
+ export type Encoder = {
10
+ encode: (data: Data, contentType: string, context?: Record<string, unknown>) => string;
11
+ contentTypes: Array<string>;
12
+ };
13
+ export declare const createEncoder: (encoderTypes: Array<TypeEncoder>) => Encoder;
@@ -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
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @deprecated This file re-exports the old API. Use './encoder.ts' directly instead.
3
+ */
4
+ export { EncodeError, createEncoder } from './encoder.js';
5
+ export type { TypeEncoder, Encoder } from './encoder.js';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @deprecated This file re-exports the old API. Use './encoder.ts' directly instead.
3
+ */
4
+ export { EncodeError, createEncoder } from './encoder.js';
@@ -0,0 +1,2 @@
1
+ import type { TypeEncoder } from './encoder.js';
2
+ export declare const createJsonTypeEncoder: (prettyPrint?: boolean) => TypeEncoder;
@@ -0,0 +1,6 @@
1
+ export const createJsonTypeEncoder = (prettyPrint = false) => {
2
+ return {
3
+ encode: (data) => JSON.stringify(data, undefined, prettyPrint ? 4 : undefined),
4
+ contentType: 'application/json',
5
+ };
6
+ };
@@ -0,0 +1,2 @@
1
+ import type { TypeEncoder } from './encoder.js';
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 '../data.js';
4
+ import { DATATYPE_ARRAY, DATATYPE_BOOLEAN, DATATYPE_NULL, DATATYPE_NUMBER, DATATYPE_OBJECT, DATATYPE_STRING, } from '../jsonx-datatypes.js';
5
+ import { EncodeError } from './encoder.js';
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
+ };
@@ -0,0 +1,2 @@
1
+ import type { TypeEncoder } from './encoder.js';
2
+ export declare const createUrlEncodedTypeEncoder: () => TypeEncoder;
@@ -0,0 +1,20 @@
1
+ import { stringify } from 'qs';
2
+ import { isArray, isNull, isObject } from '../data.js';
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 (isNull(value)) {
11
+ return 'null';
12
+ }
13
+ return value;
14
+ };
15
+ export const createUrlEncodedTypeEncoder = () => {
16
+ return {
17
+ encode: (data) => stringify(encodeValue(data), { encodeValuesOnly: true }),
18
+ contentType: 'application/x-www-form-urlencoded',
19
+ };
20
+ };
@@ -0,0 +1,2 @@
1
+ import type { TypeEncoder } from './encoder.js';
2
+ export declare const createYamlTypeEncoder: () => TypeEncoder;
@@ -0,0 +1,7 @@
1
+ import { stringify } from 'yaml';
2
+ export const createYamlTypeEncoder = () => {
3
+ return {
4
+ encode: (data) => stringify(data, { indent: 4 }),
5
+ contentType: 'application/x-yaml',
6
+ };
7
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @deprecated This file re-exports the old API. Use './data.ts' directly instead.
3
+ */
4
+ export { isNull, isBoolean, isNumber, isString, isArray, isObject } from './data.js';
5
+ export type { Data } from './data.js';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @deprecated This file re-exports the old API. Use './data.ts' directly instead.
3
+ */
4
+ export { isNull, isBoolean, isNumber, isString, isArray, isObject } from './data.js';
@@ -0,0 +1,36 @@
1
+ export declare const DATATYPE_OBJECT = "json:object";
2
+ export declare const DATATYPE_ARRAY = "json:array";
3
+ export declare const DATATYPE_BOOLEAN = "json:boolean";
4
+ export declare const DATATYPE_STRING = "json:string";
5
+ export declare const DATATYPE_NUMBER = "json:number";
6
+ export declare const DATATYPE_NULL = "json:null";
7
+ export type WithName = {
8
+ ':@': {
9
+ '@_name': string;
10
+ };
11
+ };
12
+ export type JsonxNullNode = {
13
+ [DATATYPE_NULL]: Array<never>;
14
+ };
15
+ export type JsonxBooleanNode = {
16
+ [DATATYPE_BOOLEAN]: Array<{
17
+ '#text': boolean;
18
+ }>;
19
+ };
20
+ export type JsonxNumberNode = {
21
+ [DATATYPE_NUMBER]: Array<{
22
+ '#text': number;
23
+ }>;
24
+ };
25
+ export type JsonxStringNode = {
26
+ [DATATYPE_STRING]: Array<{
27
+ '#text': string;
28
+ }>;
29
+ };
30
+ export type JsonxArrayNode = {
31
+ [DATATYPE_ARRAY]: Array<JsonxNullNode | JsonxBooleanNode | JsonxNumberNode | JsonxStringNode | JsonxArrayNode | JsonxObjectNode>;
32
+ };
33
+ export type JsonxObjectNode = {
34
+ [DATATYPE_OBJECT]: Array<JsonxNullNode | JsonxBooleanNode | JsonxNumberNode | JsonxStringNode | JsonxArrayNode | JsonxObjectNode>;
35
+ };
36
+ export type JsonxNode = JsonxNullNode | JsonxBooleanNode | JsonxNumberNode | JsonxStringNode | JsonxArrayNode | JsonxObjectNode;
@@ -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,7 +1,7 @@
1
1
  {
2
2
  "name": "@chubbyts/chubbyts-decode-encode",
3
3
  "type": "module",
4
- "version": "2.1.1",
4
+ "version": "2.2.0",
5
5
  "description": "A simple decode/encode solution for json / jsonx / url-encoded / xml / yaml.",
6
6
  "keywords": [
7
7
  "chubbyts",
@@ -16,16 +16,6 @@
16
16
  "author": "Dominik Zogg",
17
17
  "license": "MIT",
18
18
  "repository": "chubbyts/chubbyts-decode-encode",
19
- "scripts": {
20
- "build": "tsc",
21
- "cs-fix": "prettier --write src tests",
22
- "cs": "prettier --check src tests",
23
- "infection": "stryker run",
24
- "lint-fix": "eslint src tests eslint.config.js vitest.config.ts --fix",
25
- "lint": "eslint src tests",
26
- "prepare": "npm run build",
27
- "test": "vitest"
28
- },
29
19
  "prettier": {
30
20
  "printWidth": 120,
31
21
  "tabWidth": 2,
@@ -58,27 +48,36 @@
58
48
  }
59
49
  },
60
50
  "engines": {
61
- "node": ">=18"
51
+ "node": ">=20"
62
52
  },
63
53
  "dependencies": {
64
- "@chubbyts/chubbyts-throwable-to-error": "^2.0.2",
65
- "fast-xml-parser": "^5.3.1",
66
- "qs": "^6.14.0",
67
- "yaml": "^2.8.1"
54
+ "@chubbyts/chubbyts-throwable-to-error": "^2.1.0",
55
+ "fast-xml-parser": "^5.5.11",
56
+ "qs": "^6.15.1",
57
+ "yaml": "^2.8.3"
68
58
  },
69
59
  "devDependencies": {
70
- "@chubbyts/chubbyts-eslint": "^4.0.10",
71
- "@chubbyts/chubbyts-function-mock": "^2.0.2",
72
- "@stryker-mutator/core": "^9.3.0",
73
- "@stryker-mutator/vitest-runner": "^9.3.0",
74
- "@types/node": "^24.10.0",
75
- "@types/qs": "^6.14.0",
76
- "@vitest/coverage-v8": "^4.0.8",
77
- "prettier": "^3.6.2",
78
- "typescript": "^5.9.3",
79
- "vitest": "^4.0.8"
60
+ "@chubbyts/chubbyts-eslint": "^5.1.0",
61
+ "@chubbyts/chubbyts-function-mock": "^2.1.0",
62
+ "@stryker-mutator/core": "^9.6.1",
63
+ "@stryker-mutator/vitest-runner": "^9.6.1",
64
+ "@types/node": "^25.6.0",
65
+ "@types/qs": "^6.15.0",
66
+ "@vitest/coverage-v8": "^4.1.4",
67
+ "prettier": "^3.8.2",
68
+ "typescript": "^6.0.2",
69
+ "vitest": "^4.1.4"
80
70
  },
81
71
  "publishConfig": {
82
72
  "access": "public"
73
+ },
74
+ "scripts": {
75
+ "build": "tsc",
76
+ "cs-fix": "prettier --write src tests",
77
+ "cs": "prettier --check src tests",
78
+ "infection": "stryker run",
79
+ "lint-fix": "eslint src tests eslint.config.js vitest.config.ts --fix",
80
+ "lint": "eslint src tests",
81
+ "test": "vitest"
83
82
  }
84
- }
83
+ }