json-as 0.9.21 → 0.9.22

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.
@@ -1,76 +1,76 @@
1
- import { FieldDeclaration, IdentifierExpression, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, } from "assemblyscript/dist/assemblyscript.js";
1
+ import { FieldDeclaration, IdentifierExpression, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, NamedTypeNode } from "assemblyscript/dist/assemblyscript.js";
2
2
  import { toString, isStdlib } from "visitor-as/dist/utils.js";
3
3
  import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
4
4
  import { Transform } from "assemblyscript/dist/transform.js";
5
+ import chalk from "chalk";
6
+ const json_types = ["Array", "string", "String", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean", "Map", "Date"];
5
7
  class JSONTransform extends BaseVisitor {
6
- constructor() {
7
- super(...arguments);
8
- this.schemasList = [];
9
- this.sources = new Set();
8
+ types = json_types;
9
+ schemasList = [];
10
+ currentClass;
11
+ sources = new Set();
12
+ appendParentFields(node, schema, members) {
13
+ if (node.extendsType) {
14
+ if (schema.parent?.members) {
15
+ for (let i = schema.parent.members.length - 1; i >= 0; i--) {
16
+ const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
17
+ if (!replace) {
18
+ members.unshift(schema.parent?.members[i].node);
19
+ }
20
+ }
21
+ this.appendParentFields(schema.parent.node, schema, members);
22
+ }
23
+ }
24
+ }
25
+ handleEmptyClass(node, schema, members) {
26
+ let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}';
27
+ let SERIALIZE_PRETTY_EMPTY = '__SERIALIZE_PRETTY(): string {\n return "{}";\n}';
28
+ let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
29
+ let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
30
+ if (process.env["JSON_DEBUG"]) {
31
+ console.log(SERIALIZE_RAW_EMPTY);
32
+ console.log(SERIALIZE_PRETTY_EMPTY);
33
+ console.log(INITIALIZE_EMPTY);
34
+ console.log(DESERIALIZE_EMPTY);
35
+ }
36
+ const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
37
+ const SERIALIZE_PRETTY_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_PRETTY_EMPTY, node);
38
+ const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
39
+ const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
40
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
41
+ node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
42
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE_PRETTY"))
43
+ node.members.push(SERIALIZE_PRETTY_METHOD_EMPTY);
44
+ if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
45
+ node.members.push(INITIALIZE_METHOD_EMPTY);
46
+ if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
47
+ node.members.push(DESERIALIZE_METHOD_EMPTY);
48
+ }
49
+ filterMembers(members) {
50
+ return members.filter((v) => v instanceof FieldDeclaration && !v.decorators?.find((v) => v.name.text == "omit"));
10
51
  }
11
- visitMethodDeclaration() { }
12
52
  visitClassDeclaration(node) {
13
53
  if (!node.decorators?.length)
14
54
  return;
15
- let found = false;
16
- for (const decorator of node.decorators) {
17
- const name = decorator.name.text;
18
- if (name === "json" || name === "serializable") {
19
- found = true;
20
- break;
21
- }
22
- }
23
- if (!found)
55
+ if (!node.decorators.find((v) => v.name.text == "json" || v.name.text == "serializable"))
24
56
  return;
57
+ this.types = json_types;
25
58
  const schema = new SchemaData();
26
59
  schema.node = node;
27
60
  schema.name = node.name.text;
28
- const members = [
29
- ...node.members.filter((v) => v.kind === 54 /* NodeKind.FieldDeclaration */),
30
- ];
31
61
  if (node.extendsType) {
32
62
  schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text);
33
- if (schema.parent?.members) {
34
- for (let i = schema.parent.members.length - 1; i >= 0; i--) {
35
- const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name);
36
- if (!replace) {
37
- members.unshift(schema.parent?.members[i].node);
38
- }
39
- }
40
- }
41
63
  }
