@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.
- package/README.md +31 -0
- package/build/codegen/api.d.ts +2 -0
- package/build/codegen/cli.cjs +934 -177
- package/build/codegen/cli.cjs.map +1 -1
- package/build/codegen/languages/c.d.ts +11 -0
- package/build/codegen/languages/cpp.d.ts +8 -0
- package/build/codegen/languages/csharp.d.ts +8 -0
- package/build/codegen/languages/gdscript.d.ts +14 -0
- package/build/codegen/languages/haxe.d.ts +8 -0
- package/build/codegen/languages/java.d.ts +11 -1
- package/build/codegen/languages/js.d.ts +8 -0
- package/build/codegen/languages/lua.d.ts +8 -0
- package/build/codegen/languages/ts.d.ts +8 -0
- package/build/codegen/types.d.ts +14 -0
- package/package.json +1 -1
- package/src/codegen/api.ts +26 -15
- package/src/codegen/cli.ts +9 -15
- package/src/codegen/languages/c.ts +282 -0
- package/src/codegen/languages/cpp.ts +74 -22
- package/src/codegen/languages/csharp.ts +87 -19
- package/src/codegen/languages/gdscript.ts +219 -0
- package/src/codegen/languages/haxe.ts +41 -5
- package/src/codegen/languages/java.ts +45 -4
- package/src/codegen/languages/js.ts +62 -20
- package/src/codegen/languages/lua.ts +60 -18
- package/src/codegen/languages/ts.ts +65 -14
- package/src/codegen/types.ts +15 -0
|
@@ -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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
55
|
-
${
|
|
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
|
-
|
|
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
|
-
|
|
50
|
-
${
|
|
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
|
-
|
|
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
|
-
|
|
127
|
-
${structure.properties.map(prop => ` ${prop.name}: ${prop.type};`).join("\n")}
|
|
128
|
-
}
|
|
179
|
+
${generateInterfaceBody(structure)}
|
|
129
180
|
`;
|
|
130
181
|
}
|
package/src/codegen/types.ts
CHANGED
|
@@ -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[] = [];
|