@nanoforge-dev/schematics 1.2.2 → 2.1.0
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/dist/collection.json +10 -0
- package/dist/index.cjs +2 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -26
- package/dist/index.d.ts +1 -26
- package/dist/index.js +1 -30
- package/dist/index.js.map +1 -1
- package/dist/libs/application/application.factory.d.ts +5 -0
- package/dist/libs/application/application.factory.js +6 -2
- package/dist/libs/application/application.factory.js.map +1 -1
- package/dist/libs/application/files/js/package.json.template +2 -1
- package/dist/libs/application/files/ts/package.json.template +2 -1
- package/dist/libs/application/schema.json +6 -5
- package/dist/libs/component/component.factory.d.ts +27 -0
- package/dist/libs/component/component.factory.js +50 -0
- package/dist/libs/component/component.factory.js.map +1 -0
- package/dist/libs/component/files/js/__fileName__.component.js +78 -0
- package/dist/libs/component/files/ts/__fileName__.component.ts +61 -0
- package/dist/libs/component/schema.json +30 -0
- package/dist/libs/configuration/configuration.factory.d.ts +8 -3
- package/dist/libs/configuration/configuration.factory.js +32 -49
- package/dist/libs/configuration/configuration.factory.js.map +1 -1
- package/dist/libs/configuration/schema.json +9 -8
- package/dist/libs/docker/docker.factory.d.ts +2 -7
- package/dist/libs/docker/docker.factory.js +2 -24
- package/dist/libs/docker/docker.factory.js.map +1 -1
- package/dist/libs/docker/files/.dockerignore +1 -1
- package/dist/libs/docker/files/Dockerfile +10 -24
- package/dist/libs/docker/schema.json +4 -13
- package/dist/libs/part-base/files/js/__nanoforgeFolder__/client.save.json +1 -1
- package/dist/libs/part-base/files/js/__nanoforgeFolder__/server.save.json +1 -1
- package/dist/libs/part-base/files/js/__part__/components/example.component.js +29 -23
- package/dist/libs/part-base/files/js/__part__/systems/example.system.js +1 -1
- package/dist/libs/part-base/files/ts/__nanoforgeFolder__/client.save.json +1 -1
- package/dist/libs/part-base/files/ts/__nanoforgeFolder__/server.save.json +1 -1
- package/dist/libs/part-base/files/ts/__part__/components/example.component.ts +29 -23
- package/dist/libs/part-base/part-base.factory.d.ts +5 -10
- package/dist/libs/part-base/part-base.factory.js +6 -34
- package/dist/libs/part-base/part-base.factory.js.map +1 -1
- package/dist/libs/part-base/schema.json +4 -12
- package/dist/libs/part-main/part-main.factory.d.ts +14 -9
- package/dist/libs/part-main/part-main.factory.js +106 -63
- package/dist/libs/part-main/part-main.factory.js.map +1 -1
- package/dist/libs/part-main/schema.json +13 -12
- package/dist/libs/system/files/js/__fileName__.system.js +44 -0
- package/dist/libs/system/files/ts/__fileName__.system.ts +31 -0
- package/dist/libs/system/schema.json +30 -0
- package/dist/libs/system/system.factory.d.ts +27 -0
- package/dist/libs/system/system.factory.js +53 -0
- package/dist/libs/system/system.factory.js.map +1 -0
- package/package.json +1 -1
|
@@ -4,24 +4,16 @@
|
|
|
4
4
|
"title": "NanoForge Part Base Options Schema",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
|
-
"
|
|
7
|
+
"directory": {
|
|
8
8
|
"type": "string",
|
|
9
|
-
"description": "
|
|
10
|
-
"
|
|
11
|
-
"$source": "argv",
|
|
12
|
-
"index": 0
|
|
13
|
-
},
|
|
14
|
-
"x-prompt": "What name would you like to use for the new project ?"
|
|
9
|
+
"description": "NanoForge application destination directory",
|
|
10
|
+
"default": "."
|
|
15
11
|
},
|
|
16
12
|
"part": {
|
|
17
13
|
"type": "string",
|
|
18
14
|
"enum": ["client", "server"],
|
|
19
15
|
"description": "The part of the application to generate"
|
|
20
16
|
},
|
|
21
|
-
"directory": {
|
|
22
|
-
"type": "string",
|
|
23
|
-
"description": "NanoForge application destination directory"
|
|
24
|
-
},
|
|
25
17
|
"language": {
|
|
26
18
|
"type": "string",
|
|
27
19
|
"enum": ["ts", "js"],
|
|
@@ -39,5 +31,5 @@
|
|
|
39
31
|
"default": false
|
|
40
32
|
}
|
|
41
33
|
},
|
|
42
|
-
"required": ["
|
|
34
|
+
"required": ["part"]
|
|
43
35
|
}
|
|
@@ -2,34 +2,39 @@ import { Rule } from '@angular-devkit/schematics';
|
|
|
2
2
|
|
|
3
3
|
interface PartMainSchema {
|
|
4
4
|
/**
|
|
5
|
-
* NanoForge application
|
|
5
|
+
* NanoForge application destination directory
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
directory: string;
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* The part of the application to generate
|
|
11
11
|
*/
|
|
12
12
|
part: "client" | "server";
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* NanoForge application destination directory
|
|
16
|
-
*/
|
|
17
|
-
directory?: string;
|
|
18
|
-
|
|
19
14
|
/**
|
|
20
15
|
* NanoForge Application language
|
|
21
16
|
*/
|
|
22
|
-
language
|
|
17
|
+
language: "js" | "ts";
|
|
23
18
|
|
|
24
19
|
/**
|
|
25
20
|
* Add init functions to the application
|
|
26
21
|
*/
|
|
27
|
-
initFunctions
|
|
22
|
+
initFunctions: boolean;
|
|
28
23
|
|
|
29
24
|
/**
|
|
30
25
|
* Save file path with components and systems in JSON format
|
|
31
26
|
*/
|
|
32
27
|
saveFile?: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Path of the out file
|
|
31
|
+
*/
|
|
32
|
+
outFile?: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Build main editor
|
|
36
|
+
*/
|
|
37
|
+
editor: boolean;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
declare const main: (schema: PartMainSchema) => Rule;
|
|
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/libs/part-main/part-main.factory.ts
|
|
5
|
-
import { join, normalize, strings } from "@angular-devkit/core";
|
|
5
|
+
import { join as join3, normalize, strings } from "@angular-devkit/core";
|
|
6
6
|
import {
|
|
7
7
|
apply,
|
|
8
8
|
asSource,
|
|
@@ -12,10 +12,15 @@ import {
|
|
|
12
12
|
} from "@angular-devkit/schematics";
|
|
13
13
|
import * as fs from "fs";
|
|
14
14
|
|
|
15
|
-
// src/utils/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
// src/utils/main/main-functions.ts
|
|
16
|
+
import { join as join2 } from "path";
|
|
17
|
+
|
|
18
|
+
// src/utils/path.ts
|
|
19
|
+
import { join } from "path";
|
|
20
|
+
var joinRelative = /* @__PURE__ */ __name((...paths) => {
|
|
21
|
+
const path = join(...paths);
|
|
22
|
+
return path.startsWith("./") || path.startsWith("../") ? path : `./${path}`;
|
|
23
|
+
}, "joinRelative");
|
|
19
24
|
|
|
20
25
|
// src/utils/main/const.ts
|
|
21
26
|
var LIBS_FUNCTIONS_NAME = {
|
|
@@ -27,6 +32,15 @@ var LIBS_FUNCTIONS_NAME = {
|
|
|
27
32
|
["sound" /* SOUND */]: "useSound"
|
|
28
33
|
};
|
|
29
34
|
|
|
35
|
+
// src/utils/main/main-utils.ts
|
|
36
|
+
var getStringParam = /* @__PURE__ */ __name((value) => {
|
|
37
|
+
if (typeof value === "string") return `"${value}"`;
|
|
38
|
+
if (typeof value === "number") return value.toString();
|
|
39
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
40
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
41
|
+
return "undefined";
|
|
42
|
+
}, "getStringParam");
|
|
43
|
+
|
|
30
44
|
// src/utils/main/main.generator.ts
|
|
31
45
|
var MainGenerator = class {
|
|
32
46
|
static {
|
|
@@ -34,26 +48,44 @@ var MainGenerator = class {
|
|
|
34
48
|
}
|
|
35
49
|
buffer = "";
|
|
36
50
|
indentation = 0;
|
|
51
|
+
editor;
|
|
52
|
+
pathToRoot;
|
|
53
|
+
constructor(editor = false, pathToRoot = "") {
|
|
54
|
+
this.editor = editor;
|
|
55
|
+
this.pathToRoot = pathToRoot;
|
|
56
|
+
}
|
|
37
57
|
toString() {
|
|
38
58
|
return this.buffer;
|
|
39
59
|
}
|
|
40
60
|
generateBaseImports(hasTypes) {
|
|
41
|
-
if (
|
|
42
|
-
|
|
61
|
+
if (this.editor) {
|
|
62
|
+
if (hasTypes)
|
|
63
|
+
this.writeLine(
|
|
64
|
+
`import { type IEditorRunOptions, NanoforgeFactory } from "@nanoforge-dev/core-editor";`
|
|
65
|
+
);
|
|
66
|
+
else this.writeLine(`import { NanoforgeFactory } from "@nanoforge-dev/core-editor";`);
|
|
67
|
+
} else {
|
|
68
|
+
if (hasTypes) this.writeLine(`import { type IRunOptions } from "@nanoforge-dev/common";`);
|
|
69
|
+
this.writeLine(`import { NanoforgeFactory } from "@nanoforge-dev/core";`);
|
|
70
|
+
}
|
|
43
71
|
this.endSection();
|
|
44
72
|
return this;
|
|
45
73
|
}
|
|
46
74
|
generateLibsImports(libs) {
|
|
47
|
-
return this.generateImports(libs);
|
|
75
|
+
return this.generateImports(libs, false);
|
|
48
76
|
}
|
|
49
77
|
generateComponentsImports(libs) {
|
|
50
|
-
return this.generateImports(libs);
|
|
78
|
+
return this.generateImports(libs, true);
|
|
51
79
|
}
|
|
52
80
|
generateSystemsImports(libs) {
|
|
53
|
-
return this.generateImports(libs);
|
|
81
|
+
return this.generateImports(libs, true);
|
|
54
82
|
}
|
|
55
83
|
generateMainFunction(hasTypes, cb) {
|
|
56
|
-
this.
|
|
84
|
+
if (this.editor)
|
|
85
|
+
this.writeLine(
|
|
86
|
+
`export async function main(options${hasTypes ? ": IEditorRunOptions" : ""}) {`
|
|
87
|
+
);
|
|
88
|
+
else this.writeLine(`export async function main(options${hasTypes ? ": IRunOptions" : ""}) {`);
|
|
57
89
|
this.indentation += 1;
|
|
58
90
|
cb(this);
|
|
59
91
|
this.indentation -= 1;
|
|
@@ -91,8 +123,8 @@ var MainGenerator = class {
|
|
|
91
123
|
this.endSection();
|
|
92
124
|
return this;
|
|
93
125
|
}
|
|
94
|
-
generateEntities(entities) {
|
|
95
|
-
entities.forEach((entity) => this.generateEntity(entity));
|
|
126
|
+
generateEntities(components, entities) {
|
|
127
|
+
entities.forEach((entity, index) => this.generateEntity(components, entity, index));
|
|
96
128
|
return this;
|
|
97
129
|
}
|
|
98
130
|
generateSystems(systems) {
|
|
@@ -106,14 +138,17 @@ var MainGenerator = class {
|
|
|
106
138
|
}
|
|
107
139
|
generateInitFunctionsImportsIfNeeded(needed) {
|
|
108
140
|
if (!needed) return this;
|
|
109
|
-
return this.generateImports(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
141
|
+
return this.generateImports(
|
|
142
|
+
[
|
|
143
|
+
{ name: "afterInit", path: "./init/after-init" },
|
|
144
|
+
{ name: "afterRegistryInit", path: "./init/after-registry-init" },
|
|
145
|
+
{ name: "afterRun", path: "./init/after-run" },
|
|
146
|
+
{ name: "beforeInit", path: "./init/before-init" },
|
|
147
|
+
{ name: "beforeRegistryInit", path: "./init/before-registry-init" },
|
|
148
|
+
{ name: "beforeRun", path: "./init/before-run" }
|
|
149
|
+
],
|
|
150
|
+
true
|
|
151
|
+
);
|
|
117
152
|
}
|
|
118
153
|
generateInitFunction(func) {
|
|
119
154
|
const params = ["app"];
|
|
@@ -123,16 +158,35 @@ var MainGenerator = class {
|
|
|
123
158
|
if (func !== "afterRun" /* AFTER_RUN */) this.endSection();
|
|
124
159
|
return this;
|
|
125
160
|
}
|
|
126
|
-
generateImports(els) {
|
|
127
|
-
els.sort((a, b) => a.path.localeCompare(b.path)).forEach(
|
|
161
|
+
generateImports(els, relative) {
|
|
162
|
+
els.sort((a, b) => a.path.localeCompare(b.path)).forEach(
|
|
163
|
+
({ name, path }) => this.writeLine(
|
|
164
|
+
`import { ${name} } from "${relative ? joinRelative(this.pathToRoot, path) : path}";`
|
|
165
|
+
)
|
|
166
|
+
);
|
|
128
167
|
this.endSection();
|
|
129
168
|
return this;
|
|
130
169
|
}
|
|
131
|
-
generateEntity(entity) {
|
|
170
|
+
generateEntity(components, entity, entityIndex) {
|
|
132
171
|
this.writeLine(`const ${entity.id} = registry.spawnEntity();`);
|
|
133
|
-
entity.components.forEach(
|
|
134
|
-
({ name
|
|
135
|
-
|
|
172
|
+
Object.entries(entity.components).forEach(([componentName, rawParams]) => {
|
|
173
|
+
const originalsParams = components.find(({ name }) => name === componentName)?.paramsNames;
|
|
174
|
+
if (!originalsParams)
|
|
175
|
+
throw new Error("Missing component in entity or inexistent saved component");
|
|
176
|
+
const params = !this.editor ? Object.values(originalsParams).map((ogParam) => {
|
|
177
|
+
return getStringParam(rawParams[ogParam]);
|
|
178
|
+
}) : Object.values(originalsParams).map((ogParam) => {
|
|
179
|
+
return `options.editor.save.entities[${entityIndex}].components["${componentName}"]["${ogParam}"]`;
|
|
180
|
+
});
|
|
181
|
+
this.writeLine(
|
|
182
|
+
`registry.addComponent(${entity.id}, new ${componentName}(${params.join(", ")}));`
|
|
183
|
+
);
|
|
184
|
+
});
|
|
185
|
+
if (this.editor) {
|
|
186
|
+
this.writeLine(
|
|
187
|
+
`registry.addComponent(${entity.id}, { name: "__RESERVED_entityId", entityId: "${entity.id}" });`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
136
190
|
this.endSection();
|
|
137
191
|
}
|
|
138
192
|
getInitFunction(name, type) {
|
|
@@ -155,40 +209,23 @@ var generateMain = /* @__PURE__ */ __name((options, save) => {
|
|
|
155
209
|
const isServer = options.part === "server";
|
|
156
210
|
const hasTypes = options.language === "ts";
|
|
157
211
|
const initFunctions = options.initFunctions;
|
|
158
|
-
return new MainGenerator()
|
|
159
|
-
|
|
212
|
+
return (!options.editor ? new MainGenerator() : new MainGenerator(
|
|
213
|
+
true,
|
|
214
|
+
join2(
|
|
215
|
+
"../".repeat(options.outFile ? options.outFile.split("/").length - 1 : 3),
|
|
216
|
+
options.part
|
|
217
|
+
)
|
|
218
|
+
)).generateBaseImports(hasTypes).generateLibsImports(save.libraries).generateInitFunctionsImportsIfNeeded(initFunctions).generateComponentsImports(save.components).generateSystemsImports(save.systems).generateMainFunction(hasTypes, (generator) => {
|
|
219
|
+
generator.generateApp(isServer).generateLibsInstances(save.libraries).generateLibsInit(save.libraries).generateInitFunctionIfNeeded(initFunctions, "beforeInit" /* BEFORE_INIT */).generateAppInit().generateInitFunctionIfNeeded(initFunctions, "afterInit" /* AFTER_INIT */).generateRegistry(save.libraries).generateInitFunctionIfNeeded(initFunctions, "beforeRegistryInit" /* BEFORE_REGISTRY_INIT */).generateEntities(save.components, save.entities).generateSystems(save.systems).generateInitFunctionIfNeeded(initFunctions, "afterRegistryInit" /* AFTER_REGISTRY_INIT */).generateInitFunctionIfNeeded(initFunctions, "beforeRun" /* BEFORE_RUN */).generateAppRun(initFunctions).generateInitFunctionIfNeeded(initFunctions, "afterRun" /* AFTER_RUN */);
|
|
160
220
|
}).toString();
|
|
161
221
|
}, "generateMain");
|
|
162
222
|
|
|
163
|
-
// src/utils/name.ts
|
|
164
|
-
import { basename, parse } from "path";
|
|
165
|
-
var resolvePackageName = /* @__PURE__ */ __name((path) => {
|
|
166
|
-
const { base: baseFilename, dir: dirname } = parse(path);
|
|
167
|
-
if (baseFilename === ".") {
|
|
168
|
-
return basename(process.cwd());
|
|
169
|
-
}
|
|
170
|
-
if (dirname.match(/^@[^\s]/)) {
|
|
171
|
-
return `${dirname}/${baseFilename}`;
|
|
172
|
-
}
|
|
173
|
-
return baseFilename;
|
|
174
|
-
}, "resolvePackageName");
|
|
175
|
-
|
|
176
|
-
// src/defaults.ts
|
|
177
|
-
var DEFAULT_APP_NAME = "nanoforge-app";
|
|
178
|
-
var DEFAULT_LANGUAGE = "ts";
|
|
179
|
-
|
|
180
223
|
// src/libs/part-main/part-main.factory.ts
|
|
181
224
|
var transform = /* @__PURE__ */ __name((schema) => {
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
name,
|
|
185
|
-
part: schema.part,
|
|
186
|
-
language: schema.language ?? DEFAULT_LANGUAGE,
|
|
187
|
-
initFunctions: schema.initFunctions ?? false,
|
|
188
|
-
saveFile: schema.saveFile
|
|
189
|
-
};
|
|
225
|
+
void schema;
|
|
226
|
+
return {};
|
|
190
227
|
}, "transform");
|
|
191
|
-
var generate = /* @__PURE__ */ __name((options, path) => {
|
|
228
|
+
var generate = /* @__PURE__ */ __name((options, path, schema) => {
|
|
192
229
|
const rules = [
|
|
193
230
|
template({
|
|
194
231
|
...strings,
|
|
@@ -196,26 +233,32 @@ var generate = /* @__PURE__ */ __name((options, path) => {
|
|
|
196
233
|
}),
|
|
197
234
|
move(normalize(path))
|
|
198
235
|
];
|
|
199
|
-
return apply(asSource(writeMain(
|
|
236
|
+
return apply(asSource(writeMain(schema, path)), rules);
|
|
200
237
|
}, "generate");
|
|
201
|
-
var
|
|
238
|
+
var getMainPath = /* @__PURE__ */ __name((schema) => {
|
|
239
|
+
if (schema.outFile) return schema.outFile;
|
|
240
|
+
if (schema.editor)
|
|
241
|
+
return join3(".nanoforge/editor", schema.part, `main.${schema.language}`);
|
|
242
|
+
return join3(schema.part, `main.${schema.language}`);
|
|
243
|
+
}, "getMainPath");
|
|
244
|
+
var writeMain = /* @__PURE__ */ __name((schema, path) => {
|
|
202
245
|
return (tree) => {
|
|
203
|
-
const save = getSave(path,
|
|
204
|
-
const resPath =
|
|
205
|
-
const content = generateMain(
|
|
206
|
-
fs.rmSync(
|
|
246
|
+
const save = getSave(path, schema.part, schema.saveFile);
|
|
247
|
+
const resPath = getMainPath(schema);
|
|
248
|
+
const content = generateMain(schema, save);
|
|
249
|
+
fs.rmSync(join3(path, resPath), { force: true });
|
|
207
250
|
tree.create(resPath, content);
|
|
208
251
|
return tree;
|
|
209
252
|
};
|
|
210
253
|
}, "writeMain");
|
|
211
254
|
var getSave = /* @__PURE__ */ __name((path, part, saveFile) => {
|
|
212
255
|
return JSON.parse(
|
|
213
|
-
fs.readFileSync(saveFile ??
|
|
256
|
+
fs.readFileSync(saveFile ?? join3(path, `.nanoforge/${part}.save.json`), "utf-8")
|
|
214
257
|
);
|
|
215
258
|
}, "getSave");
|
|
216
259
|
var main = /* @__PURE__ */ __name((schema) => {
|
|
217
260
|
const options = transform(schema);
|
|
218
|
-
return mergeWith(generate(options, schema.directory
|
|
261
|
+
return mergeWith(generate(options, schema.directory, schema));
|
|
219
262
|
}, "main");
|
|
220
263
|
export {
|
|
221
264
|
main
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/libs/part-main/part-main.factory.ts","../../../src/utils/formatting.ts","../../../src/utils/main/const.ts","../../../src/utils/main/main.generator.ts","../../../src/utils/main/main-functions.ts","../../../src/utils/name.ts","../../../src/defaults.ts"],"sourcesContent":["import { type Path, join, normalize, strings } from \"@angular-devkit/core\";\nimport {\n type Rule,\n type Source,\n type Tree,\n apply,\n asSource,\n mergeWith,\n move,\n template,\n} from \"@angular-devkit/schematics\";\nimport * as fs from \"node:fs\";\n\nimport { toKebabCase } from \"@utils/formatting\";\nimport { generateMain } from \"@utils/main/main-functions\";\nimport { type Save } from \"@utils/main/save.type\";\nimport { resolvePackageName } from \"@utils/name\";\n\nimport { DEFAULT_APP_NAME, DEFAULT_LANGUAGE } from \"~/defaults\";\n\nimport { type PartMainOptions } from \"./part-main.options\";\nimport { type PartMainSchema } from \"./part-main.schema\";\n\nconst transform = (schema: PartMainSchema): PartMainOptions => {\n const name = resolvePackageName(toKebabCase(schema.name?.toString() ?? DEFAULT_APP_NAME));\n\n return {\n name,\n part: schema.part,\n language: schema.language ?? DEFAULT_LANGUAGE,\n initFunctions: schema.initFunctions ?? false,\n saveFile: schema.saveFile,\n };\n};\n\nconst generate = (options: PartMainOptions, path: string): Source => {\n const rules = [\n template({\n ...strings,\n ...options,\n }),\n move(normalize(path)),\n ];\n\n return apply(asSource(writeMain(options, path)), rules);\n};\n\nconst writeMain = (options: PartMainOptions, path: string) => {\n return (tree: Tree) => {\n const save = getSave(path, options.part, options.saveFile);\n const resPath = join(options.part as Path, `main.${options.language}`);\n const content = generateMain(options, save);\n fs.rmSync(join(path as Path, resPath), { force: true });\n tree.create(resPath, content);\n return tree;\n };\n};\n\nconst getSave = (path: string, part: \"client\" | \"server\", saveFile?: string): Save => {\n return JSON.parse(\n fs.readFileSync(saveFile ?? join(path as Path, `.nanoforge/${part}.save.json`), \"utf-8\"),\n ) as Save;\n};\n\nexport const main = (schema: PartMainSchema): Rule => {\n const options = transform(schema);\n\n return mergeWith(generate(options, schema.directory ?? options.name));\n};\n","export const toKebabCase = (str: string): string => {\n return str\n .replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n};\n","import { SaveLibraryTypeEnum } from \"@utils/main/save.type\";\n\nexport const LIBS_FUNCTIONS_NAME: Record<SaveLibraryTypeEnum | string, string> = {\n [SaveLibraryTypeEnum.ASSET_MANAGER]: \"useAssetManager\",\n [SaveLibraryTypeEnum.COMPONENT_SYSTEM]: \"useComponentSystem\",\n [SaveLibraryTypeEnum.GRAPHICS]: \"useGraphics\",\n [SaveLibraryTypeEnum.INPUT]: \"useInput\",\n [SaveLibraryTypeEnum.NETWORK]: \"useNetwork\",\n [SaveLibraryTypeEnum.SOUND]: \"useSound\",\n};\n","import { InitFunctionEnum } from \"@utils/main/enums\";\n\nimport { LIBS_FUNCTIONS_NAME } from \"./const\";\nimport {\n type SaveComponent,\n type SaveEntity,\n type SaveLibrary,\n SaveLibraryTypeEnum,\n type SaveSystem,\n} from \"./save.type\";\n\nexport class MainGenerator {\n private buffer = \"\";\n private indentation = 0;\n\n toString(): string {\n return this.buffer;\n }\n\n generateBaseImports(hasTypes: boolean): MainGenerator {\n if (hasTypes) this.writeLine(`import { type IRunOptions } from \"@nanoforge-dev/common\";`);\n this.writeLine(`import { NanoforgeFactory } from \"@nanoforge-dev/core\";`);\n this.endSection();\n return this;\n }\n\n generateLibsImports(libs: SaveLibrary[]): MainGenerator {\n return this.generateImports(libs);\n }\n\n generateComponentsImports(libs: SaveComponent[]): MainGenerator {\n return this.generateImports(libs);\n }\n\n generateSystemsImports(libs: SaveSystem[]): MainGenerator {\n return this.generateImports(libs);\n }\n\n generateMainFunction(hasTypes: boolean, cb: (generator: MainGenerator) => void): MainGenerator {\n this.writeLine(`export async function main(options${hasTypes ? \": IRunOptions\" : \"\"}) {`);\n this.indentation += 1;\n cb(this);\n this.indentation -= 1;\n this.writeLine(\"}\");\n return this;\n }\n\n generateApp(isServer: boolean): MainGenerator {\n this.writeLine(`const app = NanoforgeFactory.create${isServer ? \"Server\" : \"Client\"}();`);\n this.endSection();\n return this;\n }\n\n generateAppInit(): MainGenerator {\n this.writeLine(`await app.init(options);`);\n this.endSection();\n return this;\n }\n\n generateAppRun(hasInitFunctions: boolean): MainGenerator {\n this.writeLine(`await app.run();`);\n if (hasInitFunctions) this.endSection();\n return this;\n }\n\n generateLibsInstances(libs: SaveLibrary[]): MainGenerator {\n libs.forEach(({ id, name }) => this.writeLine(`const ${id} = new ${name}();`));\n this.endSection();\n return this;\n }\n\n generateLibsInit(libs: SaveLibrary[]): MainGenerator {\n libs.forEach(({ id, type }) => this.writeLine(this.getInitFunction(id, type)));\n this.endSection();\n return this;\n }\n\n generateRegistry(libs: SaveLibrary[]): MainGenerator {\n const libName =\n libs.find((lib) => lib.type === SaveLibraryTypeEnum.COMPONENT_SYSTEM)?.id ?? \"ecsLibrary\";\n this.writeLine(`const registry = ${libName}.registry;`);\n this.endSection();\n return this;\n }\n\n generateEntities(entities: SaveEntity[]): MainGenerator {\n entities.forEach((entity) => this.generateEntity(entity));\n return this;\n }\n\n generateSystems(systems: SaveSystem[]): MainGenerator {\n systems.forEach(({ name }) => this.writeLine(`registry.addSystem(${name});`));\n this.endSection();\n return this;\n }\n\n generateInitFunctionIfNeeded(needed: boolean, func: InitFunctionEnum): MainGenerator {\n if (needed) return this.generateInitFunction(func);\n return this;\n }\n\n generateInitFunctionsImportsIfNeeded(needed: boolean): MainGenerator {\n if (!needed) return this;\n return this.generateImports([\n { name: \"afterInit\", path: \"./init/after-init\" },\n { name: \"afterRegistryInit\", path: \"./init/after-registry-init\" },\n { name: \"afterRun\", path: \"./init/after-run\" },\n { name: \"beforeInit\", path: \"./init/before-init\" },\n { name: \"beforeRegistryInit\", path: \"./init/before-registry-init\" },\n { name: \"beforeRun\", path: \"./init/before-run\" },\n ]);\n }\n\n private generateInitFunction(func: InitFunctionEnum): MainGenerator {\n const params = [\"app\"];\n if (\n [InitFunctionEnum.BEFORE_REGISTRY_INIT, InitFunctionEnum.AFTER_REGISTRY_INIT].includes(func)\n )\n params.push(\"registry\");\n this.writeLine(`await ${func}(${params.join(\", \")});`);\n if (func !== InitFunctionEnum.AFTER_RUN) this.endSection();\n return this;\n }\n\n private generateImports(els: { name: string; path: string }[]): MainGenerator {\n els\n .sort((a, b) => a.path.localeCompare(b.path))\n .forEach(({ name, path }) => this.writeLine(`import { ${name} } from \"${path}\";`));\n this.endSection();\n return this;\n }\n\n private generateEntity(entity: SaveEntity): void {\n this.writeLine(`const ${entity.id} = registry.spawnEntity();`);\n entity.components.forEach(({ name, params }) =>\n this.writeLine(`registry.addComponent(${entity.id}, new ${name}(${params.join(\", \")}));`),\n );\n this.endSection();\n }\n\n private getInitFunction(name: string, type: SaveLibraryTypeEnum | string): string {\n const baseName = LIBS_FUNCTIONS_NAME[type];\n if (baseName) return `app.${baseName}(${name});`;\n return `app.use(Symbol(\"${type}\"), ${name});`;\n }\n\n private writeLine(text: string, indentation = true): void {\n const line = `${\" \".repeat(indentation ? this.indentation * 2 : 0)}${text}\\n`;\n this.buffer += line;\n }\n\n private endSection(): void {\n this.writeLine(\"\");\n }\n}\n","import { InitFunctionEnum } from \"@utils/main/enums\";\n\nimport { MainGenerator } from \"./main.generator\";\nimport { type Save } from \"./save.type\";\n\nexport interface MainOptions {\n part: \"client\" | \"server\";\n language: \"js\" | \"ts\";\n initFunctions: boolean;\n}\n\nexport const generateMain = (options: MainOptions, save: Save) => {\n const isServer = options.part === \"server\";\n const hasTypes = options.language === \"ts\";\n const initFunctions = options.initFunctions;\n\n return new MainGenerator()\n .generateBaseImports(hasTypes)\n .generateLibsImports(save.libraries)\n .generateInitFunctionsImportsIfNeeded(initFunctions)\n .generateComponentsImports(save.components)\n .generateSystemsImports(save.systems)\n\n .generateMainFunction(hasTypes, (generator) => {\n generator\n .generateApp(isServer)\n\n .generateLibsInstances(save.libraries)\n .generateLibsInit(save.libraries)\n\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.BEFORE_INIT)\n .generateAppInit()\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.AFTER_INIT)\n\n .generateRegistry(save.libraries)\n\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.BEFORE_REGISTRY_INIT)\n .generateEntities(save.entities)\n .generateSystems(save.systems)\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.AFTER_REGISTRY_INIT)\n\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.BEFORE_RUN)\n .generateAppRun(initFunctions)\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.AFTER_RUN);\n })\n .toString();\n};\n","import { basename, parse } from \"path\";\n\nexport const resolvePackageName = (path: string): string => {\n const { base: baseFilename, dir: dirname } = parse(path);\n if (baseFilename === \".\") {\n return basename(process.cwd());\n }\n if (dirname.match(/^@[^\\s]/)) {\n return `${dirname}/${baseFilename}`;\n }\n return baseFilename;\n};\n","export const DEFAULT_APP_NAME = \"nanoforge-app\";\nexport const DEFAULT_VERSION = \"0.0.0\";\nexport const DEFAULT_AUTHOR = \"\";\nexport const DEFAULT_DESCRIPTION = \"\";\nexport const DEFAULT_LANGUAGE = \"ts\";\nexport const DEFAULT_PACKAGE_MANAGER = \"npm\";\nexport const DEFAULT_CONFIG = {\n client: {\n build: {\n entryFile: \"client/main.ts\",\n outDir: \".nanoforge/client\",\n },\n runtime: {\n dir: \".nanoforge/client\",\n },\n },\n};\nexport const DEFAULT_SERVER_CONFIG = {\n server: {\n enable: true,\n build: {\n entryFile: \"server/main.ts\",\n outDir: \".nanoforge/server\",\n },\n runtime: {\n dir: \".nanoforge/server\",\n },\n },\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/libs/part-main/part-main.factory.ts","../../../src/utils/main/main-functions.ts","../../../src/utils/path.ts","../../../src/utils/main/const.ts","../../../src/utils/main/main-utils.ts","../../../src/utils/main/main.generator.ts"],"sourcesContent":["import { type Path, join, normalize, strings } from \"@angular-devkit/core\";\nimport {\n type Rule,\n type Source,\n type Tree,\n apply,\n asSource,\n mergeWith,\n move,\n template,\n} from \"@angular-devkit/schematics\";\nimport * as fs from \"fs\";\n\nimport { generateMain } from \"@utils/main/main-functions\";\nimport { type Save } from \"@utils/main/save.type\";\n\nimport { type PartMainOptions } from \"./part-main.options\";\nimport { type PartMainSchema } from \"./part-main.schema\";\n\nconst transform = (schema: PartMainSchema): PartMainOptions => {\n void schema;\n\n return {};\n};\n\nconst generate = (options: PartMainOptions, path: string, schema: PartMainSchema): Source => {\n const rules = [\n template({\n ...strings,\n ...options,\n }),\n move(normalize(path)),\n ];\n\n return apply(asSource(writeMain(schema, path)), rules);\n};\n\nconst getMainPath = (schema: PartMainSchema): string => {\n if (schema.outFile) return schema.outFile;\n if (schema.editor)\n return join(\".nanoforge/editor\" as Path, schema.part, `main.${schema.language}`);\n return join(schema.part as Path, `main.${schema.language}`);\n};\n\nconst writeMain = (schema: PartMainSchema, path: string) => {\n return (tree: Tree) => {\n const save = getSave(path, schema.part, schema.saveFile);\n\n const resPath = getMainPath(schema);\n\n const content = generateMain(schema, save);\n fs.rmSync(join(path as Path, resPath), { force: true });\n tree.create(resPath, content);\n return tree;\n };\n};\n\nconst getSave = (path: string, part: \"client\" | \"server\", saveFile?: string): Save => {\n return JSON.parse(\n fs.readFileSync(saveFile ?? join(path as Path, `.nanoforge/${part}.save.json`), \"utf-8\"),\n ) as Save;\n};\n\nexport const main = (schema: PartMainSchema): Rule => {\n const options = transform(schema);\n\n return mergeWith(generate(options, schema.directory, schema));\n};\n","import { join } from \"path\";\n\nimport { InitFunctionEnum } from \"@utils/main/enums\";\n\nimport { MainGenerator } from \"./main.generator\";\nimport { type Save } from \"./save.type\";\n\nexport interface MainOptions {\n part: \"client\" | \"server\";\n language: \"js\" | \"ts\";\n initFunctions: boolean;\n editor: boolean;\n outFile?: string;\n}\n\nexport const generateMain = (options: MainOptions, save: Save) => {\n const isServer = options.part === \"server\";\n const hasTypes = options.language === \"ts\";\n const initFunctions = options.initFunctions;\n\n return (\n !options.editor\n ? new MainGenerator()\n : new MainGenerator(\n true,\n join(\n \"../\".repeat(options.outFile ? options.outFile.split(\"/\").length - 1 : 3),\n options.part,\n ),\n )\n )\n .generateBaseImports(hasTypes)\n .generateLibsImports(save.libraries)\n .generateInitFunctionsImportsIfNeeded(initFunctions)\n .generateComponentsImports(save.components)\n .generateSystemsImports(save.systems)\n\n .generateMainFunction(hasTypes, (generator) => {\n generator\n .generateApp(isServer)\n\n .generateLibsInstances(save.libraries)\n .generateLibsInit(save.libraries)\n\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.BEFORE_INIT)\n .generateAppInit()\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.AFTER_INIT)\n\n .generateRegistry(save.libraries)\n\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.BEFORE_REGISTRY_INIT)\n .generateEntities(save.components, save.entities)\n .generateSystems(save.systems)\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.AFTER_REGISTRY_INIT)\n\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.BEFORE_RUN)\n .generateAppRun(initFunctions)\n .generateInitFunctionIfNeeded(initFunctions, InitFunctionEnum.AFTER_RUN);\n })\n .toString();\n};\n","import { join } from \"path\";\n\nexport const joinRelative = (...paths: [string, ...string[]]): string => {\n const path = join(...paths);\n return path.startsWith(\"./\") || path.startsWith(\"../\") ? path : `./${path}`;\n};\n","import { SaveLibraryTypeEnum } from \"@utils/main/save.type\";\n\nexport const LIBS_FUNCTIONS_NAME: Record<SaveLibraryTypeEnum | string, string> = {\n [SaveLibraryTypeEnum.ASSET_MANAGER]: \"useAssetManager\",\n [SaveLibraryTypeEnum.COMPONENT_SYSTEM]: \"useComponentSystem\",\n [SaveLibraryTypeEnum.GRAPHICS]: \"useGraphics\",\n [SaveLibraryTypeEnum.INPUT]: \"useInput\",\n [SaveLibraryTypeEnum.NETWORK]: \"useNetwork\",\n [SaveLibraryTypeEnum.SOUND]: \"useSound\",\n};\n","export const getStringParam = (value: any): string => {\n if (typeof value === \"string\") return `\"${value}\"`;\n if (typeof value === \"number\") return value.toString();\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return \"undefined\";\n};\n","import { joinRelative } from \"@utils/path\";\n\nimport { LIBS_FUNCTIONS_NAME } from \"./const\";\nimport { InitFunctionEnum } from \"./enums\";\nimport { getStringParam } from \"./main-utils\";\nimport {\n type SaveComponent,\n type SaveEntity,\n type SaveLibrary,\n SaveLibraryTypeEnum,\n type SaveSystem,\n} from \"./save.type\";\n\nexport class MainGenerator {\n private buffer = \"\";\n private indentation = 0;\n private readonly editor: boolean;\n private readonly pathToRoot: string;\n\n constructor(editor: boolean = false, pathToRoot: string = \"\") {\n this.editor = editor;\n this.pathToRoot = pathToRoot;\n }\n\n toString(): string {\n return this.buffer;\n }\n\n generateBaseImports(hasTypes: boolean): MainGenerator {\n if (this.editor) {\n if (hasTypes)\n this.writeLine(\n `import { type IEditorRunOptions, NanoforgeFactory } from \"@nanoforge-dev/core-editor\";`,\n );\n else this.writeLine(`import { NanoforgeFactory } from \"@nanoforge-dev/core-editor\";`);\n } else {\n if (hasTypes) this.writeLine(`import { type IRunOptions } from \"@nanoforge-dev/common\";`);\n this.writeLine(`import { NanoforgeFactory } from \"@nanoforge-dev/core\";`);\n }\n\n this.endSection();\n return this;\n }\n\n generateLibsImports(libs: SaveLibrary[]): MainGenerator {\n return this.generateImports(libs, false);\n }\n\n generateComponentsImports(libs: SaveComponent[]): MainGenerator {\n return this.generateImports(libs, true);\n }\n\n generateSystemsImports(libs: SaveSystem[]): MainGenerator {\n return this.generateImports(libs, true);\n }\n\n generateMainFunction(hasTypes: boolean, cb: (generator: MainGenerator) => void): MainGenerator {\n if (this.editor)\n this.writeLine(\n `export async function main(options${hasTypes ? \": IEditorRunOptions\" : \"\"}) {`,\n );\n else this.writeLine(`export async function main(options${hasTypes ? \": IRunOptions\" : \"\"}) {`);\n this.indentation += 1;\n cb(this);\n this.indentation -= 1;\n this.writeLine(\"}\");\n return this;\n }\n\n generateApp(isServer: boolean): MainGenerator {\n this.writeLine(`const app = NanoforgeFactory.create${isServer ? \"Server\" : \"Client\"}();`);\n this.endSection();\n return this;\n }\n\n generateAppInit(): MainGenerator {\n this.writeLine(`await app.init(options);`);\n this.endSection();\n return this;\n }\n\n generateAppRun(hasInitFunctions: boolean): MainGenerator {\n this.writeLine(`await app.run();`);\n if (hasInitFunctions) this.endSection();\n return this;\n }\n\n generateLibsInstances(libs: SaveLibrary[]): MainGenerator {\n libs.forEach(({ id, name }) => this.writeLine(`const ${id} = new ${name}();`));\n this.endSection();\n return this;\n }\n\n generateLibsInit(libs: SaveLibrary[]): MainGenerator {\n libs.forEach(({ id, type }) => this.writeLine(this.getInitFunction(id, type)));\n this.endSection();\n return this;\n }\n\n generateRegistry(libs: SaveLibrary[]): MainGenerator {\n const libName =\n libs.find((lib) => lib.type === SaveLibraryTypeEnum.COMPONENT_SYSTEM)?.id ?? \"ecsLibrary\";\n this.writeLine(`const registry = ${libName}.registry;`);\n this.endSection();\n return this;\n }\n\n generateEntities(components: SaveComponent[], entities: SaveEntity[]): MainGenerator {\n entities.forEach((entity, index) => this.generateEntity(components, entity, index));\n return this;\n }\n\n generateSystems(systems: SaveSystem[]): MainGenerator {\n systems.forEach(({ name }) => this.writeLine(`registry.addSystem(${name});`));\n this.endSection();\n return this;\n }\n\n generateInitFunctionIfNeeded(needed: boolean, func: InitFunctionEnum): MainGenerator {\n if (needed) return this.generateInitFunction(func);\n return this;\n }\n\n generateInitFunctionsImportsIfNeeded(needed: boolean): MainGenerator {\n if (!needed) return this;\n return this.generateImports(\n [\n { name: \"afterInit\", path: \"./init/after-init\" },\n { name: \"afterRegistryInit\", path: \"./init/after-registry-init\" },\n { name: \"afterRun\", path: \"./init/after-run\" },\n { name: \"beforeInit\", path: \"./init/before-init\" },\n { name: \"beforeRegistryInit\", path: \"./init/before-registry-init\" },\n { name: \"beforeRun\", path: \"./init/before-run\" },\n ],\n true,\n );\n }\n\n private generateInitFunction(func: InitFunctionEnum): MainGenerator {\n const params = [\"app\"];\n if (\n [InitFunctionEnum.BEFORE_REGISTRY_INIT, InitFunctionEnum.AFTER_REGISTRY_INIT].includes(func)\n )\n params.push(\"registry\");\n this.writeLine(`await ${func}(${params.join(\", \")});`);\n if (func !== InitFunctionEnum.AFTER_RUN) this.endSection();\n return this;\n }\n\n private generateImports(els: { name: string; path: string }[], relative: boolean): MainGenerator {\n els\n .sort((a, b) => a.path.localeCompare(b.path))\n .forEach(({ name, path }) =>\n this.writeLine(\n `import { ${name} } from \"${relative ? joinRelative(this.pathToRoot, path) : path}\";`,\n ),\n );\n this.endSection();\n return this;\n }\n\n private generateEntity(\n components: SaveComponent[],\n entity: SaveEntity,\n entityIndex: number,\n ): void {\n this.writeLine(`const ${entity.id} = registry.spawnEntity();`);\n Object.entries(entity.components).forEach(([componentName, rawParams]) => {\n const originalsParams = components.find(({ name }) => name === componentName)?.paramsNames;\n if (!originalsParams)\n throw new Error(\"Missing component in entity or inexistent saved component\");\n const params: string[] = !this.editor\n ? Object.values(originalsParams).map((ogParam) => {\n return getStringParam(rawParams[ogParam]);\n })\n : Object.values(originalsParams).map((ogParam) => {\n return `options.editor.save.entities[${entityIndex}].components[\"${componentName}\"][\"${ogParam}\"]`;\n });\n this.writeLine(\n `registry.addComponent(${entity.id}, new ${componentName}(${params.join(\", \")}));`,\n );\n });\n if (this.editor) {\n this.writeLine(\n `registry.addComponent(${entity.id}, { name: \"__RESERVED_entityId\", entityId: \"${entity.id}\" });`,\n );\n }\n this.endSection();\n }\n\n private getInitFunction(name: string, type: SaveLibraryTypeEnum | string): string {\n const baseName = LIBS_FUNCTIONS_NAME[type];\n if (baseName) return `app.${baseName}(${name});`;\n return `app.use(Symbol(\"${type}\"), ${name});`;\n }\n\n private writeLine(text: string, indentation = true): void {\n const line = `${\" \".repeat(indentation ? this.indentation * 2 : 0)}${text}\\n`;\n this.buffer += line;\n }\n\n private endSection(): void {\n this.writeLine(\"\");\n }\n}\n"],"mappings":"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","names":["join","join","join","join"]}
|
|
@@ -4,24 +4,16 @@
|
|
|
4
4
|
"title": "NanoForge Part Main Options Schema",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
|
-
"
|
|
7
|
+
"directory": {
|
|
8
8
|
"type": "string",
|
|
9
|
-
"description": "
|
|
10
|
-
"
|
|
11
|
-
"$source": "argv",
|
|
12
|
-
"index": 0
|
|
13
|
-
},
|
|
14
|
-
"x-prompt": "What name would you like to use for the new project ?"
|
|
9
|
+
"description": "NanoForge application destination directory",
|
|
10
|
+
"default": "."
|
|
15
11
|
},
|
|
16
12
|
"part": {
|
|
17
13
|
"type": "string",
|
|
18
14
|
"enum": ["client", "server"],
|
|
19
15
|
"description": "The part of the application to generate"
|
|
20
16
|
},
|
|
21
|
-
"directory": {
|
|
22
|
-
"type": "string",
|
|
23
|
-
"description": "NanoForge application destination directory"
|
|
24
|
-
},
|
|
25
17
|
"language": {
|
|
26
18
|
"type": "string",
|
|
27
19
|
"enum": ["ts", "js"],
|
|
@@ -36,7 +28,16 @@
|
|
|
36
28
|
"saveFile": {
|
|
37
29
|
"type": "string",
|
|
38
30
|
"description": "Save file path with components and systems in JSON format"
|
|
31
|
+
},
|
|
32
|
+
"outFile": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"description": "Path of the out file"
|
|
35
|
+
},
|
|
36
|
+
"editor": {
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"description": "Build main editor",
|
|
39
|
+
"default": false
|
|
39
40
|
}
|
|
40
41
|
},
|
|
41
|
-
"required": ["
|
|
42
|
+
"required": ["part"]
|
|
42
43
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("@nanoforge-dev/common").Context} Context
|
|
3
|
+
* @typedef {import("@nanoforge-dev/ecs-<%= part %>").EditorSystemManifest} EditorSystemManifest
|
|
4
|
+
* @typedef {import("@nanoforge-dev/ecs-<%= part %>").Registry} Registry
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ExampleComponent } from "../components/example.component";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* <%= functionName %> system
|
|
11
|
+
* This system end the game when paramB reaches 0 for any entity with ExampleComponent
|
|
12
|
+
* @param {Registry} registry - ECS registry instance
|
|
13
|
+
* @param {Context} ctx - Nanoforge <%= part %> instance
|
|
14
|
+
*/
|
|
15
|
+
export const <%= functionName %>System = (registry, ctx) => {
|
|
16
|
+
const entities = registry.getZipper([ExampleComponent]);
|
|
17
|
+
|
|
18
|
+
entities.forEach((entity) => {
|
|
19
|
+
if (entity.ExampleComponent.paramA === "end") {
|
|
20
|
+
ctx.app.setIsRunning(false);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (entity.ExampleComponent.paramB === 0) entity.ExampleComponent.paramA = "end";
|
|
25
|
+
|
|
26
|
+
if (entity.ExampleComponent.paramB >= 0)
|
|
27
|
+
entity.ExampleComponent.paramB = entity.ExampleComponent.paramB - 1;
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// * Required to generate code
|
|
32
|
+
export default <%= functionName %>System.name;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Editor component manifest
|
|
36
|
+
* * Required for the editor to display the system and generate code
|
|
37
|
+
* @type {EditorSystemManifest}
|
|
38
|
+
*/
|
|
39
|
+
export const EDITOR_SYSTEM_MANIFEST = {
|
|
40
|
+
name: "<%= functionName %>",
|
|
41
|
+
description:
|
|
42
|
+
"This system end the game when paramB reaches 0 for any entity with ExampleComponent",
|
|
43
|
+
dependencies: ["ExampleComponent"],
|
|
44
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Context } from "@nanoforge-dev/common";
|
|
2
|
+
import { type EditorSystemManifest, type Registry } from "@nanoforge-dev/ecs-<%= part %>";
|
|
3
|
+
|
|
4
|
+
import { ExampleComponent } from "../components/example.component";
|
|
5
|
+
|
|
6
|
+
export const <%= functionName %>System = (registry: Registry, ctx: Context) => {
|
|
7
|
+
const entities = registry.getZipper([ExampleComponent]);
|
|
8
|
+
|
|
9
|
+
entities.forEach((entity) => {
|
|
10
|
+
if (entity.ExampleComponent.paramA === "end") {
|
|
11
|
+
ctx.app.setIsRunning(false);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (entity.ExampleComponent.paramB === 0) entity.ExampleComponent.paramA = "end";
|
|
16
|
+
|
|
17
|
+
if (entity.ExampleComponent.paramB >= 0)
|
|
18
|
+
entity.ExampleComponent.paramB = entity.ExampleComponent.paramB - 1;
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// * Required to generate code
|
|
23
|
+
export default <%= functionName %>System.name;
|
|
24
|
+
|
|
25
|
+
// * Required for the editor to display the system and generate code
|
|
26
|
+
export const EDITOR_SYSTEM_MANIFEST: EditorSystemManifest = {
|
|
27
|
+
name: "<%= functionName %>",
|
|
28
|
+
description:
|
|
29
|
+
"This system end the game when paramB reaches 0 for any entity with ExampleComponent",
|
|
30
|
+
dependencies: ["ExampleComponent"],
|
|
31
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema",
|
|
3
|
+
"$id": "SchematicsNanoForgeSystem",
|
|
4
|
+
"title": "NanoForge System Options Schema",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"name": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "System name",
|
|
10
|
+
"default": "example"
|
|
11
|
+
},
|
|
12
|
+
"directory": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "System destination directory",
|
|
15
|
+
"default": "."
|
|
16
|
+
},
|
|
17
|
+
"part": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"enum": ["client", "server"],
|
|
20
|
+
"description": "The part of the application to generate"
|
|
21
|
+
},
|
|
22
|
+
"language": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"enum": ["ts", "js"],
|
|
25
|
+
"description": "NanoForge application language",
|
|
26
|
+
"default": "ts"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"required": ["part"]
|
|
30
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Rule } from '@angular-devkit/schematics';
|
|
2
|
+
|
|
3
|
+
interface SystemSchema {
|
|
4
|
+
/**
|
|
5
|
+
* System destination directory
|
|
6
|
+
*/
|
|
7
|
+
name: string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* System destination directory
|
|
11
|
+
*/
|
|
12
|
+
directory: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The part of the application to generate
|
|
16
|
+
*/
|
|
17
|
+
part: "client" | "server";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* NanoForge Application language
|
|
21
|
+
*/
|
|
22
|
+
language: "js" | "ts";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare const main: (schema: SystemSchema) => Rule;
|
|
26
|
+
|
|
27
|
+
export { main };
|