create-moost 0.5.32 → 0.6.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/README.md +2 -2
- package/dist/index.cjs +75 -38
- package/dist/index.mjs +75 -38
- package/package.json +36 -36
- package/templates/cli/package.jsonc +11 -5
- package/templates/common/.oxfmtrc.json +10 -0
- package/templates/common/.oxlintrc.json +54 -0
- package/templates/http/package.jsonc +14 -7
- package/templates/http/src/main.ts +21 -22
- package/templates/wf/src/workflow/wf2html.interceptor.ts +34 -54
- package/templates/ws/README.md +74 -0
- package/templates/ws/package.jsonc +33 -0
- package/templates/ws/rolldown.config.ts +14 -0
- package/templates/ws/src/main.ts +34 -0
- package/templates/ws-addon/src/controllers/ws.controller.ts +43 -0
- package/templates/common/.domelintrc.yml +0 -14
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ To create a Moost HTTP app, use the following command in your terminal:
|
|
|
21
21
|
npm create moost -- --http
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
This command will initiate the creation of a new Moost HTTP app. It will prompt you
|
|
24
|
+
This command will initiate the creation of a new Moost HTTP app. It will prompt you to configure the project name, whether to include a Moost Workflows example, and whether to add do-me-lint (smart eslint installer).
|
|
25
25
|
|
|
26
26
|
### Creating a CLI App
|
|
27
27
|
|
|
@@ -31,6 +31,6 @@ To create a Moost CLI app, use the following command in your terminal:
|
|
|
31
31
|
npm create moost -- --cli
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
This command will start the creation process for a new Moost CLI app. It will
|
|
34
|
+
This command will start the creation process for a new Moost CLI app. It will prompt you to configure the project name and whether to add do-me-lint (smart eslint installer).
|
|
35
35
|
|
|
36
36
|
## [Official Documentation](https://moost.org/)
|
package/dist/index.cjs
CHANGED
|
@@ -63,24 +63,35 @@ async function getPrompts(inputs) {
|
|
|
63
63
|
{
|
|
64
64
|
name: "type",
|
|
65
65
|
type: () => {
|
|
66
|
-
if (inputs.cli && !inputs.http) {
|
|
66
|
+
if (inputs.ws && !inputs.cli && !inputs.http) {
|
|
67
|
+
predefined.type = "ws";
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
if (inputs.cli && !inputs.http && !inputs.ws) {
|
|
67
71
|
predefined.type = "cli";
|
|
68
72
|
return null;
|
|
69
73
|
}
|
|
70
|
-
if (!inputs.cli && inputs.
|
|
74
|
+
if (inputs.http && !inputs.cli && !inputs.ws) {
|
|
71
75
|
predefined.type = "http";
|
|
72
76
|
return null;
|
|
73
77
|
}
|
|
74
78
|
return "select";
|
|
75
79
|
},
|
|
76
80
|
message: "Moost Adapter:",
|
|
77
|
-
choices: [
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
choices: [
|
|
82
|
+
{
|
|
83
|
+
title: "HTTP (Web) Application",
|
|
84
|
+
value: "http"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
title: "WebSocket Application",
|
|
88
|
+
value: "ws"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
title: "CLI Application",
|
|
92
|
+
value: "cli"
|
|
93
|
+
}
|
|
94
|
+
]
|
|
84
95
|
},
|
|
85
96
|
{
|
|
86
97
|
name: "packageName",
|
|
@@ -89,18 +100,34 @@ async function getPrompts(inputs) {
|
|
|
89
100
|
initial: () => toValidPackageName(predefined.targetDir),
|
|
90
101
|
validate: (dir) => isValidPackageName(dir) || "Invalid package.json name"
|
|
91
102
|
},
|
|
103
|
+
{
|
|
104
|
+
name: "ws",
|
|
105
|
+
type: (prev, values) => {
|
|
106
|
+
const type = values.type || predefined.type;
|
|
107
|
+
if (type !== "http" || inputs.ws) return null;
|
|
108
|
+
return "toggle";
|
|
109
|
+
},
|
|
110
|
+
message: "Add WebSockets?",
|
|
111
|
+
initial: false,
|
|
112
|
+
active: "Yes",
|
|
113
|
+
inactive: "No"
|
|
114
|
+
},
|
|
92
115
|
{
|
|
93
116
|
name: "wf",
|
|
94
|
-
type: (prev, values) =>
|
|
117
|
+
type: (prev, values) => {
|
|
118
|
+
const type = values.type || predefined.type;
|
|
119
|
+
if (inputs.wf || type === "cli" || type === "ws") return null;
|
|
120
|
+
return "toggle";
|
|
121
|
+
},
|
|
95
122
|
message: "Add Moost Workflows Example?",
|
|
96
123
|
initial: false,
|
|
97
124
|
active: "Yes",
|
|
98
125
|
inactive: "No"
|
|
99
126
|
},
|
|
100
127
|
{
|
|
101
|
-
name: "
|
|
102
|
-
type: () => inputs.
|
|
103
|
-
message: "Add
|
|
128
|
+
name: "oxc",
|
|
129
|
+
type: () => inputs.oxc ? null : "toggle",
|
|
130
|
+
message: "Add OXC lint and formatter (oxlint + oxfmt)?",
|
|
104
131
|
initial: false,
|
|
105
132
|
active: "Yes",
|
|
106
133
|
inactive: "No"
|
|
@@ -129,7 +156,7 @@ function isValidPackageName(projectName) {
|
|
|
129
156
|
return /^(?:@[\d*a-z~-][\d*._a-z~-]*\/)?[\da-z~-][\d._a-z~-]*$/.test(projectName);
|
|
130
157
|
}
|
|
131
158
|
function toValidPackageName(projectName) {
|
|
132
|
-
return projectName.trim().toLowerCase().
|
|
159
|
+
return projectName.trim().toLowerCase().replaceAll(/\s+/g, "-").replace(/^[._]/, "").replaceAll(/[^\da-z~-]+/g, "-");
|
|
133
160
|
}
|
|
134
161
|
|
|
135
162
|
//#endregion
|
|
@@ -139,9 +166,8 @@ const rw = new __prostojs_rewrite.ProstoRewrite({ textPattern: [
|
|
|
139
166
|
"Dockerfile",
|
|
140
167
|
"*config",
|
|
141
168
|
".gitignore",
|
|
142
|
-
".
|
|
143
|
-
".
|
|
144
|
-
".prettierrc"
|
|
169
|
+
".oxlintrc.json",
|
|
170
|
+
".oxfmtrc.json"
|
|
145
171
|
] });
|
|
146
172
|
const root = process.cwd();
|
|
147
173
|
const { version } = JSON.parse((0, fs.readFileSync)((0, path.join)(__dirname, "../package.json")).toString());
|
|
@@ -150,39 +176,43 @@ async function scaffold(data) {
|
|
|
150
176
|
if ((0, fs.existsSync)(projectDir)) {
|
|
151
177
|
if (data.overwrite) emptyDirectorySync(projectDir);
|
|
152
178
|
} else (0, fs.mkdirSync)(projectDir);
|
|
153
|
-
const templatePath = (0, path.join)(__dirname, "../templates", data.type);
|
|
179
|
+
const templatePath = (0, path.join)(__dirname, "../templates", data.type === "ws" ? "ws" : data.type);
|
|
154
180
|
const commonPath = (0, path.join)(__dirname, "../templates/common");
|
|
155
181
|
const wfPath = (0, path.join)(__dirname, "../templates/wf");
|
|
182
|
+
const wsAddonPath = (0, path.join)(__dirname, "../templates/ws-addon");
|
|
156
183
|
const context = {
|
|
157
184
|
...data,
|
|
158
185
|
version
|
|
159
186
|
};
|
|
160
187
|
const excludeCommon = [];
|
|
161
|
-
if (!data.
|
|
188
|
+
if (!data.oxc) {
|
|
189
|
+
excludeCommon.push(".oxlintrc.json");
|
|
190
|
+
excludeCommon.push(".oxfmtrc.json");
|
|
191
|
+
}
|
|
192
|
+
const renameFile = (filename) => {
|
|
193
|
+
if (filename.endsWith(".jsonc")) return filename.replace(/c$/, "");
|
|
194
|
+
return filename;
|
|
195
|
+
};
|
|
162
196
|
await rw.rewriteDir({
|
|
163
197
|
baseDir: templatePath,
|
|
164
198
|
output: projectDir,
|
|
165
|
-
renameFile
|
|
166
|
-
if (filename.endsWith(".jsonc")) return filename.replace(/c$/, "");
|
|
167
|
-
return filename;
|
|
168
|
-
}
|
|
199
|
+
renameFile
|
|
169
200
|
}, context);
|
|
170
201
|
await rw.rewriteDir({
|
|
171
202
|
baseDir: commonPath,
|
|
172
203
|
output: projectDir,
|
|
173
204
|
exclude: excludeCommon,
|
|
174
|
-
renameFile
|
|
175
|
-
if (filename.endsWith(".jsonc")) return filename.replace(/c$/, "");
|
|
176
|
-
return filename;
|
|
177
|
-
}
|
|
205
|
+
renameFile
|
|
178
206
|
}, context);
|
|
179
|
-
if (data.wf) await rw.rewriteDir({
|
|
207
|
+
if (data.wf && data.type === "http") await rw.rewriteDir({
|
|
180
208
|
baseDir: wfPath,
|
|
181
209
|
output: projectDir,
|
|
182
|
-
renameFile
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
210
|
+
renameFile
|
|
211
|
+
}, context);
|
|
212
|
+
if (data.ws && data.type === "http") await rw.rewriteDir({
|
|
213
|
+
baseDir: wsAddonPath,
|
|
214
|
+
output: projectDir,
|
|
215
|
+
renameFile
|
|
186
216
|
}, context);
|
|
187
217
|
}
|
|
188
218
|
function emptyDirectorySync(directory) {
|
|
@@ -219,18 +249,20 @@ let Commands = class Commands$1 extends __moostjs_event_cli.CliApp {
|
|
|
219
249
|
return this.execute(name);
|
|
220
250
|
}
|
|
221
251
|
async execute(name) {
|
|
222
|
-
(0, __wooksjs_event_cli.useAutoHelp)()
|
|
252
|
+
if ((0, __wooksjs_event_cli.useAutoHelp)()) process.exit(0);
|
|
223
253
|
const prompts$2 = await getPrompts({
|
|
224
254
|
name,
|
|
225
255
|
http: !!(0, __wooksjs_event_cli.useCliOption)("http"),
|
|
226
256
|
cli: !!(0, __wooksjs_event_cli.useCliOption)("cli"),
|
|
257
|
+
ws: !!(0, __wooksjs_event_cli.useCliOption)("ws"),
|
|
227
258
|
wf: !!(0, __wooksjs_event_cli.useCliOption)("wf"),
|
|
228
|
-
|
|
259
|
+
oxc: !!(0, __wooksjs_event_cli.useCliOption)("oxc"),
|
|
229
260
|
force: !!(0, __wooksjs_event_cli.useCliOption)("force")
|
|
230
261
|
});
|
|
231
262
|
console.log("\nScaffolding a new project...");
|
|
232
263
|
await scaffold(prompts$2);
|
|
233
264
|
const cli = prompts$2.type === "cli";
|
|
265
|
+
const ws = prompts$2.type === "ws";
|
|
234
266
|
return `
|
|
235
267
|
[97m[1mSuccess! [22mYour new "${prompts$2.projectName}" project has been created successfully. [39m
|
|
236
268
|
|
|
@@ -245,10 +277,10 @@ ${cli ? `
|
|
|
245
277
|
3. Make bin.js executable:
|
|
246
278
|
[36mchmod +x ./bin.js [39m
|
|
247
279
|
` : ""}
|
|
248
|
-
${cli ? "4" : "3"}. Start the development server:
|
|
280
|
+
${cli ? "4" : "3"}. ${ws ? "Build and start" : "Start the development server"}:
|
|
249
281
|
[36mnpm run dev${cli ? " -- hello World" : ""}[39m
|
|
250
282
|
|
|
251
|
-
[32mYou're all set
|
|
283
|
+
[32mYou're all set!${ws ? "" : " The development server will help you in building your application."}
|
|
252
284
|
Enjoy coding, and build something amazing![39m
|
|
253
285
|
`;
|
|
254
286
|
}
|
|
@@ -278,14 +310,19 @@ function run() {
|
|
|
278
310
|
description: "Use Moost CLI",
|
|
279
311
|
type: Boolean
|
|
280
312
|
},
|
|
313
|
+
{
|
|
314
|
+
keys: ["ws"],
|
|
315
|
+
description: "Use Moost WebSocket",
|
|
316
|
+
type: Boolean
|
|
317
|
+
},
|
|
281
318
|
{
|
|
282
319
|
keys: ["wf"],
|
|
283
320
|
description: "Add Workflow Adapter",
|
|
284
321
|
type: Boolean
|
|
285
322
|
},
|
|
286
323
|
{
|
|
287
|
-
keys: ["
|
|
288
|
-
description: "Add
|
|
324
|
+
keys: ["oxc"],
|
|
325
|
+
description: "Add OXC lint and formatter (oxlint + oxfmt)",
|
|
289
326
|
type: Boolean
|
|
290
327
|
},
|
|
291
328
|
{
|
package/dist/index.mjs
CHANGED
|
@@ -40,24 +40,35 @@ async function getPrompts(inputs) {
|
|
|
40
40
|
{
|
|
41
41
|
name: "type",
|
|
42
42
|
type: () => {
|
|
43
|
-
if (inputs.cli && !inputs.http) {
|
|
43
|
+
if (inputs.ws && !inputs.cli && !inputs.http) {
|
|
44
|
+
predefined.type = "ws";
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
if (inputs.cli && !inputs.http && !inputs.ws) {
|
|
44
48
|
predefined.type = "cli";
|
|
45
49
|
return null;
|
|
46
50
|
}
|
|
47
|
-
if (!inputs.cli && inputs.
|
|
51
|
+
if (inputs.http && !inputs.cli && !inputs.ws) {
|
|
48
52
|
predefined.type = "http";
|
|
49
53
|
return null;
|
|
50
54
|
}
|
|
51
55
|
return "select";
|
|
52
56
|
},
|
|
53
57
|
message: "Moost Adapter:",
|
|
54
|
-
choices: [
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
choices: [
|
|
59
|
+
{
|
|
60
|
+
title: "HTTP (Web) Application",
|
|
61
|
+
value: "http"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
title: "WebSocket Application",
|
|
65
|
+
value: "ws"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
title: "CLI Application",
|
|
69
|
+
value: "cli"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
61
72
|
},
|
|
62
73
|
{
|
|
63
74
|
name: "packageName",
|
|
@@ -66,18 +77,34 @@ async function getPrompts(inputs) {
|
|
|
66
77
|
initial: () => toValidPackageName(predefined.targetDir),
|
|
67
78
|
validate: (dir) => isValidPackageName(dir) || "Invalid package.json name"
|
|
68
79
|
},
|
|
80
|
+
{
|
|
81
|
+
name: "ws",
|
|
82
|
+
type: (prev, values) => {
|
|
83
|
+
const type = values.type || predefined.type;
|
|
84
|
+
if (type !== "http" || inputs.ws) return null;
|
|
85
|
+
return "toggle";
|
|
86
|
+
},
|
|
87
|
+
message: "Add WebSockets?",
|
|
88
|
+
initial: false,
|
|
89
|
+
active: "Yes",
|
|
90
|
+
inactive: "No"
|
|
91
|
+
},
|
|
69
92
|
{
|
|
70
93
|
name: "wf",
|
|
71
|
-
type: (prev, values) =>
|
|
94
|
+
type: (prev, values) => {
|
|
95
|
+
const type = values.type || predefined.type;
|
|
96
|
+
if (inputs.wf || type === "cli" || type === "ws") return null;
|
|
97
|
+
return "toggle";
|
|
98
|
+
},
|
|
72
99
|
message: "Add Moost Workflows Example?",
|
|
73
100
|
initial: false,
|
|
74
101
|
active: "Yes",
|
|
75
102
|
inactive: "No"
|
|
76
103
|
},
|
|
77
104
|
{
|
|
78
|
-
name: "
|
|
79
|
-
type: () => inputs.
|
|
80
|
-
message: "Add
|
|
105
|
+
name: "oxc",
|
|
106
|
+
type: () => inputs.oxc ? null : "toggle",
|
|
107
|
+
message: "Add OXC lint and formatter (oxlint + oxfmt)?",
|
|
81
108
|
initial: false,
|
|
82
109
|
active: "Yes",
|
|
83
110
|
inactive: "No"
|
|
@@ -106,7 +133,7 @@ function isValidPackageName(projectName) {
|
|
|
106
133
|
return /^(?:@[\d*a-z~-][\d*._a-z~-]*\/)?[\da-z~-][\d._a-z~-]*$/.test(projectName);
|
|
107
134
|
}
|
|
108
135
|
function toValidPackageName(projectName) {
|
|
109
|
-
return projectName.trim().toLowerCase().
|
|
136
|
+
return projectName.trim().toLowerCase().replaceAll(/\s+/g, "-").replace(/^[._]/, "").replaceAll(/[^\da-z~-]+/g, "-");
|
|
110
137
|
}
|
|
111
138
|
|
|
112
139
|
//#endregion
|
|
@@ -116,9 +143,8 @@ const rw = new ProstoRewrite({ textPattern: [
|
|
|
116
143
|
"Dockerfile",
|
|
117
144
|
"*config",
|
|
118
145
|
".gitignore",
|
|
119
|
-
".
|
|
120
|
-
".
|
|
121
|
-
".prettierrc"
|
|
146
|
+
".oxlintrc.json",
|
|
147
|
+
".oxfmtrc.json"
|
|
122
148
|
] });
|
|
123
149
|
const root = process.cwd();
|
|
124
150
|
const { version } = JSON.parse(readFileSync(join(__dirname, "../package.json")).toString());
|
|
@@ -127,39 +153,43 @@ async function scaffold(data) {
|
|
|
127
153
|
if (existsSync(projectDir)) {
|
|
128
154
|
if (data.overwrite) emptyDirectorySync(projectDir);
|
|
129
155
|
} else mkdirSync(projectDir);
|
|
130
|
-
const templatePath = join(__dirname, "../templates", data.type);
|
|
156
|
+
const templatePath = join(__dirname, "../templates", data.type === "ws" ? "ws" : data.type);
|
|
131
157
|
const commonPath = join(__dirname, "../templates/common");
|
|
132
158
|
const wfPath = join(__dirname, "../templates/wf");
|
|
159
|
+
const wsAddonPath = join(__dirname, "../templates/ws-addon");
|
|
133
160
|
const context = {
|
|
134
161
|
...data,
|
|
135
162
|
version
|
|
136
163
|
};
|
|
137
164
|
const excludeCommon = [];
|
|
138
|
-
if (!data.
|
|
165
|
+
if (!data.oxc) {
|
|
166
|
+
excludeCommon.push(".oxlintrc.json");
|
|
167
|
+
excludeCommon.push(".oxfmtrc.json");
|
|
168
|
+
}
|
|
169
|
+
const renameFile = (filename) => {
|
|
170
|
+
if (filename.endsWith(".jsonc")) return filename.replace(/c$/, "");
|
|
171
|
+
return filename;
|
|
172
|
+
};
|
|
139
173
|
await rw.rewriteDir({
|
|
140
174
|
baseDir: templatePath,
|
|
141
175
|
output: projectDir,
|
|
142
|
-
renameFile
|
|
143
|
-
if (filename.endsWith(".jsonc")) return filename.replace(/c$/, "");
|
|
144
|
-
return filename;
|
|
145
|
-
}
|
|
176
|
+
renameFile
|
|
146
177
|
}, context);
|
|
147
178
|
await rw.rewriteDir({
|
|
148
179
|
baseDir: commonPath,
|
|
149
180
|
output: projectDir,
|
|
150
181
|
exclude: excludeCommon,
|
|
151
|
-
renameFile
|
|
152
|
-
if (filename.endsWith(".jsonc")) return filename.replace(/c$/, "");
|
|
153
|
-
return filename;
|
|
154
|
-
}
|
|
182
|
+
renameFile
|
|
155
183
|
}, context);
|
|
156
|
-
if (data.wf) await rw.rewriteDir({
|
|
184
|
+
if (data.wf && data.type === "http") await rw.rewriteDir({
|
|
157
185
|
baseDir: wfPath,
|
|
158
186
|
output: projectDir,
|
|
159
|
-
renameFile
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
187
|
+
renameFile
|
|
188
|
+
}, context);
|
|
189
|
+
if (data.ws && data.type === "http") await rw.rewriteDir({
|
|
190
|
+
baseDir: wsAddonPath,
|
|
191
|
+
output: projectDir,
|
|
192
|
+
renameFile
|
|
163
193
|
}, context);
|
|
164
194
|
}
|
|
165
195
|
function emptyDirectorySync(directory) {
|
|
@@ -196,18 +226,20 @@ let Commands = class Commands$1 extends CliApp {
|
|
|
196
226
|
return this.execute(name);
|
|
197
227
|
}
|
|
198
228
|
async execute(name) {
|
|
199
|
-
useAutoHelp()
|
|
229
|
+
if (useAutoHelp()) process.exit(0);
|
|
200
230
|
const prompts$1 = await getPrompts({
|
|
201
231
|
name,
|
|
202
232
|
http: !!useCliOption("http"),
|
|
203
233
|
cli: !!useCliOption("cli"),
|
|
234
|
+
ws: !!useCliOption("ws"),
|
|
204
235
|
wf: !!useCliOption("wf"),
|
|
205
|
-
|
|
236
|
+
oxc: !!useCliOption("oxc"),
|
|
206
237
|
force: !!useCliOption("force")
|
|
207
238
|
});
|
|
208
239
|
console.log("\nScaffolding a new project...");
|
|
209
240
|
await scaffold(prompts$1);
|
|
210
241
|
const cli = prompts$1.type === "cli";
|
|
242
|
+
const ws = prompts$1.type === "ws";
|
|
211
243
|
return `
|
|
212
244
|
[97m[1mSuccess! [22mYour new "${prompts$1.projectName}" project has been created successfully. [39m
|
|
213
245
|
|
|
@@ -222,10 +254,10 @@ ${cli ? `
|
|
|
222
254
|
3. Make bin.js executable:
|
|
223
255
|
[36mchmod +x ./bin.js [39m
|
|
224
256
|
` : ""}
|
|
225
|
-
${cli ? "4" : "3"}. Start the development server:
|
|
257
|
+
${cli ? "4" : "3"}. ${ws ? "Build and start" : "Start the development server"}:
|
|
226
258
|
[36mnpm run dev${cli ? " -- hello World" : ""}[39m
|
|
227
259
|
|
|
228
|
-
[32mYou're all set
|
|
260
|
+
[32mYou're all set!${ws ? "" : " The development server will help you in building your application."}
|
|
229
261
|
Enjoy coding, and build something amazing![39m
|
|
230
262
|
`;
|
|
231
263
|
}
|
|
@@ -255,14 +287,19 @@ function run() {
|
|
|
255
287
|
description: "Use Moost CLI",
|
|
256
288
|
type: Boolean
|
|
257
289
|
},
|
|
290
|
+
{
|
|
291
|
+
keys: ["ws"],
|
|
292
|
+
description: "Use Moost WebSocket",
|
|
293
|
+
type: Boolean
|
|
294
|
+
},
|
|
258
295
|
{
|
|
259
296
|
keys: ["wf"],
|
|
260
297
|
description: "Add Workflow Adapter",
|
|
261
298
|
type: Boolean
|
|
262
299
|
},
|
|
263
300
|
{
|
|
264
|
-
keys: ["
|
|
265
|
-
description: "Add
|
|
301
|
+
keys: ["oxc"],
|
|
302
|
+
description: "Add OXC lint and formatter (oxlint + oxfmt)",
|
|
266
303
|
type: Boolean
|
|
267
304
|
},
|
|
268
305
|
{
|
package/package.json
CHANGED
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-moost",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "create-moost",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"composables",
|
|
7
|
+
"framework",
|
|
8
|
+
"moost",
|
|
9
|
+
"moostjs",
|
|
10
|
+
"prostojs",
|
|
11
|
+
"wooksjs"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/moostjs/moostjs/tree/main/packages/create-moost#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/moostjs/moostjs/issues"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "Artem Maltsev",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/moostjs/moostjs.git",
|
|
22
|
+
"directory": "packages/create-moost"
|
|
23
|
+
},
|
|
24
|
+
"bin": {
|
|
25
|
+
"create-moost": "./bin.cjs"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"templates",
|
|
30
|
+
"bin.js"
|
|
31
|
+
],
|
|
32
|
+
"type": "module",
|
|
33
|
+
"sideEffects": false,
|
|
5
34
|
"main": "dist/index.cjs",
|
|
6
35
|
"module": "dist/index.mjs",
|
|
7
36
|
"types": "dist/index.d.ts",
|
|
8
|
-
"sideEffects": false,
|
|
9
|
-
"type": "module",
|
|
10
37
|
"exports": {
|
|
11
38
|
"./package.json": "./package.json",
|
|
12
39
|
".": {
|
|
@@ -15,47 +42,20 @@
|
|
|
15
42
|
"require": "./dist/index.cjs"
|
|
16
43
|
}
|
|
17
44
|
},
|
|
18
|
-
"bin": {
|
|
19
|
-
"create-moost": "./bin.cjs"
|
|
20
|
-
},
|
|
21
|
-
"files": [
|
|
22
|
-
"dist",
|
|
23
|
-
"templates",
|
|
24
|
-
"bin.js"
|
|
25
|
-
],
|
|
26
|
-
"repository": {
|
|
27
|
-
"type": "git",
|
|
28
|
-
"url": "git+https://github.com/moostjs/moostjs.git",
|
|
29
|
-
"directory": "packages/create-moost"
|
|
30
|
-
},
|
|
31
|
-
"keywords": [
|
|
32
|
-
"moost",
|
|
33
|
-
"moostjs",
|
|
34
|
-
"composables",
|
|
35
|
-
"framework",
|
|
36
|
-
"wooksjs",
|
|
37
|
-
"prostojs"
|
|
38
|
-
],
|
|
39
|
-
"author": "Artem Maltsev",
|
|
40
|
-
"license": "MIT",
|
|
41
|
-
"bugs": {
|
|
42
|
-
"url": "https://github.com/moostjs/moostjs/issues"
|
|
43
|
-
},
|
|
44
|
-
"homepage": "https://github.com/moostjs/moostjs/tree/main/packages/create-moost#readme",
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@prostojs/rewrite": "^0.1.1",
|
|
47
|
-
"@wooksjs/event-cli": "^0.
|
|
47
|
+
"@wooksjs/event-cli": "^0.7.3",
|
|
48
48
|
"prompts": "^2.4.2",
|
|
49
|
-
"@moostjs/event-cli": "^0.
|
|
50
|
-
"moost": "^0.
|
|
49
|
+
"@moostjs/event-cli": "^0.6.0",
|
|
50
|
+
"moost": "^0.6.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/prompts": "^2.4.9",
|
|
54
54
|
"rolldown": "1.0.0-beta.19",
|
|
55
|
-
"unplugin-swc": "^1.5.
|
|
56
|
-
"vite": "^6.1
|
|
55
|
+
"unplugin-swc": "^1.5.9",
|
|
56
|
+
"vite": "^6.4.1",
|
|
57
57
|
"vitest": "3.2.4",
|
|
58
|
-
"@moostjs/vite": "^0.
|
|
58
|
+
"@moostjs/vite": "^0.6.0"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"pub": "pnpm publish --access public",
|
|
@@ -12,11 +12,13 @@
|
|
|
12
12
|
"bin.js"
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
|
-
//=IF (domelint)
|
|
16
|
-
"postinstall": "npx do-me-lint",
|
|
17
|
-
//=END IF
|
|
18
15
|
"dev": "pnpm build && node ./dist/main.js",
|
|
19
16
|
"build": "rolldown build -c rolldown.config.ts",
|
|
17
|
+
//=IF (oxc)
|
|
18
|
+
"lint": "oxlint",
|
|
19
|
+
"format": "oxfmt .",
|
|
20
|
+
"format:check": "oxfmt --check .",
|
|
21
|
+
//=END IF
|
|
20
22
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
21
23
|
},
|
|
22
24
|
"keywords": [],
|
|
@@ -26,8 +28,12 @@
|
|
|
26
28
|
"@moostjs/event-cli": "^{{ version }}"
|
|
27
29
|
},
|
|
28
30
|
"devDependencies": {
|
|
31
|
+
//=IF (oxc)
|
|
32
|
+
"oxlint": "^1.49.0",
|
|
33
|
+
"oxfmt": "^0.34.0",
|
|
34
|
+
//=END IF
|
|
29
35
|
"typescript": "^5.7.2",
|
|
30
|
-
"unplugin-swc": "^1.5.
|
|
31
|
-
"rolldown": "1.0.0-beta.
|
|
36
|
+
"unplugin-swc": "^1.5.9",
|
|
37
|
+
"rolldown": "1.0.0-beta.19"
|
|
32
38
|
}
|
|
33
39
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
|
3
|
+
"plugins": ["import", "typescript"],
|
|
4
|
+
"env": {
|
|
5
|
+
"es2021": true,
|
|
6
|
+
"node": true
|
|
7
|
+
},
|
|
8
|
+
"categories": {
|
|
9
|
+
"correctness": "error",
|
|
10
|
+
"suspicious": "warn"
|
|
11
|
+
},
|
|
12
|
+
"ignorePatterns": ["node_modules", "dist"],
|
|
13
|
+
"rules": {
|
|
14
|
+
"no-unused-vars": "off",
|
|
15
|
+
"no-use-before-define": "off",
|
|
16
|
+
"no-inline-comments": "off",
|
|
17
|
+
"no-warning-comments": "off",
|
|
18
|
+
"no-negated-condition": "off",
|
|
19
|
+
"no-shadow": "off",
|
|
20
|
+
|
|
21
|
+
"eqeqeq": "error",
|
|
22
|
+
"prefer-const": "error",
|
|
23
|
+
"prefer-template": "error",
|
|
24
|
+
"no-var": "error",
|
|
25
|
+
"curly": "error",
|
|
26
|
+
"no-self-compare": "error",
|
|
27
|
+
"no-template-curly-in-string": "error",
|
|
28
|
+
"array-callback-return": "error",
|
|
29
|
+
|
|
30
|
+
"import/first": "error",
|
|
31
|
+
"import/no-duplicates": "error",
|
|
32
|
+
"import/no-self-import": "error",
|
|
33
|
+
"import/no-default-export": "error",
|
|
34
|
+
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
|
35
|
+
|
|
36
|
+
"typescript/consistent-type-imports": "error",
|
|
37
|
+
"typescript/no-extraneous-class": "off",
|
|
38
|
+
"typescript/no-explicit-any": "warn",
|
|
39
|
+
"typescript/no-non-null-assertion": "warn",
|
|
40
|
+
|
|
41
|
+
"max-params": ["warn", { "max": 4 }],
|
|
42
|
+
"complexity": "off",
|
|
43
|
+
"max-lines-per-function": "off",
|
|
44
|
+
"max-statements": "off"
|
|
45
|
+
},
|
|
46
|
+
"overrides": [
|
|
47
|
+
{
|
|
48
|
+
"files": ["**/*.config.*"],
|
|
49
|
+
"rules": {
|
|
50
|
+
"import/no-default-export": "off"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
@@ -5,31 +5,38 @@
|
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
|
-
//=IF (domelint)
|
|
9
|
-
"postinstall": "npx do-me-lint",
|
|
10
|
-
//=END IF
|
|
11
8
|
"dev": "vite dev",
|
|
12
9
|
"build": "vite build",
|
|
10
|
+
//=IF (oxc)
|
|
11
|
+
"lint": "oxlint",
|
|
12
|
+
"format": "oxfmt .",
|
|
13
|
+
"format:check": "oxfmt --check .",
|
|
14
|
+
//=END IF
|
|
13
15
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
14
16
|
},
|
|
15
17
|
"keywords": [],
|
|
16
18
|
"author": "",
|
|
17
19
|
"license": "ISC",
|
|
18
20
|
"dependencies": {
|
|
19
|
-
//=IF (type === 'http')
|
|
20
21
|
"@moostjs/event-http": "^{{ version }}",
|
|
22
|
+
//=IF (ws)
|
|
23
|
+
"@moostjs/event-ws": "^{{ version }}",
|
|
21
24
|
//=END IF
|
|
22
25
|
//=IF (wf)
|
|
23
26
|
"@moostjs/event-wf": "^{{ version }}",
|
|
24
|
-
"@wooksjs/http-static": "^0.
|
|
27
|
+
"@wooksjs/http-static": "^0.7.3",
|
|
25
28
|
//=END IF
|
|
26
29
|
"moost": "^{{ version }}"
|
|
27
30
|
},
|
|
28
31
|
"devDependencies": {
|
|
29
32
|
"@moostjs/vite": "^{{ version }}",
|
|
30
33
|
"@types/node": "^22.10.2",
|
|
34
|
+
//=IF (oxc)
|
|
35
|
+
"oxlint": "^1.49.0",
|
|
36
|
+
"oxfmt": "^0.34.0",
|
|
37
|
+
//=END IF
|
|
31
38
|
"typescript": "^5.7.2",
|
|
32
|
-
"unplugin-swc": "^1.5.
|
|
33
|
-
"vite": "^
|
|
39
|
+
"unplugin-swc": "^1.5.9",
|
|
40
|
+
"vite": "^7.0.0"
|
|
34
41
|
}
|
|
35
42
|
}
|
|
@@ -1,49 +1,48 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Main Entry Point for Moost Application Template
|
|
3
|
-
*
|
|
4
|
-
* This file serves as the primary entry point for the Moost application.
|
|
5
|
-
*
|
|
6
|
-
* For more details on Moost Webapp and Moost Workflows, visit:
|
|
7
|
-
* - Moost Webapp: https://moost.org/webapp/
|
|
8
|
-
* - Moost Workflows: https://moost.org/wf/
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
1
|
import { MoostHttp } from "@moostjs/event-http";
|
|
2
|
+
//=IF (ws)
|
|
3
|
+
import { MoostWs } from "@moostjs/event-ws";
|
|
4
|
+
//=END IF
|
|
12
5
|
//=IF (wf)
|
|
13
6
|
import { MoostWf } from "@moostjs/event-wf";
|
|
14
7
|
//=END IF
|
|
15
8
|
import { Moost } from "moost";
|
|
16
9
|
|
|
17
10
|
import { AppController } from "./controllers/app.controller";
|
|
11
|
+
//=IF (ws)
|
|
12
|
+
import { WsController } from "./controllers/ws.controller";
|
|
13
|
+
//=END IF
|
|
18
14
|
//=IF (wf)
|
|
19
15
|
import { WfController } from "./workflow/wf.controller";
|
|
20
16
|
//=END IF
|
|
21
17
|
|
|
22
|
-
/**
|
|
23
|
-
* Initializes and configures the Moost application.
|
|
24
|
-
*
|
|
25
|
-
* The application performs the following steps:
|
|
26
|
-
* 1. Creates a new instance of the Moost application.
|
|
27
|
-
* 2. Sets up the moost adapters.
|
|
28
|
-
* 3. Registers controllers.
|
|
29
|
-
* 4. Initializes the application to start handling incoming events.
|
|
30
|
-
*/
|
|
31
18
|
const app = new Moost();
|
|
32
19
|
|
|
33
20
|
// Configure the HTTP adapter and start listening on port 3000
|
|
34
|
-
|
|
21
|
+
const http = new MoostHttp();
|
|
22
|
+
app.adapter(http).listen(3000, () => {
|
|
35
23
|
app.getLogger("[{{ projectName }}]").info("Server started on port 3000");
|
|
36
24
|
});
|
|
37
25
|
|
|
26
|
+
//=IF (ws)
|
|
27
|
+
// Configure the WebSocket adapter integrated with the HTTP server
|
|
28
|
+
app.adapter(new MoostWs({ httpApp: http }));
|
|
29
|
+
//=END IF
|
|
30
|
+
|
|
38
31
|
//=IF (wf)
|
|
39
32
|
// Configure the Workflow adapter to handle workflow-related events
|
|
40
33
|
app.adapter(new MoostWf());
|
|
41
34
|
//=END IF
|
|
42
35
|
|
|
43
36
|
// Register application controllers
|
|
44
|
-
//=IF (wf)
|
|
37
|
+
//=IF (wf && ws)
|
|
38
|
+
app.registerControllers(AppController, WsController, WfController).init();
|
|
39
|
+
//=END IF
|
|
40
|
+
//=IF (wf && !ws)
|
|
45
41
|
app.registerControllers(AppController, WfController).init();
|
|
46
42
|
//=END IF
|
|
47
|
-
//=IF (!wf)
|
|
43
|
+
//=IF (!wf && ws)
|
|
44
|
+
app.registerControllers(AppController, WsController).init();
|
|
45
|
+
//=END IF
|
|
46
|
+
//=IF (!wf && !ws)
|
|
48
47
|
app.registerControllers(AppController).init();
|
|
49
48
|
//=END IF
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
|
|
21
21
|
import { Body } from "@moostjs/event-http";
|
|
22
22
|
import type { TFlowOutput } from "@moostjs/event-wf";
|
|
23
|
-
import type {
|
|
24
|
-
import {
|
|
23
|
+
import type { TOvertakeFn } from "moost";
|
|
24
|
+
import { After, Before, Intercept, Interceptor, Overtake, Response } from "moost";
|
|
25
25
|
|
|
26
26
|
import { decryptState, encryptState } from "./wf.encrypt";
|
|
27
27
|
import type {
|
|
@@ -38,65 +38,45 @@ import type {
|
|
|
38
38
|
* This interceptor handles the encryption and decryption of the workflow state to ensure
|
|
39
39
|
* secure transmission between the backend and frontend.
|
|
40
40
|
*/
|
|
41
|
-
@
|
|
42
|
-
class Wf2HtmlPageInterceptor
|
|
43
|
-
/**
|
|
44
|
-
* The input payload containing user inputs and the workflow state.
|
|
45
|
-
*
|
|
46
|
-
* @type {TWfExampleInput & { wfState: string | TWfState | undefined }}
|
|
47
|
-
*/
|
|
41
|
+
@Interceptor(undefined, "FOR_EVENT")
|
|
42
|
+
class Wf2HtmlPageInterceptor {
|
|
48
43
|
@Body()
|
|
49
44
|
input?: TWfExampleInput & { wfState: string | TWfState | undefined };
|
|
50
45
|
|
|
51
46
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* @type {TInterceptorFn}
|
|
47
|
+
* Pre-processing: decrypts the workflow state if it is a string,
|
|
48
|
+
* or clears it if it is not.
|
|
55
49
|
*/
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
*/
|
|
65
|
-
before(() => {
|
|
66
|
-
if (typeof this.input?.wfState === "string") {
|
|
67
|
-
this.input.wfState = decryptState(this.input.wfState);
|
|
68
|
-
} else if (this.input) {
|
|
69
|
-
this.input.wfState = undefined;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
50
|
+
@Before()
|
|
51
|
+
decryptState() {
|
|
52
|
+
if (typeof this.input?.wfState === "string") {
|
|
53
|
+
this.input.wfState = decryptState(this.input.wfState);
|
|
54
|
+
} else if (this.input) {
|
|
55
|
+
this.input.wfState = undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
72
58
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const wfOutput = response as TFlowOutput<
|
|
85
|
-
TWfExampleContext,
|
|
86
|
-
TWfExampleInput,
|
|
87
|
-
TWfExampleInputSchema
|
|
88
|
-
>;
|
|
59
|
+
/**
|
|
60
|
+
* Post-processing: renders an HTML input form or final output page
|
|
61
|
+
* based on the workflow response.
|
|
62
|
+
*/
|
|
63
|
+
@After()
|
|
64
|
+
renderOutput(@Response() response: unknown, @Overtake() reply: TOvertakeFn) {
|
|
65
|
+
const wfOutput = response as TFlowOutput<
|
|
66
|
+
TWfExampleContext,
|
|
67
|
+
TWfExampleInput,
|
|
68
|
+
TWfExampleInputSchema
|
|
69
|
+
>;
|
|
89
70
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
};
|
|
71
|
+
if (wfOutput.inputRequired) {
|
|
72
|
+
reply(
|
|
73
|
+
renderInputPage(wfOutput.inputRequired, encryptState(wfOutput.state))
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
if (wfOutput.finished) {
|
|
77
|
+
reply(renderOutputPage(wfOutput.state.context));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
100
80
|
}
|
|
101
81
|
|
|
102
82
|
/**
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# {{ projectName }}
|
|
2
|
+
|
|
3
|
+
## Moost WebSocket Template
|
|
4
|
+
|
|
5
|
+
This template provides a standalone WebSocket application using Moost WS. It demonstrates how to handle WebSocket connections and messages with decorators.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- Node.js (v18 or later)
|
|
10
|
+
- A package manager like [npm](https://www.npmjs.com/)
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
This template is installed via:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm create moost@latest -- --ws
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
After the setup, navigate into the project folder and install dependencies:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cd {{ packageName }}
|
|
24
|
+
npm install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Running Locally
|
|
28
|
+
|
|
29
|
+
### Development Mode
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm run dev
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This command builds the project and starts the WebSocket server on port 3000.
|
|
36
|
+
|
|
37
|
+
### Build for Production
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm run build
|
|
41
|
+
node ./dist/main.js
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## WebSocket Protocol
|
|
45
|
+
|
|
46
|
+
The server uses a JSON-based message protocol. Send messages in this format:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"event": "message",
|
|
51
|
+
"data": { "text": "Hello!" }
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The server will reply with:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"event": "message",
|
|
60
|
+
"data": { "echo": { "text": "Hello!" } }
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Files Overview
|
|
65
|
+
|
|
66
|
+
- **`src/main.ts`** - Defines WebSocket handlers using decorators.
|
|
67
|
+
- **`rolldown.config.ts`** - Build configuration (including SWC for decorators).
|
|
68
|
+
- **`package.json`** - Contains scripts, dependencies, and configuration.
|
|
69
|
+
|
|
70
|
+
## Customization
|
|
71
|
+
|
|
72
|
+
- **Add New Message Handlers:** Use `@Message(event, path?)` to handle different event types.
|
|
73
|
+
- **Access Connection Info:** Use `@ConnectionId()` to get the connection UUID.
|
|
74
|
+
- **Use Rooms:** Import `useWsRooms()` from `@moostjs/event-ws` for room-based messaging.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{ packageName }}",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/main.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "npm run build && node ./dist/main.js",
|
|
9
|
+
"build": "rolldown build -c rolldown.config.ts",
|
|
10
|
+
//=IF (oxc)
|
|
11
|
+
"lint": "oxlint",
|
|
12
|
+
"format": "oxfmt .",
|
|
13
|
+
"format:check": "oxfmt --check .",
|
|
14
|
+
//=END IF
|
|
15
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [],
|
|
18
|
+
"author": "",
|
|
19
|
+
"license": "ISC",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@moostjs/event-ws": "^{{ version }}",
|
|
22
|
+
"moost": "^{{ version }}"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
//=IF (oxc)
|
|
26
|
+
"oxlint": "^1.49.0",
|
|
27
|
+
"oxfmt": "^0.34.0",
|
|
28
|
+
//=END IF
|
|
29
|
+
"typescript": "^5.7.2",
|
|
30
|
+
"unplugin-swc": "^1.5.9",
|
|
31
|
+
"rolldown": "1.0.0-beta.19"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from 'rolldown'
|
|
2
|
+
import swc from 'unplugin-swc';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
input: 'src/main.ts',
|
|
6
|
+
output: {
|
|
7
|
+
format: 'esm',
|
|
8
|
+
file: 'dist/main.js',
|
|
9
|
+
},
|
|
10
|
+
external: ['@moostjs/event-ws', 'moost'],
|
|
11
|
+
plugins: [
|
|
12
|
+
swc.rolldown(),
|
|
13
|
+
]
|
|
14
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WsApp,
|
|
3
|
+
Connect,
|
|
4
|
+
Disconnect,
|
|
5
|
+
Message,
|
|
6
|
+
MessageData,
|
|
7
|
+
ConnectionId,
|
|
8
|
+
Controller,
|
|
9
|
+
} from '@moostjs/event-ws'
|
|
10
|
+
|
|
11
|
+
@Controller()
|
|
12
|
+
class ChatController {
|
|
13
|
+
@Connect()
|
|
14
|
+
onConnect(@ConnectionId() id: string) {
|
|
15
|
+
console.log(`Client connected: ${id}`)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@Message('message')
|
|
19
|
+
onMessage(@MessageData() data: unknown) {
|
|
20
|
+
return { echo: data }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@Disconnect()
|
|
24
|
+
onDisconnect(@ConnectionId() id: string) {
|
|
25
|
+
console.log(`Client disconnected: ${id}`)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
new WsApp()
|
|
30
|
+
.controllers(ChatController)
|
|
31
|
+
.start(3000)
|
|
32
|
+
.then(() => {
|
|
33
|
+
console.log('WebSocket server started on port 3000')
|
|
34
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Upgrade } from "@moostjs/event-http";
|
|
2
|
+
import {
|
|
3
|
+
Connect,
|
|
4
|
+
ConnectionId,
|
|
5
|
+
Disconnect,
|
|
6
|
+
Message,
|
|
7
|
+
MessageData,
|
|
8
|
+
WooksWs,
|
|
9
|
+
} from "@moostjs/event-ws";
|
|
10
|
+
import { Controller, Param } from "moost";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* `WsController` handles the WebSocket upgrade route
|
|
14
|
+
* and WebSocket message/connection events.
|
|
15
|
+
*
|
|
16
|
+
* The @Upgrade decorator registers an HTTP route that upgrades
|
|
17
|
+
* the connection to WebSocket. Message handlers use the
|
|
18
|
+
* @Message decorator to handle incoming WebSocket messages.
|
|
19
|
+
*/
|
|
20
|
+
@Controller()
|
|
21
|
+
export class WsController {
|
|
22
|
+
constructor(private ws: WooksWs) {}
|
|
23
|
+
|
|
24
|
+
@Upgrade("ws")
|
|
25
|
+
handleUpgrade() {
|
|
26
|
+
return this.ws.upgrade();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Connect()
|
|
30
|
+
onConnect(@ConnectionId() id: string) {
|
|
31
|
+
console.log(`WS client connected: ${id}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@Message("message")
|
|
35
|
+
onMessage(@MessageData() data: unknown) {
|
|
36
|
+
return { echo: data };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Disconnect()
|
|
40
|
+
onDisconnect(@ConnectionId() id: string) {
|
|
41
|
+
console.log(`WS client disconnected: ${id}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
ignoredRules:
|
|
2
|
-
# for Moost controllers: they don't typically use 'this'
|
|
3
|
-
- '@typescript-eslint/class-methods-use-this'
|
|
4
|
-
|
|
5
|
-
# For Moost decorators: it's common to pull url route params from the url
|
|
6
|
-
- max-params
|
|
7
|
-
|
|
8
|
-
# Too strict, hinders readability
|
|
9
|
-
- '@typescript-eslint/strict-boolean-expressions'
|
|
10
|
-
|
|
11
|
-
# Empty class is a valid use case for Moost's controller composition
|
|
12
|
-
- '@typescript-eslint/no-extraneous-class'
|
|
13
|
-
|
|
14
|
-
- '@typescript-eslint/consistent-type-imports'
|