@evitcastudio/kit 3.3.0 → 3.3.2
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/lib/bundle/cli/cli.js +1635 -1513
- package/lib/bundle/cli/kit-game-templates/multi/package.json +0 -2
- package/lib/bundle/cli/kit-game-templates/single/package.json +0 -2
- package/lib/cli/app-bundler.d.ts.map +1 -1
- package/lib/cli/app-bundler.js +44 -6
- package/lib/cli/create.d.ts.map +1 -1
- package/lib/cli/create.js +7 -6
- package/lib/cli/doctor.d.ts.map +1 -1
- package/lib/cli/doctor.js +57 -30
- package/lib/cli/host.d.ts.map +1 -1
- package/lib/cli/host.js +19 -12
- package/lib/cli/init.d.ts.map +1 -1
- package/lib/cli/init.js +20 -17
- package/lib/cli/resource-builder.d.ts.map +1 -1
- package/lib/cli/resource-builder.js +11 -8
- package/lib/cli/theme.d.ts +36 -0
- package/lib/cli/theme.d.ts.map +1 -0
- package/lib/cli/theme.js +41 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-bundler.d.ts","sourceRoot":"","sources":["../../src/cli/app-bundler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app-bundler.d.ts","sourceRoot":"","sources":["../../src/cli/app-bundler.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC5B,YAAY,EAAE,mBAAmB,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAYvE;AA+DD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CA6NhI"}
|
package/lib/cli/app-bundler.js
CHANGED
|
@@ -2,6 +2,7 @@ import { promises as fs, existsSync } from 'node:fs';
|
|
|
2
2
|
import { join, dirname, extname } from 'node:path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import Bun from 'bun';
|
|
5
|
+
import { theme } from './theme';
|
|
5
6
|
/**
|
|
6
7
|
* Detects the project architecture based on existing entrypoints in the source directory.
|
|
7
8
|
* @param pSrcDir - Path to the project's source directory.
|
|
@@ -123,6 +124,7 @@ export async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
|
|
|
123
124
|
const startStamp = Date.now();
|
|
124
125
|
const clientResult = await Bun.build({
|
|
125
126
|
entrypoints: [join(srcDir, 'index.ts')],
|
|
127
|
+
root: pProjectRoot,
|
|
126
128
|
naming: {
|
|
127
129
|
entry: 'index.[ext]',
|
|
128
130
|
chunk: '[name]-[hash].[ext]',
|
|
@@ -136,7 +138,21 @@ export async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
|
|
|
136
138
|
identifiers: shouldObfuscate,
|
|
137
139
|
syntax: true,
|
|
138
140
|
whitespace: true
|
|
139
|
-
} : false
|
|
141
|
+
} : false,
|
|
142
|
+
plugins: [
|
|
143
|
+
{
|
|
144
|
+
name: 'kit-project-resolver',
|
|
145
|
+
setup(build) {
|
|
146
|
+
build.onResolve({ filter: /^resource\.json$/ }, () => {
|
|
147
|
+
const resourcePath = join(pProjectRoot, 'resource.json');
|
|
148
|
+
if (existsSync(resourcePath)) {
|
|
149
|
+
return { path: resourcePath };
|
|
150
|
+
}
|
|
151
|
+
return undefined;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
]
|
|
140
156
|
});
|
|
141
157
|
if (!clientResult.success) {
|
|
142
158
|
console.error(clientResult.logs);
|
|
@@ -153,7 +169,7 @@ export async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
|
|
|
153
169
|
}
|
|
154
170
|
const elapsed = Date.now() - startStamp;
|
|
155
171
|
if (isVerbose) {
|
|
156
|
-
console.log(
|
|
172
|
+
console.log(theme.info(`[Kit CLI] Singleplayer Client Build took: ${elapsed}ms`));
|
|
157
173
|
}
|
|
158
174
|
return { architecture: 'single', clientBuildTime: elapsed, success: true };
|
|
159
175
|
}
|
|
@@ -166,6 +182,7 @@ export async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
|
|
|
166
182
|
const clientStart = Date.now();
|
|
167
183
|
const clientResult = await Bun.build({
|
|
168
184
|
entrypoints: [clientEntry],
|
|
185
|
+
root: pProjectRoot,
|
|
169
186
|
naming: {
|
|
170
187
|
entry: 'index.[ext]',
|
|
171
188
|
chunk: '[name]-[hash].[ext]',
|
|
@@ -179,7 +196,21 @@ export async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
|
|
|
179
196
|
identifiers: shouldObfuscate,
|
|
180
197
|
syntax: true,
|
|
181
198
|
whitespace: true
|
|
182
|
-
} : false
|
|
199
|
+
} : false,
|
|
200
|
+
plugins: [
|
|
201
|
+
{
|
|
202
|
+
name: 'kit-project-resolver',
|
|
203
|
+
setup(build) {
|
|
204
|
+
build.onResolve({ filter: /^resource\.json$/ }, () => {
|
|
205
|
+
const resourcePath = join(pProjectRoot, 'resource.json');
|
|
206
|
+
if (existsSync(resourcePath)) {
|
|
207
|
+
return { path: resourcePath };
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
]
|
|
183
214
|
});
|
|
184
215
|
if (!clientResult.success) {
|
|
185
216
|
console.error(clientResult.logs);
|
|
@@ -197,6 +228,7 @@ export async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
|
|
|
197
228
|
const serverStart = Date.now();
|
|
198
229
|
const serverResult = await Bun.build({
|
|
199
230
|
entrypoints: [serverEntry],
|
|
231
|
+
root: pProjectRoot,
|
|
200
232
|
naming: {
|
|
201
233
|
entry: 'server.[ext]',
|
|
202
234
|
chunk: '[name]-[hash].[ext]',
|
|
@@ -228,10 +260,10 @@ export async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
|
|
|
228
260
|
}
|
|
229
261
|
if (isVerbose) {
|
|
230
262
|
if (clientElapsed) {
|
|
231
|
-
console.log(
|
|
263
|
+
console.log(theme.info(`[Kit CLI] Multiplayer Client Build took: ${clientElapsed}ms`));
|
|
232
264
|
}
|
|
233
265
|
if (serverElapsed) {
|
|
234
|
-
console.log(
|
|
266
|
+
console.log(theme.info(`[Kit CLI] Multiplayer Server Build took: ${serverElapsed}ms`));
|
|
235
267
|
}
|
|
236
268
|
}
|
|
237
269
|
return {
|
|
@@ -244,7 +276,13 @@ export async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
|
|
|
244
276
|
return { architecture: 'none', success: true };
|
|
245
277
|
}
|
|
246
278
|
catch (pError) {
|
|
247
|
-
console.error(
|
|
279
|
+
console.error(theme.error(`[Kit CLI Build Error] ${pError}`));
|
|
280
|
+
if (pError?.logs) {
|
|
281
|
+
console.error(pError.logs);
|
|
282
|
+
}
|
|
283
|
+
else if (pError?.errors) {
|
|
284
|
+
console.error(pError.errors);
|
|
285
|
+
}
|
|
248
286
|
return { architecture, success: false };
|
|
249
287
|
}
|
|
250
288
|
}
|
package/lib/cli/create.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAkDD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C1E"}
|
package/lib/cli/create.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
+
import { theme } from './theme';
|
|
4
5
|
/**
|
|
5
6
|
* Formats a given name into a PascalCase class name.
|
|
6
7
|
* @param pName - Raw identifier input.
|
|
@@ -53,12 +54,12 @@ export class ${pClassName} extends KitPlugin {
|
|
|
53
54
|
export async function processCreate(pOptions) {
|
|
54
55
|
const { type, name, verbose } = pOptions;
|
|
55
56
|
if (!type || !name) {
|
|
56
|
-
console.error(
|
|
57
|
+
console.error(theme.error('\nError: Both type and name are required. Usage: kit create <type> <name>'));
|
|
57
58
|
process.exit(1);
|
|
58
59
|
}
|
|
59
60
|
const normalizedType = type.toLowerCase();
|
|
60
61
|
if (normalizedType !== 'plugin') {
|
|
61
|
-
console.error(
|
|
62
|
+
console.error(theme.error(`\nError: Unknown create type '${type}'. Supported types: 'plugin'`));
|
|
62
63
|
process.exit(1);
|
|
63
64
|
}
|
|
64
65
|
const className = toPascalCase(name);
|
|
@@ -70,19 +71,19 @@ export async function processCreate(pOptions) {
|
|
|
70
71
|
await fs.mkdir(pluginsDir, { recursive: true });
|
|
71
72
|
const fileExists = await fs.stat(targetPath).then(() => true).catch(() => false);
|
|
72
73
|
if (fileExists) {
|
|
73
|
-
console.error(
|
|
74
|
+
console.error(theme.error(`\nError: File already exists at ${targetPath}`));
|
|
74
75
|
process.exit(1);
|
|
75
76
|
}
|
|
76
77
|
const sourceCode = generatePluginSource(className, className);
|
|
77
78
|
await fs.writeFile(targetPath, sourceCode, 'utf8');
|
|
78
|
-
console.log(`\n ${
|
|
79
|
+
console.log(`\n ${theme.successIcon('✓')} Created plugin ${theme.brandBold(className)} at ${theme.secondary(targetPath)}\n`);
|
|
79
80
|
if (verbose) {
|
|
80
|
-
console.log(
|
|
81
|
+
console.log(theme.secondary(sourceCode));
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
catch (pError) {
|
|
84
85
|
const message = pError instanceof Error ? pError.message : String(pError);
|
|
85
|
-
console.error(
|
|
86
|
+
console.error(theme.error(`\nError creating plugin: ${message}`));
|
|
86
87
|
process.exit(1);
|
|
87
88
|
}
|
|
88
89
|
}
|
package/lib/cli/doctor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAUD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,QAAQ,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0MlF"}
|
package/lib/cli/doctor.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
|
+
import { theme } from './theme';
|
|
5
6
|
/**
|
|
6
7
|
* Runs diagnostics on the local development environment and project health.
|
|
7
8
|
* @param pOptions - Options passed from the CLI.
|
|
@@ -9,24 +10,34 @@ import chalk from 'chalk';
|
|
|
9
10
|
export async function processDoctor(pOptions = {}) {
|
|
10
11
|
const isVerbose = Boolean(pOptions.verbose);
|
|
11
12
|
const results = [];
|
|
12
|
-
console.log(`\n ${
|
|
13
|
+
console.log(`\n ${theme.brandBold('Kit Doctor')} ${chalk.dim('-')} Environment & Project Health Check\n`);
|
|
13
14
|
// 1. Runtime Check: Bun
|
|
14
|
-
|
|
15
|
-
if (!bunCheck.error && bunCheck.status === 0) {
|
|
15
|
+
if (typeof Bun !== 'undefined') {
|
|
16
16
|
results.push({
|
|
17
17
|
category: 'Runtime',
|
|
18
18
|
title: 'Bun Runtime',
|
|
19
19
|
passed: true,
|
|
20
|
-
details: `
|
|
20
|
+
details: `v${Bun.version}`
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
else {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
const bunCheck = spawnSync('bun', ['--version'], { encoding: 'utf8', shell: true });
|
|
25
|
+
if (!bunCheck.error && bunCheck.status === 0) {
|
|
26
|
+
results.push({
|
|
27
|
+
category: 'Runtime',
|
|
28
|
+
title: 'Bun Runtime',
|
|
29
|
+
passed: true,
|
|
30
|
+
details: `v${bunCheck.stdout.trim()}`
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
results.push({
|
|
35
|
+
category: 'Runtime',
|
|
36
|
+
title: 'Bun Runtime',
|
|
37
|
+
passed: false,
|
|
38
|
+
details: 'Bun is not installed or not in PATH. Download at https://bun.sh/'
|
|
39
|
+
});
|
|
40
|
+
}
|
|
30
41
|
}
|
|
31
42
|
// 2. Version Control Check: Git
|
|
32
43
|
const gitCheck = spawnSync('git', ['--version'], { encoding: 'utf8', shell: true });
|
|
@@ -54,33 +65,48 @@ export async function processDoctor(pOptions = {}) {
|
|
|
54
65
|
try {
|
|
55
66
|
const rawPkg = readFileSync(pkgPath, 'utf8');
|
|
56
67
|
const pkg = JSON.parse(rawPkg);
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
pkg.
|
|
68
|
+
const isKitCoreRepo = pkg.name === '@evitcastudio/kit';
|
|
69
|
+
const kitVersionSpec = pkg.dependencies?.['@evitcastudio/kit'] ||
|
|
70
|
+
pkg.devDependencies?.['@evitcastudio/kit'];
|
|
71
|
+
const hasKitDependency = Boolean(kitVersionSpec || isKitCoreRepo);
|
|
60
72
|
results.push({
|
|
61
73
|
category: 'Project',
|
|
62
74
|
title: 'package.json configuration',
|
|
63
75
|
passed: true,
|
|
64
|
-
details:
|
|
76
|
+
details: `${pkg.name || 'unnamed'}${pkg.version ? ` v${pkg.version}` : ''}`
|
|
65
77
|
});
|
|
78
|
+
let kitDependencyDetails = 'Missing @evitcastudio/kit dependency in package.json';
|
|
79
|
+
if (isKitCoreRepo) {
|
|
80
|
+
kitDependencyDetails = 'Core Framework Repository';
|
|
81
|
+
}
|
|
82
|
+
else if (kitVersionSpec) {
|
|
83
|
+
kitDependencyDetails = `@evitcastudio/kit: ${kitVersionSpec}`;
|
|
84
|
+
}
|
|
66
85
|
results.push({
|
|
67
86
|
category: 'Project',
|
|
68
87
|
title: 'Kit framework dependency',
|
|
69
88
|
passed: hasKitDependency,
|
|
70
|
-
details:
|
|
71
|
-
? 'Found @evitcastudio/kit in project configuration'
|
|
72
|
-
: 'Missing @evitcastudio/kit dependency in package.json'
|
|
89
|
+
details: kitDependencyDetails
|
|
73
90
|
});
|
|
74
91
|
// If running inside a consumer game project, check game asset directory structure
|
|
75
|
-
const isKitCoreRepo = pkg.name === '@evitcastudio/kit';
|
|
76
92
|
if (!isKitCoreRepo) {
|
|
77
93
|
const resourcesDir = join(cwd, 'src', 'resources');
|
|
78
94
|
const hasResources = existsSync(resourcesDir);
|
|
95
|
+
let assetDetails = 'src/resources directory not found';
|
|
96
|
+
if (hasResources) {
|
|
97
|
+
try {
|
|
98
|
+
const items = readdirSync(resourcesDir, { recursive: true });
|
|
99
|
+
assetDetails = `Ready (${items.length} asset${items.length === 1 ? '' : 's'})`;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
assetDetails = 'Asset directory present';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
79
105
|
results.push({
|
|
80
106
|
category: 'Project',
|
|
81
107
|
title: 'Asset Directory (src/resources)',
|
|
82
108
|
passed: hasResources,
|
|
83
|
-
details:
|
|
109
|
+
details: assetDetails
|
|
84
110
|
});
|
|
85
111
|
}
|
|
86
112
|
// Detect project type (multiplayer vs single-player)
|
|
@@ -132,13 +158,13 @@ export async function processDoctor(pOptions = {}) {
|
|
|
132
158
|
const buildPipelinePassed = hasBuildScript || hasKitBuildScript;
|
|
133
159
|
let buildDetails = 'No build pipeline configured';
|
|
134
160
|
if (hasKitBuildScript && hasBuildScript) {
|
|
135
|
-
buildDetails = '
|
|
161
|
+
buildDetails = 'Native CLI build ("kit build") + bun-build.ts';
|
|
136
162
|
}
|
|
137
163
|
else if (hasKitBuildScript) {
|
|
138
|
-
buildDetails = '
|
|
164
|
+
buildDetails = 'Native CLI build ("kit build")';
|
|
139
165
|
}
|
|
140
166
|
else if (hasBuildScript) {
|
|
141
|
-
buildDetails = 'Legacy bun-build.ts
|
|
167
|
+
buildDetails = 'Legacy build script (bun-build.ts)';
|
|
142
168
|
}
|
|
143
169
|
results.push({
|
|
144
170
|
category: 'Project',
|
|
@@ -158,11 +184,12 @@ export async function processDoctor(pOptions = {}) {
|
|
|
158
184
|
// Render results
|
|
159
185
|
let allPassed = true;
|
|
160
186
|
for (const res of results) {
|
|
161
|
-
const icon = res.passed ?
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
187
|
+
const icon = res.passed ? theme.successIcon('✓') : theme.error('✗');
|
|
188
|
+
const categoryBadge = `${theme.bracket('[')}${theme.brandBold(res.category)}${theme.bracket(']')}`;
|
|
189
|
+
const titleText = res.passed ? theme.title(res.title) : theme.error(res.title);
|
|
190
|
+
console.log(` ${icon} ${categoryBadge} ${titleText}`);
|
|
191
|
+
if (res.details) {
|
|
192
|
+
console.log(` ${theme.secondary(res.details)}`);
|
|
166
193
|
}
|
|
167
194
|
if (!res.passed) {
|
|
168
195
|
allPassed = false;
|
|
@@ -170,10 +197,10 @@ export async function processDoctor(pOptions = {}) {
|
|
|
170
197
|
}
|
|
171
198
|
console.log('\n');
|
|
172
199
|
if (allPassed) {
|
|
173
|
-
console.log(` ${
|
|
200
|
+
console.log(` ${theme.successIcon('✔')} ${theme.brandBold('All doctor diagnostics passed!')}\n`);
|
|
174
201
|
}
|
|
175
202
|
else {
|
|
176
|
-
console.log(` ${
|
|
203
|
+
console.log(` ${theme.warning('▲ Some issues were detected. Check the items above.')}\n`);
|
|
177
204
|
}
|
|
178
205
|
return allPassed;
|
|
179
206
|
}
|
package/lib/cli/host.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/cli/host.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/cli/host.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,MAAM,CAAC,EAAE;QAAE,IAAI,IAAI,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3C;AAoBD;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,QAAQ,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAuHjF"}
|
package/lib/cli/host.js
CHANGED
|
@@ -3,6 +3,7 @@ import { join, resolve } from 'path';
|
|
|
3
3
|
import { networkInterfaces } from 'os';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { detectArchitecture } from './app-bundler';
|
|
6
|
+
import { theme } from './theme';
|
|
6
7
|
/**
|
|
7
8
|
* Retrieves the primary local IPv4 address for local network access.
|
|
8
9
|
* @returns Primary LAN IPv4 address or localhost fallback.
|
|
@@ -35,7 +36,7 @@ export async function processHost(pOptions = {}) {
|
|
|
35
36
|
const architecture = detectArchitecture(join(cwd, 'src'));
|
|
36
37
|
if (!existsSync(distDir)) {
|
|
37
38
|
const message = `Target directory "${distDir}" does not exist. Run "kit build" or use "kit host -b" first.`;
|
|
38
|
-
console.error(
|
|
39
|
+
console.error(theme.error(`\n[Kit Host] ${message}\n`));
|
|
39
40
|
return { success: false, message };
|
|
40
41
|
}
|
|
41
42
|
// Multiplayer Hosting
|
|
@@ -43,10 +44,10 @@ export async function processHost(pOptions = {}) {
|
|
|
43
44
|
const serverJsPath = join(distDir, 'server.js');
|
|
44
45
|
if (!existsSync(serverJsPath)) {
|
|
45
46
|
const message = `Cannot host multiplayer project: "${serverJsPath}" was not found. Please compile the server first using "kit build".`;
|
|
46
|
-
console.error(
|
|
47
|
+
console.error(theme.error(`\n[Kit Host] ${message}\n`));
|
|
47
48
|
return { success: false, message };
|
|
48
49
|
}
|
|
49
|
-
console.log(
|
|
50
|
+
console.log(`\n ${theme.brandBold('Kit Multiplayer Server')} ${theme.muted('─')} ${theme.secondary(distDir)}\n`);
|
|
50
51
|
let serverSettingsPort = port;
|
|
51
52
|
const settingsPath = join(distDir, 'settings.json');
|
|
52
53
|
if (existsSync(settingsPath)) {
|
|
@@ -65,7 +66,13 @@ export async function processHost(pOptions = {}) {
|
|
|
65
66
|
stderr: 'inherit',
|
|
66
67
|
stdin: 'inherit'
|
|
67
68
|
});
|
|
68
|
-
console.log(
|
|
69
|
+
console.log(` ${theme.successIcon('✓')} ${theme.title('Multiplayer server process spawned')} ${theme.secondary(`(configured port: ${serverSettingsPort})`)}`);
|
|
70
|
+
console.log(` ${theme.title('Local:')} ${theme.url(`http://localhost:${serverSettingsPort}`)}`);
|
|
71
|
+
const lanIp = getNetworkAddress();
|
|
72
|
+
if (lanIp !== 'localhost') {
|
|
73
|
+
console.log(` ${theme.title('Network:')} ${theme.url(`http://${lanIp}:${serverSettingsPort}`)}`);
|
|
74
|
+
}
|
|
75
|
+
console.log(theme.muted('\n Press Ctrl+C to stop the server\n'));
|
|
69
76
|
process.on('SIGINT', () => {
|
|
70
77
|
proc.kill();
|
|
71
78
|
process.exit(0);
|
|
@@ -81,7 +88,7 @@ export async function processHost(pOptions = {}) {
|
|
|
81
88
|
const indexPath = join(distDir, 'index.html');
|
|
82
89
|
if (!existsSync(indexPath)) {
|
|
83
90
|
const message = `Missing entrypoint: "${indexPath}" was not found in dist. Run "kit build" or use "kit host -b" to compile.`;
|
|
84
|
-
console.error(
|
|
91
|
+
console.error(theme.error(`\n[Kit Host] ${message}\n`));
|
|
85
92
|
return { success: false, message };
|
|
86
93
|
}
|
|
87
94
|
const lanIp = getNetworkAddress();
|
|
@@ -93,22 +100,22 @@ export async function processHost(pOptions = {}) {
|
|
|
93
100
|
const file = Bun.file(join(distDir, target));
|
|
94
101
|
if (!await file.exists()) {
|
|
95
102
|
if (pOptions.verbose) {
|
|
96
|
-
console.warn(
|
|
103
|
+
console.warn(theme.warning(`[Kit Host] 404 Not Found: ${target}`));
|
|
97
104
|
}
|
|
98
105
|
return new Response('Not Found', { status: 404 });
|
|
99
106
|
}
|
|
100
107
|
return new Response(file);
|
|
101
108
|
}
|
|
102
109
|
});
|
|
103
|
-
console.log(
|
|
104
|
-
console.log(` ${
|
|
110
|
+
console.log(`\n ${theme.brandBold('Kit Game Host Server')}\n`);
|
|
111
|
+
console.log(` ${theme.title('Local:')} ${theme.url(`http://localhost:${server.port}`)}`);
|
|
105
112
|
if (lanIp !== 'localhost') {
|
|
106
|
-
console.log(` ${
|
|
113
|
+
console.log(` ${theme.title('Network:')} ${theme.url(`http://${lanIp}:${server.port}`)}`);
|
|
107
114
|
}
|
|
108
|
-
console.log(
|
|
109
|
-
console.log(
|
|
115
|
+
console.log(theme.secondary(`\n Serving files from: ${distDir}`));
|
|
116
|
+
console.log(theme.muted(' Press Ctrl+C to stop the server\n'));
|
|
110
117
|
process.on('SIGINT', () => {
|
|
111
|
-
console.log(
|
|
118
|
+
console.log(theme.warning('\nShutting down host server...'));
|
|
112
119
|
server.stop();
|
|
113
120
|
process.exit(0);
|
|
114
121
|
});
|
package/lib/cli/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AA0FD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwLtE"}
|
package/lib/cli/init.js
CHANGED
|
@@ -6,6 +6,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
6
6
|
import { spawnSync, execSync } from 'node:child_process';
|
|
7
7
|
import os from 'node:os';
|
|
8
8
|
import packageJSON from '../../package.json';
|
|
9
|
+
import { theme } from './theme';
|
|
9
10
|
/**
|
|
10
11
|
* Gets the git user name and email from the local system.
|
|
11
12
|
* @returns The formatted author string.
|
|
@@ -24,6 +25,8 @@ function getGitUser() {
|
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
function checkBun() {
|
|
28
|
+
if (typeof Bun !== 'undefined')
|
|
29
|
+
return true;
|
|
27
30
|
const result = spawnSync('bun', ['--version'], { stdio: 'ignore', shell: true });
|
|
28
31
|
return !result.error && result.status === 0;
|
|
29
32
|
}
|
|
@@ -91,16 +94,16 @@ function copyTemplate(pSrc, pDest, pProjectName, pVersion, pAuthor) {
|
|
|
91
94
|
* @param pOptions - Options for initialization.
|
|
92
95
|
*/
|
|
93
96
|
export async function processInit(pOptions) {
|
|
94
|
-
intro(
|
|
97
|
+
intro(theme.brand(`Kit CLI v${packageJSON.version}`));
|
|
95
98
|
// Environment Check
|
|
96
99
|
if (!checkBun()) {
|
|
97
|
-
note(`Kit requires the Bun runtime to build and run projects.\nYou can download it manually at ${
|
|
100
|
+
note(`Kit requires the Bun runtime to build and run projects.\nYou can download it manually at ${theme.brand('https://bun.sh/')}`, 'Bun Not Found');
|
|
98
101
|
const install = await confirm({
|
|
99
102
|
message: 'Would you like to install Bun automatically now?',
|
|
100
103
|
initialValue: true,
|
|
101
104
|
});
|
|
102
105
|
if (isCancel(install) || !install) {
|
|
103
|
-
cancel(`Please install Bun manually to use Kit: ${
|
|
106
|
+
cancel(`Please install Bun manually to use Kit: ${theme.brand('https://bun.sh/')}\nNote: Kit projects cannot build or run without Bun.`);
|
|
104
107
|
process.exit(1);
|
|
105
108
|
}
|
|
106
109
|
const sInstall = spinner();
|
|
@@ -108,7 +111,7 @@ export async function processInit(pOptions) {
|
|
|
108
111
|
const success = installBun();
|
|
109
112
|
if (!success) {
|
|
110
113
|
sInstall.stop(chalk.red('Automatic installation failed.'));
|
|
111
|
-
note(`Please install Bun manually: ${
|
|
114
|
+
note(`Please install Bun manually: ${theme.brand('https://bun.sh/')}`, 'Manual Installation Required');
|
|
112
115
|
process.exit(1);
|
|
113
116
|
}
|
|
114
117
|
sInstall.stop();
|
|
@@ -170,7 +173,7 @@ export async function processInit(pOptions) {
|
|
|
170
173
|
if (fs.existsSync(projectDir)) {
|
|
171
174
|
if (isInteractive) {
|
|
172
175
|
const overwrite = await confirm({
|
|
173
|
-
message: `Directory ${
|
|
176
|
+
message: `Directory ${theme.brand(projectName)} already exists. Overwrite?`,
|
|
174
177
|
initialValue: false,
|
|
175
178
|
});
|
|
176
179
|
if (isCancel(overwrite) || !overwrite) {
|
|
@@ -184,7 +187,7 @@ export async function processInit(pOptions) {
|
|
|
184
187
|
}
|
|
185
188
|
}
|
|
186
189
|
const s = spinner();
|
|
187
|
-
s.start(`Scaffolding ${
|
|
190
|
+
s.start(`Scaffolding ${theme.brand(projectName)}...`);
|
|
188
191
|
try {
|
|
189
192
|
const projectPath = path.join(process.cwd(), projectName);
|
|
190
193
|
if (fs.existsSync(projectPath)) {
|
|
@@ -228,27 +231,27 @@ export async function processInit(pOptions) {
|
|
|
228
231
|
installSpinner.start('Installing project dependencies with Bun...');
|
|
229
232
|
const installResult = spawnSync('bun', ['install'], { cwd: projectPath, stdio: 'ignore', shell: true });
|
|
230
233
|
if (installResult.status === 0) {
|
|
231
|
-
installSpinner.stop(
|
|
234
|
+
installSpinner.stop(theme.success('Dependencies installed successfully!'));
|
|
232
235
|
}
|
|
233
236
|
else {
|
|
234
|
-
installSpinner.stop(
|
|
237
|
+
installSpinner.stop(theme.warning('Dependency installation finished with warnings.'));
|
|
235
238
|
}
|
|
236
239
|
}
|
|
237
|
-
console.log(`${
|
|
238
|
-
console.log(`${
|
|
239
|
-
console.log(`${
|
|
240
|
+
console.log(`${theme.brand('│')}`);
|
|
241
|
+
console.log(`${theme.brand('│')} ${theme.title('Next steps:')}`);
|
|
242
|
+
console.log(`${theme.brand('│')} ${theme.stepNumber('1.')} cd ${theme.brandBold(projectName)}`);
|
|
240
243
|
if (!shouldInstall) {
|
|
241
|
-
console.log(`${
|
|
242
|
-
console.log(`${
|
|
244
|
+
console.log(`${theme.brand('│')} ${theme.stepNumber('2.')} bun install`);
|
|
245
|
+
console.log(`${theme.brand('│')} ${theme.stepNumber('3.')} bun run build`);
|
|
243
246
|
}
|
|
244
247
|
else {
|
|
245
|
-
console.log(`${
|
|
248
|
+
console.log(`${theme.brand('│')} ${theme.stepNumber('2.')} bun run build`);
|
|
246
249
|
}
|
|
247
|
-
console.log(`${
|
|
248
|
-
outro(
|
|
250
|
+
console.log(`${theme.brand('│')}`);
|
|
251
|
+
outro(theme.brandBold('Happy coding!'));
|
|
249
252
|
}
|
|
250
253
|
catch (pError) {
|
|
251
|
-
s.stop(
|
|
254
|
+
s.stop(theme.error('Scaffolding failed.'));
|
|
252
255
|
// Cleanup partially created directory
|
|
253
256
|
if (projectName) {
|
|
254
257
|
const projectPath = path.join(process.cwd(), projectName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-builder.d.ts","sourceRoot":"","sources":["../../src/cli/resource-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"resource-builder.d.ts","sourceRoot":"","sources":["../../src/cli/resource-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA8oB9C;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCvL"}
|
|
@@ -5,11 +5,12 @@ import { watch as chokidarWatch } from 'chokidar';
|
|
|
5
5
|
import { v4 as uuidv4 } from 'uuid';
|
|
6
6
|
import { VYI } from '../vendor/vyi';
|
|
7
7
|
import { bundleApp } from './app-bundler';
|
|
8
|
+
import { theme } from './theme';
|
|
8
9
|
// Logging helpers
|
|
9
10
|
const log = console.log;
|
|
10
|
-
const info =
|
|
11
|
-
const error =
|
|
12
|
-
const alert =
|
|
11
|
+
const info = theme.info;
|
|
12
|
+
const error = theme.error;
|
|
13
|
+
const alert = theme.alert;
|
|
13
14
|
// Resource types and valid file extensions
|
|
14
15
|
const RESOURCE_TYPES = ['interface', 'icon', 'map', 'sound', 'macros'];
|
|
15
16
|
const VALID_EXTENSIONS = ['vyint', 'vyi', 'vym', 'vymac', 'mp3', 'aac', 'wav', 'm4a', 'ogg', 'flac'];
|
|
@@ -363,11 +364,13 @@ async function clearResourceTypeDirectories(pBaseDirectory) {
|
|
|
363
364
|
try {
|
|
364
365
|
const directoryExists = await fs.stat(pBaseDirectory).then(stat => stat.isDirectory()).catch(() => false);
|
|
365
366
|
if (directoryExists) {
|
|
366
|
-
await fs.rm(pBaseDirectory, { recursive: true });
|
|
367
|
+
await fs.rm(pBaseDirectory, { recursive: true, force: true });
|
|
367
368
|
}
|
|
368
369
|
}
|
|
369
370
|
catch (pError) {
|
|
370
|
-
|
|
371
|
+
if (pError?.code !== 'ENOENT') {
|
|
372
|
+
log(`${error(`[Error]`)} clearing resource directory: ${pError}`);
|
|
373
|
+
}
|
|
371
374
|
}
|
|
372
375
|
}
|
|
373
376
|
/**
|
|
@@ -445,9 +448,9 @@ async function runWatch() {
|
|
|
445
448
|
pathsToWatch.push(srcDir);
|
|
446
449
|
}
|
|
447
450
|
const displayPaths = pathsToWatch
|
|
448
|
-
.map(p =>
|
|
451
|
+
.map(p => theme.highlight(relative(projectRootDirectory, p) || p))
|
|
449
452
|
.join(', ');
|
|
450
|
-
console.log(
|
|
453
|
+
console.log(`\n ${theme.brandBold('Watching for changes in:')} ${displayPaths}`);
|
|
451
454
|
let debounceTimer = null;
|
|
452
455
|
let isRebuilding = false;
|
|
453
456
|
let queuedChange = null;
|
|
@@ -461,7 +464,7 @@ async function runWatch() {
|
|
|
461
464
|
}
|
|
462
465
|
isRebuilding = true;
|
|
463
466
|
try {
|
|
464
|
-
console.log(
|
|
467
|
+
console.log(`\n ${theme.accent('›')} ${theme.title('File changed:')} ${theme.highlight(pFilename)} ${theme.secondary('(rebuilding...)')}`);
|
|
465
468
|
await runBuild();
|
|
466
469
|
}
|
|
467
470
|
finally {
|