jasone 0.0.2 → 0.0.3
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/index.cjs +1 -1
- package/index.d.cts +234 -1
- package/index.d.ts +234 -1
- package/index.js +1 -1
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var c=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var w=(t,e)=>{for(var r in e)c(t,r,{get:e[r],enumerable:!0})},J=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of I(e))!b.call(t,o)&&o!==r&&c(t,o,{get:()=>e[o],enumerable:!(n=g(e,o))||n.enumerable});return t};var x=t=>J(c({},"__esModule",{value:!0}),t);var E={};w(E,{Jasone:()=>i,bigIntType:()=>a,createType:()=>s,dateType:()=>y,defaultTypes:()=>l,mapType:()=>T,regExpType:()=>f,setType:()=>m,undefinedType:()=>u,urlType:()=>h});module.exports=x(E);var s=t=>t;var a=s({matches:t=>typeof t=="bigint",typeId:2,encode:t=>({bigint:t.toString()}),decode:({bigint:t})=>BigInt(t)});var y=s({target:Date,typeId:1,encode:t=>({timestamp:t.getTime()}),decode:({timestamp:t})=>new Date(t)});var T=s({matches:t=>t instanceof Map,typeId:5,encode:(t,e)=>({map:Array.from(t.entries().map(([r,n])=>[e(r),e(n)]))}),decode:({map:t},e)=>new Map(t.map(([r,n])=>{if(r===void 0||n===void 0)throw new Error("Illegal value received.",{cause:t});return[e(r),e(n)]}))});var f=s({matches:t=>t instanceof RegExp,typeId:3,encode:t=>({source:t.source,flags:t.flags}),decode:({source:t,flags:e})=>new RegExp(t,e)});var m=s({matches:t=>t instanceof Set,typeId:4,encode:(t,e)=>({set:Array.from(t.values().map(r=>e(r)))}),decode:({set:t},e)=>new Set(t.map(r=>e(r)))});var u=s({matches:t=>t===void 0,typeId:0,encode:()=>({}),decode:()=>{}});var h=s({matches:t=>t instanceof URL,typeId:6,encode:t=>({url:t.toString()}),decode:({url:t})=>new URL(t)});var l=[u,y,a,f,m,T,h];var i=class t{#e;#r=new Map;#n=new Map;#o=[];constructor(e={}){this.#e=e.typeIdentifier??"$";for(let r of e.types??[])this.register(r)}register(e){this.#r.set(e.typeId,e.decode),"matches"in e?this.#o.push({matches:e.matches,typeId:e.typeId,encode:e.encode}):this.#n.set(e.target,{typeId:e.typeId,encode:e.encode})}encode(e){switch(typeof e){case"string":case"number":case"boolean":return e;case"object":if(e===null)return null;if(Array.isArray(e))return e.map(o=>this.encode(o));if(Object.getPrototypeOf(e)===Object.prototype){let o=Object.fromEntries(Object.entries(e).map(([d,p])=>[d,this.encode(p)]));return this.#e in o&&(o[this.#e]=[this.encode(o[this.#e])]),o}}let r;if(typeof e=="object"&&e!==null&&(r=this.#n.get(e.constructor)),r||(r=this.#o.find(({matches:o})=>o(e))),!r)throw new Error("No encoder found.",{cause:e});let n=r.encode(e,this.encode.bind(this));return{[this.#e]:r.typeId,...n}}decode(e){return this.#t(e)}#t(e,r=!1){switch(typeof e){case"string":case"number":case"boolean":return e;case"object":if(e===null)return null;if(Array.isArray(e))return e.map(n=>this.#t(n));if(this.#e in e&&!Array.isArray(e)&&!r){let n=e[this.#e];if(Array.isArray(n)){if(n.length!==1)throw new Error("Illegal value received. Escaped type identifiers must have exactly one element.",{cause:e});let[d]=n,p={...e};return p[this.#e]=d,this.#t(p,!0)}let o=this.#r.get(n);if(!o)throw new Error(`No decoder found for type id: ${n}`,{cause:e});return o(e,this.decode.bind(this))}if(Object.getPrototypeOf(e)===Object.prototype)return Object.fromEntries(Object.entries(e).map(([n,o])=>[n,this.#t(o)]));break}throw new Error("Illegal value received.",{cause:e})}serialize(e){return this.encode(e)}deserialize(e){return this.decode(e)}stringify(e){return JSON.stringify(this.encode(e))}parse(e){return this.decode(JSON.parse(e))}static default=new t({types:l});static register=t.default.register.bind(t.default);static encode=t.default.encode.bind(t.default);static serialize=t.default.serialize.bind(t.default);static decode=t.default.decode.bind(t.default);static deserialize=t.default.deserialize.bind(t.default);static stringify=t.default.stringify.bind(t.default);static parse=t.default.parse.bind(t.default)};0&&(module.exports={Jasone,bigIntType,createType,dateType,defaultTypes,mapType,regExpType,setType,undefinedType,urlType});
|
package/index.d.cts
CHANGED
|
@@ -1,8 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A JSON-compatible value.
|
|
3
|
+
*/
|
|
1
4
|
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
2
5
|
[key: string]: JsonValue;
|
|
3
6
|
};
|
|
7
|
+
/**
|
|
8
|
+
* The id of an encoded type to identify it on decoding.
|
|
9
|
+
*/
|
|
4
10
|
type TypeId = string | number;
|
|
11
|
+
/**
|
|
12
|
+
* A function that is responsible to encode a type into a JSON-compatible value.
|
|
13
|
+
*
|
|
14
|
+
* @param value The value to encode.
|
|
15
|
+
* @param encode A function that works exactly the same as `Jasone.encode` useful
|
|
16
|
+
* to encode values recursively. This function comes from the instance
|
|
17
|
+
* where the type transformer is registered, so it has the same types.
|
|
18
|
+
* @returns A JSON-compatible value.
|
|
19
|
+
*/
|
|
5
20
|
type TypeEncoder<TType = unknown, TJson extends Record<string, JsonValue> = Record<string, JsonValue>> = (value: TType, encode: <T = unknown>(value: T) => JsonValue) => TJson;
|
|
21
|
+
/**
|
|
22
|
+
* A function that is responsible to decode a type back to its decoded value.
|
|
23
|
+
*
|
|
24
|
+
* @param value The value to decode.
|
|
25
|
+
* @param encode A function that works exactly the same as `Jasone.decode` useful
|
|
26
|
+
* to decode values recursively. This function comes from the instance
|
|
27
|
+
* where the type transformer is registered, so it has the same types.
|
|
28
|
+
* @returns A JSON-compatible value.
|
|
29
|
+
*/
|
|
6
30
|
type TypeDecoder<TType = unknown, TJson extends Record<string, JsonValue> = Record<string, JsonValue>> = (value: TJson, decode: <T = unknown>(value: JsonValue) => T) => TType;
|
|
7
31
|
type MatchesFn<TType = unknown> = (value: unknown) => value is TType;
|
|
8
32
|
type ClassLike<TInstance> = new (...args: unknown[]) => TInstance;
|
|
@@ -10,31 +34,240 @@ declare const typeOf: "string" | "number" | "bigint" | "boolean" | "symbol" | "u
|
|
|
10
34
|
type TypeOf = typeof typeOf;
|
|
11
35
|
|
|
12
36
|
type TypeMatcher<TType> = {
|
|
37
|
+
/**
|
|
38
|
+
* The function that is responsible to determine if a value can be
|
|
39
|
+
* encoded with this transformer.
|
|
40
|
+
*/
|
|
13
41
|
matches: MatchesFn<TType>;
|
|
14
42
|
} | {
|
|
43
|
+
/**
|
|
44
|
+
* The class that can be encoded with this transformer.
|
|
45
|
+
*
|
|
46
|
+
* Using the `target` property only works on classes with an
|
|
47
|
+
* `constructor`. Internally, Jasone matches the constructor of the
|
|
48
|
+
* class with the `target` property.
|
|
49
|
+
*/
|
|
15
50
|
target: ClassLike<TType>;
|
|
16
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* A type transformer which is responsible for encoding and decoding a type.
|
|
54
|
+
*/
|
|
17
55
|
type TypeTransformer<TType, TJson extends Record<string, JsonValue> = Record<string, JsonValue>> = TypeMatcher<TType> & {
|
|
56
|
+
/**
|
|
57
|
+
* The id of the type that is used to identify the type on decoding.
|
|
58
|
+
*
|
|
59
|
+
* This id should be unique for each type and it is recommended to use strings
|
|
60
|
+
* to avoid conflicts with built-in types (which used positive integers).
|
|
61
|
+
*/
|
|
18
62
|
typeId: string | number;
|
|
63
|
+
/**
|
|
64
|
+
* The function that is responsible to encode the type into a JSON-compatible
|
|
65
|
+
* value.
|
|
66
|
+
*/
|
|
19
67
|
encode: TypeEncoder<TType, TJson>;
|
|
68
|
+
/**
|
|
69
|
+
* The function that is responsible to decode the type from a JSON-compatible
|
|
70
|
+
* value.
|
|
71
|
+
*/
|
|
20
72
|
decode: TypeDecoder<TType, TJson>;
|
|
21
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* A convenience function to create a type transformer which automatically
|
|
76
|
+
* infer the types for you, so you don't have to.
|
|
77
|
+
*
|
|
78
|
+
* @param transformer The transformer to create.
|
|
79
|
+
* @returns The exact same transformer you passed in, but with the types inferred.
|
|
80
|
+
*/
|
|
22
81
|
declare const createType: <TType, TJson extends Record<string, JsonValue>>(transformer: TypeTransformer<TType, TJson>) => TypeTransformer<TType, TJson>;
|
|
23
82
|
|
|
83
|
+
declare const bigIntType: TypeTransformer<bigint, {
|
|
84
|
+
bigint: string;
|
|
85
|
+
}>;
|
|
86
|
+
|
|
87
|
+
declare const dateType: TypeTransformer<Date, {
|
|
88
|
+
timestamp: number;
|
|
89
|
+
}>;
|
|
90
|
+
|
|
91
|
+
declare const mapType: TypeTransformer<Map<any, any>, {
|
|
92
|
+
map: JsonValue[][];
|
|
93
|
+
}>;
|
|
94
|
+
|
|
95
|
+
declare const regExpType: TypeTransformer<RegExp, {
|
|
96
|
+
source: string;
|
|
97
|
+
flags: string;
|
|
98
|
+
}>;
|
|
99
|
+
|
|
100
|
+
declare const setType: TypeTransformer<Set<any>, {
|
|
101
|
+
set: JsonValue[];
|
|
102
|
+
}>;
|
|
103
|
+
|
|
104
|
+
declare const undefinedType: TypeTransformer<undefined, {}>;
|
|
105
|
+
|
|
106
|
+
declare const urlType: TypeTransformer<URL, {
|
|
107
|
+
url: string;
|
|
108
|
+
}>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The default types that are used by the default Jasone instance.
|
|
112
|
+
*/
|
|
113
|
+
declare const defaultTypes: TypeTransformer<any, any>[];
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Jasone options that can be passed to the Jasone constructor.
|
|
117
|
+
*/
|
|
24
118
|
type JasoneOptions = {
|
|
119
|
+
/**
|
|
120
|
+
* The type identifier that is used to determine if an object is a typed object.
|
|
121
|
+
*
|
|
122
|
+
* @default "$"
|
|
123
|
+
*/
|
|
25
124
|
typeIdentifier?: string;
|
|
125
|
+
/**
|
|
126
|
+
* The types that are used to encode and decode objects.
|
|
127
|
+
*
|
|
128
|
+
* If not provided, the default types are used. By providing your own types,
|
|
129
|
+
* the default types are not used anymore, so be sure to also include them.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* // your custom type WITH default types
|
|
134
|
+
* const jasone = new Jasone({ types: [myCustomType, ...defaultTypes] });
|
|
135
|
+
*
|
|
136
|
+
* // your custom type WITHOUT default types
|
|
137
|
+
* const jasone = new Jasone({ types: [myCustomType] });
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
26
140
|
types?: TypeTransformer<any, any>[];
|
|
27
141
|
};
|
|
142
|
+
/**
|
|
143
|
+
* Jasone is a JSON encoder and decoder that can handle custom types.
|
|
144
|
+
*
|
|
145
|
+
* It exposes the default Jasone instance as `Jasone.default` and also
|
|
146
|
+
* registers the methods as static methods on the class itself, so you
|
|
147
|
+
* can easily use them without having to create an instance.
|
|
148
|
+
*
|
|
149
|
+
* ```ts
|
|
150
|
+
* const encoded = Jasone.encode(value);
|
|
151
|
+
* const decoded = Jasone.decode(value);
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* If you want to use your own types, you can either register them on any
|
|
155
|
+
* instance (even on `Jasone.default`) or instantiate your own Jasone instance.
|
|
156
|
+
*
|
|
157
|
+
* ```ts
|
|
158
|
+
* // use our own types without the default types (Date, BigInt, Map, etc.)
|
|
159
|
+
* const myInstance = new Jasone({ types: [myCustomType] });
|
|
160
|
+
*
|
|
161
|
+
* // or use our own types with the default types (recommend)
|
|
162
|
+
* const myInstance = new Jasone({ types: [myCustomType, ...defaultTypes] });
|
|
163
|
+
*
|
|
164
|
+
* const encoded = myInstance.encode(value);
|
|
165
|
+
* const decoded = myInstance.decode(value);
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
28
168
|
declare class Jasone {
|
|
29
169
|
#private;
|
|
30
170
|
constructor(options?: JasoneOptions);
|
|
171
|
+
/**
|
|
172
|
+
* Register a new type to this Jasone instance.
|
|
173
|
+
*
|
|
174
|
+
* @param type The type to register.
|
|
175
|
+
*/
|
|
31
176
|
register<TType, TJson extends Record<string, JsonValue>>(type: TypeTransformer<TType, TJson>): void;
|
|
177
|
+
/**
|
|
178
|
+
* Encode an arbitrary value to a JSON-compatible Jasone encoded value.
|
|
179
|
+
*
|
|
180
|
+
* @param value The value to encode.
|
|
181
|
+
* @returns A JSON-compatible Jasone encoded value.
|
|
182
|
+
*/
|
|
32
183
|
encode(value: unknown): JsonValue;
|
|
184
|
+
/**
|
|
185
|
+
* Decode an Jasone encoded value to its decoded value.
|
|
186
|
+
*
|
|
187
|
+
* @param value The Jasone encoded value to decode.
|
|
188
|
+
* @returns The decoded value.
|
|
189
|
+
*/
|
|
33
190
|
decode<T = unknown>(value: JsonValue): T;
|
|
191
|
+
/**
|
|
192
|
+
* Alias for `encode`.
|
|
193
|
+
*/
|
|
194
|
+
serialize(value: unknown): JsonValue;
|
|
195
|
+
/**
|
|
196
|
+
* Alias for `decode`.
|
|
197
|
+
*/
|
|
198
|
+
deserialize<T = unknown>(value: JsonValue): T;
|
|
199
|
+
/**
|
|
200
|
+
* A wrapper around `JSON.stringify` that encodes a value and stringifies it.
|
|
201
|
+
*
|
|
202
|
+
* Under the hood, this functions looks like this:
|
|
203
|
+
*
|
|
204
|
+
* ```ts
|
|
205
|
+
* JSON.stringify(this.encode(value));
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
stringify(value: unknown): string;
|
|
209
|
+
/**
|
|
210
|
+
* A wrapper around `JSON.parse` that parses a Jasone encoded value and decodes it.
|
|
211
|
+
*
|
|
212
|
+
* Under the hood, this functions looks like this:
|
|
213
|
+
*
|
|
214
|
+
* ```ts
|
|
215
|
+
* this.decode(JSON.parse(value));
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
parse<T = unknown>(value: string): T;
|
|
219
|
+
/**
|
|
220
|
+
* The default Jasone instance with the default types already registered.
|
|
221
|
+
*/
|
|
34
222
|
static default: Jasone;
|
|
223
|
+
/**
|
|
224
|
+
* Register a new type to the default Jasone instance.
|
|
225
|
+
*
|
|
226
|
+
* @param type The type to register.
|
|
227
|
+
*/
|
|
35
228
|
static register: <TType, TJson extends Record<string, JsonValue>>(type: TypeTransformer<TType, TJson>) => void;
|
|
229
|
+
/**
|
|
230
|
+
* Encode an arbitrary value to a JSON-compatible Jasone encoded value.
|
|
231
|
+
*
|
|
232
|
+
* @param value The value to encode.
|
|
233
|
+
* @returns A JSON-compatible Jasone encoded value.
|
|
234
|
+
*/
|
|
36
235
|
static encode: (value: unknown) => JsonValue;
|
|
236
|
+
/**
|
|
237
|
+
* Alias for `encode`.
|
|
238
|
+
*/
|
|
239
|
+
static serialize: (value: unknown) => JsonValue;
|
|
240
|
+
/**
|
|
241
|
+
* Decode an Jasone encoded value to its decoded value.
|
|
242
|
+
*
|
|
243
|
+
* @param value The Jasone encoded value to decode.
|
|
244
|
+
* @returns The decoded value.
|
|
245
|
+
*/
|
|
37
246
|
static decode: <T = unknown>(value: JsonValue) => T;
|
|
247
|
+
/**
|
|
248
|
+
* Alias for `decode`.
|
|
249
|
+
*/
|
|
250
|
+
static deserialize: <T = unknown>(value: JsonValue) => T;
|
|
251
|
+
/**
|
|
252
|
+
* A wrapper around `JSON.stringify` that encodes a value and stringifies it.
|
|
253
|
+
*
|
|
254
|
+
* Under the hood, this functions looks like this:
|
|
255
|
+
*
|
|
256
|
+
* ```ts
|
|
257
|
+
* JSON.stringify(Jasone.encode(value));
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
static stringify: (value: unknown) => string;
|
|
261
|
+
/**
|
|
262
|
+
* A wrapper around `JSON.parse` that parses a Jasone encoded value and decodes it.
|
|
263
|
+
*
|
|
264
|
+
* Under the hood, this functions looks like this:
|
|
265
|
+
*
|
|
266
|
+
* ```ts
|
|
267
|
+
* Jasone.decode(JSON.parse(value));
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
static parse: <T = unknown>(value: string) => T;
|
|
38
271
|
}
|
|
39
272
|
|
|
40
|
-
export { type ClassLike, Jasone, type JasoneOptions, type JsonValue, type MatchesFn, type TypeDecoder, type TypeEncoder, type TypeId, type TypeMatcher, type TypeOf, type TypeTransformer, createType };
|
|
273
|
+
export { type ClassLike, Jasone, type JasoneOptions, type JsonValue, type MatchesFn, type TypeDecoder, type TypeEncoder, type TypeId, type TypeMatcher, type TypeOf, type TypeTransformer, bigIntType, createType, dateType, defaultTypes, mapType, regExpType, setType, undefinedType, urlType };
|
package/index.d.ts
CHANGED
|
@@ -1,8 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A JSON-compatible value.
|
|
3
|
+
*/
|
|
1
4
|
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
2
5
|
[key: string]: JsonValue;
|
|
3
6
|
};
|
|
7
|
+
/**
|
|
8
|
+
* The id of an encoded type to identify it on decoding.
|
|
9
|
+
*/
|
|
4
10
|
type TypeId = string | number;
|
|
11
|
+
/**
|
|
12
|
+
* A function that is responsible to encode a type into a JSON-compatible value.
|
|
13
|
+
*
|
|
14
|
+
* @param value The value to encode.
|
|
15
|
+
* @param encode A function that works exactly the same as `Jasone.encode` useful
|
|
16
|
+
* to encode values recursively. This function comes from the instance
|
|
17
|
+
* where the type transformer is registered, so it has the same types.
|
|
18
|
+
* @returns A JSON-compatible value.
|
|
19
|
+
*/
|
|
5
20
|
type TypeEncoder<TType = unknown, TJson extends Record<string, JsonValue> = Record<string, JsonValue>> = (value: TType, encode: <T = unknown>(value: T) => JsonValue) => TJson;
|
|
21
|
+
/**
|
|
22
|
+
* A function that is responsible to decode a type back to its decoded value.
|
|
23
|
+
*
|
|
24
|
+
* @param value The value to decode.
|
|
25
|
+
* @param encode A function that works exactly the same as `Jasone.decode` useful
|
|
26
|
+
* to decode values recursively. This function comes from the instance
|
|
27
|
+
* where the type transformer is registered, so it has the same types.
|
|
28
|
+
* @returns A JSON-compatible value.
|
|
29
|
+
*/
|
|
6
30
|
type TypeDecoder<TType = unknown, TJson extends Record<string, JsonValue> = Record<string, JsonValue>> = (value: TJson, decode: <T = unknown>(value: JsonValue) => T) => TType;
|
|
7
31
|
type MatchesFn<TType = unknown> = (value: unknown) => value is TType;
|
|
8
32
|
type ClassLike<TInstance> = new (...args: unknown[]) => TInstance;
|
|
@@ -10,31 +34,240 @@ declare const typeOf: "string" | "number" | "bigint" | "boolean" | "symbol" | "u
|
|
|
10
34
|
type TypeOf = typeof typeOf;
|
|
11
35
|
|
|
12
36
|
type TypeMatcher<TType> = {
|
|
37
|
+
/**
|
|
38
|
+
* The function that is responsible to determine if a value can be
|
|
39
|
+
* encoded with this transformer.
|
|
40
|
+
*/
|
|
13
41
|
matches: MatchesFn<TType>;
|
|
14
42
|
} | {
|
|
43
|
+
/**
|
|
44
|
+
* The class that can be encoded with this transformer.
|
|
45
|
+
*
|
|
46
|
+
* Using the `target` property only works on classes with an
|
|
47
|
+
* `constructor`. Internally, Jasone matches the constructor of the
|
|
48
|
+
* class with the `target` property.
|
|
49
|
+
*/
|
|
15
50
|
target: ClassLike<TType>;
|
|
16
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* A type transformer which is responsible for encoding and decoding a type.
|
|
54
|
+
*/
|
|
17
55
|
type TypeTransformer<TType, TJson extends Record<string, JsonValue> = Record<string, JsonValue>> = TypeMatcher<TType> & {
|
|
56
|
+
/**
|
|
57
|
+
* The id of the type that is used to identify the type on decoding.
|
|
58
|
+
*
|
|
59
|
+
* This id should be unique for each type and it is recommended to use strings
|
|
60
|
+
* to avoid conflicts with built-in types (which used positive integers).
|
|
61
|
+
*/
|
|
18
62
|
typeId: string | number;
|
|
63
|
+
/**
|
|
64
|
+
* The function that is responsible to encode the type into a JSON-compatible
|
|
65
|
+
* value.
|
|
66
|
+
*/
|
|
19
67
|
encode: TypeEncoder<TType, TJson>;
|
|
68
|
+
/**
|
|
69
|
+
* The function that is responsible to decode the type from a JSON-compatible
|
|
70
|
+
* value.
|
|
71
|
+
*/
|
|
20
72
|
decode: TypeDecoder<TType, TJson>;
|
|
21
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* A convenience function to create a type transformer which automatically
|
|
76
|
+
* infer the types for you, so you don't have to.
|
|
77
|
+
*
|
|
78
|
+
* @param transformer The transformer to create.
|
|
79
|
+
* @returns The exact same transformer you passed in, but with the types inferred.
|
|
80
|
+
*/
|
|
22
81
|
declare const createType: <TType, TJson extends Record<string, JsonValue>>(transformer: TypeTransformer<TType, TJson>) => TypeTransformer<TType, TJson>;
|
|
23
82
|
|
|
83
|
+
declare const bigIntType: TypeTransformer<bigint, {
|
|
84
|
+
bigint: string;
|
|
85
|
+
}>;
|
|
86
|
+
|
|
87
|
+
declare const dateType: TypeTransformer<Date, {
|
|
88
|
+
timestamp: number;
|
|
89
|
+
}>;
|
|
90
|
+
|
|
91
|
+
declare const mapType: TypeTransformer<Map<any, any>, {
|
|
92
|
+
map: JsonValue[][];
|
|
93
|
+
}>;
|
|
94
|
+
|
|
95
|
+
declare const regExpType: TypeTransformer<RegExp, {
|
|
96
|
+
source: string;
|
|
97
|
+
flags: string;
|
|
98
|
+
}>;
|
|
99
|
+
|
|
100
|
+
declare const setType: TypeTransformer<Set<any>, {
|
|
101
|
+
set: JsonValue[];
|
|
102
|
+
}>;
|
|
103
|
+
|
|
104
|
+
declare const undefinedType: TypeTransformer<undefined, {}>;
|
|
105
|
+
|
|
106
|
+
declare const urlType: TypeTransformer<URL, {
|
|
107
|
+
url: string;
|
|
108
|
+
}>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The default types that are used by the default Jasone instance.
|
|
112
|
+
*/
|
|
113
|
+
declare const defaultTypes: TypeTransformer<any, any>[];
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Jasone options that can be passed to the Jasone constructor.
|
|
117
|
+
*/
|
|
24
118
|
type JasoneOptions = {
|
|
119
|
+
/**
|
|
120
|
+
* The type identifier that is used to determine if an object is a typed object.
|
|
121
|
+
*
|
|
122
|
+
* @default "$"
|
|
123
|
+
*/
|
|
25
124
|
typeIdentifier?: string;
|
|
125
|
+
/**
|
|
126
|
+
* The types that are used to encode and decode objects.
|
|
127
|
+
*
|
|
128
|
+
* If not provided, the default types are used. By providing your own types,
|
|
129
|
+
* the default types are not used anymore, so be sure to also include them.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* // your custom type WITH default types
|
|
134
|
+
* const jasone = new Jasone({ types: [myCustomType, ...defaultTypes] });
|
|
135
|
+
*
|
|
136
|
+
* // your custom type WITHOUT default types
|
|
137
|
+
* const jasone = new Jasone({ types: [myCustomType] });
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
26
140
|
types?: TypeTransformer<any, any>[];
|
|
27
141
|
};
|
|
142
|
+
/**
|
|
143
|
+
* Jasone is a JSON encoder and decoder that can handle custom types.
|
|
144
|
+
*
|
|
145
|
+
* It exposes the default Jasone instance as `Jasone.default` and also
|
|
146
|
+
* registers the methods as static methods on the class itself, so you
|
|
147
|
+
* can easily use them without having to create an instance.
|
|
148
|
+
*
|
|
149
|
+
* ```ts
|
|
150
|
+
* const encoded = Jasone.encode(value);
|
|
151
|
+
* const decoded = Jasone.decode(value);
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* If you want to use your own types, you can either register them on any
|
|
155
|
+
* instance (even on `Jasone.default`) or instantiate your own Jasone instance.
|
|
156
|
+
*
|
|
157
|
+
* ```ts
|
|
158
|
+
* // use our own types without the default types (Date, BigInt, Map, etc.)
|
|
159
|
+
* const myInstance = new Jasone({ types: [myCustomType] });
|
|
160
|
+
*
|
|
161
|
+
* // or use our own types with the default types (recommend)
|
|
162
|
+
* const myInstance = new Jasone({ types: [myCustomType, ...defaultTypes] });
|
|
163
|
+
*
|
|
164
|
+
* const encoded = myInstance.encode(value);
|
|
165
|
+
* const decoded = myInstance.decode(value);
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
28
168
|
declare class Jasone {
|
|
29
169
|
#private;
|
|
30
170
|
constructor(options?: JasoneOptions);
|
|
171
|
+
/**
|
|
172
|
+
* Register a new type to this Jasone instance.
|
|
173
|
+
*
|
|
174
|
+
* @param type The type to register.
|
|
175
|
+
*/
|
|
31
176
|
register<TType, TJson extends Record<string, JsonValue>>(type: TypeTransformer<TType, TJson>): void;
|
|
177
|
+
/**
|
|
178
|
+
* Encode an arbitrary value to a JSON-compatible Jasone encoded value.
|
|
179
|
+
*
|
|
180
|
+
* @param value The value to encode.
|
|
181
|
+
* @returns A JSON-compatible Jasone encoded value.
|
|
182
|
+
*/
|
|
32
183
|
encode(value: unknown): JsonValue;
|
|
184
|
+
/**
|
|
185
|
+
* Decode an Jasone encoded value to its decoded value.
|
|
186
|
+
*
|
|
187
|
+
* @param value The Jasone encoded value to decode.
|
|
188
|
+
* @returns The decoded value.
|
|
189
|
+
*/
|
|
33
190
|
decode<T = unknown>(value: JsonValue): T;
|
|
191
|
+
/**
|
|
192
|
+
* Alias for `encode`.
|
|
193
|
+
*/
|
|
194
|
+
serialize(value: unknown): JsonValue;
|
|
195
|
+
/**
|
|
196
|
+
* Alias for `decode`.
|
|
197
|
+
*/
|
|
198
|
+
deserialize<T = unknown>(value: JsonValue): T;
|
|
199
|
+
/**
|
|
200
|
+
* A wrapper around `JSON.stringify` that encodes a value and stringifies it.
|
|
201
|
+
*
|
|
202
|
+
* Under the hood, this functions looks like this:
|
|
203
|
+
*
|
|
204
|
+
* ```ts
|
|
205
|
+
* JSON.stringify(this.encode(value));
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
stringify(value: unknown): string;
|
|
209
|
+
/**
|
|
210
|
+
* A wrapper around `JSON.parse` that parses a Jasone encoded value and decodes it.
|
|
211
|
+
*
|
|
212
|
+
* Under the hood, this functions looks like this:
|
|
213
|
+
*
|
|
214
|
+
* ```ts
|
|
215
|
+
* this.decode(JSON.parse(value));
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
parse<T = unknown>(value: string): T;
|
|
219
|
+
/**
|
|
220
|
+
* The default Jasone instance with the default types already registered.
|
|
221
|
+
*/
|
|
34
222
|
static default: Jasone;
|
|
223
|
+
/**
|
|
224
|
+
* Register a new type to the default Jasone instance.
|
|
225
|
+
*
|
|
226
|
+
* @param type The type to register.
|
|
227
|
+
*/
|
|
35
228
|
static register: <TType, TJson extends Record<string, JsonValue>>(type: TypeTransformer<TType, TJson>) => void;
|
|
229
|
+
/**
|
|
230
|
+
* Encode an arbitrary value to a JSON-compatible Jasone encoded value.
|
|
231
|
+
*
|
|
232
|
+
* @param value The value to encode.
|
|
233
|
+
* @returns A JSON-compatible Jasone encoded value.
|
|
234
|
+
*/
|
|
36
235
|
static encode: (value: unknown) => JsonValue;
|
|
236
|
+
/**
|
|
237
|
+
* Alias for `encode`.
|
|
238
|
+
*/
|
|
239
|
+
static serialize: (value: unknown) => JsonValue;
|
|
240
|
+
/**
|
|
241
|
+
* Decode an Jasone encoded value to its decoded value.
|
|
242
|
+
*
|
|
243
|
+
* @param value The Jasone encoded value to decode.
|
|
244
|
+
* @returns The decoded value.
|
|
245
|
+
*/
|
|
37
246
|
static decode: <T = unknown>(value: JsonValue) => T;
|
|
247
|
+
/**
|
|
248
|
+
* Alias for `decode`.
|
|
249
|
+
*/
|
|
250
|
+
static deserialize: <T = unknown>(value: JsonValue) => T;
|
|
251
|
+
/**
|
|
252
|
+
* A wrapper around `JSON.stringify` that encodes a value and stringifies it.
|
|
253
|
+
*
|
|
254
|
+
* Under the hood, this functions looks like this:
|
|
255
|
+
*
|
|
256
|
+
* ```ts
|
|
257
|
+
* JSON.stringify(Jasone.encode(value));
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
static stringify: (value: unknown) => string;
|
|
261
|
+
/**
|
|
262
|
+
* A wrapper around `JSON.parse` that parses a Jasone encoded value and decodes it.
|
|
263
|
+
*
|
|
264
|
+
* Under the hood, this functions looks like this:
|
|
265
|
+
*
|
|
266
|
+
* ```ts
|
|
267
|
+
* Jasone.decode(JSON.parse(value));
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
static parse: <T = unknown>(value: string) => T;
|
|
38
271
|
}
|
|
39
272
|
|
|
40
|
-
export { type ClassLike, Jasone, type JasoneOptions, type JsonValue, type MatchesFn, type TypeDecoder, type TypeEncoder, type TypeId, type TypeMatcher, type TypeOf, type TypeTransformer, createType };
|
|
273
|
+
export { type ClassLike, Jasone, type JasoneOptions, type JsonValue, type MatchesFn, type TypeDecoder, type TypeEncoder, type TypeId, type TypeMatcher, type TypeOf, type TypeTransformer, bigIntType, createType, dateType, defaultTypes, mapType, regExpType, setType, undefinedType, urlType };
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var o=t=>t;var c=o({matches:t=>typeof t=="bigint",typeId:2,encode:t=>({bigint:t.toString()}),decode:({bigint:t})=>BigInt(t)});var a=o({target:Date,typeId:1,encode:t=>({timestamp:t.getTime()}),decode:({timestamp:t})=>new Date(t)});var y=o({matches:t=>t instanceof Map,typeId:5,encode:(t,e)=>({map:Array.from(t.entries().map(([r,n])=>[e(r),e(n)]))}),decode:({map:t},e)=>new Map(t.map(([r,n])=>{if(r===void 0||n===void 0)throw new Error("Illegal value received.",{cause:t});return[e(r),e(n)]}))});var T=o({matches:t=>t instanceof RegExp,typeId:3,encode:t=>({source:t.source,flags:t.flags}),decode:({source:t,flags:e})=>new RegExp(t,e)});var f=o({matches:t=>t instanceof Set,typeId:4,encode:(t,e)=>({set:Array.from(t.values().map(r=>e(r)))}),decode:({set:t},e)=>new Set(t.map(r=>e(r)))});var m=o({matches:t=>t===void 0,typeId:0,encode:()=>({}),decode:()=>{}});var u=o({matches:t=>t instanceof URL,typeId:6,encode:t=>({url:t.toString()}),decode:({url:t})=>new URL(t)});var h=[m,a,c,T,f,y,u];var d=class t{#e;#r=new Map;#n=new Map;#o=[];constructor(e={}){this.#e=e.typeIdentifier??"$";for(let r of e.types??[])this.register(r)}register(e){this.#r.set(e.typeId,e.decode),"matches"in e?this.#o.push({matches:e.matches,typeId:e.typeId,encode:e.encode}):this.#n.set(e.target,{typeId:e.typeId,encode:e.encode})}encode(e){switch(typeof e){case"string":case"number":case"boolean":return e;case"object":if(e===null)return null;if(Array.isArray(e))return e.map(s=>this.encode(s));if(Object.getPrototypeOf(e)===Object.prototype){let s=Object.fromEntries(Object.entries(e).map(([i,p])=>[i,this.encode(p)]));return this.#e in s&&(s[this.#e]=[this.encode(s[this.#e])]),s}}let r;if(typeof e=="object"&&e!==null&&(r=this.#n.get(e.constructor)),r||(r=this.#o.find(({matches:s})=>s(e))),!r)throw new Error("No encoder found.",{cause:e});let n=r.encode(e,this.encode.bind(this));return{[this.#e]:r.typeId,...n}}decode(e){return this.#t(e)}#t(e,r=!1){switch(typeof e){case"string":case"number":case"boolean":return e;case"object":if(e===null)return null;if(Array.isArray(e))return e.map(n=>this.#t(n));if(this.#e in e&&!Array.isArray(e)&&!r){let n=e[this.#e];if(Array.isArray(n)){if(n.length!==1)throw new Error("Illegal value received. Escaped type identifiers must have exactly one element.",{cause:e});let[i]=n,p={...e};return p[this.#e]=i,this.#t(p,!0)}let s=this.#r.get(n);if(!s)throw new Error(`No decoder found for type id: ${n}`,{cause:e});return s(e,this.decode.bind(this))}if(Object.getPrototypeOf(e)===Object.prototype)return Object.fromEntries(Object.entries(e).map(([n,s])=>[n,this.#t(s)]));break}throw new Error("Illegal value received.",{cause:e})}serialize(e){return this.encode(e)}deserialize(e){return this.decode(e)}stringify(e){return JSON.stringify(this.encode(e))}parse(e){return this.decode(JSON.parse(e))}static default=new t({types:h});static register=t.default.register.bind(t.default);static encode=t.default.encode.bind(t.default);static serialize=t.default.serialize.bind(t.default);static decode=t.default.decode.bind(t.default);static deserialize=t.default.deserialize.bind(t.default);static stringify=t.default.stringify.bind(t.default);static parse=t.default.parse.bind(t.default)};export{d as Jasone,c as bigIntType,o as createType,a as dateType,h as defaultTypes,y as mapType,T as regExpType,f as setType,m as undefinedType,u as urlType};
|