server init
This commit is contained in:
commit
b6ec8de3ba
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
bun.lock
|
||||
|
||||
.idea
|
5
package.json
Normal file
5
package.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"inquirer": "^12.3.3"
|
||||
}
|
||||
}
|
179
packages/server/.gitignore
vendored
Normal file
179
packages/server/.gitignore
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
_.log
|
||||
npm-debug.log_
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Caches
|
||||
|
||||
.cache
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
_.pid
|
||||
_.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
|
||||
profiles
|
||||
manifests
|
||||
assets
|
6
packages/server/.prettierignore
Normal file
6
packages/server/.prettierignore
Normal file
@ -0,0 +1,6 @@
|
||||
# Ignore artifacts:
|
||||
assets
|
||||
dist
|
||||
manifests
|
||||
node_modules
|
||||
profiles
|
1
packages/server/.prettierrc
Normal file
1
packages/server/.prettierrc
Normal file
@ -0,0 +1 @@
|
||||
{}
|
15
packages/server/README.md
Normal file
15
packages/server/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# skymp-server
|
||||
|
||||
To install dependencies:
|
||||
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
|
||||
To run:
|
||||
|
||||
```bash
|
||||
bun run src/index.ts
|
||||
```
|
||||
|
||||
This project was created using `bun init` in bun v1.2.2. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|
22
packages/server/package.json
Normal file
22
packages/server/package.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "skymp-server",
|
||||
"module": "src/index.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "bun --watch run src/index.ts",
|
||||
"build:win": "bun build --compile --target=bun-windows-x64 src/index.ts --outfile dist/build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
"prettier": "3.4.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.7.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@elysiajs/static": "^1.2.0",
|
||||
"chalk": "^5.4.1",
|
||||
"elysia": "^1.2.10",
|
||||
"uuid": "^11.0.5"
|
||||
}
|
||||
}
|
37
packages/server/src/commands/changeProfileEnabled.ts
Normal file
37
packages/server/src/commands/changeProfileEnabled.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import chalk from "chalk";
|
||||
|
||||
import { commandHandler, helpers } from "../core";
|
||||
|
||||
import type { Command } from "../core";
|
||||
|
||||
const changeProfileEnabled: Command = {
|
||||
name: "change-profile-enabled",
|
||||
description:
|
||||
"Enable profile with the given name. Usage: change-profile-enabled [true/false] <profile name>",
|
||||
execute: async (args: string[]) => {
|
||||
if (args.length < 2) {
|
||||
console.log(chalk.red("Please provide profile status and name"));
|
||||
return;
|
||||
}
|
||||
|
||||
const status = String(args[0]).toLowerCase() === "true";
|
||||
const profileName = args.slice(1).join(" ");
|
||||
|
||||
const profiles = await helpers.profile.getAll();
|
||||
const profile = profiles.find((profile) => profile.name === profileName);
|
||||
if (!profile) {
|
||||
console.log(chalk.red(`Profile "${profileName}" not found`));
|
||||
return;
|
||||
}
|
||||
|
||||
profile.enabled = status;
|
||||
await helpers.profile.save(profile.id, JSON.stringify(profile));
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
`Profile "${profileName}" is now ${status ? chalk.green("enabled") : chalk.red("disabled")}`,
|
||||
),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
commandHandler.registerCommand(changeProfileEnabled);
|
39
packages/server/src/commands/createProfile.ts
Normal file
39
packages/server/src/commands/createProfile.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import chalk from "chalk";
|
||||
|
||||
import { commandHandler, helpers } from "../core";
|
||||
|
||||
import type { Command } from "../core";
|
||||
import type { ProfileFile } from "./types";
|
||||
|
||||
const createProfileCommand: Command = {
|
||||
name: "create-profile",
|
||||
description:
|
||||
"Creates a new profile with the given name. Usage: create-profile <profile name>",
|
||||
execute: async (args: string[]) => {
|
||||
if (args.length < 1) {
|
||||
console.log(chalk.red("Please provide a profile name"));
|
||||
return;
|
||||
}
|
||||
|
||||
const profileName = args.join(" ");
|
||||
console.log(chalk.yellow(`Creating profile for ${profileName}...`));
|
||||
const id = uuidv4();
|
||||
|
||||
const assetsFolder = profileName.split(" ").join("-").toLowerCase();
|
||||
|
||||
const profileData: ProfileFile = {
|
||||
id,
|
||||
name: profileName,
|
||||
assetsFolder,
|
||||
enabled: false,
|
||||
};
|
||||
|
||||
await helpers.profile.save(id, JSON.stringify(profileData));
|
||||
await helpers.asset.init(assetsFolder);
|
||||
|
||||
console.log(chalk.green(`Profile "${profileName}" created with id: ${id}`));
|
||||
},
|
||||
};
|
||||
|
||||
commandHandler.registerCommand(createProfileCommand);
|
3
packages/server/src/commands/index.ts
Normal file
3
packages/server/src/commands/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import "./createProfile";
|
||||
import "./syncup";
|
||||
import "./changeProfileEnabled";
|
26
packages/server/src/commands/sync.ts
Normal file
26
packages/server/src/commands/sync.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { readdir } from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import chalk from "chalk";
|
||||
|
||||
import { commandHandler, helpers } from "../core";
|
||||
import { ASSETS_FOLDER, PROFILES_FOLDER } from "../consts";
|
||||
|
||||
import type { ProfileFile } from "./types";
|
||||
import type { Command } from "../core";
|
||||
|
||||
const syncUpCommand: Command = {
|
||||
name: "sync-up",
|
||||
description: "Syncs up all assets folders with the manifest. Usage: sync-up",
|
||||
execute: async (args: string[]) => {
|
||||
const profileName = args.slice(1).join(" ");
|
||||
|
||||
const profiles = await helpers.profile.getAll();
|
||||
const profile = profiles.find((profile) => profile.name === profileName);
|
||||
if (!profile) {
|
||||
console.log(chalk.red(`Profile "${profileName}" not found`));
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
commandHandler.registerCommand(syncUpCommand);
|
41
packages/server/src/commands/syncup.ts
Normal file
41
packages/server/src/commands/syncup.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { readdir } from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import chalk from "chalk";
|
||||
|
||||
import { commandHandler, helpers } from "../core";
|
||||
import { ASSETS_FOLDER, PROFILES_FOLDER } from "../consts";
|
||||
|
||||
import type { ProfileFile } from "./types";
|
||||
import type { Command } from "../core";
|
||||
|
||||
const syncUpCommand: Command = {
|
||||
name: "sync-up",
|
||||
description: "Syncs up all assets folders with the manifest. Usage: sync-up",
|
||||
execute: async () => {
|
||||
if (await helpers.manifest.isFolderExists()) {
|
||||
const dirEntries = await readdir(PROFILES_FOLDER, {
|
||||
withFileTypes: true,
|
||||
});
|
||||
|
||||
for (const entry of dirEntries) {
|
||||
const file = Bun.file(path.join(PROFILES_FOLDER, entry.name));
|
||||
const data: ProfileFile = JSON.parse(await file.text());
|
||||
|
||||
console.log(chalk.green(`Syncing up profile: ${data.id}`));
|
||||
|
||||
const pathToAssets = path.join(ASSETS_FOLDER, data.assetsFolder);
|
||||
const generatedManifest = await helpers.manifest.generate(pathToAssets);
|
||||
|
||||
await helpers.manifest.save(
|
||||
data.id,
|
||||
JSON.stringify(generatedManifest),
|
||||
await helpers.manifest.isExists(data.id),
|
||||
);
|
||||
}
|
||||
|
||||
console.log(chalk.green("Sync up complete!"));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
commandHandler.registerCommand(syncUpCommand);
|
11
packages/server/src/commands/types/index.ts
Normal file
11
packages/server/src/commands/types/index.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export interface ProfileFile {
|
||||
id: string;
|
||||
name: string;
|
||||
enabled: boolean;
|
||||
assetsFolder: string;
|
||||
}
|
||||
|
||||
export interface ManifestFile {
|
||||
path: string;
|
||||
hash: string;
|
||||
}
|
5
packages/server/src/consts/index.ts
Normal file
5
packages/server/src/consts/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import * as path from "node:path";
|
||||
|
||||
export const MANIFEST_FOLDER = path.join(process.cwd(), "manifests");
|
||||
export const PROFILES_FOLDER = path.join(process.cwd(), "profiles");
|
||||
export const ASSETS_FOLDER = path.join(process.cwd(), "assets");
|
92
packages/server/src/core/commandHandler.ts
Normal file
92
packages/server/src/core/commandHandler.ts
Normal file
@ -0,0 +1,92 @@
|
||||
import readline from "readline";
|
||||
import chalk from "chalk";
|
||||
|
||||
export interface Command {
|
||||
name: string;
|
||||
description: string;
|
||||
execute: (args: string[]) => void | Promise<void>;
|
||||
}
|
||||
|
||||
class CommandHandler {
|
||||
private commands: Map<string, Command>;
|
||||
private rl: readline.Interface;
|
||||
|
||||
constructor() {
|
||||
this.commands = new Map();
|
||||
this.rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
prompt: chalk.blue("> "),
|
||||
});
|
||||
|
||||
this.registerCommand({
|
||||
name: "help",
|
||||
description: "Shows all available commands",
|
||||
execute: this.handleHelp.bind(this),
|
||||
});
|
||||
|
||||
this.registerCommand({
|
||||
name: "exit",
|
||||
description: "Exits the application",
|
||||
execute: () => {
|
||||
console.log(chalk.yellow("Goodbye!"));
|
||||
this.rl.close();
|
||||
process.exit(0);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public registerCommand(command: Command): void {
|
||||
this.commands.set(command.name, command);
|
||||
}
|
||||
|
||||
private handleHelp(): void {
|
||||
console.log(chalk.green("\nAvailable commands:"));
|
||||
this.commands.forEach((command) => {
|
||||
console.log(chalk.cyan(`${command.name}: `) + command.description);
|
||||
});
|
||||
console.log();
|
||||
}
|
||||
|
||||
private async executeCommand(input: string): Promise<void> {
|
||||
const args = input.trim().split(/\s+/);
|
||||
const commandName = args.shift()?.toLowerCase();
|
||||
|
||||
if (!commandName) {
|
||||
return;
|
||||
}
|
||||
|
||||
const command = this.commands.get(commandName);
|
||||
|
||||
if (!command) {
|
||||
console.log(chalk.red(`Unknown command: ${commandName}`));
|
||||
console.log(chalk.yellow('Type "help" to see available commands'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await command.execute(args);
|
||||
} catch (error) {
|
||||
console.error(chalk.red("Error executing command:"), error);
|
||||
}
|
||||
}
|
||||
|
||||
public start(): void {
|
||||
console.log(chalk.green("Welcome to the SkyMP LaunchServer CLI!"));
|
||||
console.log(chalk.yellow('Type "help" to see available commands\n'));
|
||||
|
||||
this.rl.prompt();
|
||||
|
||||
this.rl.on("line", async (input) => {
|
||||
await this.executeCommand(input.trim());
|
||||
this.rl.prompt();
|
||||
});
|
||||
|
||||
this.rl.on("close", () => {
|
||||
console.log(chalk.yellow("Goodbye!"));
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const commandHandler = new CommandHandler();
|
27
packages/server/src/core/elysia.ts
Normal file
27
packages/server/src/core/elysia.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { Elysia } from "elysia";
|
||||
import chalk from "chalk";
|
||||
import staticPlugin from "@elysiajs/static";
|
||||
|
||||
import { helpers } from "./helpers.ts";
|
||||
|
||||
new Elysia()
|
||||
.use(
|
||||
staticPlugin({
|
||||
prefix: "/api/assets",
|
||||
assets: "assets",
|
||||
}),
|
||||
)
|
||||
.group("/api", (group) => {
|
||||
return group
|
||||
.get("/profiles", async () => {
|
||||
const allProfiles = await helpers.profile.getAll();
|
||||
|
||||
return allProfiles.filter((profile) => profile.enabled);
|
||||
})
|
||||
.get("/manifest/:id", async ({ params: { id } }) => {
|
||||
return await helpers.manifest.get(id);
|
||||
});
|
||||
})
|
||||
.listen(5454);
|
||||
|
||||
console.log(chalk.green("Server started on port 5454"));
|
149
packages/server/src/core/helpers.ts
Normal file
149
packages/server/src/core/helpers.ts
Normal file
@ -0,0 +1,149 @@
|
||||
import { exists, mkdir, readdir, readFile, stat } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import * as crypto from "node:crypto";
|
||||
|
||||
import { ASSETS_FOLDER, MANIFEST_FOLDER, PROFILES_FOLDER } from "../consts";
|
||||
|
||||
import type { ManifestFile, ProfileFile } from "../commands/types";
|
||||
|
||||
export interface FileInfo {
|
||||
path: string;
|
||||
hash: string;
|
||||
size: number;
|
||||
}
|
||||
|
||||
export const helpers = {
|
||||
manifest: {
|
||||
init: async () => {
|
||||
if (!(await exists(MANIFEST_FOLDER))) {
|
||||
try {
|
||||
await mkdir(MANIFEST_FOLDER, { recursive: true });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
isFolderExists: async () => {
|
||||
if (await exists(MANIFEST_FOLDER)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
await helpers.manifest.init();
|
||||
return true;
|
||||
},
|
||||
isExists: async (id: string) => {
|
||||
const manifestPath = path.join(MANIFEST_FOLDER, `${id}.json`);
|
||||
return await exists(manifestPath);
|
||||
},
|
||||
save: async (id: string, data: string, resave: boolean) => {
|
||||
if (resave) {
|
||||
await Bun.file(path.join(MANIFEST_FOLDER, `${id}.json`)).delete();
|
||||
}
|
||||
|
||||
await Bun.write(path.join(MANIFEST_FOLDER, `${id}.json`), data);
|
||||
},
|
||||
generate: async (dir: string): Promise<FileInfo[]> => {
|
||||
const files: FileInfo[] = [];
|
||||
|
||||
async function scanDir(currentDir: string) {
|
||||
const dirEntries = await readdir(currentDir, { withFileTypes: true });
|
||||
|
||||
for (const entry of dirEntries) {
|
||||
const fullPath = path.join(currentDir, entry.name);
|
||||
const relPath = path.relative(dir, fullPath);
|
||||
if (entry.isDirectory()) {
|
||||
await scanDir(fullPath);
|
||||
} else if (entry.isFile()) {
|
||||
const fileBuffer = await readFile(fullPath);
|
||||
const hash = crypto
|
||||
.createHash("sha256")
|
||||
.update(fileBuffer)
|
||||
.digest("hex");
|
||||
const { size } = await stat(fullPath);
|
||||
files.push({ path: relPath, hash, size });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await scanDir(dir);
|
||||
return files;
|
||||
},
|
||||
get: async (id: string): Promise<ManifestFile[]> => {
|
||||
const isProfileEnabled = await helpers.profile.enabled(id);
|
||||
|
||||
if (!isProfileEnabled) return [];
|
||||
const manifestFilePath = path.join(MANIFEST_FOLDER, `${id}.json`);
|
||||
|
||||
const file = Bun.file(manifestFilePath);
|
||||
return JSON.parse(await file.text());
|
||||
},
|
||||
},
|
||||
profile: {
|
||||
save: async (name: string, data: string) => {
|
||||
if (!(await exists(PROFILES_FOLDER))) {
|
||||
await mkdir(PROFILES_FOLDER, { recursive: true });
|
||||
}
|
||||
|
||||
await Bun.write(path.join(PROFILES_FOLDER, `${name}.json`), data);
|
||||
},
|
||||
getAll: async (): Promise<ProfileFile[]> => {
|
||||
const dirEntries = await readdir(PROFILES_FOLDER, {
|
||||
withFileTypes: true,
|
||||
});
|
||||
const profiles = [];
|
||||
|
||||
for (const entry of dirEntries) {
|
||||
const file = Bun.file(path.join(PROFILES_FOLDER, entry.name));
|
||||
const data: ProfileFile = JSON.parse(await file.text());
|
||||
profiles.push(data);
|
||||
}
|
||||
|
||||
return profiles;
|
||||
},
|
||||
enabled: async (id: string): Promise<Boolean> => {
|
||||
const profilePath = path.join(PROFILES_FOLDER, `${id}.json`);
|
||||
|
||||
if (!(await exists(profilePath))) return false;
|
||||
|
||||
const file = Bun.file(profilePath);
|
||||
const data: ProfileFile = JSON.parse(await file.text());
|
||||
|
||||
return data.enabled;
|
||||
},
|
||||
},
|
||||
asset: {
|
||||
init: async (dir: string) => {
|
||||
const targetPath = path.join(ASSETS_FOLDER, dir);
|
||||
|
||||
if (await exists(targetPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await mkdir(targetPath, { recursive: true });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
await Bun.write(
|
||||
path.join(targetPath, "your-assets-here.txt"),
|
||||
"Place your assets here",
|
||||
);
|
||||
},
|
||||
},
|
||||
system: {
|
||||
init: async () => {
|
||||
if (!(await exists(ASSETS_FOLDER))) {
|
||||
await mkdir(ASSETS_FOLDER, { recursive: true });
|
||||
}
|
||||
|
||||
if (!(await exists(PROFILES_FOLDER))) {
|
||||
await mkdir(PROFILES_FOLDER, { recursive: true });
|
||||
}
|
||||
|
||||
if (!(await exists(MANIFEST_FOLDER))) {
|
||||
await mkdir(MANIFEST_FOLDER, { recursive: true });
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
2
packages/server/src/core/index.ts
Normal file
2
packages/server/src/core/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./helpers.ts";
|
||||
export * from "./commandHandler.ts";
|
9
packages/server/src/index.ts
Normal file
9
packages/server/src/index.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { helpers } from "./core";
|
||||
import { commandHandler } from "./core";
|
||||
import "./commands";
|
||||
|
||||
await helpers.system.init();
|
||||
|
||||
import "./core/elysia";
|
||||
|
||||
commandHandler.start();
|
24
packages/server/tsconfig.json
Normal file
24
packages/server/tsconfig.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Enable latest features
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user