@evitcastudio/kit 3.2.0 → 3.2.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 +587 -149
- package/lib/cli/app-bundler.d.ts.map +1 -1
- package/lib/cli/app-bundler.js +8 -0
- package/lib/cli/host.js +2 -2
- package/lib/cli/resource-builder.d.ts.map +1 -1
- package/lib/cli/resource-builder.js +17 -4
- package/lib/cli-runner.cjs +18 -0
- package/package.json +2 -2
package/lib/bundle/cli/cli.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
2
3
|
|
|
3
4
|
/*!
|
|
4
|
-
* @evitcastudio/kit@3.
|
|
5
|
-
* Compiled Wed, 09 Sep 2026
|
|
5
|
+
* @evitcastudio/kit@3.2.2 git+https://github.com/EvitcaStudio/Kit.git
|
|
6
|
+
* Compiled Wed, 09 Sep 2026 14:01:08 UTC
|
|
6
7
|
* Copyright (c) 2026 Jared Bates, Evitca Studio, "doubleactii"
|
|
7
8
|
*
|
|
8
9
|
* @evitcastudio/kit is licensed under the MIT License.
|
|
9
10
|
* http://www.opensource.org/licenses/mit-license
|
|
10
11
|
*/
|
|
11
|
-
import { createRequire } from "node:module";
|
|
12
12
|
var __create = Object.create;
|
|
13
13
|
var __getProtoOf = Object.getPrototypeOf;
|
|
14
14
|
var __defProp = Object.defineProperty;
|
|
@@ -26,7 +26,6 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
26
26
|
return to;
|
|
27
27
|
};
|
|
28
28
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
29
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
30
29
|
|
|
31
30
|
// node_modules/commander/lib/error.js
|
|
32
31
|
var require_error = __commonJS((exports) => {
|
|
@@ -351,7 +350,7 @@ var require_help = __commonJS((exports) => {
|
|
|
351
350
|
return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
|
|
352
351
|
}
|
|
353
352
|
wrap(str, width, indent, minColumnWidth = 40) {
|
|
354
|
-
const indents = " \\f\\t\\v
|
|
353
|
+
const indents = " \\f\\t\\v\xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF";
|
|
355
354
|
const manualIndent = new RegExp(`[\\n][${indents}]+`);
|
|
356
355
|
if (str.match(manualIndent))
|
|
357
356
|
return str;
|
|
@@ -363,7 +362,7 @@ var require_help = __commonJS((exports) => {
|
|
|
363
362
|
`, `
|
|
364
363
|
`);
|
|
365
364
|
const indentString = " ".repeat(indent);
|
|
366
|
-
const zeroWidthSpace = "
|
|
365
|
+
const zeroWidthSpace = "\u200B";
|
|
367
366
|
const breaks = `\\s${zeroWidthSpace}`;
|
|
368
367
|
const regex = new RegExp(`
|
|
369
368
|
|.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`, "g");
|
|
@@ -606,11 +605,11 @@ var require_suggestSimilar = __commonJS((exports) => {
|
|
|
606
605
|
|
|
607
606
|
// node_modules/commander/lib/command.js
|
|
608
607
|
var require_command = __commonJS((exports) => {
|
|
609
|
-
var EventEmitter =
|
|
610
|
-
var childProcess =
|
|
611
|
-
var path =
|
|
612
|
-
var fs =
|
|
613
|
-
var process2 =
|
|
608
|
+
var EventEmitter = import.meta.require("events").EventEmitter;
|
|
609
|
+
var childProcess = import.meta.require("child_process");
|
|
610
|
+
var path = import.meta.require("path");
|
|
611
|
+
var fs = import.meta.require("fs");
|
|
612
|
+
var process2 = import.meta.require("process");
|
|
614
613
|
var { Argument, humanReadableArgName } = require_argument();
|
|
615
614
|
var { CommanderError } = require_error();
|
|
616
615
|
var { Help } = require_help();
|
|
@@ -1943,8 +1942,8 @@ var {
|
|
|
1943
1942
|
} = import__.default;
|
|
1944
1943
|
|
|
1945
1944
|
// src/cli/resource-builder.ts
|
|
1946
|
-
import { promises as
|
|
1947
|
-
import { join, extname, basename, resolve } from "path";
|
|
1945
|
+
import { promises as fs2, watch as fsWatch, existsSync as existsSync2 } from "fs";
|
|
1946
|
+
import { join as join2, extname as extname2, basename, resolve } from "path";
|
|
1948
1947
|
|
|
1949
1948
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
1950
1949
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -2124,9 +2123,9 @@ var ansiStyles = assembleStyles();
|
|
|
2124
2123
|
var ansi_styles_default = ansiStyles;
|
|
2125
2124
|
|
|
2126
2125
|
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
2127
|
-
import process2 from "
|
|
2128
|
-
import os from "
|
|
2129
|
-
import tty from "
|
|
2126
|
+
import process2 from "process";
|
|
2127
|
+
import os from "os";
|
|
2128
|
+
import tty from "tty";
|
|
2130
2129
|
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
|
|
2131
2130
|
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
2132
2131
|
const position = argv.indexOf(prefix + flag);
|
|
@@ -7987,6 +7986,215 @@ class WorkerPool {
|
|
|
7987
7986
|
}
|
|
7988
7987
|
}
|
|
7989
7988
|
|
|
7989
|
+
// src/cli/app-bundler.ts
|
|
7990
|
+
import { promises as fs, existsSync } from "fs";
|
|
7991
|
+
import { join, dirname, extname } from "path";
|
|
7992
|
+
var Bun2 = globalThis.Bun;
|
|
7993
|
+
function detectArchitecture(pSrcDir) {
|
|
7994
|
+
const hasClientEntry = existsSync(join(pSrcDir, "client", "index.ts"));
|
|
7995
|
+
const hasServerEntry = existsSync(join(pSrcDir, "server", "index.ts"));
|
|
7996
|
+
const hasSingleEntry = existsSync(join(pSrcDir, "index.ts"));
|
|
7997
|
+
if (hasClientEntry || hasServerEntry) {
|
|
7998
|
+
return "multi";
|
|
7999
|
+
}
|
|
8000
|
+
if (hasSingleEntry) {
|
|
8001
|
+
return "single";
|
|
8002
|
+
}
|
|
8003
|
+
return "none";
|
|
8004
|
+
}
|
|
8005
|
+
async function copyDirectoryRecursive(pSourceDir, pDestDir) {
|
|
8006
|
+
if (!existsSync(pSourceDir))
|
|
8007
|
+
return;
|
|
8008
|
+
const entries = await fs.readdir(pSourceDir, { withFileTypes: true });
|
|
8009
|
+
await fs.mkdir(pDestDir, { recursive: true });
|
|
8010
|
+
for (const entry of entries) {
|
|
8011
|
+
const srcPath = join(pSourceDir, entry.name);
|
|
8012
|
+
const destPath = join(pDestDir, entry.name);
|
|
8013
|
+
if (entry.isDirectory()) {
|
|
8014
|
+
await copyDirectoryRecursive(srcPath, destPath);
|
|
8015
|
+
} else {
|
|
8016
|
+
await fs.copyFile(srcPath, destPath);
|
|
8017
|
+
}
|
|
8018
|
+
}
|
|
8019
|
+
}
|
|
8020
|
+
async function copyStaticWebFiles(pSourceDir, pDestDir, pBaseDir) {
|
|
8021
|
+
if (!existsSync(pSourceDir))
|
|
8022
|
+
return;
|
|
8023
|
+
const entries = await fs.readdir(pSourceDir, { withFileTypes: true });
|
|
8024
|
+
for (const entry of entries) {
|
|
8025
|
+
const fullPath = join(pSourceDir, entry.name);
|
|
8026
|
+
if (entry.isDirectory()) {
|
|
8027
|
+
if (entry.name === "vendor" || entry.name === "resources" || entry.name === "node_modules") {
|
|
8028
|
+
continue;
|
|
8029
|
+
}
|
|
8030
|
+
await copyStaticWebFiles(fullPath, pDestDir, pBaseDir);
|
|
8031
|
+
} else {
|
|
8032
|
+
const ext = extname(entry.name).toLowerCase();
|
|
8033
|
+
if ([".html", ".css", ".ico"].includes(ext)) {
|
|
8034
|
+
const relativePath = fullPath.slice(pBaseDir.length).replace(/^[/\\]+/, "");
|
|
8035
|
+
const targetPath = join(pDestDir, relativePath);
|
|
8036
|
+
await fs.mkdir(dirname(targetPath), { recursive: true });
|
|
8037
|
+
await fs.copyFile(fullPath, targetPath);
|
|
8038
|
+
if ([".css", ".ico"].includes(ext)) {
|
|
8039
|
+
const rootTargetPath = join(pDestDir, entry.name);
|
|
8040
|
+
if (targetPath !== rootTargetPath && !existsSync(rootTargetPath)) {
|
|
8041
|
+
await fs.copyFile(fullPath, rootTargetPath);
|
|
8042
|
+
}
|
|
8043
|
+
}
|
|
8044
|
+
}
|
|
8045
|
+
}
|
|
8046
|
+
}
|
|
8047
|
+
}
|
|
8048
|
+
async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
|
|
8049
|
+
const srcDir = join(pProjectRoot, "src");
|
|
8050
|
+
const architecture = detectArchitecture(srcDir);
|
|
8051
|
+
const isVerbose = Boolean(pOptions.verbose);
|
|
8052
|
+
if (architecture === "none") {
|
|
8053
|
+
if (isVerbose) {
|
|
8054
|
+
console.log(source_default.yellow("[Kit CLI] No application entrypoint detected (src/index.ts or src/client/index.ts). Skipping code bundle."));
|
|
8055
|
+
}
|
|
8056
|
+
return { architecture: "none", success: true };
|
|
8057
|
+
}
|
|
8058
|
+
const isProd = Boolean(pOptions.prod);
|
|
8059
|
+
const shouldMinify = isProd || Boolean(pOptions.minify);
|
|
8060
|
+
const shouldObfuscate = isProd || Boolean(pOptions.obfuscate);
|
|
8061
|
+
const sourcemapMode = pOptions.sourcemap ?? (isProd ? "none" : "linked");
|
|
8062
|
+
let banner = "";
|
|
8063
|
+
const pkgPath = join(pProjectRoot, "package.json");
|
|
8064
|
+
if (existsSync(pkgPath)) {
|
|
8065
|
+
try {
|
|
8066
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, "utf8"));
|
|
8067
|
+
banner = [
|
|
8068
|
+
"/*!",
|
|
8069
|
+
` * ${pkg.name || "game"}@${pkg.version || "1.0.0"}`,
|
|
8070
|
+
` * Compiled ${new Date().toUTCString().replace(/GMT/g, "UTC")}`,
|
|
8071
|
+
" *",
|
|
8072
|
+
` * ${pkg.name || "game"} is privately licensed. All rights reserved.`,
|
|
8073
|
+
` * Author: ${pkg.author ?? "Unnamed"}`,
|
|
8074
|
+
" */"
|
|
8075
|
+
].join(`
|
|
8076
|
+
`);
|
|
8077
|
+
} catch {
|
|
8078
|
+
}
|
|
8079
|
+
}
|
|
8080
|
+
try {
|
|
8081
|
+
if (architecture === "single") {
|
|
8082
|
+
const startStamp = Date.now();
|
|
8083
|
+
const clientResult = await Bun2.build({
|
|
8084
|
+
entrypoints: [join(srcDir, "index.ts")],
|
|
8085
|
+
naming: "index.js",
|
|
8086
|
+
outdir: pOutDir,
|
|
8087
|
+
target: "browser",
|
|
8088
|
+
banner,
|
|
8089
|
+
sourcemap: sourcemapMode,
|
|
8090
|
+
minify: shouldMinify ? {
|
|
8091
|
+
identifiers: shouldObfuscate,
|
|
8092
|
+
syntax: true,
|
|
8093
|
+
whitespace: true
|
|
8094
|
+
} : false
|
|
8095
|
+
});
|
|
8096
|
+
if (!clientResult.success) {
|
|
8097
|
+
console.error(clientResult.logs);
|
|
8098
|
+
throw new AggregateError(clientResult.logs, "Client build failed");
|
|
8099
|
+
}
|
|
8100
|
+
await copyStaticWebFiles(srcDir, pOutDir, srcDir);
|
|
8101
|
+
const rootFavicon = join(pProjectRoot, "favicon.ico");
|
|
8102
|
+
if (existsSync(rootFavicon)) {
|
|
8103
|
+
await fs.copyFile(rootFavicon, join(pOutDir, "favicon.ico"));
|
|
8104
|
+
}
|
|
8105
|
+
const vendorDir = join(srcDir, "vendor");
|
|
8106
|
+
if (existsSync(vendorDir)) {
|
|
8107
|
+
await copyDirectoryRecursive(vendorDir, join(pOutDir, "vendor"));
|
|
8108
|
+
}
|
|
8109
|
+
const elapsed = Date.now() - startStamp;
|
|
8110
|
+
if (isVerbose) {
|
|
8111
|
+
console.log(source_default.hex("#ffa552")(`[Kit CLI] Singleplayer Client Build took: ${elapsed}ms`));
|
|
8112
|
+
}
|
|
8113
|
+
return { architecture: "single", clientBuildTime: elapsed, success: true };
|
|
8114
|
+
}
|
|
8115
|
+
if (architecture === "multi") {
|
|
8116
|
+
const clientEntry = join(srcDir, "client", "index.ts");
|
|
8117
|
+
const serverEntry = join(srcDir, "server", "index.ts");
|
|
8118
|
+
let clientElapsed = 0;
|
|
8119
|
+
let serverElapsed = 0;
|
|
8120
|
+
if (existsSync(clientEntry)) {
|
|
8121
|
+
const clientStart = Date.now();
|
|
8122
|
+
const clientResult = await Bun2.build({
|
|
8123
|
+
entrypoints: [clientEntry],
|
|
8124
|
+
naming: "index.js",
|
|
8125
|
+
outdir: pOutDir,
|
|
8126
|
+
target: "browser",
|
|
8127
|
+
banner,
|
|
8128
|
+
sourcemap: sourcemapMode,
|
|
8129
|
+
minify: shouldMinify ? {
|
|
8130
|
+
identifiers: shouldObfuscate,
|
|
8131
|
+
syntax: true,
|
|
8132
|
+
whitespace: true
|
|
8133
|
+
} : false
|
|
8134
|
+
});
|
|
8135
|
+
if (!clientResult.success) {
|
|
8136
|
+
console.error(clientResult.logs);
|
|
8137
|
+
throw new AggregateError(clientResult.logs, "Multiplayer client build failed");
|
|
8138
|
+
}
|
|
8139
|
+
const clientSrc = join(srcDir, "client");
|
|
8140
|
+
await copyStaticWebFiles(clientSrc, pOutDir, clientSrc);
|
|
8141
|
+
const clientVendor = join(clientSrc, "vendor");
|
|
8142
|
+
if (existsSync(clientVendor)) {
|
|
8143
|
+
await copyDirectoryRecursive(clientVendor, join(pOutDir, "vendor"));
|
|
8144
|
+
}
|
|
8145
|
+
clientElapsed = Date.now() - clientStart;
|
|
8146
|
+
}
|
|
8147
|
+
if (existsSync(serverEntry)) {
|
|
8148
|
+
const serverStart = Date.now();
|
|
8149
|
+
const serverResult = await Bun2.build({
|
|
8150
|
+
entrypoints: [serverEntry],
|
|
8151
|
+
naming: "server.js",
|
|
8152
|
+
outdir: pOutDir,
|
|
8153
|
+
target: "node",
|
|
8154
|
+
banner,
|
|
8155
|
+
sourcemap: sourcemapMode,
|
|
8156
|
+
minify: shouldMinify ? {
|
|
8157
|
+
identifiers: shouldObfuscate,
|
|
8158
|
+
syntax: true,
|
|
8159
|
+
whitespace: true
|
|
8160
|
+
} : false
|
|
8161
|
+
});
|
|
8162
|
+
if (!serverResult.success) {
|
|
8163
|
+
console.error(serverResult.logs);
|
|
8164
|
+
throw new AggregateError(serverResult.logs, "Multiplayer server build failed");
|
|
8165
|
+
}
|
|
8166
|
+
const settingsFile = join(srcDir, "server", "settings.json");
|
|
8167
|
+
if (existsSync(settingsFile)) {
|
|
8168
|
+
await fs.copyFile(settingsFile, join(pOutDir, "settings.json"));
|
|
8169
|
+
}
|
|
8170
|
+
serverElapsed = Date.now() - serverStart;
|
|
8171
|
+
}
|
|
8172
|
+
const rootFavicon = join(pProjectRoot, "favicon.ico");
|
|
8173
|
+
if (existsSync(rootFavicon)) {
|
|
8174
|
+
await fs.copyFile(rootFavicon, join(pOutDir, "favicon.ico"));
|
|
8175
|
+
}
|
|
8176
|
+
if (isVerbose) {
|
|
8177
|
+
if (clientElapsed) {
|
|
8178
|
+
console.log(source_default.hex("#ffa552")(`[Kit CLI] Multiplayer Client Build took: ${clientElapsed}ms`));
|
|
8179
|
+
}
|
|
8180
|
+
if (serverElapsed) {
|
|
8181
|
+
console.log(source_default.hex("#ffa552")(`[Kit CLI] Multiplayer Server Build took: ${serverElapsed}ms`));
|
|
8182
|
+
}
|
|
8183
|
+
}
|
|
8184
|
+
return {
|
|
8185
|
+
architecture: "multi",
|
|
8186
|
+
clientBuildTime: clientElapsed,
|
|
8187
|
+
serverBuildTime: serverElapsed,
|
|
8188
|
+
success: true
|
|
8189
|
+
};
|
|
8190
|
+
}
|
|
8191
|
+
return { architecture: "none", success: true };
|
|
8192
|
+
} catch (pError) {
|
|
8193
|
+
console.error(source_default.hex("#c42847")(`[Kit CLI Build Error] ${pError}`));
|
|
8194
|
+
return { architecture, success: false };
|
|
8195
|
+
}
|
|
8196
|
+
}
|
|
8197
|
+
|
|
7990
8198
|
// src/cli/resource-builder.ts
|
|
7991
8199
|
var log = console.log;
|
|
7992
8200
|
var info = source_default.hex("#ffa552");
|
|
@@ -8009,7 +8217,7 @@ function initializeResourceJSON() {
|
|
|
8009
8217
|
}, {});
|
|
8010
8218
|
}
|
|
8011
8219
|
function prepareFileForProcessing(pFilePath) {
|
|
8012
|
-
const extension =
|
|
8220
|
+
const extension = extname2(pFilePath).slice(1);
|
|
8013
8221
|
const fileName = basename(pFilePath);
|
|
8014
8222
|
const resourceIdentifier = `${v4_default()}.vyr`;
|
|
8015
8223
|
const type = getResourceType(extension);
|
|
@@ -8045,19 +8253,19 @@ function getResourceType(pExtension) {
|
|
|
8045
8253
|
}
|
|
8046
8254
|
async function processDirectory(pDirectoryPath) {
|
|
8047
8255
|
try {
|
|
8048
|
-
const contents = await
|
|
8256
|
+
const contents = await fs2.readdir(pDirectoryPath);
|
|
8049
8257
|
for (const item of contents) {
|
|
8050
|
-
const itemPath =
|
|
8258
|
+
const itemPath = join2(pDirectoryPath, item);
|
|
8051
8259
|
if (resolve(itemPath) === resourceOutDirectory) {
|
|
8052
8260
|
continue;
|
|
8053
8261
|
}
|
|
8054
|
-
const stats = await
|
|
8262
|
+
const stats = await fs2.stat(itemPath);
|
|
8055
8263
|
if (stats.isDirectory()) {
|
|
8056
8264
|
if (pDirectoryPath === resourceInDirectory) {
|
|
8057
8265
|
subdirectoriesToMirror.push(item);
|
|
8058
8266
|
}
|
|
8059
8267
|
await processDirectory(itemPath);
|
|
8060
|
-
} else if (isValidExtension(
|
|
8268
|
+
} else if (isValidExtension(extname2(itemPath).slice(1))) {
|
|
8061
8269
|
prepareFileForProcessing(itemPath);
|
|
8062
8270
|
}
|
|
8063
8271
|
}
|
|
@@ -8068,18 +8276,22 @@ async function processDirectory(pDirectoryPath) {
|
|
|
8068
8276
|
function isValidExtension(pExtension) {
|
|
8069
8277
|
return VALID_EXTENSIONS.includes(pExtension);
|
|
8070
8278
|
}
|
|
8279
|
+
var ENGINE_EXTENSIONS = ["vyint", "vyi", "vym", "vymac"];
|
|
8280
|
+
function isEngineExtension(pExtension) {
|
|
8281
|
+
return ENGINE_EXTENSIONS.includes(pExtension);
|
|
8282
|
+
}
|
|
8071
8283
|
async function mirrorDirectory(pSourceDir, pDestDir) {
|
|
8072
|
-
const entries = await
|
|
8073
|
-
await
|
|
8284
|
+
const entries = await fs2.readdir(pSourceDir, { withFileTypes: true });
|
|
8285
|
+
await fs2.mkdir(pDestDir, { recursive: true });
|
|
8074
8286
|
for (const entry of entries) {
|
|
8075
|
-
const srcPath =
|
|
8076
|
-
const destPath =
|
|
8287
|
+
const srcPath = join2(pSourceDir, entry.name);
|
|
8288
|
+
const destPath = join2(pDestDir, entry.name);
|
|
8077
8289
|
if (entry.isDirectory()) {
|
|
8078
8290
|
await mirrorDirectory(srcPath, destPath);
|
|
8079
8291
|
} else {
|
|
8080
|
-
const ext =
|
|
8081
|
-
if (!
|
|
8082
|
-
await
|
|
8292
|
+
const ext = extname2(entry.name).slice(1);
|
|
8293
|
+
if (!isEngineExtension(ext)) {
|
|
8294
|
+
await fs2.copyFile(srcPath, destPath);
|
|
8083
8295
|
}
|
|
8084
8296
|
}
|
|
8085
8297
|
}
|
|
@@ -8093,14 +8305,14 @@ async function processAllFiles() {
|
|
|
8093
8305
|
if (!resource) {
|
|
8094
8306
|
throw new Error(`Resource not found for file: ${fileName}`);
|
|
8095
8307
|
}
|
|
8096
|
-
const destination =
|
|
8308
|
+
const destination = join2(resourceOutDirectory, "resources");
|
|
8097
8309
|
const resourceName = resource.resourceIdentifier;
|
|
8098
8310
|
return copyFile(filePath, destination, resourceName);
|
|
8099
8311
|
});
|
|
8100
8312
|
await Promise.all(copyOperations);
|
|
8101
8313
|
for (const subDir of subdirectoriesToMirror) {
|
|
8102
|
-
const srcPath =
|
|
8103
|
-
const destPath =
|
|
8314
|
+
const srcPath = join2(resourceInDirectory, subDir);
|
|
8315
|
+
const destPath = join2(resourceOutDirectory, "resources", subDir);
|
|
8104
8316
|
await mirrorDirectory(srcPath, destPath);
|
|
8105
8317
|
}
|
|
8106
8318
|
logVerbose(`[Kit CLI] All resources have been processed.`);
|
|
@@ -8122,7 +8334,7 @@ async function buildBoundsJSON() {
|
|
|
8122
8334
|
if (type !== "icon")
|
|
8123
8335
|
continue;
|
|
8124
8336
|
try {
|
|
8125
|
-
const fileBuffer = await
|
|
8337
|
+
const fileBuffer = await fs2.readFile(filePath);
|
|
8126
8338
|
const vyi = new VYI().parse(fileBuffer);
|
|
8127
8339
|
const atlasName = basename(filePath, ".vyi");
|
|
8128
8340
|
const atlasEntry = {};
|
|
@@ -8163,7 +8375,7 @@ async function buildBoundsJSON() {
|
|
|
8163
8375
|
async function saveBoundsJSON(pBoundsData) {
|
|
8164
8376
|
const filePath = "bounds.json";
|
|
8165
8377
|
try {
|
|
8166
|
-
await
|
|
8378
|
+
await fs2.writeFile(filePath, JSON.stringify(pBoundsData));
|
|
8167
8379
|
} catch (pError) {
|
|
8168
8380
|
logError(`[Error] Saving bounds JSON: ${pError}`);
|
|
8169
8381
|
}
|
|
@@ -8174,7 +8386,7 @@ async function buildIconPointsJSON() {
|
|
|
8174
8386
|
if (type !== "icon")
|
|
8175
8387
|
continue;
|
|
8176
8388
|
try {
|
|
8177
|
-
const fileBuffer = await
|
|
8389
|
+
const fileBuffer = await fs2.readFile(filePath);
|
|
8178
8390
|
const vyi = new VYI().parse(fileBuffer);
|
|
8179
8391
|
const atlasName = basename(filePath, ".vyi");
|
|
8180
8392
|
const atlasEntry = {};
|
|
@@ -8233,7 +8445,7 @@ async function buildIconPointsJSON() {
|
|
|
8233
8445
|
async function saveIconPointsJSON(pPointsData) {
|
|
8234
8446
|
const filePath = "icon-points.json";
|
|
8235
8447
|
try {
|
|
8236
|
-
await
|
|
8448
|
+
await fs2.writeFile(filePath, JSON.stringify(pPointsData));
|
|
8237
8449
|
} catch (pError) {
|
|
8238
8450
|
logError(`[Error] Saving icon points JSON: ${pError}`);
|
|
8239
8451
|
}
|
|
@@ -8244,7 +8456,7 @@ async function buildSizesJSON() {
|
|
|
8244
8456
|
if (type !== "icon")
|
|
8245
8457
|
continue;
|
|
8246
8458
|
try {
|
|
8247
|
-
const fileBuffer = await
|
|
8459
|
+
const fileBuffer = await fs2.readFile(filePath);
|
|
8248
8460
|
const vyi = new VYI().parse(fileBuffer);
|
|
8249
8461
|
const atlasName = basename(filePath, ".vyi");
|
|
8250
8462
|
const atlasEntry = {};
|
|
@@ -8266,16 +8478,16 @@ async function buildSizesJSON() {
|
|
|
8266
8478
|
async function saveSizesJSON(pSizesData) {
|
|
8267
8479
|
const filePath = "sizes.json";
|
|
8268
8480
|
try {
|
|
8269
|
-
await
|
|
8481
|
+
await fs2.writeFile(filePath, JSON.stringify(pSizesData));
|
|
8270
8482
|
} catch (pError) {
|
|
8271
8483
|
logError(`[Error] Saving sizes JSON: ${pError}`);
|
|
8272
8484
|
}
|
|
8273
8485
|
}
|
|
8274
8486
|
async function clearResourceTypeDirectories(pBaseDirectory) {
|
|
8275
8487
|
try {
|
|
8276
|
-
const directoryExists = await
|
|
8488
|
+
const directoryExists = await fs2.stat(pBaseDirectory).then((stat) => stat.isDirectory()).catch(() => false);
|
|
8277
8489
|
if (directoryExists) {
|
|
8278
|
-
await
|
|
8490
|
+
await fs2.rm(pBaseDirectory, { recursive: true });
|
|
8279
8491
|
}
|
|
8280
8492
|
} catch (pError) {
|
|
8281
8493
|
log(`${error(`[Error]`)} clearing resource directory: ${pError}`);
|
|
@@ -8283,8 +8495,8 @@ async function clearResourceTypeDirectories(pBaseDirectory) {
|
|
|
8283
8495
|
}
|
|
8284
8496
|
async function copyFile(pSource, pDestinationDir, pNewName) {
|
|
8285
8497
|
try {
|
|
8286
|
-
await
|
|
8287
|
-
await
|
|
8498
|
+
await fs2.mkdir(pDestinationDir, { recursive: true });
|
|
8499
|
+
await fs2.copyFile(pSource, join2(pDestinationDir, pNewName));
|
|
8288
8500
|
} catch (pError) {
|
|
8289
8501
|
logError(`[Error] Copying file ${pSource}: ${pError}`);
|
|
8290
8502
|
}
|
|
@@ -8293,16 +8505,21 @@ async function saveResourceJSON() {
|
|
|
8293
8505
|
const jsonContent = JSON.stringify(resourceJSON, null, 4);
|
|
8294
8506
|
const targetPath = customManifestPath || "resource.json";
|
|
8295
8507
|
try {
|
|
8296
|
-
await
|
|
8508
|
+
await fs2.writeFile(targetPath, jsonContent, "utf8");
|
|
8297
8509
|
} catch (pError) {
|
|
8298
8510
|
logError(`[Error] Saving resource JSON to ${targetPath}: ${pError}`);
|
|
8299
8511
|
}
|
|
8300
8512
|
}
|
|
8513
|
+
var shouldBundleApp = false;
|
|
8514
|
+
var projectRootDirectory = "";
|
|
8515
|
+
var appBundleOptions = {};
|
|
8301
8516
|
async function runBuild() {
|
|
8302
8517
|
resourceJSON = initializeResourceJSON();
|
|
8303
8518
|
resourcesToProcess.length = 0;
|
|
8304
8519
|
subdirectoriesToMirror.length = 0;
|
|
8305
|
-
|
|
8520
|
+
if (existsSync2(resourceInDirectory)) {
|
|
8521
|
+
await processDirectory(resourceInDirectory);
|
|
8522
|
+
}
|
|
8306
8523
|
if (resourcesToProcess.length > 0 || subdirectoriesToMirror.length > 0) {
|
|
8307
8524
|
await processAllFiles();
|
|
8308
8525
|
} else {
|
|
@@ -8312,35 +8529,70 @@ async function runBuild() {
|
|
|
8312
8529
|
await saveIconPointsJSON({});
|
|
8313
8530
|
await saveSizesJSON({});
|
|
8314
8531
|
}
|
|
8532
|
+
if (shouldBundleApp && projectRootDirectory) {
|
|
8533
|
+
await bundleApp(projectRootDirectory, resourceOutDirectory, {
|
|
8534
|
+
...appBundleOptions,
|
|
8535
|
+
verbose: Boolean(isVerbose)
|
|
8536
|
+
});
|
|
8537
|
+
}
|
|
8315
8538
|
logVerbose(`[Kit CLI] Resources built successfully.`);
|
|
8316
8539
|
}
|
|
8317
8540
|
async function runWatch() {
|
|
8318
8541
|
await runBuild();
|
|
8319
8542
|
console.log(source_default.cyan(`
|
|
8320
|
-
|
|
8543
|
+
Watching for changes in: ${source_default.bold(resourceInDirectory)}`));
|
|
8321
8544
|
let debounceTimer = null;
|
|
8322
|
-
const
|
|
8323
|
-
if (!pFilename)
|
|
8324
|
-
return;
|
|
8545
|
+
const triggerRebuild = (pFilename) => {
|
|
8325
8546
|
if (debounceTimer)
|
|
8326
8547
|
clearTimeout(debounceTimer);
|
|
8327
8548
|
debounceTimer = setTimeout(async () => {
|
|
8328
8549
|
console.log(source_default.dim(`
|
|
8329
|
-
|
|
8550
|
+
File changed: ${pFilename}, rebuilding...`));
|
|
8330
8551
|
await runBuild();
|
|
8331
8552
|
}, 150);
|
|
8332
|
-
}
|
|
8553
|
+
};
|
|
8554
|
+
const watchers = [];
|
|
8555
|
+
if (existsSync2(resourceInDirectory)) {
|
|
8556
|
+
const resWatcher = fsWatch(resourceInDirectory, { recursive: true }, (_eventType, pFilename) => {
|
|
8557
|
+
if (pFilename)
|
|
8558
|
+
triggerRebuild(pFilename);
|
|
8559
|
+
});
|
|
8560
|
+
watchers.push(resWatcher);
|
|
8561
|
+
}
|
|
8562
|
+
const srcDir = join2(projectRootDirectory, "src");
|
|
8563
|
+
if (shouldBundleApp && existsSync2(srcDir) && srcDir !== resourceInDirectory) {
|
|
8564
|
+
const srcWatcher = fsWatch(srcDir, { recursive: true }, (_eventType, pFilename) => {
|
|
8565
|
+
if (!pFilename)
|
|
8566
|
+
return;
|
|
8567
|
+
if (pFilename.startsWith("resources"))
|
|
8568
|
+
return;
|
|
8569
|
+
triggerRebuild(pFilename);
|
|
8570
|
+
});
|
|
8571
|
+
watchers.push(srcWatcher);
|
|
8572
|
+
}
|
|
8333
8573
|
process.on("SIGINT", () => {
|
|
8334
|
-
|
|
8574
|
+
for (const w of watchers)
|
|
8575
|
+
w.close();
|
|
8335
8576
|
process.exit(0);
|
|
8336
8577
|
});
|
|
8337
8578
|
}
|
|
8338
|
-
async function processResources({ inDirectory, outDirectory, manifestPath, watch, verbose, ignoreSound }) {
|
|
8339
|
-
|
|
8340
|
-
|
|
8579
|
+
async function processResources({ inDirectory, outDirectory, manifestPath, watch, verbose, ignoreSound, app, minify, obfuscate, sourcemap, prod }) {
|
|
8580
|
+
projectRootDirectory = process.cwd();
|
|
8581
|
+
const resolvedIn = inDirectory || (existsSync2(join2(projectRootDirectory, "src", "resources")) ? "src/resources" : "");
|
|
8582
|
+
const resolvedOut = outDirectory || "dist";
|
|
8583
|
+
resourceInDirectory = resolvedIn ? resolve(resolvedIn) : "";
|
|
8584
|
+
resourceOutDirectory = resolvedOut ? resolve(resolvedOut) : "";
|
|
8341
8585
|
customManifestPath = manifestPath;
|
|
8342
8586
|
isVerbose = verbose;
|
|
8343
8587
|
ignoringSound = ignoreSound;
|
|
8588
|
+
appBundleOptions = {
|
|
8589
|
+
minify,
|
|
8590
|
+
obfuscate,
|
|
8591
|
+
sourcemap,
|
|
8592
|
+
prod
|
|
8593
|
+
};
|
|
8594
|
+
const hasAppEntry = existsSync2(join2(projectRootDirectory, "src", "index.ts")) || existsSync2(join2(projectRootDirectory, "src", "client", "index.ts")) || existsSync2(join2(projectRootDirectory, "src", "server", "index.ts"));
|
|
8595
|
+
shouldBundleApp = app !== undefined ? app : hasAppEntry;
|
|
8344
8596
|
if (!resourceInDirectory || !resourceOutDirectory) {
|
|
8345
8597
|
logError("[Error] Input and output directories must be specified");
|
|
8346
8598
|
return;
|
|
@@ -8364,11 +8616,11 @@ function logAlert(pMessage) {
|
|
|
8364
8616
|
|
|
8365
8617
|
// node_modules/@clack/core/dist/index.mjs
|
|
8366
8618
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
8367
|
-
import { styleText as D } from "
|
|
8368
|
-
import { stdout as R, stdin as q } from "
|
|
8369
|
-
import * as k from "
|
|
8370
|
-
import ot from "
|
|
8371
|
-
import { ReadStream as J } from "
|
|
8619
|
+
import { styleText as D } from "util";
|
|
8620
|
+
import { stdout as R, stdin as q } from "process";
|
|
8621
|
+
import * as k from "readline";
|
|
8622
|
+
import ot from "readline";
|
|
8623
|
+
import { ReadStream as J } from "tty";
|
|
8372
8624
|
function x(t, e, s) {
|
|
8373
8625
|
if (!s.some((u) => !u.disabled))
|
|
8374
8626
|
return t;
|
|
@@ -8452,7 +8704,7 @@ var X = (t, e = {}, s = {}) => {
|
|
|
8452
8704
|
var pt = { limit: 1 / 0, ellipsis: "", ellipsisWidth: 0 };
|
|
8453
8705
|
var S = (t, e = {}) => X(t, pt, e).width;
|
|
8454
8706
|
var T = "\x1B";
|
|
8455
|
-
var Z = "
|
|
8707
|
+
var Z = "\x9B";
|
|
8456
8708
|
var Ft = 39;
|
|
8457
8709
|
var j = "\x07";
|
|
8458
8710
|
var Q = "[";
|
|
@@ -8773,7 +9025,7 @@ class Vt extends B {
|
|
|
8773
9025
|
if (!this.userInput)
|
|
8774
9026
|
return D(["inverse", "hidden"], "_");
|
|
8775
9027
|
if (this._cursor >= this.userInput.length)
|
|
8776
|
-
return `${this.userInput}
|
|
9028
|
+
return `${this.userInput}\u2588`;
|
|
8777
9029
|
const e = this.userInput.slice(0, this._cursor), [s, ...i] = this.userInput.slice(this._cursor);
|
|
8778
9030
|
return `${e}${D("inverse", s)}${i.join("")}`;
|
|
8779
9031
|
}
|
|
@@ -8916,7 +9168,7 @@ class $t extends B {
|
|
|
8916
9168
|
return this.userInput;
|
|
8917
9169
|
const e = this.userInput;
|
|
8918
9170
|
if (this.cursor >= e.length)
|
|
8919
|
-
return `${this.userInput}
|
|
9171
|
+
return `${this.userInput}\u2588`;
|
|
8920
9172
|
const s = e.slice(0, this.cursor), [i, ...r] = e.slice(this.cursor);
|
|
8921
9173
|
return `${s}${D("inverse", i)}${r.join("")}`;
|
|
8922
9174
|
}
|
|
@@ -8933,8 +9185,8 @@ class $t extends B {
|
|
|
8933
9185
|
}
|
|
8934
9186
|
|
|
8935
9187
|
// node_modules/@clack/prompts/dist/index.mjs
|
|
8936
|
-
import { styleText as t, stripVTControlCharacters as ue } from "
|
|
8937
|
-
import N2 from "
|
|
9188
|
+
import { styleText as t, stripVTControlCharacters as ue } from "util";
|
|
9189
|
+
import N2 from "process";
|
|
8938
9190
|
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
8939
9191
|
function pt2() {
|
|
8940
9192
|
return N2.platform !== "win32" ? N2.env.TERM !== "linux" : !!N2.env.CI || !!N2.env.WT_SESSION || !!N2.env.TERMINUS_SUBLIME || N2.env.ConEmuTask === "{cmd::Cmder}" || N2.env.TERM_PROGRAM === "Terminus-Sublime" || N2.env.TERM_PROGRAM === "vscode" || N2.env.TERM === "xterm-256color" || N2.env.TERM === "alacritty" || N2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
@@ -8942,31 +9194,31 @@ function pt2() {
|
|
|
8942
9194
|
var ee = pt2();
|
|
8943
9195
|
var ce = () => process.env.CI === "true";
|
|
8944
9196
|
var I2 = (e, r) => ee ? e : r;
|
|
8945
|
-
var Re = I2("
|
|
8946
|
-
var $e = I2("
|
|
8947
|
-
var de = I2("
|
|
8948
|
-
var V = I2("
|
|
8949
|
-
var he = I2("
|
|
8950
|
-
var h = I2("
|
|
8951
|
-
var x2 = I2("
|
|
8952
|
-
var Oe = I2("
|
|
8953
|
-
var Pe = I2("
|
|
8954
|
-
var z2 = I2("
|
|
8955
|
-
var H2 = I2("
|
|
8956
|
-
var te = I2("
|
|
8957
|
-
var U2 = I2("
|
|
8958
|
-
var q2 = I2("
|
|
8959
|
-
var Ne = I2("
|
|
8960
|
-
var se = I2("
|
|
8961
|
-
var pe = I2("
|
|
8962
|
-
var We = I2("
|
|
8963
|
-
var me = I2("
|
|
8964
|
-
var ge = I2("
|
|
8965
|
-
var Ge = I2("
|
|
8966
|
-
var fe = I2("
|
|
8967
|
-
var Fe = I2("
|
|
8968
|
-
var ye = I2("
|
|
8969
|
-
var Ee = I2("
|
|
9197
|
+
var Re = I2("\u25C6", "*");
|
|
9198
|
+
var $e = I2("\u25A0", "x");
|
|
9199
|
+
var de = I2("\u25B2", "x");
|
|
9200
|
+
var V = I2("\u25C7", "o");
|
|
9201
|
+
var he = I2("\u250C", "T");
|
|
9202
|
+
var h = I2("\u2502", "|");
|
|
9203
|
+
var x2 = I2("\u2514", "\u2014");
|
|
9204
|
+
var Oe = I2("\u2510", "T");
|
|
9205
|
+
var Pe = I2("\u2518", "\u2014");
|
|
9206
|
+
var z2 = I2("\u25CF", ">");
|
|
9207
|
+
var H2 = I2("\u25CB", " ");
|
|
9208
|
+
var te = I2("\u25FB", "[\u2022]");
|
|
9209
|
+
var U2 = I2("\u25FC", "[+]");
|
|
9210
|
+
var q2 = I2("\u25FB", "[ ]");
|
|
9211
|
+
var Ne = I2("\u25AA", "\u2022");
|
|
9212
|
+
var se = I2("\u2500", "-");
|
|
9213
|
+
var pe = I2("\u256E", "+");
|
|
9214
|
+
var We = I2("\u251C", "+");
|
|
9215
|
+
var me = I2("\u256F", "+");
|
|
9216
|
+
var ge = I2("\u2570", "+");
|
|
9217
|
+
var Ge = I2("\u256D", "+");
|
|
9218
|
+
var fe = I2("\u25CF", "\u2022");
|
|
9219
|
+
var Fe = I2("\u25C6", "*");
|
|
9220
|
+
var ye = I2("\u25B2", "!");
|
|
9221
|
+
var Ee = I2("\u25A0", "x");
|
|
8970
9222
|
var W2 = (e) => {
|
|
8971
9223
|
switch (e) {
|
|
8972
9224
|
case "initial":
|
|
@@ -9070,7 +9322,7 @@ var Le = (e, r = {}, s = {}) => {
|
|
|
9070
9322
|
var Et2 = { limit: 1 / 0, ellipsis: "", ellipsisWidth: 0 };
|
|
9071
9323
|
var D2 = (e, r = {}) => Le(e, Et2, r).width;
|
|
9072
9324
|
var ae = "\x1B";
|
|
9073
|
-
var je = "
|
|
9325
|
+
var je = "\x9B";
|
|
9074
9326
|
var vt2 = 39;
|
|
9075
9327
|
var Ce = "\x07";
|
|
9076
9328
|
var ke = "[";
|
|
@@ -9273,7 +9525,7 @@ ${t("gray", f + se.repeat(n + 2) + me)}
|
|
|
9273
9525
|
`);
|
|
9274
9526
|
};
|
|
9275
9527
|
var Kt = (e) => t("magenta", e);
|
|
9276
|
-
var be = ({ indicator: e = "dots", onCancel: r, output: s = process.stdout, cancelMessage: i, errorMessage: a, frames: o = ee ? ["
|
|
9528
|
+
var be = ({ indicator: e = "dots", onCancel: r, output: s = process.stdout, cancelMessage: i, errorMessage: a, frames: o = ee ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], delay: u = ee ? 80 : 120, signal: l, ...n } = {}) => {
|
|
9277
9529
|
const c = ce();
|
|
9278
9530
|
let p, f, g = false, E = false, $ = "", m, d = performance.now();
|
|
9279
9531
|
const F = rt(s), y2 = n?.styleFrame ?? Kt, v = (B2) => {
|
|
@@ -9330,7 +9582,7 @@ var be = ({ indicator: e = "dots", onCancel: r, output: s = process.stdout, canc
|
|
|
9330
9582
|
return E;
|
|
9331
9583
|
} };
|
|
9332
9584
|
};
|
|
9333
|
-
var ze = { light: I2("
|
|
9585
|
+
var ze = { light: I2("\u2500", "-"), heavy: I2("\u2501", "="), block: I2("\u2588", "#") };
|
|
9334
9586
|
var oe = (e, r) => e.includes(`
|
|
9335
9587
|
`) ? e.split(`
|
|
9336
9588
|
`).map((s) => r(s)).join(`
|
|
@@ -9408,15 +9660,15 @@ ${l}
|
|
|
9408
9660
|
} }).prompt();
|
|
9409
9661
|
|
|
9410
9662
|
// src/cli/init.ts
|
|
9411
|
-
import
|
|
9412
|
-
import path from "
|
|
9413
|
-
import { fileURLToPath } from "
|
|
9414
|
-
import { spawnSync, execSync } from "
|
|
9415
|
-
import os2 from "
|
|
9663
|
+
import fs3 from "fs";
|
|
9664
|
+
import path from "path";
|
|
9665
|
+
import { fileURLToPath } from "url";
|
|
9666
|
+
import { spawnSync, execSync } from "child_process";
|
|
9667
|
+
import os2 from "os";
|
|
9416
9668
|
// package.json
|
|
9417
9669
|
var package_default = {
|
|
9418
9670
|
name: "@evitcastudio/kit",
|
|
9419
|
-
version: "3.
|
|
9671
|
+
version: "3.2.2",
|
|
9420
9672
|
author: "doubleactii 56242467+doubleactii@users.noreply.github.com (https://evitcastudio.com)",
|
|
9421
9673
|
main: "./lib/index.js",
|
|
9422
9674
|
types: "./lib/index.d.ts",
|
|
@@ -9459,7 +9711,7 @@ var package_default = {
|
|
|
9459
9711
|
"build-all": "bun run build-types && bun run build && bun run build-docs"
|
|
9460
9712
|
},
|
|
9461
9713
|
bin: {
|
|
9462
|
-
kit: "lib/
|
|
9714
|
+
kit: "lib/cli-runner.cjs"
|
|
9463
9715
|
},
|
|
9464
9716
|
devDependencies: {
|
|
9465
9717
|
"@eslint/create-config": "1.4.0",
|
|
@@ -9516,15 +9768,15 @@ function installBun() {
|
|
|
9516
9768
|
}
|
|
9517
9769
|
}
|
|
9518
9770
|
function copyTemplate(pSrc, pDest, pProjectName, pVersion, pAuthor) {
|
|
9519
|
-
if (!
|
|
9520
|
-
|
|
9771
|
+
if (!fs3.existsSync(pDest)) {
|
|
9772
|
+
fs3.mkdirSync(pDest, { recursive: true });
|
|
9521
9773
|
}
|
|
9522
|
-
const files =
|
|
9774
|
+
const files = fs3.readdirSync(pSrc);
|
|
9523
9775
|
for (const file of files) {
|
|
9524
9776
|
const srcPath = path.join(pSrc, file);
|
|
9525
9777
|
const destFile = file === "_gitignore" ? ".gitignore" : file;
|
|
9526
9778
|
const destPath = path.join(pDest, destFile);
|
|
9527
|
-
const stats =
|
|
9779
|
+
const stats = fs3.statSync(srcPath);
|
|
9528
9780
|
if (stats.isDirectory()) {
|
|
9529
9781
|
if (file === ".git")
|
|
9530
9782
|
continue;
|
|
@@ -9533,13 +9785,13 @@ function copyTemplate(pSrc, pDest, pProjectName, pVersion, pAuthor) {
|
|
|
9533
9785
|
const ext = path.extname(file).toLowerCase();
|
|
9534
9786
|
const textExtensions = [".ts", ".js", ".json", ".html", ".css", ".md", ".txt"];
|
|
9535
9787
|
if (textExtensions.includes(ext)) {
|
|
9536
|
-
let content =
|
|
9788
|
+
let content = fs3.readFileSync(srcPath, "utf8");
|
|
9537
9789
|
content = content.replace(/{{PROJECT_NAME}}/g, pProjectName);
|
|
9538
9790
|
content = content.replace(/{{VERSION}}/g, pVersion);
|
|
9539
9791
|
content = content.replace(/{{PROJECT_AUTHOR}}/g, pAuthor);
|
|
9540
|
-
|
|
9792
|
+
fs3.writeFileSync(destPath, content);
|
|
9541
9793
|
} else {
|
|
9542
|
-
|
|
9794
|
+
fs3.copyFileSync(srcPath, destPath);
|
|
9543
9795
|
}
|
|
9544
9796
|
}
|
|
9545
9797
|
}
|
|
@@ -9619,7 +9871,7 @@ Note: Kit projects cannot build or run without Bun.`);
|
|
|
9619
9871
|
projectName = "kit-project";
|
|
9620
9872
|
}
|
|
9621
9873
|
const projectDir = path.join(process.cwd(), projectName);
|
|
9622
|
-
if (
|
|
9874
|
+
if (fs3.existsSync(projectDir)) {
|
|
9623
9875
|
if (isInteractive) {
|
|
9624
9876
|
const overwrite = await Rt({
|
|
9625
9877
|
message: `Directory ${source_default.cyan(projectName)} already exists. Overwrite?`,
|
|
@@ -9639,18 +9891,18 @@ Error: Destination directory '${projectName}' already exists. Use --force (-f) t
|
|
|
9639
9891
|
s.start(`Scaffolding ${source_default.cyan(projectName)}...`);
|
|
9640
9892
|
try {
|
|
9641
9893
|
const projectPath = path.join(process.cwd(), projectName);
|
|
9642
|
-
if (
|
|
9643
|
-
|
|
9894
|
+
if (fs3.existsSync(projectPath)) {
|
|
9895
|
+
fs3.rmSync(projectPath, { recursive: true, force: true });
|
|
9644
9896
|
}
|
|
9645
|
-
|
|
9897
|
+
fs3.mkdirSync(projectPath, { recursive: true });
|
|
9646
9898
|
let templateType = gameType;
|
|
9647
9899
|
if (gameType === "both")
|
|
9648
9900
|
templateType = "multi";
|
|
9649
9901
|
const templatesDir = path.join(path.dirname(fileURLToPath(import.meta.url)), "kit-game-templates", templateType);
|
|
9650
9902
|
const author = getGitUser();
|
|
9651
|
-
if (!
|
|
9903
|
+
if (!fs3.existsSync(templatesDir)) {
|
|
9652
9904
|
const localTemplatesDir = path.join(process.cwd(), "kit-game-templates", templateType);
|
|
9653
|
-
if (!
|
|
9905
|
+
if (!fs3.existsSync(localTemplatesDir)) {
|
|
9654
9906
|
console.error(source_default.red(`Error: Templates not found at ${templatesDir} or ${localTemplatesDir}`));
|
|
9655
9907
|
process.exit(1);
|
|
9656
9908
|
}
|
|
@@ -9678,23 +9930,23 @@ Error: Destination directory '${projectName}' already exists. Use --force (-f) t
|
|
|
9678
9930
|
installSpinner.stop(source_default.yellow("Dependency installation finished with warnings."));
|
|
9679
9931
|
}
|
|
9680
9932
|
}
|
|
9681
|
-
console.log(`${source_default.cyan("
|
|
9682
|
-
console.log(`${source_default.cyan("
|
|
9683
|
-
console.log(`${source_default.cyan("
|
|
9933
|
+
console.log(`${source_default.cyan("\u2502")}`);
|
|
9934
|
+
console.log(`${source_default.cyan("\u2502")} ${source_default.white.bold("Next steps:")}`);
|
|
9935
|
+
console.log(`${source_default.cyan("\u2502")} ${source_default.dim("1.")} cd ${source_default.cyan(projectName)}`);
|
|
9684
9936
|
if (!shouldInstall) {
|
|
9685
|
-
console.log(`${source_default.cyan("
|
|
9686
|
-
console.log(`${source_default.cyan("
|
|
9937
|
+
console.log(`${source_default.cyan("\u2502")} ${source_default.dim("2.")} bun install`);
|
|
9938
|
+
console.log(`${source_default.cyan("\u2502")} ${source_default.dim("3.")} bun run build`);
|
|
9687
9939
|
} else {
|
|
9688
|
-
console.log(`${source_default.cyan("
|
|
9940
|
+
console.log(`${source_default.cyan("\u2502")} ${source_default.dim("2.")} bun run build`);
|
|
9689
9941
|
}
|
|
9690
|
-
console.log(`${source_default.cyan("
|
|
9942
|
+
console.log(`${source_default.cyan("\u2502")}`);
|
|
9691
9943
|
Gt(source_default.green.bold("Happy coding!"));
|
|
9692
9944
|
} catch (pError) {
|
|
9693
9945
|
s.stop(source_default.red("Scaffolding failed."));
|
|
9694
9946
|
if (projectName) {
|
|
9695
9947
|
const projectPath = path.join(process.cwd(), projectName);
|
|
9696
|
-
if (
|
|
9697
|
-
|
|
9948
|
+
if (fs3.existsSync(projectPath)) {
|
|
9949
|
+
fs3.rmSync(projectPath, { recursive: true, force: true });
|
|
9698
9950
|
}
|
|
9699
9951
|
}
|
|
9700
9952
|
console.error(pError);
|
|
@@ -9703,9 +9955,9 @@ Error: Destination directory '${projectName}' already exists. Use --force (-f) t
|
|
|
9703
9955
|
}
|
|
9704
9956
|
|
|
9705
9957
|
// src/cli/doctor.ts
|
|
9706
|
-
import { spawnSync as spawnSync2 } from "
|
|
9707
|
-
import { existsSync, readFileSync } from "
|
|
9708
|
-
import { join as
|
|
9958
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
9959
|
+
import { existsSync as existsSync3, readFileSync } from "fs";
|
|
9960
|
+
import { join as join3 } from "path";
|
|
9709
9961
|
async function processDoctor(pOptions = {}) {
|
|
9710
9962
|
const isVerbose2 = Boolean(pOptions.verbose);
|
|
9711
9963
|
const results = [];
|
|
@@ -9745,8 +9997,8 @@ async function processDoctor(pOptions = {}) {
|
|
|
9745
9997
|
});
|
|
9746
9998
|
}
|
|
9747
9999
|
const cwd = process.cwd();
|
|
9748
|
-
const pkgPath =
|
|
9749
|
-
const hasPackageJson =
|
|
10000
|
+
const pkgPath = join3(cwd, "package.json");
|
|
10001
|
+
const hasPackageJson = existsSync3(pkgPath);
|
|
9750
10002
|
if (hasPackageJson) {
|
|
9751
10003
|
try {
|
|
9752
10004
|
const rawPkg = readFileSync(pkgPath, "utf8");
|
|
@@ -9766,8 +10018,8 @@ async function processDoctor(pOptions = {}) {
|
|
|
9766
10018
|
});
|
|
9767
10019
|
const isKitCoreRepo = pkg.name === "@evitcastudio/kit";
|
|
9768
10020
|
if (!isKitCoreRepo) {
|
|
9769
|
-
const resourcesDir =
|
|
9770
|
-
const hasResources =
|
|
10021
|
+
const resourcesDir = join3(cwd, "src", "resources");
|
|
10022
|
+
const hasResources = existsSync3(resourcesDir);
|
|
9771
10023
|
results.push({
|
|
9772
10024
|
category: "Project",
|
|
9773
10025
|
title: "Asset Directory (src/resources)",
|
|
@@ -9775,6 +10027,25 @@ async function processDoctor(pOptions = {}) {
|
|
|
9775
10027
|
details: hasResources ? "Asset directory present" : "src/resources not found"
|
|
9776
10028
|
});
|
|
9777
10029
|
}
|
|
10030
|
+
const hasClientEntry = existsSync3(join3(cwd, "src", "client", "index.ts"));
|
|
10031
|
+
const hasServerEntry = existsSync3(join3(cwd, "src", "server", "index.ts"));
|
|
10032
|
+
const hasSingleEntry = existsSync3(join3(cwd, "src", "index.ts"));
|
|
10033
|
+
let projectType = "Unknown";
|
|
10034
|
+
if (hasClientEntry && hasServerEntry) {
|
|
10035
|
+
projectType = "Multiplayer (Client & Server)";
|
|
10036
|
+
} else if (hasClientEntry) {
|
|
10037
|
+
projectType = "Multiplayer (Client)";
|
|
10038
|
+
} else if (hasServerEntry) {
|
|
10039
|
+
projectType = "Dedicated Server";
|
|
10040
|
+
} else if (hasSingleEntry) {
|
|
10041
|
+
projectType = "Singleplayer";
|
|
10042
|
+
}
|
|
10043
|
+
results.push({
|
|
10044
|
+
category: "Project",
|
|
10045
|
+
title: "Project Architecture",
|
|
10046
|
+
passed: projectType !== "Unknown" || isKitCoreRepo,
|
|
10047
|
+
details: isKitCoreRepo ? "Kit Core Framework Repository" : `Detected Type: ${projectType}`
|
|
10048
|
+
});
|
|
9778
10049
|
} catch {
|
|
9779
10050
|
results.push({
|
|
9780
10051
|
category: "Project",
|
|
@@ -9783,13 +10054,31 @@ async function processDoctor(pOptions = {}) {
|
|
|
9783
10054
|
details: "package.json is malformed or invalid JSON"
|
|
9784
10055
|
});
|
|
9785
10056
|
}
|
|
9786
|
-
const buildScript =
|
|
9787
|
-
const hasBuildScript =
|
|
10057
|
+
const buildScript = join3(cwd, "bun-build.ts");
|
|
10058
|
+
const hasBuildScript = existsSync3(buildScript);
|
|
10059
|
+
let hasKitBuildScript = false;
|
|
10060
|
+
try {
|
|
10061
|
+
const rawPkg = readFileSync(pkgPath, "utf8");
|
|
10062
|
+
const pkg = JSON.parse(rawPkg);
|
|
10063
|
+
if (pkg.scripts && typeof pkg.scripts.build === "string" && pkg.scripts.build.includes("kit build")) {
|
|
10064
|
+
hasKitBuildScript = true;
|
|
10065
|
+
}
|
|
10066
|
+
} catch {
|
|
10067
|
+
}
|
|
10068
|
+
const buildPipelinePassed = hasBuildScript || hasKitBuildScript;
|
|
10069
|
+
let buildDetails = "No build pipeline configured";
|
|
10070
|
+
if (hasKitBuildScript && hasBuildScript) {
|
|
10071
|
+
buildDetails = "Kit CLI build pipeline with bun-build.ts present";
|
|
10072
|
+
} else if (hasKitBuildScript) {
|
|
10073
|
+
buildDetails = "Kit CLI native build pipeline configured";
|
|
10074
|
+
} else if (hasBuildScript) {
|
|
10075
|
+
buildDetails = "Legacy bun-build.ts present";
|
|
10076
|
+
}
|
|
9788
10077
|
results.push({
|
|
9789
10078
|
category: "Project",
|
|
9790
|
-
title: "Build Pipeline
|
|
9791
|
-
passed:
|
|
9792
|
-
details:
|
|
10079
|
+
title: "Build Pipeline",
|
|
10080
|
+
passed: buildPipelinePassed,
|
|
10081
|
+
details: buildDetails
|
|
9793
10082
|
});
|
|
9794
10083
|
} else {
|
|
9795
10084
|
results.push({
|
|
@@ -9801,7 +10090,7 @@ async function processDoctor(pOptions = {}) {
|
|
|
9801
10090
|
}
|
|
9802
10091
|
let allPassed = true;
|
|
9803
10092
|
for (const res of results) {
|
|
9804
|
-
const icon = res.passed ? source_default.green("
|
|
10093
|
+
const icon = res.passed ? source_default.green("\u2713") : source_default.red("\u2717");
|
|
9805
10094
|
const titleText = res.passed ? source_default.white(res.title) : source_default.red.bold(res.title);
|
|
9806
10095
|
console.log(` ${icon} [${source_default.cyan(res.category)}] ${titleText}`);
|
|
9807
10096
|
if (res.details && (!res.passed || isVerbose2)) {
|
|
@@ -9824,8 +10113,8 @@ async function processDoctor(pOptions = {}) {
|
|
|
9824
10113
|
}
|
|
9825
10114
|
|
|
9826
10115
|
// src/cli/create.ts
|
|
9827
|
-
import { promises as
|
|
9828
|
-
import { join as
|
|
10116
|
+
import { promises as fs4 } from "fs";
|
|
10117
|
+
import { join as join4 } from "path";
|
|
9829
10118
|
function toPascalCase(pName) {
|
|
9830
10119
|
return pName.replace(/[-_](\w)/g, (_2, c) => c.toUpperCase()).replace(/^\w/, (c) => c.toUpperCase());
|
|
9831
10120
|
}
|
|
@@ -9868,20 +10157,20 @@ Error: Unknown create type '${type}'. Supported types: 'plugin'`));
|
|
|
9868
10157
|
}
|
|
9869
10158
|
const className = toPascalCase(name);
|
|
9870
10159
|
const fileName = `${toKebabCase(name)}.ts`;
|
|
9871
|
-
const pluginsDir =
|
|
9872
|
-
const targetPath =
|
|
10160
|
+
const pluginsDir = join4(process.cwd(), "src", "plugins");
|
|
10161
|
+
const targetPath = join4(pluginsDir, fileName);
|
|
9873
10162
|
try {
|
|
9874
|
-
await
|
|
9875
|
-
const fileExists = await
|
|
10163
|
+
await fs4.mkdir(pluginsDir, { recursive: true });
|
|
10164
|
+
const fileExists = await fs4.stat(targetPath).then(() => true).catch(() => false);
|
|
9876
10165
|
if (fileExists) {
|
|
9877
10166
|
console.error(source_default.red(`
|
|
9878
10167
|
Error: File already exists at ${targetPath}`));
|
|
9879
10168
|
process.exit(1);
|
|
9880
10169
|
}
|
|
9881
10170
|
const sourceCode = generatePluginSource(className, className);
|
|
9882
|
-
await
|
|
10171
|
+
await fs4.writeFile(targetPath, sourceCode, "utf8");
|
|
9883
10172
|
console.log(`
|
|
9884
|
-
${source_default.green("
|
|
10173
|
+
${source_default.green("\u2713")} Created plugin ${source_default.cyan(className)} at ${source_default.dim(targetPath)}
|
|
9885
10174
|
`);
|
|
9886
10175
|
if (verbose) {
|
|
9887
10176
|
console.log(source_default.dim(sourceCode));
|
|
@@ -9894,6 +10183,132 @@ Error creating plugin: ${message}`));
|
|
|
9894
10183
|
}
|
|
9895
10184
|
}
|
|
9896
10185
|
|
|
10186
|
+
// src/cli/host.ts
|
|
10187
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
10188
|
+
import { join as join5, resolve as resolve2 } from "path";
|
|
10189
|
+
import { networkInterfaces } from "os";
|
|
10190
|
+
function getNetworkAddress() {
|
|
10191
|
+
const interfaces = networkInterfaces();
|
|
10192
|
+
for (const name of Object.keys(interfaces)) {
|
|
10193
|
+
const netList = interfaces[name];
|
|
10194
|
+
if (!netList)
|
|
10195
|
+
continue;
|
|
10196
|
+
for (const net of netList) {
|
|
10197
|
+
if (net.family === "IPv4" && !net.internal) {
|
|
10198
|
+
return net.address;
|
|
10199
|
+
}
|
|
10200
|
+
}
|
|
10201
|
+
}
|
|
10202
|
+
return "localhost";
|
|
10203
|
+
}
|
|
10204
|
+
async function processHost(pOptions = {}) {
|
|
10205
|
+
const cwd = process.cwd();
|
|
10206
|
+
const defaultPort = 8090;
|
|
10207
|
+
const port = pOptions.port || defaultPort;
|
|
10208
|
+
const distDir = pOptions.directory ? resolve2(pOptions.directory) : join5(cwd, "dist");
|
|
10209
|
+
const architecture = detectArchitecture(join5(cwd, "src"));
|
|
10210
|
+
if (!existsSync4(distDir)) {
|
|
10211
|
+
const message = `Target directory "${distDir}" does not exist. Run "kit build" or use "kit host -b" first.`;
|
|
10212
|
+
console.error(source_default.red(`
|
|
10213
|
+
[Kit Host] ${message}
|
|
10214
|
+
`));
|
|
10215
|
+
return { success: false, message };
|
|
10216
|
+
}
|
|
10217
|
+
if (architecture === "multi") {
|
|
10218
|
+
const serverJsPath = join5(distDir, "server.js");
|
|
10219
|
+
if (!existsSync4(serverJsPath)) {
|
|
10220
|
+
const message = `Cannot host multiplayer project: "${serverJsPath}" was not found. Please compile the server first using "kit build".`;
|
|
10221
|
+
console.error(source_default.red(`
|
|
10222
|
+
[Kit Host] ${message}
|
|
10223
|
+
`));
|
|
10224
|
+
return { success: false, message };
|
|
10225
|
+
}
|
|
10226
|
+
console.log(source_default.cyan(`
|
|
10227
|
+
Starting Multiplayer Server from ${source_default.bold(distDir)}...
|
|
10228
|
+
`));
|
|
10229
|
+
let serverSettingsPort = port;
|
|
10230
|
+
const settingsPath = join5(distDir, "settings.json");
|
|
10231
|
+
if (existsSync4(settingsPath)) {
|
|
10232
|
+
try {
|
|
10233
|
+
const settings = JSON.parse(readFileSync2(settingsPath, "utf8"));
|
|
10234
|
+
if (settings.port)
|
|
10235
|
+
serverSettingsPort = Number(settings.port);
|
|
10236
|
+
} catch {
|
|
10237
|
+
}
|
|
10238
|
+
}
|
|
10239
|
+
const proc = Bun.spawn(["node", "server.js"], {
|
|
10240
|
+
cwd: distDir,
|
|
10241
|
+
stdout: "inherit",
|
|
10242
|
+
stderr: "inherit",
|
|
10243
|
+
stdin: "inherit"
|
|
10244
|
+
});
|
|
10245
|
+
console.log(source_default.green(`\u2713 Multiplayer server process spawned (configured port: ${serverSettingsPort})`));
|
|
10246
|
+
process.on("SIGINT", () => {
|
|
10247
|
+
proc.kill();
|
|
10248
|
+
process.exit(0);
|
|
10249
|
+
});
|
|
10250
|
+
process.on("SIGTERM", () => {
|
|
10251
|
+
proc.kill();
|
|
10252
|
+
process.exit(0);
|
|
10253
|
+
});
|
|
10254
|
+
await proc.exited;
|
|
10255
|
+
return { success: true, message: "Multiplayer server finished running." };
|
|
10256
|
+
}
|
|
10257
|
+
const indexPath = join5(distDir, "index.html");
|
|
10258
|
+
if (!existsSync4(indexPath)) {
|
|
10259
|
+
const message = `Missing entrypoint: "${indexPath}" was not found in dist. Run "kit build" or use "kit host -b" to compile.`;
|
|
10260
|
+
console.error(source_default.red(`
|
|
10261
|
+
[Kit Host] ${message}
|
|
10262
|
+
`));
|
|
10263
|
+
return { success: false, message };
|
|
10264
|
+
}
|
|
10265
|
+
const lanIp = getNetworkAddress();
|
|
10266
|
+
const server = Bun.serve({
|
|
10267
|
+
port,
|
|
10268
|
+
async fetch(pReq) {
|
|
10269
|
+
const path2 = new URL(pReq.url).pathname;
|
|
10270
|
+
const target = path2 === "/" ? "/index.html" : decodeURIComponent(path2);
|
|
10271
|
+
const file = Bun.file(join5(distDir, target));
|
|
10272
|
+
if (!await file.exists()) {
|
|
10273
|
+
if (pOptions.verbose) {
|
|
10274
|
+
console.warn(source_default.yellow(`[Kit Host] 404 Not Found: ${target}`));
|
|
10275
|
+
}
|
|
10276
|
+
return new Response("Not Found", { status: 404 });
|
|
10277
|
+
}
|
|
10278
|
+
return new Response(file);
|
|
10279
|
+
}
|
|
10280
|
+
});
|
|
10281
|
+
console.log(source_default.cyan(`
|
|
10282
|
+
Kit Game Host Server
|
|
10283
|
+
`));
|
|
10284
|
+
console.log(` ${source_default.bold("Local:")} ${source_default.green(`http://localhost:${server.port}`)}`);
|
|
10285
|
+
if (lanIp !== "localhost") {
|
|
10286
|
+
console.log(` ${source_default.bold("Network:")} ${source_default.green(`http://${lanIp}:${server.port}`)}`);
|
|
10287
|
+
}
|
|
10288
|
+
console.log(source_default.dim(`
|
|
10289
|
+
Serving files from: ${distDir}`));
|
|
10290
|
+
console.log(source_default.dim(`Press Ctrl+C to stop the server
|
|
10291
|
+
`));
|
|
10292
|
+
process.on("SIGINT", () => {
|
|
10293
|
+
console.log(source_default.yellow(`
|
|
10294
|
+
Shutting down host server...`));
|
|
10295
|
+
server.stop();
|
|
10296
|
+
process.exit(0);
|
|
10297
|
+
});
|
|
10298
|
+
process.on("SIGTERM", () => {
|
|
10299
|
+
server.stop();
|
|
10300
|
+
process.exit(0);
|
|
10301
|
+
});
|
|
10302
|
+
return {
|
|
10303
|
+
success: true,
|
|
10304
|
+
message: `Serving files on port ${server.port}`,
|
|
10305
|
+
server: {
|
|
10306
|
+
stop: () => server.stop(),
|
|
10307
|
+
port: server.port
|
|
10308
|
+
}
|
|
10309
|
+
};
|
|
10310
|
+
}
|
|
10311
|
+
|
|
9897
10312
|
// src/cli/main.ts
|
|
9898
10313
|
class KitCLI {
|
|
9899
10314
|
static async processResources(pProcessOptions) {
|
|
@@ -9908,6 +10323,9 @@ class KitCLI {
|
|
|
9908
10323
|
static async create(pCreateOptions) {
|
|
9909
10324
|
await processCreate(pCreateOptions);
|
|
9910
10325
|
}
|
|
10326
|
+
static async host(pHostOptions = {}) {
|
|
10327
|
+
return await processHost(pHostOptions);
|
|
10328
|
+
}
|
|
9911
10329
|
}
|
|
9912
10330
|
|
|
9913
10331
|
// bin/cli.ts
|
|
@@ -9991,6 +10409,12 @@ var formatHelp = (pCmd) => {
|
|
|
9991
10409
|
}
|
|
9992
10410
|
if (isRoot || name === "doctor") {
|
|
9993
10411
|
output += ` ${source_default.cyan("kit doctor")}
|
|
10412
|
+
`;
|
|
10413
|
+
}
|
|
10414
|
+
if (isRoot || name === "host") {
|
|
10415
|
+
output += ` ${source_default.cyan("kit host")}
|
|
10416
|
+
`;
|
|
10417
|
+
output += ` ${source_default.cyan("kit host -p 8080 -b")}
|
|
9994
10418
|
`;
|
|
9995
10419
|
}
|
|
9996
10420
|
if (isRoot) {
|
|
@@ -10023,24 +10447,23 @@ var initCommand = program2.command("init [name]").description("Initialize a new
|
|
|
10023
10447
|
});
|
|
10024
10448
|
});
|
|
10025
10449
|
initCommand.helpInformation = () => formatHelp(initCommand);
|
|
10026
|
-
var buildCommand = program2.command("build [help]").description("Build resources
|
|
10450
|
+
var buildCommand = program2.command("build [help]").description("Build resources and bundle game application").option("-i, --in <path>", "Input directory (defaults to ./src/resources)").option("-o, --out <path>", "Output directory (defaults to ./dist)").option("-m, --manifest <path>", "Custom manifest file path").option("-w, --watch", "Watch files for changes and rebuild automatically", false).option("-is, --ignore-sound", "Ignore sound files", false).option("--app", "Bundle game code and static assets (enabled by default when project entrypoints exist)").option("--no-app", "Disable game code bundling and only process resources").option("-p, --prod", "Production build: enables minification, identifier obfuscation, and strips sourcemaps", false).option("--minify", "Minify bundled JavaScript syntax, whitespace, and identifiers", false).option("--obfuscate", "Mangle and obfuscate variable and property identifiers", false).option("--sourcemap <mode>", "Sourcemap generation mode (none, linked, inline, external)").action((pHelp, pCmdOptions) => {
|
|
10027
10451
|
if (pHelp === "help") {
|
|
10028
10452
|
console.log(buildCommand.helpInformation());
|
|
10029
10453
|
return;
|
|
10030
10454
|
}
|
|
10031
10455
|
const verbose = program2.opts().verbose;
|
|
10032
|
-
if (!pCmdOptions.in || !pCmdOptions.out) {
|
|
10033
|
-
console.error(source_default.red(`
|
|
10034
|
-
Error: --in and --out are required flags for the build command.`));
|
|
10035
|
-
console.log(buildCommand.helpInformation());
|
|
10036
|
-
process.exit(1);
|
|
10037
|
-
}
|
|
10038
10456
|
const processOptions = {
|
|
10039
10457
|
inDirectory: pCmdOptions.in,
|
|
10040
10458
|
outDirectory: pCmdOptions.out,
|
|
10041
10459
|
manifestPath: pCmdOptions.manifest,
|
|
10042
10460
|
watch: pCmdOptions.watch || false,
|
|
10043
10461
|
ignoreSound: pCmdOptions.ignoreSound || false,
|
|
10462
|
+
app: pCmdOptions.app,
|
|
10463
|
+
minify: pCmdOptions.minify || false,
|
|
10464
|
+
obfuscate: pCmdOptions.obfuscate || false,
|
|
10465
|
+
sourcemap: pCmdOptions.sourcemap,
|
|
10466
|
+
prod: pCmdOptions.prod || false,
|
|
10044
10467
|
verbose: verbose || false
|
|
10045
10468
|
};
|
|
10046
10469
|
KitCLI.processResources(processOptions);
|
|
@@ -10067,6 +10490,21 @@ var doctorCommand = program2.command("doctor").description("Inspect environment
|
|
|
10067
10490
|
}
|
|
10068
10491
|
});
|
|
10069
10492
|
doctorCommand.helpInformation = () => formatHelp(doctorCommand);
|
|
10493
|
+
var hostCommand = program2.command("host").description("Host the game application locally").option("-p, --port <number>", "Port to run host server on (default: 8090)", "8090").option("-d, --dir <path>", "Directory to serve (default: ./dist)").option("-b, --build", "Build the project before hosting", false).action(async (pCmdOptions) => {
|
|
10494
|
+
const verbose = program2.opts().verbose;
|
|
10495
|
+
if (pCmdOptions.build) {
|
|
10496
|
+
await KitCLI.processResources({ verbose });
|
|
10497
|
+
}
|
|
10498
|
+
const result = await KitCLI.host({
|
|
10499
|
+
port: Number(pCmdOptions.port) || 8090,
|
|
10500
|
+
directory: pCmdOptions.dir,
|
|
10501
|
+
verbose
|
|
10502
|
+
});
|
|
10503
|
+
if (!result.success) {
|
|
10504
|
+
process.exitCode = 1;
|
|
10505
|
+
}
|
|
10506
|
+
});
|
|
10507
|
+
hostCommand.helpInformation = () => formatHelp(hostCommand);
|
|
10070
10508
|
program2.command("help [command]").description("Display help for a command").action((pCommandName) => {
|
|
10071
10509
|
if (pCommandName) {
|
|
10072
10510
|
const cmd = program2.commands.find((c) => c.name() === pCommandName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-bundler.d.ts","sourceRoot":"","sources":["../../src/cli/app-bundler.ts"],"names":[],"mappings":"AAKA,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;
|
|
1
|
+
{"version":3,"file":"app-bundler.d.ts","sourceRoot":"","sources":["../../src/cli/app-bundler.ts"],"names":[],"mappings":"AAKA,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,CA6KhI"}
|
package/lib/cli/app-bundler.js
CHANGED
|
@@ -65,6 +65,14 @@ async function copyStaticWebFiles(pSourceDir, pDestDir, pBaseDir) {
|
|
|
65
65
|
const targetPath = join(pDestDir, relativePath);
|
|
66
66
|
await fs.mkdir(dirname(targetPath), { recursive: true });
|
|
67
67
|
await fs.copyFile(fullPath, targetPath);
|
|
68
|
+
// If the asset is located in a nested directory, also provide a copy at destination root
|
|
69
|
+
// to support projects where root HTML references sub-folder styles directly
|
|
70
|
+
if (['.css', '.ico'].includes(ext)) {
|
|
71
|
+
const rootTargetPath = join(pDestDir, entry.name);
|
|
72
|
+
if (targetPath !== rootTargetPath && !existsSync(rootTargetPath)) {
|
|
73
|
+
await fs.copyFile(fullPath, rootTargetPath);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
68
76
|
}
|
|
69
77
|
}
|
|
70
78
|
}
|
package/lib/cli/host.js
CHANGED
|
@@ -46,7 +46,7 @@ export async function processHost(pOptions = {}) {
|
|
|
46
46
|
console.error(chalk.red(`\n[Kit Host] ${message}\n`));
|
|
47
47
|
return { success: false, message };
|
|
48
48
|
}
|
|
49
|
-
console.log(chalk.cyan(`\
|
|
49
|
+
console.log(chalk.cyan(`\nStarting Multiplayer Server from ${chalk.bold(distDir)}...\n`));
|
|
50
50
|
let serverSettingsPort = port;
|
|
51
51
|
const settingsPath = join(distDir, 'settings.json');
|
|
52
52
|
if (existsSync(settingsPath)) {
|
|
@@ -100,7 +100,7 @@ export async function processHost(pOptions = {}) {
|
|
|
100
100
|
return new Response(file);
|
|
101
101
|
}
|
|
102
102
|
});
|
|
103
|
-
console.log(chalk.cyan('\
|
|
103
|
+
console.log(chalk.cyan('\nKit Game Host Server\n'));
|
|
104
104
|
console.log(` ${chalk.bold('Local:')} ${chalk.green(`http://localhost:${server.port}`)}`);
|
|
105
105
|
if (lanIp !== 'localhost') {
|
|
106
106
|
console.log(` ${chalk.bold('Network:')} ${chalk.green(`http://${lanIp}:${server.port}`)}`);
|
|
@@ -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;AA+gB9C;;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"}
|
|
@@ -100,9 +100,22 @@ async function processDirectory(pDirectoryPath) {
|
|
|
100
100
|
function isValidExtension(pExtension) {
|
|
101
101
|
return VALID_EXTENSIONS.includes(pExtension);
|
|
102
102
|
}
|
|
103
|
+
// Engine resource formats handled by Vylocity obfuscation
|
|
104
|
+
const ENGINE_EXTENSIONS = ['vyint', 'vyi', 'vym', 'vymac'];
|
|
105
|
+
/**
|
|
106
|
+
* Checks if a file extension is a Vylocity engine binary/definition format.
|
|
107
|
+
* @param pExtension - The file extension to test.
|
|
108
|
+
* @returns True if the extension is an engine format.
|
|
109
|
+
*/
|
|
110
|
+
function isEngineExtension(pExtension) {
|
|
111
|
+
return ENGINE_EXTENSIONS.includes(pExtension);
|
|
112
|
+
}
|
|
103
113
|
/**
|
|
104
114
|
* Recursively copies a directory to destination, preserving subdirectories and files.
|
|
105
|
-
* Ignores engine resource files that are
|
|
115
|
+
* Ignores engine resource files (vyint, vyi, vym, vymac) that are handled by Vylocity obfuscation,
|
|
116
|
+
* while ensuring media and custom assets (sounds, images, fonts, json) retain their structure.
|
|
117
|
+
* @param pSourceDir - The source directory to copy.
|
|
118
|
+
* @param pDestDir - The target destination directory.
|
|
106
119
|
*/
|
|
107
120
|
async function mirrorDirectory(pSourceDir, pDestDir) {
|
|
108
121
|
const entries = await fs.readdir(pSourceDir, { withFileTypes: true });
|
|
@@ -115,8 +128,8 @@ async function mirrorDirectory(pSourceDir, pDestDir) {
|
|
|
115
128
|
}
|
|
116
129
|
else {
|
|
117
130
|
const ext = extname(entry.name).slice(1);
|
|
118
|
-
//
|
|
119
|
-
if (!
|
|
131
|
+
// Copy all assets except internal Vylocity engine binary formats
|
|
132
|
+
if (!isEngineExtension(ext)) {
|
|
120
133
|
await fs.copyFile(srcPath, destPath);
|
|
121
134
|
}
|
|
122
135
|
}
|
|
@@ -417,7 +430,7 @@ async function runBuild() {
|
|
|
417
430
|
*/
|
|
418
431
|
async function runWatch() {
|
|
419
432
|
await runBuild();
|
|
420
|
-
console.log(chalk.cyan(`\
|
|
433
|
+
console.log(chalk.cyan(`\nWatching for changes in: ${chalk.bold(resourceInDirectory)}`));
|
|
421
434
|
let debounceTimer = null;
|
|
422
435
|
const triggerRebuild = (pFilename) => {
|
|
423
436
|
if (debounceTimer)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { spawnSync } = require('child_process');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
// Target the compiled Bun bundle
|
|
6
|
+
const cliScript = path.join(__dirname, 'bundle', 'cli', 'cli.js');
|
|
7
|
+
|
|
8
|
+
// If currently running under Bun, import and execute directly
|
|
9
|
+
if (typeof Bun !== 'undefined') {
|
|
10
|
+
import(cliScript);
|
|
11
|
+
} else {
|
|
12
|
+
// Running under Node.js -> delegate to Bun runtime
|
|
13
|
+
const result = spawnSync('bun', [cliScript, ...process.argv.slice(2)], {
|
|
14
|
+
stdio: 'inherit',
|
|
15
|
+
shell: process.platform === 'win32'
|
|
16
|
+
});
|
|
17
|
+
process.exit(result.status ?? 0);
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evitcastudio/kit",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"author": "doubleactii 56242467+doubleactii@users.noreply.github.com (https://evitcastudio.com)",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"build-all": "bun run build-types && bun run build && bun run build-docs"
|
|
44
44
|
},
|
|
45
45
|
"bin": {
|
|
46
|
-
"kit": "lib/
|
|
46
|
+
"kit": "lib/cli-runner.cjs"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@eslint/create-config": "1.4.0",
|