json-as 0.9.4 → 0.9.6
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/.github/workflows/release-package.yml +18 -4
- package/CHANGELOG +1 -0
- package/README.md +12 -1
- package/assembly/index.d.ts +6 -0
- package/assembly/test.ts +42 -16
- package/package.json +4 -2
- package/transform/lib/index.js +43 -23
- package/transform/package.json +1 -1
- package/transform/src/index.ts +43 -23
|
@@ -11,9 +11,23 @@ jobs:
|
|
|
11
11
|
- uses: actions/checkout@v4
|
|
12
12
|
- uses: actions/setup-node@v3
|
|
13
13
|
with:
|
|
14
|
-
node-version: 16
|
|
15
|
-
|
|
16
|
-
-
|
|
14
|
+
node-version: 16
|
|
15
|
+
|
|
16
|
+
- name: Install Wasmtime
|
|
17
|
+
uses: jcbhmr/setup-wasmtime@v2
|
|
18
|
+
|
|
19
|
+
- name: Setup Node.js
|
|
20
|
+
uses: actions/setup-node@v2
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
if: steps.node-cache.outputs.cache-hit != 'true'
|
|
24
|
+
run: yarn
|
|
25
|
+
|
|
26
|
+
- name: Build tests
|
|
27
|
+
run: yarn run tests:build
|
|
28
|
+
|
|
29
|
+
- name: Perform tests
|
|
30
|
+
run: yarn run test
|
|
17
31
|
|
|
18
32
|
publish-gpr:
|
|
19
33
|
needs: build
|
|
@@ -25,7 +39,7 @@ jobs:
|
|
|
25
39
|
- uses: actions/checkout@v4
|
|
26
40
|
- uses: actions/setup-node@v3
|
|
27
41
|
with:
|
|
28
|
-
node-version:
|
|
42
|
+
node-version: 22
|
|
29
43
|
registry-url: https://npm.pkg.github.com/
|
|
30
44
|
- run: npm ci
|
|
31
45
|
- run: npm publish
|
package/CHANGELOG
CHANGED
|
@@ -9,5 +9,6 @@ v0.9.1 - Fix #71
|
|
|
9
9
|
v0.9.2 - Fix #75 + Build sizes significantly reduced
|
|
10
10
|
v0.9.3 - Fix #76
|
|
11
11
|
v0.9.4 - Fix #77
|
|
12
|
+
v0.9.5 - Fix #46
|
|
12
13
|
|
|
13
14
|
[UNRELEASED] v0.9.x - Port JSON.Value from the `develop` branch to allow for union types, parsing of arbitrary data, and whatever the hell you want.
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
██║ ██║███████║ ╚█████╔╝███████║╚██████╔╝██║ ╚████║
|
|
8
8
|
╚═╝ ╚═╝╚══════╝ ╚════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═══╝
|
|
9
9
|
|
|
10
|
-
v0.9.
|
|
10
|
+
v0.9.6
|
|
11
11
|
</pre>
|
|
12
12
|
</h3>
|
|
13
13
|
|
|
@@ -111,6 +111,17 @@ const serialized = JSON.stringify(arr);
|
|
|
111
111
|
const parsed = JSON.parse<Base[]>(serialized);
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
+
Classes can even have inheritance. Here's a nasty example
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
@json
|
|
118
|
+
class Base {}
|
|
119
|
+
|
|
120
|
+
const serialized = JSON.stringify(arr);
|
|
121
|
+
// [{"x":1.0},{"x":1.0,"y":2.0},{"y":2.0,"x":1.0,"z":3.0}]
|
|
122
|
+
const parsed = JSON.parse<Base[]>(serialized);
|
|
123
|
+
```
|
|
124
|
+
|
|
114
125
|
If you use this project in your codebase, consider dropping a [star](https://github.com/JairusSW/as-json). I would really appreciate it!
|
|
115
126
|
|
|
116
127
|
## Notes
|
package/assembly/index.d.ts
CHANGED
|
@@ -28,3 +28,9 @@ declare function omitif(condition: string): Function;
|
|
|
28
28
|
* Property decorator that allows a field to be omitted when a property is null.
|
|
29
29
|
*/
|
|
30
30
|
declare function omitnull(): Function;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Property decorator that allows a field to be flattened.
|
|
34
|
+
* @param fieldName - Points to the field to flatten. Can use dot-notation here like @omit("foo.identifier.text")
|
|
35
|
+
*/
|
|
36
|
+
declare function flatten(fieldName: string = "value"): Function;
|
package/assembly/test.ts
CHANGED
|
@@ -1,25 +1,51 @@
|
|
|
1
1
|
import { JSON } from ".";
|
|
2
2
|
|
|
3
|
+
// @json or @serializable work here
|
|
3
4
|
@json
|
|
4
|
-
class
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
class Vec3 {
|
|
6
|
+
x: f32 = 0.0;
|
|
7
|
+
y: f32 = 0.0;
|
|
8
|
+
z: f32 = 0.0;
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
-
class
|
|
11
|
-
|
|
12
|
-
y: f32 = 2.0;
|
|
10
|
+
|
|
11
|
+
class Box<T> {
|
|
12
|
+
value: T;
|
|
13
13
|
}
|
|
14
|
+
|
|
14
15
|
@json
|
|
15
|
-
class
|
|
16
|
-
|
|
16
|
+
class Player {
|
|
17
|
+
@alias("first name")
|
|
18
|
+
@omitnull()
|
|
19
|
+
firstName: string | null;
|
|
20
|
+
lastName!: string;
|
|
21
|
+
lastActive!: i32[];
|
|
22
|
+
// Drop in a code block, function, or expression that evaluates to a boolean
|
|
23
|
+
@omitif("this.age < 18")
|
|
24
|
+
age!: i32;
|
|
25
|
+
@omitnull()
|
|
26
|
+
pos!: Vec3 | null;
|
|
27
|
+
isVerified!: boolean;
|
|
28
|
+
@flatten("value")
|
|
29
|
+
box: Box<i32> | null;
|
|
17
30
|
}
|
|
18
31
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
32
|
+
const player: Player = {
|
|
33
|
+
firstName: null,
|
|
34
|
+
lastName: "West",
|
|
35
|
+
lastActive: [8, 27, 2022],
|
|
36
|
+
age: 23,
|
|
37
|
+
pos: {
|
|
38
|
+
x: 3.4,
|
|
39
|
+
y: 1.2,
|
|
40
|
+
z: 8.3
|
|
41
|
+
},
|
|
42
|
+
isVerified: true,
|
|
43
|
+
box: null
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const stringified = JSON.stringify<Player>(player);
|
|
47
|
+
|
|
48
|
+
const parsed = JSON.parse<Player>(stringified);
|
|
24
49
|
|
|
25
|
-
console.log(
|
|
50
|
+
console.log("Stringified: " + stringified);
|
|
51
|
+
console.log("Parsed: " + JSON.stringify(parsed));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.6",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"types": "assembly/index.ts",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
],
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"scripts": {
|
|
18
|
-
"test": "
|
|
18
|
+
"test": "npm run test:serialize && npm run test:deserialize",
|
|
19
|
+
"test:serialize": "wasmtime build/serialize.spec.wasm",
|
|
20
|
+
"test:deserialize": "wasmtime build/deserialize.spec.wasm",
|
|
19
21
|
"tests:build": "asc assembly/__tests__/serialize.spec.ts -o build/serialize.spec.wasm --transform ./transform --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --optimizeLevel 0 --shrinkLevel 0 --noAssert --uncheckedBehavior always & asc assembly/__tests__/deserialize.spec.ts -o build/deserialize.spec.wasm --transform ./transform --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --optimizeLevel 0 --shrinkLevel 0 --noAssert --uncheckedBehavior always",
|
|
20
22
|
"build:test": "JSON_DEBUG=true asc assembly/test.ts -o build/test.wasm --transform ./transform --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --optimizeLevel 0 --shrinkLevel 0 --noAssert --uncheckedBehavior always",
|
|
21
23
|
"build:bench": "asc bench/benchmark.ts -o bench/benchmark.wasm --transform ./transform --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub",
|
package/transform/lib/index.js
CHANGED
|
@@ -85,48 +85,67 @@ class JSONTransform extends BaseVisitor {
|
|
|
85
85
|
mem.value = value;
|
|
86
86
|
mem.node = member;
|
|
87
87
|
if (member.decorators) {
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
let decorator = null;
|
|
89
|
+
if (decorator = member.decorators.find(v => v.name.text == "alias")) {
|
|
90
90
|
if (decorator.name.text == "alias") {
|
|
91
91
|
if (!decorator.args?.length)
|
|
92
92
|
throw new Error("Expected 1 argument but got zero at @alias in " + node.range.source.normalizedPath);
|
|
93
|
-
mem.
|
|
93
|
+
mem.flags.push(PropertyFlags.Alias);
|
|
94
94
|
mem.alias = decorator.args[0].value;
|
|
95
95
|
}
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
}
|
|
97
|
+
for (let i = 0; i < (member.decorators).length; i++) {
|
|
98
|
+
const decorator = member.decorators[i];
|
|
99
|
+
if (decorator.name.text == "omitnull") {
|
|
100
|
+
mem.flags.push(PropertyFlags.OmitNull);
|
|
98
101
|
}
|
|
99
102
|
else if (decorator.name.text == "omitif") {
|
|
100
103
|
if (!decorator.args?.length)
|
|
101
104
|
throw new Error("Expected 1 argument but got zero at @omitif in " + node.range.source.normalizedPath);
|
|
102
105
|
mem.args?.push(decorator.args[0].value);
|
|
103
|
-
mem.
|
|
106
|
+
mem.flags.push(PropertyFlags.OmitIf);
|
|
107
|
+
}
|
|
108
|
+
else if (decorator.name.text == "flatten") {
|
|
109
|
+
if (!decorator.args?.length)
|
|
110
|
+
throw new Error("Expected 1 argument but got zero at @flatten in " + node.range.source.normalizedPath);
|
|
111
|
+
mem.flags.push(PropertyFlags.Flatten);
|
|
112
|
+
mem.args = [decorator.args[0].value];
|
|
104
113
|
}
|
|
105
114
|
}
|
|
106
115
|
}
|
|
107
|
-
if (mem.
|
|
108
|
-
mem.
|
|
109
|
-
|
|
110
|
-
else if (mem.flag === PropertyFlags.None) {
|
|
111
|
-
mem.serialize = escapeString(JSON.stringify(mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
116
|
+
if (!mem.flags.length) {
|
|
117
|
+
mem.flags = [PropertyFlags.None];
|
|
118
|
+
mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
112
119
|
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
|
|
113
120
|
}
|
|
114
|
-
if (mem.
|
|
115
|
-
mem.serialize = "${changetype<usize>(this." + mem.name + ") == <usize>0" + " ? \"\" : '" + escapeString(JSON.stringify(mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
|
|
121
|
+
if (mem.flags.includes(PropertyFlags.OmitNull)) {
|
|
122
|
+
mem.serialize = "${changetype<usize>(this." + mem.name + ") == <usize>0" + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
|
|
116
123
|
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
|
|
117
124
|
}
|
|
118
|
-
else if (mem.
|
|
119
|
-
mem.serialize = "${" + mem.args[0] + " ? \"\" : '" + escapeString(JSON.stringify(mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
|
|
125
|
+
else if (mem.flags.includes(PropertyFlags.OmitIf)) {
|
|
126
|
+
mem.serialize = "${" + mem.args[0] + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
|
|
120
127
|
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
|
|
121
128
|
}
|
|
122
|
-
else if (mem.
|
|
123
|
-
mem.serialize = escapeString(JSON.stringify(mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
129
|
+
else if (mem.flags.includes(PropertyFlags.Alias)) {
|
|
130
|
+
mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
124
131
|
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));";
|
|
125
132
|
mem.name = name.text;
|
|
126
133
|
}
|
|
134
|
+
else if (mem.flags.includes(PropertyFlags.Flatten)) {
|
|
135
|
+
const nullable = mem.node.type.isNullable;
|
|
136
|
+
if (nullable) {
|
|
137
|
+
mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${this." + name.text + " ? __SERIALIZE(changetype<nonnull<" + type + ">>(this." + name.text + ")" + (mem.args?.length ? '.' + mem.args[0] : '') + ") : \"null\"}";
|
|
138
|
+
mem.deserialize = "if (value_end - value_start == 4 && load<u64>(changetype<usize>(data) + <usize>(value_start << 1)) == " + charCodeAt64("null", 0) + ") {\n this." + name.text + " = null;\n } else {\n this." + name.text + " = " + "__DESERIALIZE<" + type + ">('{\"" + mem.args[0] + "\":' + data.substring(value_start, value_end) + \"}\");\n }";
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${this." + name.text + " ? __SERIALIZE(this." + name.text + (mem.args?.length ? '.' + mem.args[0] : '') + ") : \"null\"}";
|
|
142
|
+
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">('{\"" + mem.args[0] + "\":' + data.substring(value_start, value_end) + \"}\");";
|
|
143
|
+
}
|
|
144
|
+
mem.name = name.text;
|
|
145
|
+
}
|
|
127
146
|
const t = mem.node.type.name.identifier.text;
|
|
128
147
|
if (this.schemasList.find(v => v.name == t)) {
|
|
129
|
-
mem.initialize = "this." + name.text + " = changetype<nonnull<" +
|
|
148
|
+
mem.initialize = "this." + name.text + " = changetype<nonnull<" + mem.type + ">>(__new(offsetof<nonnull<" + mem.type + ">>(), idof<nonnull<" + mem.type + ">>()));\n changetype<nonnull<" + mem.type + ">>(this." + name.text + ").__INITIALIZE()";
|
|
130
149
|
}
|
|
131
150
|
else if (mem.value) {
|
|
132
151
|
mem.initialize = "this." + name.text + " = " + mem.value;
|
|
@@ -141,8 +160,8 @@ class JSONTransform extends BaseVisitor {
|
|
|
141
160
|
if (!schema.members.length)
|
|
142
161
|
return;
|
|
143
162
|
found = false;
|
|
144
|
-
if (schema.members[0]?.
|
|
145
|
-
|| schema.members[0]?.
|
|
163
|
+
if (schema.members[0]?.flags.includes(PropertyFlags.OmitNull)
|
|
164
|
+
|| schema.members[0]?.flags.includes(PropertyFlags.OmitIf)) {
|
|
146
165
|
SERIALIZE_RAW += schema.members[0]?.serialize;
|
|
147
166
|
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
|
|
148
167
|
}
|
|
@@ -157,8 +176,8 @@ class JSONTransform extends BaseVisitor {
|
|
|
157
176
|
const member = schema.members[i];
|
|
158
177
|
if (member.initialize)
|
|
159
178
|
INITIALIZE += " " + member.initialize + ";\n";
|
|
160
|
-
if (member.
|
|
161
|
-
|| member.
|
|
179
|
+
if (member.flags.includes(PropertyFlags.OmitNull)
|
|
180
|
+
|| member.flags.includes(PropertyFlags.OmitIf)) {
|
|
162
181
|
SERIALIZE_RAW += member.serialize;
|
|
163
182
|
SERIALIZE_PRETTY += member.serialize;
|
|
164
183
|
}
|
|
@@ -348,6 +367,7 @@ var PropertyFlags;
|
|
|
348
367
|
PropertyFlags[PropertyFlags["OmitNull"] = 2] = "OmitNull";
|
|
349
368
|
PropertyFlags[PropertyFlags["OmitIf"] = 3] = "OmitIf";
|
|
350
369
|
PropertyFlags[PropertyFlags["Alias"] = 4] = "Alias";
|
|
370
|
+
PropertyFlags[PropertyFlags["Flatten"] = 5] = "Flatten";
|
|
351
371
|
})(PropertyFlags || (PropertyFlags = {}));
|
|
352
372
|
class Property {
|
|
353
373
|
constructor() {
|
|
@@ -355,7 +375,7 @@ class Property {
|
|
|
355
375
|
this.alias = null;
|
|
356
376
|
this.type = "";
|
|
357
377
|
this.value = null;
|
|
358
|
-
this.
|
|
378
|
+
this.flags = [];
|
|
359
379
|
this.args = [];
|
|
360
380
|
this.serialize = null;
|
|
361
381
|
this.deserialize = null;
|
package/transform/package.json
CHANGED
package/transform/src/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
|
12
12
|
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
13
13
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
14
14
|
import { CommonFlags } from "types:assemblyscript/src/common";
|
|
15
|
+
import { DecoratorNode } from "types:assemblyscript/src/ast";
|
|
15
16
|
|
|
16
17
|
class JSONTransform extends BaseVisitor {
|
|
17
18
|
public schemasList: SchemaData[] = [];
|
|
@@ -105,44 +106,62 @@ class JSONTransform extends BaseVisitor {
|
|
|
105
106
|
mem.node = member;
|
|
106
107
|
|
|
107
108
|
if (member.decorators) {
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
let decorator: DecoratorNode | null = null;
|
|
110
|
+
if (decorator = member.decorators.find(v => (<IdentifierExpression>v.name).text == "alias") as DecoratorNode | null) {
|
|
110
111
|
if ((<IdentifierExpression>decorator.name).text == "alias") {
|
|
111
112
|
if (!decorator.args?.length) throw new Error("Expected 1 argument but got zero at @alias in " + node.range.source.normalizedPath);
|
|
112
|
-
mem.
|
|
113
|
+
mem.flags.push(PropertyFlags.Alias);
|
|
113
114
|
mem.alias = (decorator.args[0] as StringLiteralExpression).value;
|
|
114
|
-
}
|
|
115
|
-
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
for (let i = 0; i < (member.decorators).length; i++) {
|
|
119
|
+
const decorator = member.decorators[i]!;
|
|
120
|
+
if ((<IdentifierExpression>decorator.name).text == "omitnull") {
|
|
121
|
+
mem.flags.push(PropertyFlags.OmitNull);
|
|
116
122
|
} else if ((<IdentifierExpression>decorator.name).text == "omitif") {
|
|
117
123
|
if (!decorator.args?.length) throw new Error("Expected 1 argument but got zero at @omitif in " + node.range.source.normalizedPath);
|
|
118
124
|
mem.args?.push((decorator.args[0] as StringLiteralExpression).value);
|
|
119
|
-
mem.
|
|
125
|
+
mem.flags.push(PropertyFlags.OmitIf);
|
|
126
|
+
} else if ((<IdentifierExpression>decorator.name).text == "flatten") {
|
|
127
|
+
if (!decorator.args?.length) throw new Error("Expected 1 argument but got zero at @flatten in " + node.range.source.normalizedPath);
|
|
128
|
+
mem.flags.push(PropertyFlags.Flatten);
|
|
129
|
+
mem.args = [(decorator.args[0] as StringLiteralExpression).value];
|
|
120
130
|
}
|
|
121
131
|
}
|
|
122
132
|
}
|
|
123
133
|
|
|
124
|
-
if (mem.
|
|
125
|
-
mem.
|
|
126
|
-
|
|
127
|
-
mem.serialize = escapeString(JSON.stringify(mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
134
|
+
if (!mem.flags.length) {
|
|
135
|
+
mem.flags = [PropertyFlags.None];
|
|
136
|
+
mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
128
137
|
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));"
|
|
129
138
|
}
|
|
130
139
|
|
|
131
|
-
if (mem.
|
|
132
|
-
mem.serialize = "${changetype<usize>(this." + mem.name + ") == <usize>0" + " ? \"\" : '" + escapeString(JSON.stringify(mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
|
|
140
|
+
if (mem.flags.includes(PropertyFlags.OmitNull)) {
|
|
141
|
+
mem.serialize = "${changetype<usize>(this." + mem.name + ") == <usize>0" + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
|
|
133
142
|
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));"
|
|
134
|
-
} else if (mem.
|
|
135
|
-
mem.serialize = "${" + mem.args![0]! + " ? \"\" : '" + escapeString(JSON.stringify(mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
|
|
143
|
+
} else if (mem.flags.includes(PropertyFlags.OmitIf)) {
|
|
144
|
+
mem.serialize = "${" + mem.args![0]! + " ? \"\" : '" + escapeString(JSON.stringify(mem.alias || mem.name)) + ":' + __SERIALIZE<" + type + ">(this." + name.text + ") + \",\"}";
|
|
136
145
|
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));"
|
|
137
|
-
} else if (mem.
|
|
138
|
-
mem.serialize = escapeString(JSON.stringify(mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
146
|
+
} else if (mem.flags.includes(PropertyFlags.Alias)) {
|
|
147
|
+
mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${__SERIALIZE<" + type + ">(this." + name.text + ")}";
|
|
139
148
|
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end));"
|
|
140
149
|
mem.name = name.text;
|
|
150
|
+
} else if (mem.flags.includes(PropertyFlags.Flatten)) {
|
|
151
|
+
const nullable = (mem.node.type as NamedTypeNode).isNullable;
|
|
152
|
+
if (nullable) {
|
|
153
|
+
mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${this." + name.text + " ? __SERIALIZE(changetype<nonnull<" + type + ">>(this." + name.text + ")" + (mem.args?.length ? '.' + mem.args[0]! : '') + ") : \"null\"}";
|
|
154
|
+
mem.deserialize = "if (value_end - value_start == 4 && load<u64>(changetype<usize>(data) + <usize>(value_start << 1)) == " + charCodeAt64("null", 0) + ") {\n this." + name.text + " = null;\n } else {\n this." + name.text + " = " + "__DESERIALIZE<" + type + ">('{\"" + mem.args![0]! + "\":' + data.substring(value_start, value_end) + \"}\");\n }";
|
|
155
|
+
} else {
|
|
156
|
+
mem.serialize = escapeString(JSON.stringify(mem.alias || mem.name)) + ":${this." + name.text + " ? __SERIALIZE(this." + name.text + (mem.args?.length ? '.' + mem.args[0]! : '') + ") : \"null\"}";
|
|
157
|
+
mem.deserialize = "this." + name.text + " = " + "__DESERIALIZE<" + type + ">('{\"" + mem.args![0]! + "\":' + data.substring(value_start, value_end) + \"}\");";
|
|
158
|
+
}
|
|
159
|
+
mem.name = name.text;
|
|
141
160
|
}
|
|
142
161
|
|
|
143
162
|
const t = (mem.node.type as NamedTypeNode).name.identifier.text;
|
|
144
163
|
if (this.schemasList.find(v => v.name == t)) {
|
|
145
|
-
mem.initialize = "this." + name.text + " = changetype<nonnull<" +
|
|
164
|
+
mem.initialize = "this." + name.text + " = changetype<nonnull<" + mem.type + ">>(__new(offsetof<nonnull<" + mem.type + ">>(), idof<nonnull<" + mem.type + ">>()));\n changetype<nonnull<" + mem.type + ">>(this." + name.text + ").__INITIALIZE()";
|
|
146
165
|
} else if (mem.value) {
|
|
147
166
|
mem.initialize = "this." + name.text + " = " + mem.value;
|
|
148
167
|
}
|
|
@@ -163,8 +182,8 @@ class JSONTransform extends BaseVisitor {
|
|
|
163
182
|
found = false;
|
|
164
183
|
|
|
165
184
|
if (
|
|
166
|
-
schema.members[0]?.
|
|
167
|
-
|| schema.members[0]?.
|
|
185
|
+
schema.members[0]?.flags.includes(PropertyFlags.OmitNull)
|
|
186
|
+
|| schema.members[0]?.flags.includes(PropertyFlags.OmitIf)
|
|
168
187
|
) {
|
|
169
188
|
SERIALIZE_RAW += schema.members[0]?.serialize;
|
|
170
189
|
SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
|
|
@@ -180,8 +199,8 @@ class JSONTransform extends BaseVisitor {
|
|
|
180
199
|
const member = schema.members[i]!;
|
|
181
200
|
if (member.initialize) INITIALIZE += " " + member.initialize + ";\n";
|
|
182
201
|
if (
|
|
183
|
-
member.
|
|
184
|
-
|| member.
|
|
202
|
+
member.flags.includes(PropertyFlags.OmitNull)
|
|
203
|
+
|| member.flags.includes(PropertyFlags.OmitIf)
|
|
185
204
|
) {
|
|
186
205
|
SERIALIZE_RAW += member.serialize;
|
|
187
206
|
SERIALIZE_PRETTY += member.serialize;
|
|
@@ -362,7 +381,8 @@ enum PropertyFlags {
|
|
|
362
381
|
Omit,
|
|
363
382
|
OmitNull,
|
|
364
383
|
OmitIf,
|
|
365
|
-
Alias
|
|
384
|
+
Alias,
|
|
385
|
+
Flatten
|
|
366
386
|
}
|
|
367
387
|
|
|
368
388
|
class Property {
|
|
@@ -370,7 +390,7 @@ class Property {
|
|
|
370
390
|
public alias: string | null = null;
|
|
371
391
|
public type: string = "";
|
|
372
392
|
public value: string | null = null;
|
|
373
|
-
public
|
|
393
|
+
public flags: PropertyFlags[] = [];
|
|
374
394
|
public args: string[] | null = [];
|
|
375
395
|
|
|
376
396
|
public serialize: string | null = null;
|