@colyseus/schema 4.0.13 → 4.0.14

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,6 +1,8 @@
1
1
  import { Class, Property, File, getCommentHeader, getInheritanceTree, Context } from "../types.js";
2
2
  import { GenerateOptions } from "../api.js";
3
3
 
4
+ export const name = "LUA";
5
+
4
6
  /**
5
7
  TODO:
6
8
  - Support inheritance
@@ -23,9 +25,14 @@ const typeMaps: { [key: string]: string } = {
23
25
  "float64": "number",
24
26
  }
25
27
 
28
+ const COMMON_IMPORTS = `local schema = require 'colyseus.serializer.schema.schema'`;
29
+
26
30
  const distinct = (value: string, index: number, self: string[]) =>
27
31
  self.indexOf(value) === index;
28
32
 
33
+ /**
34
+ * Generate individual files for each class
35
+ */
29
36
  export function generate (context: Context, options: GenerateOptions): File[] {
30
37
  return context.classes.map(klass => ({
31
38
  name: klass.name + ".lua",
@@ -33,6 +40,49 @@ export function generate (context: Context, options: GenerateOptions): File[] {
33
40
  }));
34
41
  }
35
42
 
43
+ /**
44
+ * Generate a single bundled file containing all classes
45
+ */
46
+ export function renderBundle(context: Context, options: GenerateOptions): File {
47
+ const fileName = options.namespace ? `${options.namespace}.lua` : "schema.lua";
48
+
49
+ const classBodies = context.classes.map(klass => generateClassBody(klass));
50
+ const classNames = context.classes.map(klass => ` ${klass.name} = ${klass.name},`).join("\n");
51
+
52
+ const content = `${getCommentHeader().replace(/\/\//mg, "--")}
53
+
54
+ ${COMMON_IMPORTS}
55
+
56
+ ${classBodies.join("\n\n")}
57
+
58
+ return {
59
+ ${classNames}
60
+ }
61
+ `;
62
+
63
+ return { name: fileName, content };
64
+ }
65
+
66
+ /**
67
+ * Generate just the class body (without requires) for bundling
68
+ */
69
+ function generateClassBody(klass: Class): string {
70
+ // Inheritance support
71
+ const inherits = (klass.extends !== "Schema")
72
+ ? `, ${klass.extends}`
73
+ : "";
74
+
75
+ return `---@class ${klass.name}: ${klass.extends}
76
+ ${klass.properties.map(prop => `---@field ${prop.name} ${getLUATypeAnnotation(prop)}`).join("\n")}
77
+ local ${klass.name} = schema.define({
78
+ ${klass.properties.map(prop => generatePropertyDeclaration(prop)).join(",\n")},
79
+ ["_fields_by_index"] = { ${klass.properties.map(prop => `"${prop.name}"`).join(", ")} },
80
+ }${inherits})`;
81
+ }
82
+
83
+ /**
84
+ * Generate a complete class file with requires (for individual file mode)
85
+ */
36
86
  function generateClass(klass: Class, namespace: string, allClasses: Class[]) {
37
87
  const allRefs: Property[] = [];
38
88
  klass.properties.forEach(property => {
@@ -44,28 +94,20 @@ function generateClass(klass: Class, namespace: string, allClasses: Class[]) {
44
94
  }
45
95
  });
46
96
 
47
- // Inheritance support
48
- const inherits = (klass.extends !== "Schema")
49
- ? `, ${klass.extends}`
50
- : "";
97
+ const localRequires = allRefs.
98
+ filter(ref => ref.childType && typeMaps[ref.childType] === undefined).
99
+ map(ref => ref.childType).
100
+ concat(getInheritanceTree(klass, allClasses, false).map(klass => klass.name)).
101
+ filter(distinct).
102
+ map(childType => `local ${childType} = require '${(namespace ? `${namespace}.` : '')}${childType}'`).
103
+ join("\n");
51
104
 
52
105
  return `${getCommentHeader().replace(/\/\//mg, "--")}
53
106
 
54
- local schema = require 'colyseus.serializer.schema.schema'
55
- ${allRefs.
56
- filter(ref => ref.childType && typeMaps[ref.childType] === undefined).
57
- map(ref => ref.childType).
58
- concat(getInheritanceTree(klass, allClasses, false).map(klass => klass.name)).
59
- filter(distinct).
60
- map(childType => `local ${childType} = require '${(namespace ? `${namespace}.` : '')}${childType}'`).
61
- join("\n")}
107
+ ${COMMON_IMPORTS}
108
+ ${localRequires}
62
109
 
63
- ---@class ${klass.name}: ${klass.extends}
64
- ${klass.properties.map(prop => `---@field ${prop.name} ${getLUATypeAnnotation(prop)}`).join("\n")}
65
- local ${klass.name} = schema.define({
66
- ${klass.properties.map(prop => generatePropertyDeclaration(prop)).join(",\n")},
67
- ["_fields_by_index"] = { ${klass.properties.map(prop => `"${prop.name}"`).join(", ")} },
68
- }${inherits})
110
+ ${generateClassBody(klass)}
69
111
 
70
112
  return ${klass.name}
71
113
  `;
@@ -1,6 +1,8 @@
1
1
  import { Class, Property, File, getCommentHeader, getInheritanceTree, Context, Interface } from "../types.js";
2
2
  import { GenerateOptions } from "../api.js";
3
3
 
4
+ export const name = "TypeScript";
5
+
4
6
  const typeMaps: { [key: string]: string } = {
5
7
  "string": "string",
6
8
  "number": "number",
@@ -17,9 +19,14 @@ const typeMaps: { [key: string]: string } = {
17
19
  "float64": "number",
18
20
  }
19
21
 
22
+ const COMMON_IMPORTS = `import { Schema, type, ArraySchema, MapSchema, SetSchema, DataChange } from '@colyseus/schema';`;
23
+
20
24
  const distinct = (value: string, index: number, self: string[]) =>
21
25
  self.indexOf(value) === index;
22
26
 
27
+ /**
28
+ * Generate individual files for each class/interface
29
+ */
23
30
  export function generate (context: Context, options: GenerateOptions): File[] {
24
31
  return [
25
32
  ...context.classes.map(structure => ({
@@ -33,6 +40,49 @@ export function generate (context: Context, options: GenerateOptions): File[] {
33
40
  ];
34
41
  }
35
42
 
43
+ /**
44
+ * Generate a single bundled file containing all classes and interfaces
45
+ */
46
+ export function renderBundle(context: Context, options: GenerateOptions): File {
47
+ const fileName = options.namespace ? `${options.namespace}.ts` : "schema.ts";
48
+
49
+ // Collect all class bodies
50
+ const classBodies = context.classes.map(klass => generateClassBody(klass));
51
+
52
+ // Collect all interface bodies
53
+ const interfaceBodies = context.interfaces.map(iface => generateInterfaceBody(iface));
54
+
55
+ const content = `${getCommentHeader()}
56
+
57
+ ${COMMON_IMPORTS}
58
+
59
+ ${classBodies.join("\n\n")}
60
+ ${interfaceBodies.length > 0 ? "\n" + interfaceBodies.join("\n\n") : ""}`;
61
+
62
+ return { name: fileName, content };
63
+ }
64
+
65
+ /**
66
+ * Generate just the class body (without imports) for bundling
67
+ */
68
+ function generateClassBody(klass: Class): string {
69
+ return `export class ${klass.name} extends ${klass.extends} {
70
+ ${klass.properties.map(prop => ` ${generateProperty(prop)}`).join("\n")}
71
+ }`;
72
+ }
73
+
74
+ /**
75
+ * Generate just the interface body (without imports) for bundling
76
+ */
77
+ function generateInterfaceBody(iface: Interface): string {
78
+ return `export interface ${iface.name} {
79
+ ${iface.properties.map(prop => ` ${prop.name}: ${prop.type};`).join("\n")}
80
+ }`;
81
+ }
82
+
83
+ /**
84
+ * Generate a complete class file with imports (for individual file mode)
85
+ */
36
86
  function generateClass(klass: Class, namespace: string, allClasses: Class[]) {
37
87
  const allRefs: Property[] = [];
38
88
  klass.properties.forEach(property => {
@@ -44,20 +94,20 @@ function generateClass(klass: Class, namespace: string, allClasses: Class[]) {
44
94
  }
45
95
  });
46
96
 
97
+ const localImports = allRefs.
98
+ filter(ref => ref.childType && typeMaps[ref.childType] === undefined).
99
+ map(ref => ref.childType).
100
+ concat(getInheritanceTree(klass, allClasses, false).map(klass => klass.name)).
101
+ filter(distinct).
102
+ map(childType => `import { ${childType} } from './${childType}'`).
103
+ join("\n");
104
+
47
105
  return `${getCommentHeader()}
48
106
 
49
- import { Schema, type, ArraySchema, MapSchema, SetSchema, DataChange } from '@colyseus/schema';
50
- ${allRefs.
51
- filter(ref => ref.childType && typeMaps[ref.childType] === undefined).
52
- map(ref => ref.childType).
53
- concat(getInheritanceTree(klass, allClasses, false).map(klass => klass.name)).
54
- filter(distinct).
55
- map(childType => `import { ${childType} } from './${childType}'`).
56
- join("\n")}
107
+ ${COMMON_IMPORTS}
108
+ ${localImports}
57
109
 
58
- export class ${klass.name} extends ${klass.extends} {
59
- ${klass.properties.map(prop => ` ${generateProperty(prop)}`).join("\n")}
60
- }
110
+ ${generateClassBody(klass)}
61
111
  `;
62
112
  }
63
113
 
@@ -120,11 +170,12 @@ function generateProperty(prop: Property) {
120
170
  }
121
171
 
122
172
 
173
+ /**
174
+ * Generate a complete interface file with header (for individual file mode)
175
+ */
123
176
  function generateInterface(structure: Interface, namespace: string, allClasses: Class[]) {
124
177
  return `${getCommentHeader()}
125
178
 
126
- export interface ${structure.name} {
127
- ${structure.properties.map(prop => ` ${prop.name}: ${prop.type};`).join("\n")}
128
- }
179
+ ${generateInterfaceBody(structure)}
129
180
  `;
130
181
  }
@@ -166,6 +166,21 @@ export interface File {
166
166
  content: string;
167
167
  }
168
168
 
169
+ /**
170
+ * Structured file representation for code generation.
171
+ * Separates imports, local references, and body content to enable
172
+ * clean bundling without string parsing.
173
+ */
174
+ export interface GeneratedFile {
175
+ name: string;
176
+ /** External imports (e.g., "@colyseus/schema", "Colyseus.Schema") */
177
+ imports: string[];
178
+ /** References to other generated classes (used for imports in non-bundle mode) */
179
+ localRefs: string[];
180
+ /** The class/interface/enum definition body (without imports or namespace wrapper) */
181
+ body: string;
182
+ }
183
+
169
184
  export function getInheritanceTree(klass: Class, allClasses: Class[], includeSelf: boolean = true) {
170
185
  let currentClass = klass;
171
186
  let inheritanceTree: Class[] = [];