@awsless/json 0.0.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 +50 -0
- package/dist/index.cjs +99 -0
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +71 -0
- package/package.json +37 -0
package/README.MD
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
# @awsless/json
|
|
3
|
+
|
|
4
|
+
The `@awsless/json` package adds support for more JavaScript native types to JSON.
|
|
5
|
+
|
|
6
|
+
## The Problem
|
|
7
|
+
|
|
8
|
+
JSON doesn't have support for types like Date, BigInt, or BigFloat.
|
|
9
|
+
Having to decode & encode these type of values can get quite annoying.
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { parse, stringify } from '@awsless/json';
|
|
15
|
+
|
|
16
|
+
// Stringify a bigint.
|
|
17
|
+
// The output will be {"$bigint": "1"}
|
|
18
|
+
const json = stringify(1n)
|
|
19
|
+
|
|
20
|
+
// Parse the json with a bigint inside.
|
|
21
|
+
const value = parse(json)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Extending Supported Types
|
|
25
|
+
|
|
26
|
+
We let you extend JSON to support your own custom types.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { parse, stringify, Serializable } from '@awsless/json';
|
|
30
|
+
|
|
31
|
+
class Custom {
|
|
32
|
+
readonly value
|
|
33
|
+
|
|
34
|
+
constructor(value: string) {
|
|
35
|
+
this.value = value
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const $custom: Serializable<Custom> = {
|
|
40
|
+
is: v => v instanceof Custom,
|
|
41
|
+
parse: v => new Custom(v),
|
|
42
|
+
stringify: v => v.value,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Stringify your custom type
|
|
46
|
+
const json = stringify(new Custom('example'), { $custom })
|
|
47
|
+
|
|
48
|
+
// Parse the json with your custom type
|
|
49
|
+
const value = parse(json, { $custom })
|
|
50
|
+
```
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
createReplacer: () => createReplacer,
|
|
24
|
+
createReviver: () => createReviver,
|
|
25
|
+
parse: () => parse,
|
|
26
|
+
stringify: () => stringify
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(src_exports);
|
|
29
|
+
var import_big_float = require("@awsless/big-float");
|
|
30
|
+
var $bigfloat = {
|
|
31
|
+
is: (v) => v instanceof import_big_float.BigFloat,
|
|
32
|
+
parse: (v) => new import_big_float.BigFloat(v),
|
|
33
|
+
stringify: (v) => v.toString()
|
|
34
|
+
};
|
|
35
|
+
var $bigint = {
|
|
36
|
+
is: (v) => typeof v === "bigint",
|
|
37
|
+
parse: (v) => BigInt(v),
|
|
38
|
+
stringify: (v) => v.toString()
|
|
39
|
+
};
|
|
40
|
+
var $date = {
|
|
41
|
+
is: (v) => v instanceof Date,
|
|
42
|
+
parse: (v) => new Date(v),
|
|
43
|
+
stringify: (v) => v.toISOString()
|
|
44
|
+
};
|
|
45
|
+
var baseTypes = {
|
|
46
|
+
$bigfloat,
|
|
47
|
+
$bigint,
|
|
48
|
+
$date
|
|
49
|
+
};
|
|
50
|
+
var parse = (json, types = {}) => {
|
|
51
|
+
return JSON.parse(json, createReviver(types));
|
|
52
|
+
};
|
|
53
|
+
var createReviver = (types = {}) => {
|
|
54
|
+
types = {
|
|
55
|
+
...baseTypes,
|
|
56
|
+
...types
|
|
57
|
+
};
|
|
58
|
+
return function(key, value) {
|
|
59
|
+
const original = this[key];
|
|
60
|
+
if (original !== null && typeof original === "object") {
|
|
61
|
+
const keys = Object.keys(original);
|
|
62
|
+
if (keys.length === 1) {
|
|
63
|
+
const typeName = keys[0];
|
|
64
|
+
if (typeName in types && types[typeName]) {
|
|
65
|
+
const type = types[typeName];
|
|
66
|
+
return type.parse(original[typeName]);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
var stringify = (value, types = {}) => {
|
|
74
|
+
return JSON.stringify(value, createReplacer(types));
|
|
75
|
+
};
|
|
76
|
+
var createReplacer = (types = {}) => {
|
|
77
|
+
types = {
|
|
78
|
+
...baseTypes,
|
|
79
|
+
...types
|
|
80
|
+
};
|
|
81
|
+
return function(key, value) {
|
|
82
|
+
const original = this[key];
|
|
83
|
+
for (const [typeName, type] of Object.entries(types)) {
|
|
84
|
+
if (type.is(original)) {
|
|
85
|
+
return {
|
|
86
|
+
[typeName]: type.stringify(original)
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return value;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
94
|
+
0 && (module.exports = {
|
|
95
|
+
createReplacer,
|
|
96
|
+
createReviver,
|
|
97
|
+
parse,
|
|
98
|
+
stringify
|
|
99
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type Serializable<T> = {
|
|
2
|
+
is: (value: unknown) => boolean;
|
|
3
|
+
parse: (value: string) => T;
|
|
4
|
+
stringify: (value: T) => string;
|
|
5
|
+
};
|
|
6
|
+
type SerializableTypes = Record<string, Serializable<any>>;
|
|
7
|
+
declare const parse: (json: string, types?: SerializableTypes) => any;
|
|
8
|
+
type Reviver = (this: any, key: string, value: any) => any;
|
|
9
|
+
type Replacer = (this: any, key: string, value: any) => any;
|
|
10
|
+
declare const createReviver: (types?: SerializableTypes) => Reviver;
|
|
11
|
+
declare const stringify: (value: unknown, types?: SerializableTypes) => string;
|
|
12
|
+
declare const createReplacer: (types?: SerializableTypes) => Replacer;
|
|
13
|
+
|
|
14
|
+
export { type Serializable, createReplacer, createReviver, parse, stringify };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type Serializable<T> = {
|
|
2
|
+
is: (value: unknown) => boolean;
|
|
3
|
+
parse: (value: string) => T;
|
|
4
|
+
stringify: (value: T) => string;
|
|
5
|
+
};
|
|
6
|
+
type SerializableTypes = Record<string, Serializable<any>>;
|
|
7
|
+
declare const parse: (json: string, types?: SerializableTypes) => any;
|
|
8
|
+
type Reviver = (this: any, key: string, value: any) => any;
|
|
9
|
+
type Replacer = (this: any, key: string, value: any) => any;
|
|
10
|
+
declare const createReviver: (types?: SerializableTypes) => Reviver;
|
|
11
|
+
declare const stringify: (value: unknown, types?: SerializableTypes) => string;
|
|
12
|
+
declare const createReplacer: (types?: SerializableTypes) => Replacer;
|
|
13
|
+
|
|
14
|
+
export { type Serializable, createReplacer, createReviver, parse, stringify };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { BigFloat } from "@awsless/big-float";
|
|
3
|
+
var $bigfloat = {
|
|
4
|
+
is: (v) => v instanceof BigFloat,
|
|
5
|
+
parse: (v) => new BigFloat(v),
|
|
6
|
+
stringify: (v) => v.toString()
|
|
7
|
+
};
|
|
8
|
+
var $bigint = {
|
|
9
|
+
is: (v) => typeof v === "bigint",
|
|
10
|
+
parse: (v) => BigInt(v),
|
|
11
|
+
stringify: (v) => v.toString()
|
|
12
|
+
};
|
|
13
|
+
var $date = {
|
|
14
|
+
is: (v) => v instanceof Date,
|
|
15
|
+
parse: (v) => new Date(v),
|
|
16
|
+
stringify: (v) => v.toISOString()
|
|
17
|
+
};
|
|
18
|
+
var baseTypes = {
|
|
19
|
+
$bigfloat,
|
|
20
|
+
$bigint,
|
|
21
|
+
$date
|
|
22
|
+
};
|
|
23
|
+
var parse = (json, types = {}) => {
|
|
24
|
+
return JSON.parse(json, createReviver(types));
|
|
25
|
+
};
|
|
26
|
+
var createReviver = (types = {}) => {
|
|
27
|
+
types = {
|
|
28
|
+
...baseTypes,
|
|
29
|
+
...types
|
|
30
|
+
};
|
|
31
|
+
return function(key, value) {
|
|
32
|
+
const original = this[key];
|
|
33
|
+
if (original !== null && typeof original === "object") {
|
|
34
|
+
const keys = Object.keys(original);
|
|
35
|
+
if (keys.length === 1) {
|
|
36
|
+
const typeName = keys[0];
|
|
37
|
+
if (typeName in types && types[typeName]) {
|
|
38
|
+
const type = types[typeName];
|
|
39
|
+
return type.parse(original[typeName]);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
var stringify = (value, types = {}) => {
|
|
47
|
+
return JSON.stringify(value, createReplacer(types));
|
|
48
|
+
};
|
|
49
|
+
var createReplacer = (types = {}) => {
|
|
50
|
+
types = {
|
|
51
|
+
...baseTypes,
|
|
52
|
+
...types
|
|
53
|
+
};
|
|
54
|
+
return function(key, value) {
|
|
55
|
+
const original = this[key];
|
|
56
|
+
for (const [typeName, type] of Object.entries(types)) {
|
|
57
|
+
if (type.is(original)) {
|
|
58
|
+
return {
|
|
59
|
+
[typeName]: type.stringify(original)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return value;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
export {
|
|
67
|
+
createReplacer,
|
|
68
|
+
createReviver,
|
|
69
|
+
parse,
|
|
70
|
+
stringify
|
|
71
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@awsless/json",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/awsless/awsless.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/awsless/awsless/issues"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
17
|
+
"module": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"require": "./dist/index.cjs",
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@awsless/big-float": "^0.0.4"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@awsless/big-float": "^0.0.4"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"test": "pnpm code test",
|
|
34
|
+
"build": "pnpm tsup src/index.ts --format cjs,esm --dts --clean",
|
|
35
|
+
"prepublish": "if pnpm test; then pnpm build; else exit; fi"
|
|
36
|
+
}
|
|
37
|
+
}
|