@jpp-toolkit/plugin-build-fivem 0.0.3 → 0.0.5
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/index.d.mts +1 -0
- package/dist/index.mjs +24 -20
- package/dist/index.mjs.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +4 -4
- package/src/fivem-build-command.ts +27 -14
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { createFivemRspackConfig } from "@jpp-toolkit/rspack-config";
|
|
|
4
4
|
import { getErrMsg } from "@jpp-toolkit/utils";
|
|
5
5
|
import { Flags } from "@oclif/core";
|
|
6
6
|
import { rspack } from "@rspack/core";
|
|
7
|
-
import
|
|
7
|
+
import Rcon from "rcon";
|
|
8
8
|
|
|
9
9
|
//#region src/fivem-build-command.ts
|
|
10
10
|
var FivemBuildCommand = class FivemBuildCommand extends Command {
|
|
@@ -77,16 +77,8 @@ var FivemBuildCommand = class FivemBuildCommand extends Command {
|
|
|
77
77
|
const resourceName = flags.resourceName ?? path.basename(process.cwd());
|
|
78
78
|
const compiler = rspack(createFivemRspackConfig({ mode }));
|
|
79
79
|
if (autoReload) {
|
|
80
|
-
if (!password)
|
|
81
|
-
|
|
82
|
-
this.exit(1);
|
|
83
|
-
}
|
|
84
|
-
const rcon = new Rcon({
|
|
85
|
-
host,
|
|
86
|
-
port,
|
|
87
|
-
password
|
|
88
|
-
});
|
|
89
|
-
await this._enableAutoReload(compiler, rcon, resourceName);
|
|
80
|
+
if (!password) this.fatalError("RCON password is required for auto-reload. Please provide it using the --password flag.");
|
|
81
|
+
await this._enableAutoReload(compiler, resourceName, host, port, password);
|
|
90
82
|
}
|
|
91
83
|
if (flags.watch) {
|
|
92
84
|
this.logger.info(`Building FiveM resource in watch mode...\n`);
|
|
@@ -94,6 +86,7 @@ var FivemBuildCommand = class FivemBuildCommand extends Command {
|
|
|
94
86
|
} else {
|
|
95
87
|
this.logger.info(`Building FiveM resource...\n`);
|
|
96
88
|
compiler.run(this._compilerCallback.bind(this));
|
|
89
|
+
this.exit(0);
|
|
97
90
|
}
|
|
98
91
|
}
|
|
99
92
|
_parseServerAddress(address) {
|
|
@@ -113,21 +106,32 @@ var FivemBuildCommand = class FivemBuildCommand extends Command {
|
|
|
113
106
|
}
|
|
114
107
|
if (stats) this.logger.log(stats.toString(), "\n");
|
|
115
108
|
}
|
|
116
|
-
async
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
109
|
+
async _connectRcon(host, port, password) {
|
|
110
|
+
return new Promise((resolve, reject) => {
|
|
111
|
+
const rcon = new Rcon(host, port, password, {
|
|
112
|
+
tcp: false,
|
|
113
|
+
challenge: false
|
|
114
|
+
});
|
|
115
|
+
rcon.on("auth", () => resolve(rcon));
|
|
116
|
+
rcon.on("error", reject);
|
|
117
|
+
rcon.on("end", () => reject(/* @__PURE__ */ new Error("RCON connection ended unexpectedly.")));
|
|
118
|
+
rcon.connect();
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async _enableAutoReload(compiler, resourceName, host, port, password) {
|
|
122
|
+
const rcon = await this._connectRcon(host, port, password);
|
|
123
|
+
rcon.on("response", (res) => {
|
|
124
|
+
if (res.includes("Couldn't find resource")) this.fatalError("Couldn't find resource");
|
|
125
|
+
if (res === "rint Invalid password") this.fatalError("Invalid password");
|
|
126
|
+
});
|
|
127
|
+
compiler.hooks.done.tap("FivemAutoReloadPlugin", (stats) => {
|
|
124
128
|
if (stats.hasErrors()) {
|
|
125
129
|
this.logger.warning("Build failed. Skipping FiveM resource reload.\n");
|
|
126
130
|
return;
|
|
127
131
|
}
|
|
128
132
|
this.logger.info(`Reloading FiveM resource "${resourceName}"...`);
|
|
129
133
|
try {
|
|
130
|
-
|
|
134
|
+
rcon.send(`refresh; ensure ${resourceName}`);
|
|
131
135
|
this.logger.success(`FiveM resource reloaded successfully.\n`);
|
|
132
136
|
} catch (error) {
|
|
133
137
|
this.logger.error(`Failed to reload FiveM resource: ${getErrMsg(error)}\n`);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/fivem-build-command.ts","../src/index.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { Command } from '@jpp-toolkit/core';\nimport { createFivemRspackConfig } from '@jpp-toolkit/rspack-config';\nimport { getErrMsg } from '@jpp-toolkit/utils';\nimport { Flags } from '@oclif/core';\nimport type { Compiler, Stats } from '@rspack/core';\nimport { rspack } from '@rspack/core';\nimport
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/fivem-build-command.ts","../src/index.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { Command } from '@jpp-toolkit/core';\nimport { createFivemRspackConfig } from '@jpp-toolkit/rspack-config';\nimport { getErrMsg } from '@jpp-toolkit/utils';\nimport { Flags } from '@oclif/core';\nimport type { Compiler, Stats } from '@rspack/core';\nimport { rspack } from '@rspack/core';\nimport Rcon from 'rcon';\n\ntype Mode = 'development' | 'production';\ntype ServerAddress = { readonly host: string; readonly port: number };\n\nexport class FivemBuildCommand extends Command {\n static override summary = 'Build the FiveM resource using predefined config.';\n\n static override flags = {\n watch: Flags.boolean({\n char: 'w',\n description: 'Watch files for changes and rebuild automatically.',\n default: false,\n }),\n mode: Flags.string({\n char: 'm',\n description: 'Set the build mode (development or production).',\n options: ['development', 'production'],\n required: false,\n }),\n autoReload: Flags.boolean({\n char: 'r',\n description: 'Automatically reload FiveM resource after build.',\n default: false,\n }),\n server: Flags.string({\n char: 's',\n description: 'Server \"ip:port\" to connect for reloading FiveM resource after build.',\n default: '127.0.0.1:30120',\n required: false,\n }),\n password: Flags.string({\n char: 'p',\n description: 'RCON password for the FiveM server to reload resource after build.',\n required: false,\n }),\n resourceName: Flags.string({\n char: 'n',\n description:\n 'Name of the FiveM resource to reload. If not provided, the name of the folder containing the resource will be used.',\n required: false,\n }),\n };\n\n static override examples = [\n {\n description: 'Build the FiveM resource.',\n command: '<%= config.bin %> <%= command.id %>',\n },\n {\n description: 'Build the FiveM resource in watch mode.',\n command: '<%= config.bin %> <%= command.id %> --watch',\n },\n {\n description: 'Build the FiveM resource in production mode.',\n command: '<%= config.bin %> <%= command.id %> --mode=production',\n },\n {\n description:\n 'Build the FiveM resource and automatically reload it on the server after build.',\n command:\n '<%= config.bin %> <%= command.id %> --auto-reload --password your_rcon_password',\n },\n {\n description:\n 'Build the FiveM resource in watch mode and automatically reload it on the server after each build.',\n command:\n '<%= config.bin %> <%= command.id %> --watch --auto-reload --password your_rcon_password',\n },\n {\n description:\n 'Build the FiveM resource and connect to a specific server for auto-reload.',\n command:\n '<%= config.bin %> <%= command.id %> --auto-reload --server=127.0.0.1:30120 --password your_rcon_password',\n },\n ];\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(FivemBuildCommand);\n\n const { watch, autoReload, password } = flags;\n const mode = (flags.mode ?? (watch ? 'development' : 'production')) as Mode;\n const { host, port } = this._parseServerAddress(flags.server);\n const resourceName = flags.resourceName ?? path.basename(process.cwd());\n\n const config = createFivemRspackConfig({ mode });\n const compiler = rspack(config);\n\n if (autoReload) {\n if (!password) {\n this.fatalError(\n 'RCON password is required for auto-reload. Please provide it using the --password flag.',\n );\n }\n\n await this._enableAutoReload(compiler, resourceName, host, port, password);\n }\n\n if (flags.watch) {\n this.logger.info(`Building FiveM resource in watch mode...\\n`);\n compiler.watch({}, this._compilerCallback.bind(this));\n } else {\n this.logger.info(`Building FiveM resource...\\n`);\n compiler.run(this._compilerCallback.bind(this));\n this.exit(0);\n }\n }\n\n private _parseServerAddress(address: string): ServerAddress {\n const match = /^(?<host>[^:]+):(?<port>\\d+)$/u.exec(address);\n const { host, port } = match?.groups ?? {};\n\n if (!host || !port) {\n throw new Error(\n `Invalid server address format: ${address}. Expected format is \"ip:port\".`,\n );\n }\n\n return { host, port: parseInt(port) };\n }\n\n private _compilerCallback(err: Error | null, stats: Stats | undefined): void {\n if (err) {\n this.logger.error(getErrMsg(err));\n if ('details' in err) this.logger.error(err.details as string);\n if ('stack' in err) this.logger.error(err.stack);\n return;\n }\n\n if (stats) this.logger.log(stats.toString(), '\\n');\n }\n\n private async _connectRcon(host: string, port: number, password: string): Promise<Rcon> {\n return new Promise((resolve, reject) => {\n const rcon = new Rcon(host, port, password, { tcp: false, challenge: false });\n\n rcon.on('auth', () => resolve(rcon));\n rcon.on('error', reject);\n rcon.on('end', () => reject(new Error('RCON connection ended unexpectedly.')));\n\n rcon.connect();\n });\n }\n\n private async _enableAutoReload(\n compiler: Compiler,\n resourceName: string,\n host: string,\n port: number,\n password: string,\n ): Promise<void> {\n const rcon = await this._connectRcon(host, port, password);\n\n rcon.on('response', (res: string) => {\n if (res.includes(\"Couldn't find resource\")) this.fatalError(\"Couldn't find resource\");\n if (res === 'rint Invalid password') this.fatalError('Invalid password');\n });\n\n compiler.hooks.done.tap('FivemAutoReloadPlugin', (stats) => {\n if (stats.hasErrors()) {\n this.logger.warning('Build failed. Skipping FiveM resource reload.\\n');\n return;\n }\n\n this.logger.info(`Reloading FiveM resource \"${resourceName}\"...`);\n try {\n rcon.send(`refresh; ensure ${resourceName}`);\n this.logger.success(`FiveM resource reloaded successfully.\\n`);\n } catch (error) {\n this.logger.error(`Failed to reload FiveM resource: ${getErrMsg(error)}\\n`);\n }\n });\n }\n}\n","import { FivemBuildCommand } from './fivem-build-command';\n\nexport const commands = {\n 'build:fivem': FivemBuildCommand,\n};\n"],"mappings":"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"}
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jpp-toolkit/plugin-build-fivem",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Plugin that add the fivem build command to the jpp cli.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jpp",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@oclif/core": "4.8.0",
|
|
38
38
|
"@rspack/core": "1.6.7",
|
|
39
|
-
"rcon
|
|
39
|
+
"rcon": "1.1.0",
|
|
40
|
+
"@jpp-toolkit/core": "0.0.15",
|
|
40
41
|
"@jpp-toolkit/rspack-config": "0.0.2",
|
|
41
|
-
"@jpp-toolkit/utils": "0.0.14"
|
|
42
|
-
"@jpp-toolkit/core": "0.0.14"
|
|
42
|
+
"@jpp-toolkit/utils": "0.0.14"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"oclif": "4.22.54"
|
|
@@ -6,7 +6,7 @@ import { getErrMsg } from '@jpp-toolkit/utils';
|
|
|
6
6
|
import { Flags } from '@oclif/core';
|
|
7
7
|
import type { Compiler, Stats } from '@rspack/core';
|
|
8
8
|
import { rspack } from '@rspack/core';
|
|
9
|
-
import
|
|
9
|
+
import Rcon from 'rcon';
|
|
10
10
|
|
|
11
11
|
type Mode = 'development' | 'production';
|
|
12
12
|
type ServerAddress = { readonly host: string; readonly port: number };
|
|
@@ -96,14 +96,12 @@ export class FivemBuildCommand extends Command {
|
|
|
96
96
|
|
|
97
97
|
if (autoReload) {
|
|
98
98
|
if (!password) {
|
|
99
|
-
this.
|
|
99
|
+
this.fatalError(
|
|
100
100
|
'RCON password is required for auto-reload. Please provide it using the --password flag.',
|
|
101
101
|
);
|
|
102
|
-
this.exit(1);
|
|
103
102
|
}
|
|
104
103
|
|
|
105
|
-
|
|
106
|
-
await this._enableAutoReload(compiler, rcon, resourceName);
|
|
104
|
+
await this._enableAutoReload(compiler, resourceName, host, port, password);
|
|
107
105
|
}
|
|
108
106
|
|
|
109
107
|
if (flags.watch) {
|
|
@@ -112,6 +110,7 @@ export class FivemBuildCommand extends Command {
|
|
|
112
110
|
} else {
|
|
113
111
|
this.logger.info(`Building FiveM resource...\n`);
|
|
114
112
|
compiler.run(this._compilerCallback.bind(this));
|
|
113
|
+
this.exit(0);
|
|
115
114
|
}
|
|
116
115
|
}
|
|
117
116
|
|
|
@@ -139,19 +138,33 @@ export class FivemBuildCommand extends Command {
|
|
|
139
138
|
if (stats) this.logger.log(stats.toString(), '\n');
|
|
140
139
|
}
|
|
141
140
|
|
|
141
|
+
private async _connectRcon(host: string, port: number, password: string): Promise<Rcon> {
|
|
142
|
+
return new Promise((resolve, reject) => {
|
|
143
|
+
const rcon = new Rcon(host, port, password, { tcp: false, challenge: false });
|
|
144
|
+
|
|
145
|
+
rcon.on('auth', () => resolve(rcon));
|
|
146
|
+
rcon.on('error', reject);
|
|
147
|
+
rcon.on('end', () => reject(new Error('RCON connection ended unexpectedly.')));
|
|
148
|
+
|
|
149
|
+
rcon.connect();
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
142
153
|
private async _enableAutoReload(
|
|
143
154
|
compiler: Compiler,
|
|
144
|
-
rcon: Rcon,
|
|
145
155
|
resourceName: string,
|
|
156
|
+
host: string,
|
|
157
|
+
port: number,
|
|
158
|
+
password: string,
|
|
146
159
|
): Promise<void> {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
this.
|
|
152
|
-
}
|
|
160
|
+
const rcon = await this._connectRcon(host, port, password);
|
|
161
|
+
|
|
162
|
+
rcon.on('response', (res: string) => {
|
|
163
|
+
if (res.includes("Couldn't find resource")) this.fatalError("Couldn't find resource");
|
|
164
|
+
if (res === 'rint Invalid password') this.fatalError('Invalid password');
|
|
165
|
+
});
|
|
153
166
|
|
|
154
|
-
compiler.hooks.done.
|
|
167
|
+
compiler.hooks.done.tap('FivemAutoReloadPlugin', (stats) => {
|
|
155
168
|
if (stats.hasErrors()) {
|
|
156
169
|
this.logger.warning('Build failed. Skipping FiveM resource reload.\n');
|
|
157
170
|
return;
|
|
@@ -159,7 +172,7 @@ export class FivemBuildCommand extends Command {
|
|
|
159
172
|
|
|
160
173
|
this.logger.info(`Reloading FiveM resource "${resourceName}"...`);
|
|
161
174
|
try {
|
|
162
|
-
|
|
175
|
+
rcon.send(`refresh; ensure ${resourceName}`);
|
|
163
176
|
this.logger.success(`FiveM resource reloaded successfully.\n`);
|
|
164
177
|
} catch (error) {
|
|
165
178
|
this.logger.error(`Failed to reload FiveM resource: ${getErrMsg(error)}\n`);
|