64
+ const _members = [...node.members];
65
+ this.appendParentFields(node, schema, _members);
66
+ const members = this.filterMembers(_members);
42
67
  if (!members.length) {
43
- let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}';
44
- //let SERIALIZE_PRETTY_EMPTY = "__SERIALIZE_PRETTY(): string {\n return \"{}\";\n}";
45
- let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
46
- let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}";
47
- if (process.env["JSON_DEBUG"]) {
48
- console.log(SERIALIZE_RAW_EMPTY);
49
- //console.log(SERIALIZE_PRETTY_EMPTY);
50
- console.log(INITIALIZE_EMPTY);
51
- console.log(DESERIALIZE_EMPTY);
52
- }
53
- const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
54
- //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
55
- const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
56
- const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
57
- if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
58
- node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
59
- if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
60
- node.members.push(INITIALIZE_METHOD_EMPTY);
61
- if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
62
- node.members.push(DESERIALIZE_METHOD_EMPTY);
63
- this.schemasList.push(schema);
68
+ this.handleEmptyClass(node, schema, members);
64
69
  }
65
70
  for (const member of members) {
66
71
  const name = member.name;
67
- if (!(member instanceof FieldDeclaration))
68
- continue;
69
72
  if (!member.type) {
70
- throw new Error("Fields must be strongly typed! Found " +
71
- toString(member) +
72
- " at " +
73
- node.range.source.normalizedPath);
73
+ throw new Error("Fields must be strongly typed! Found " + toString(member) + " at " + node.range.source.normalizedPath);
74
74
  }
75
75
  const type = toString(member.type);
76
76
  if (type.startsWith("(") && type.includes("=>"))
@@ -100,8 +100,7 @@ class JSONTransform extends BaseVisitor {
100
100
  switch (decoratorName) {
101
101
  case "alias": {
102
102
  if (!args.length)
103
- throw new Error("Expected 1 argument but got zero at @alias in " +
104
- node.range.source.normalizedPath);
103
+ throw new Error("Expected 1 argument but got zero at @alias in " + node.range.source.normalizedPath);
105
104
  mem.alias = args[0];
106
105
  mem.flags.set(PropertyFlags.Alias, args);
107
106
  break;
@@ -112,8 +111,7 @@ class JSONTransform extends BaseVisitor {
112
111
  }
113
112
  case "omitif": {
114
113
  if (!decorator.args?.length)
115
- throw new Error("Expected 1 argument but got zero at @omitif in " +
116
- node.range.source.normalizedPath);
114
+ throw new Error("Expected 1 argument but got zero at @omitif in " + node.range.source.normalizedPath);
117
115
  mem.flags.set(PropertyFlags.OmitIf, args);
118
116
  break;
119
117
  }
@@ -124,22 +122,10 @@ class JSONTransform extends BaseVisitor {
124
122
  }
125
123
  }
126
124
  }
127
- mem.generate();
125
+ if (!mem.flags.get(PropertyFlags.Omit))
126
+ mem.generate();
128
127
  if (this.schemasList.find((v) => v.name == type)) {
129
- mem.initialize =
130
- "this." +
131
- name.text +
132
- " = changetype<nonnull<" +
133
- mem.type +
134
- ">>(__new(offsetof<nonnull<" +
135
- mem.type +
136
- ">>(), idof<nonnull<" +
137
- mem.type +
138
- ">>()));\n changetype<nonnull<" +
139
- mem.type +
140
- ">>(this." +
141
- name.text +
142
- ").__INITIALIZE()";
128
+ 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()";
143
129
  }
144
130
  else if (mem.value) {
145
131
  mem.initialize = "this." + name.text + " = " + mem.value;
@@ -151,8 +137,7 @@ class JSONTransform extends BaseVisitor {
151
137
  mem.initialize = "this." + name.text + ' = ""';
152
138
  }
153
139
  else if (type === "Array") {
154
- mem.initialize =
155
- "this." + name.text + " = instantiate<" + mem.type + ">()";
140
+ mem.initialize = "this." + name.text + " = instantiate<" + mem.type + ">()";
156
141
  }
157
142
  else if (type === "bool" || type === "boolean") {
158
143
  mem.initialize = "this." + name.text + " = false";
@@ -160,14 +145,7 @@ class JSONTransform extends BaseVisitor {
160
145
  else if (type === "JSON.Raw") {
161
146
  mem.initialize = "this." + name.text + ' = ""';
162
147
  }
163
- else if (type === "u8" ||
164
- type === "u16" ||
165
- type === "u32" ||
166
- type === "u64" ||
167
- type === "i8" ||
168
- type === "i16" ||
169
- type === "i32" ||
170
- type === "i64") {
148
+ else if (type === "u8" || type === "u16" || type === "u32" || type === "u64" || type === "i8" || type === "i16" || type === "i32" || type === "i64") {
171
149
  mem.initialize = "this." + name.text + " = 0";
172
150
  }
173
151
  else if (type === "f32" || type === "f64") {
@@ -182,15 +160,14 @@ class JSONTransform extends BaseVisitor {
182
160
  let indent = " ";
183
161
  if (!schema.members.length)
184
162
  return;
185
- found = false;
186
- if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) ||
187
- schema.members[0]?.flags.has(PropertyFlags.OmitIf)) {
163
+ let found = false;
164
+ if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) || schema.members[0]?.flags.has(PropertyFlags.OmitIf)) {
188
165
  SERIALIZE_RAW += schema.members[0]?.serialize;
189
- SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize;
166
+ SERIALIZE_PRETTY += "\\n" + indent + schema.members[0]?.serialize_pretty;
190
167
  }
191
168
  else {
192
169
  SERIALIZE_RAW += schema.members[0]?.serialize + ",";
193
- SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n";
170
+ SERIALIZE_PRETTY += "\\n" + indent + schema.members[0]?.serialize_pretty + ",\\n";
194
171
  found = true;
195
172
  }
196
173
  if (schema.members[0]?.initialize)
@@ -199,22 +176,21 @@ class JSONTransform extends BaseVisitor {
199
176
  const member = schema.members[i];
200
177
  if (member.initialize)
201
178
  INITIALIZE += " " + member.initialize + ";\n";
202
- if (member.flags.has(PropertyFlags.OmitNull) ||
203
- member.flags.has(PropertyFlags.OmitIf)) {
179
+ if (member.flags.has(PropertyFlags.Omit))
180
+ continue;
181
+ if (member.flags.has(PropertyFlags.OmitNull) || member.flags.has(PropertyFlags.OmitIf)) {
204
182
  SERIALIZE_RAW += member.serialize;
205
- SERIALIZE_PRETTY += member.serialize;
183
+ SERIALIZE_PRETTY += member.serialize_pretty;
206
184
  }
207
185
  else {
208
186
  SERIALIZE_RAW += member.serialize + ",";
209
- SERIALIZE_PRETTY += indent + member.serialize + ",\\n";
187
+ SERIALIZE_PRETTY += indent + member.serialize_pretty + ",\\n";
210
188
  found = true;
211
189
  }
212
190
  }
213
191
  if (found) {
214
- SERIALIZE_RAW +=
215
- "`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
216
- SERIALIZE_PRETTY +=
217
- "`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
192
+ SERIALIZE_RAW += "`;\n store<u16>(changetype<usize>(out) + ((out.length - 1) << 1), 125);\n return out;\n}";
193
+ SERIALIZE_PRETTY += "`;\n store<u32>(changetype<usize>(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}";
218
194
  }
219
195
  else {
220
196
  SERIALIZE_RAW += "}`;\n return out;\n}";
@@ -243,35 +219,29 @@ class JSONTransform extends BaseVisitor {
243
219
  const _name = encodeKey(firstMember.alias || firstMember.name);
244
220
  if (_name.length === 1) {
245
221
  if (first) {
246
- DESERIALIZE +=
247
- " if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
222
+ DESERIALIZE += " if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
248
223
  first = false;
249
224
  }
250
225
  else {
251
- DESERIALIZE +=
252
- "else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
226
+ DESERIALIZE += "else if (1 === len) {\n switch (load<u16>(changetype<usize>(data) + (key_start << 1))) {\n";
253
227
  }
254
228
  }
255
229
  else if (_name.length === 2) {
256
230
  if (first) {
257
- DESERIALIZE +=
258
- " if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
231
+ DESERIALIZE += " if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
259
232
  first = false;
260
233
  }
261
234
  else {
262
- DESERIALIZE +=
263
- "else if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
235
+ DESERIALIZE += "else if (2 === len) {\n switch (load<u32>(changetype<usize>(data) + (key_start << 1))) {\n";
264
236
  }
265
237
  }
266
238
  else if (_name.length === 4) {
267
239
  if (first) {
268
- DESERIALIZE +=
269
- " if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
240
+ DESERIALIZE += " if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
270
241
  first = false;
271
242
  }
272
243
  else {
273
- DESERIALIZE +=
274
- "else if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
244
+ DESERIALIZE += "else if (4 === len) {\n const code = load<u64>(changetype<usize>(data) + (key_start << 1));\n";
275
245
  }
276
246
  }
277
247
  else {
@@ -301,9 +271,7 @@ class JSONTransform extends BaseVisitor {
301
271
  DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
302
272
  }
303
273
  else {
304
- DESERIALIZE =
305
- DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
306
- `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
274
+ DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`;
307
275
  }
308
276
  }
309
277
  else {
@@ -312,9 +280,7 @@ class JSONTransform extends BaseVisitor {
312
280
  DESERIALIZE += ` if (0 === memory.compare(changetype<usize>("${escapeQuote(escapeSlash(_name))}"), changetype<usize>(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
313
281
  }
314
282
  else {
315
- DESERIALIZE =
316
- DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
317
- ` else if (0 === memory.compare(changetype<usize>("${escapeQuote(escapeSlash(_name))}"), changetype<usize>(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
283
+ DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else if (0 === memory.compare(changetype<usize>("${escapeQuote(escapeSlash(_name))}"), changetype<usize>(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`;
318
284
  }
319
285
  }
320
286
  }
@@ -322,14 +288,10 @@ class JSONTransform extends BaseVisitor {
322
288
  DESERIALIZE += ` default: {\n return false;\n }\n }\n`;
323
289
  }
324
290
  else if (_name.length == 4) {
325
- DESERIALIZE =
326
- DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
327
- ` else {\n return false;\n }\n`;
291
+ DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
328
292
  }
329
293
  else {
330
- DESERIALIZE =
331
- DESERIALIZE.slice(0, DESERIALIZE.length - 1) +
332
- ` else {\n return false;\n }\n`;
294
+ DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`;
333
295
  }
334
296
  DESERIALIZE += " } ";
335
297
  }
@@ -337,16 +299,18 @@ class JSONTransform extends BaseVisitor {
337
299
  //console.log(sortedMembers);
338
300
  if (process.env["JSON_DEBUG"]) {
339
301
  console.log(SERIALIZE_RAW);
340
- //console.log(SERIALIZE_PRETTY);
302
+ console.log(SERIALIZE_PRETTY);
341
303
  console.log(INITIALIZE);
342
304
  console.log(DESERIALIZE);
343
305
  }
344
306
  const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node);
345
- //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
307
+ const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node);
346
308
  const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
347
309
  const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
348
310
  if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
349
311
  node.members.push(SERIALIZE_RAW_METHOD);
312
+ if (!node.members.find((v) => v.name.text == "__SERIALIZE_PRETTY"))
313
+ node.members.push(SERIALIZE_PRETTY_METHOD);
350
314
  if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
351
315
  node.members.push(INITIALIZE_METHOD);
352
316
  if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
@@ -372,15 +336,13 @@ export default class Transformer extends Transform {
372
336
  .sort((_a, _b) => {
373
337
  const a = _a.internalPath;
374
338
  const b = _b.internalPath;
375
- if (a[0] === "~" && b[0] !== "~") {
376
- return -1;
377
- }
378
- else if (a[0] !== "~" && b[0] === "~") {
339
+ if (a[0] !== "~" && b[0] === "~") {
379
340
  return 1;
380
341
  }
381
- else {
382
- return 0;
342
+ if (a[0] === "~" && b[0] !== "~") {
343
+ return -1;
383
344
  }
345
+ return 0;
384
346
  });
385
347
  // Loop over every source
386
348
  for (const source of sources) {
@@ -392,14 +354,70 @@ export default class Transformer extends Transform {
392
354
  // Check that every parent and child class is hooked up correctly
393
355
  const schemas = transformer.schemasList;
394
356
  for (const schema of schemas) {
395
- if (schema.parent) {
396
- const parent = schemas.find((v) => v.name === schema.parent?.name);
397
- if (!parent)
398
- throw new Error(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator! Add the decorator and rebuild.`);
357
+ checkInheritance(schema, schemas);
358
+ const invalidType = checkTypeCorrectness(schema, schemas);
359
+ if (invalidType) {
360
+ logError(`Type ${invalidType.type} implemented in property ${invalidType.path} is not a JSON-compatible type!\nEither decorate it with @omit or fix it!`);
399
361
  }
400
362
  }
401
363
  }
402
364
  }
365
+ function checkInheritance(schema, schemas) {
366
+ if (!schema.parent && schema.node.extendsType) {
367
+ if (schemas.find(v => v.node.name.text === schema.node.extendsType?.name.identifier.text))
368
+ return;
369
+ const extending = toString(schema.node.extendsType);
370
+ logError(`Schema ${schema.name} extends ${extending}, but ${extending} does not include the @json decorator!`);
371
+ }
372
+ }
373
+ function checkTypeCorrectness(schema, schemas) {
374
+ const parent = schemas.find((v) => v.name === schema.parent?.name);
375
+ const generic_types = [...(schema?.node.typeParameters?.map((v) => v.name.text) || []), ...(parent?.node.typeParameters?.map((v) => v.name.text) || [])];
376
+ const member_types = [...(schema.members.map((v) => v.node.type.name.identifier.text) || [])];
377
+ const scopeTypes = new Set([...json_types, ...generic_types, ...member_types]);
378
+ for (const typ of member_types) {
379
+ if (typ === "JSON")
380
+ continue; // JSON.Raw, JSON.Box, JSON.Any, ect...
381
+ if (json_types.includes(typ))
382
+ continue;
383
+ if (generic_types.includes(typ))
384
+ continue;
385
+ const check = schemas.find((v) => v.name == typ);
386
+ if (!check)
387
+ logError(`Type ${typ} is not a JSON compatible type or does not include the @json flag!`);
388
+ }
389
+ for (const member of schema.members) {
390
+ const invalidType = checkType(schema, schemas, member.node.type, member, scopeTypes, schema.name);
391
+ if (invalidType)
392
+ logError(`Type ${invalidType.type} in ${invalidType.path} does not implement a JSON compatible type!\n${chalk.dim(` at ${member.node.range.source.normalizedPath.replace("~lib/", "./node_modules/")}`)}`);
393
+ }
394
+ return null;
395
+ }
396
+ function checkType(schema, schemas, typ, member, scopeTypes, path) {
397
+ path += "." + member.name;
398
+ if (schemas.find(v => v.node.name.text === typ.name.identifier.text))
399
+ scopeTypes.add(typ.name.identifier.text);
400
+ if (!scopeTypes.has(typ.name.identifier.text))
401
+ return { type: toString(typ), path };
402
+ if (typ.isNullable && isPrimitive(typ))
403
+ return { type: toString(typ), path };
404
+ if (typ.typeArguments?.length && typ.typeArguments?.length > 0) {
405
+ for (const ty of typ.typeArguments.filter((v) => v instanceof NamedTypeNode)) {
406
+ const check = checkType(schema, schemas, ty, member, scopeTypes, path);
407
+ if (check)
408
+ return { type: toString(typ), path };
409
+ }
410
+ }
411
+ else {
412
+ if (scopeTypes.has(typ.name.identifier.text))
413
+ return null;
414
+ }
415
+ return null;
416
+ }
417
+ function logError(message) {
418
+ console.log("\n" + chalk.bold.bgRed(" Error ") + chalk.dim(":") + " " + message + "\n");
419
+ process.exit(1);
420
+ }
403
421
  var PropertyFlags;
404
422
  (function (PropertyFlags) {
405
423
  PropertyFlags[PropertyFlags["Null"] = 0] = "Null";
@@ -410,18 +428,18 @@ var PropertyFlags;
410
428
  PropertyFlags[PropertyFlags["JSON_Raw"] = 5] = "JSON_Raw";
411
429
  })(PropertyFlags || (PropertyFlags = {}));
412
430
  class Property {
413
- constructor() {
414
- this.name = "";
415
- this.alias = null;
416
- this.type = "";
417
- this.value = null;
418
- this.flags = new Map();
419
- this.serialize = null;
420
- this.deserialize = null;
421
- this.initialize = null;
422
- this.right_s = "";
423
- this.right_d = "";
424
- }
431
+ name = "";
432
+ alias = null;
433
+ type = "";
434
+ value = null;
435
+ flags = new Map();
436
+ serialize = null;
437
+ serialize_pretty = null;
438
+ deserialize = null;
439
+ initialize = null;
440
+ node;
441
+ right_s = "";
442
+ right_d = "";
425
443
  generate() {
426
444
  const name = this.name;
427
445
  const escapedName = escapeString(JSON.stringify(this.alias || this.name));
@@ -430,7 +448,7 @@ class Property {
430
448
  return;
431
449
  if (this.flags.has(PropertyFlags.JSON_Raw)) {
432
450
  if (this.flags.has(PropertyFlags.Null)) {
433
- this.right_s = "(this." + name + " || \"null\")";
451
+ this.right_s = "(this." + name + ' || "null")';
434
452
  this.right_d = "value_start === value_end - 4 && 30399761348886638 === load<u64>(changetype<usize>(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)";
435
453
  }
436
454
  else {
@@ -440,47 +458,33 @@ class Property {
440
458
  }
441
459
  else {
442
460
  this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")";
443
- this.right_d =
444
- "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end))";
461
+ this.right_d = "__DESERIALIZE<" + type + ">(data.substring(value_start, value_end))";
445
462
  }
446
463
  if (this.flags.has(PropertyFlags.OmitIf)) {
447
464
  const condition = this.flags.get(PropertyFlags.OmitIf)[0];
448
465
  if (!condition)
449
466
  throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition");
450
- this.serialize =
451
- "${" +
452
- condition +
453
- ' ? "" : \'' +
454
- escapedName +
455
- ":' + " +
456
- this.right_s +
457
- ' + ","}';
467
+ this.serialize = "${" + condition + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}';
468
+ this.serialize_pretty = "${" + condition + ' ? "" : \'' + escapedName + ": ' + " + this.right_s + ' + ","}';
458
469
  this.deserialize = "this." + name + " = " + this.right_d + ";";
459
470
  }
460
471
  else if (this.flags.has(PropertyFlags.OmitNull)) {
461
- this.serialize =
462
- "${changetype<usize>(this." +
463
- name +
464
- ") == <usize>0" +
465
- ' ? "" : \'' +
466
- escapedName +
467
- ":' + " +
468
- this.right_s +
469
- ' + ","}';
472
+ this.serialize = "${changetype<usize>(this." + name + ") == <usize>0" + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}';
473
+ this.serialize_pretty = "${changetype<usize>(this." + name + ") == <usize>0" + ' ? "" : \'' + escapedName + ": ' + " + this.right_s + ' + ","}';
470
474
  this.deserialize = "this." + name + " = " + this.right_d + ";";
471
475
  }
472
476
  else {
473
477
  this.serialize = escapedName + ":${" + this.right_s + "}";
478
+ this.serialize_pretty = escapedName + ": ${" + this.right_s + "}";
474
479
  this.deserialize = "this." + name + " = " + this.right_d + ";";
475
480
  }
476
481
  }
477
482
  }
478
483
  class SchemaData {
479
- constructor() {
480
- this.name = "";
481
- this.members = [];
482
- this.parent = null;
483
- }
484
+ name = "";
485
+ members = [];
486
+ parent = null;
487
+ node;
484
488
  }
485
489
  function charCodeAt32(data, offset) {
486
490
  return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset);
@@ -493,10 +497,7 @@ function charCodeAt64(data, offset) {
493
497
  const secondCharCode = BigInt(data.charCodeAt(offset + 1));
494
498
  const thirdCharCode = BigInt(data.charCodeAt(offset + 2));
495
499
  const fourthCharCode = BigInt(data.charCodeAt(offset + 3));
496
- const u64Value = (fourthCharCode << 48n) |
497
- (thirdCharCode << 32n) |
498
- (secondCharCode << 16n) |
499
- firstCharCode;
500
+ const u64Value = (fourthCharCode << 48n) | (thirdCharCode << 32n) | (secondCharCode << 16n) | firstCharCode;
500
501
  return u64Value;
501
502
  }
502
503
  function encodeKey(key) {
@@ -541,3 +542,7 @@ function getArgs(args) {
541
542
  }
542
543
  return out;
543
544
  }
545
+ function isPrimitive(type) {
546
+ const primitives = new Set(["u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean"]);
547
+ return primitives.has(type.name.identifier.text);
548
+ }