mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-09 16:12:17 +00:00
[Manual Mirror] RS Pack try 2 (#11172)
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -22,8 +22,6 @@ jobs:
|
||||
# Caches
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup_bun
|
||||
with:
|
||||
restore-yarn-cache: true
|
||||
- name: Restore Bootstrap cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -18,6 +18,9 @@
|
||||
"gitlens.advanced.blame.customArguments": [
|
||||
"-w", "--ignore-revs-file", ".git-blame-ignore-revs"
|
||||
],
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
},
|
||||
"tgstationTestExplorer.project.resultsType": "json",
|
||||
"[dm]": {
|
||||
"files.eol": "\n",
|
||||
|
||||
@@ -17,7 +17,7 @@ export RUST_G_VERSION=3.11.0
|
||||
export NODE_VERSION_LTS=22.14.0
|
||||
|
||||
# Bun version
|
||||
export BUN_VERSION=1.2.16
|
||||
export BUN_VERSION=1.2.18
|
||||
|
||||
# SpacemanDMM git tag
|
||||
export SPACEMAN_DMM_VERSION=suite-1.10
|
||||
|
||||
15
tgui/.swcrc
15
tgui/.swcrc
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"$schema": "https://swc.rs/schema.json",
|
||||
"jsc": {
|
||||
"loose": true,
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true
|
||||
},
|
||||
"transform": {
|
||||
"react": {
|
||||
"runtime": "automatic"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
561
tgui/bun.lock
561
tgui/bun.lock
File diff suppressed because it is too large
Load Diff
@@ -2,13 +2,13 @@
|
||||
"private": true,
|
||||
"name": "tgui-workspace",
|
||||
"version": "6.0.0",
|
||||
"packageManager": "bun@1.2.16",
|
||||
"packageManager": "bun@1.2.18",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
"scripts": {
|
||||
"tgui:analyze": "webpack --analyze",
|
||||
"tgui:build": "webpack",
|
||||
"tgui:analyze": "rspack --analyze",
|
||||
"tgui:build": "rspack build",
|
||||
"tgui:dev": "bun packages/tgui-dev-server/index.ts",
|
||||
"tgui:lint": "eslint packages --ext .js,.cjs,.ts,.tsx",
|
||||
"tgui:prettier": "prettier --check .",
|
||||
@@ -18,26 +18,21 @@
|
||||
"tgui:eslint-fix": "eslint --fix packages --ext .js,.cjs,.ts,.jsx,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@swc/core": "^1.12.1",
|
||||
"@rspack/cli": "^1.4.3",
|
||||
"@rspack/core": "^1.4.3",
|
||||
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||
"@typescript-eslint/parser": "^8.28.0",
|
||||
"@typescript-eslint/utils": "^8.28.0",
|
||||
"css-loader": "^7.1.2",
|
||||
"esbuild-loader": "^4.3.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-react": "^7.34.1",
|
||||
"eslint-plugin-simple-import-sort": "^12.0.0",
|
||||
"eslint-plugin-unused-imports": "^4.1.4",
|
||||
"mini-css-extract-plugin": "^2.9.2",
|
||||
"prettier": "^3.5.3",
|
||||
"sass": "^1.80.6",
|
||||
"sass-loader": "^16.0.3",
|
||||
"swc-loader": "^0.2.6",
|
||||
"typescript": "^5.8.3",
|
||||
"webpack": "^5.99.9",
|
||||
"webpack-bundle-analyzer": "^4.10.2",
|
||||
"webpack-cli": "^6.0.1"
|
||||
"sass-embedded": "^1.89.2",
|
||||
"sass-loader": "^16.0.5",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@happy-dom/global-registrator": "^17.4.7",
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
import fs from 'node:fs';
|
||||
|
||||
import { reloadByondCache } from './reloader';
|
||||
import { createCompiler } from './webpack';
|
||||
import { RspackCompiler } from './webpack';
|
||||
|
||||
const reloadOnce = process.argv.includes('--reload');
|
||||
|
||||
async function setupServer() {
|
||||
fs.mkdirSync('./public/.tmp', { recursive: true });
|
||||
|
||||
const compiler = await createCompiler({ mode: 'development', hot: true });
|
||||
const compiler = new RspackCompiler();
|
||||
|
||||
await compiler.setup();
|
||||
|
||||
// Reload cache once
|
||||
if (reloadOnce) {
|
||||
|
||||
@@ -1,66 +1,39 @@
|
||||
/**
|
||||
* @file
|
||||
* @copyright 2020 Aleksej Komarov
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { createRequire } from 'module';
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
import { config } from '../../rspack.config-dev';
|
||||
import { loadSourceMaps } from './link/retrace';
|
||||
import { broadcastMessage, setupLink } from './link/server';
|
||||
import { createLogger } from './logging.js';
|
||||
import { reloadByondCache } from './reloader.js';
|
||||
import { createLogger } from './logging';
|
||||
import { reloadByondCache } from './reloader';
|
||||
import { resolveGlob } from './util';
|
||||
|
||||
const logger = createLogger('webpack');
|
||||
const logger = createLogger('rspack');
|
||||
|
||||
export async function createCompiler(
|
||||
options: Record<string, any>,
|
||||
): Promise<WebpackCompiler> {
|
||||
const compiler = new WebpackCompiler();
|
||||
await compiler.setup(options);
|
||||
export class RspackCompiler {
|
||||
rspack: any;
|
||||
config: any;
|
||||
bundleDir: string;
|
||||
|
||||
return compiler;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
||||
type WebpackImport = typeof import('webpack');
|
||||
|
||||
class WebpackCompiler {
|
||||
public webpack: WebpackImport;
|
||||
public config: Record<string, any>;
|
||||
public bundleDir: string;
|
||||
|
||||
async setup(options: Record<string, any>): Promise<void> {
|
||||
async setup() {
|
||||
// Create a require context that is relative to project root
|
||||
// and retrieve all necessary dependencies.
|
||||
const requireFromRoot = createRequire(import.meta.dirname + '/../../..');
|
||||
const webpack: WebpackImport = await requireFromRoot('webpack');
|
||||
const requireFromRoot = createRequire(`${import.meta.dirname}/../../..`);
|
||||
const rspack = await requireFromRoot('@rspack/core');
|
||||
|
||||
const createConfig = await requireFromRoot('./webpack.config.js');
|
||||
const config = createConfig({}, options);
|
||||
|
||||
// Inject the HMR plugin into the config if we're using it
|
||||
if (options.hot) {
|
||||
config.plugins.push(new webpack.HotModuleReplacementPlugin());
|
||||
}
|
||||
|
||||
this.webpack = webpack;
|
||||
this.rspack = rspack;
|
||||
this.config = config;
|
||||
this.bundleDir = config.output.path;
|
||||
this.bundleDir = config.output?.path || '';
|
||||
}
|
||||
|
||||
async watch(): Promise<void> {
|
||||
async watch() {
|
||||
logger.log('setting up');
|
||||
// Setup link
|
||||
const link = setupLink();
|
||||
setupLink();
|
||||
// Instantiate the compiler
|
||||
const compiler = this.webpack.webpack(this.config);
|
||||
const compiler = this.rspack.rspack(this.config);
|
||||
|
||||
// Clear garbage before compiling
|
||||
compiler.hooks.watchRun.tapPromise('tgui-dev-server', async () => {
|
||||
const files = await resolveGlob(this.bundleDir, '*.hot-update.*');
|
||||
logger.log(`clearing garbage (${files.length} files)`);
|
||||
for (const file of files) {
|
||||
await Bun.file(file).delete();
|
||||
}
|
||||
@@ -78,7 +51,6 @@ class WebpackCompiler {
|
||||
type: 'hotUpdate',
|
||||
});
|
||||
});
|
||||
|
||||
// Start watching
|
||||
logger.log('watching for changes');
|
||||
compiler.watch({}, (err, stats) => {
|
||||
@@ -87,7 +59,7 @@ class WebpackCompiler {
|
||||
return;
|
||||
}
|
||||
stats
|
||||
?.toString(this.config.devServer?.stats)
|
||||
?.toString(this.config.stats)
|
||||
.split('\n')
|
||||
.forEach((line) => logger.log(line));
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"tgui": "workspace:*",
|
||||
"tgui-core": "^4.3.2",
|
||||
"tgui-core": "^4.3.3",
|
||||
"tgui-dev-server": "workspace:*"
|
||||
},
|
||||
"private": true
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"tgui": "workspace:*",
|
||||
"tgui-core": "^4.3.2"
|
||||
"tgui-core": "^4.3.3"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"marked": "^15.0.11",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"tgui-core": "^4.3.2",
|
||||
"tgui-core": "^4.3.3",
|
||||
"tgui-dev-server": "workspace:*"
|
||||
},
|
||||
"private": true
|
||||
|
||||
29
tgui/rspack.config-dev.ts
Normal file
29
tgui/rspack.config-dev.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import path from 'node:path';
|
||||
|
||||
import rspack, { type Configuration } from '@rspack/core';
|
||||
|
||||
import oldConfig, { createStats } from './rspack.config';
|
||||
|
||||
export const config = {
|
||||
...oldConfig,
|
||||
devtool: 'cheap-module-source-map',
|
||||
devServer: {
|
||||
hot: true,
|
||||
},
|
||||
mode: 'development',
|
||||
output: {
|
||||
...oldConfig.output,
|
||||
path: path.resolve(import.meta.dirname, './public/.tmp'),
|
||||
},
|
||||
plugins: [
|
||||
new rspack.CssExtractRspackPlugin({
|
||||
chunkFilename: '[name].bundle.css',
|
||||
filename: '[name].bundle.css',
|
||||
}),
|
||||
new rspack.EnvironmentPlugin({
|
||||
NODE_ENV: 'development',
|
||||
}),
|
||||
new rspack.HotModuleReplacementPlugin(),
|
||||
],
|
||||
stats: createStats(false),
|
||||
} satisfies Configuration;
|
||||
139
tgui/rspack.config.ts
Normal file
139
tgui/rspack.config.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
import path from 'node:path';
|
||||
|
||||
import { defineConfig } from '@rspack/cli';
|
||||
import rspack, { type StatsOptions } from '@rspack/core';
|
||||
|
||||
export function createStats(verbose: boolean): StatsOptions {
|
||||
return {
|
||||
assets: verbose,
|
||||
builtAt: verbose,
|
||||
cached: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
colors: true,
|
||||
entrypoints: true,
|
||||
hash: false,
|
||||
modules: false,
|
||||
performance: false,
|
||||
timings: verbose,
|
||||
version: verbose,
|
||||
};
|
||||
}
|
||||
const dirname = path.resolve();
|
||||
|
||||
export default defineConfig({
|
||||
context: dirname,
|
||||
devtool: false,
|
||||
entry: {
|
||||
tgui: './packages/tgui',
|
||||
'tgui-panel': './packages/tgui-panel',
|
||||
'tgui-say': './packages/tgui-say',
|
||||
},
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.([tj]s(x)?|cjs)$/,
|
||||
type: 'javascript/auto',
|
||||
use: [
|
||||
{
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
tsx: true,
|
||||
},
|
||||
transform: {
|
||||
react: {
|
||||
runtime: 'automatic',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(s)?css$/,
|
||||
type: 'javascript/auto',
|
||||
use: [
|
||||
rspack.CssExtractRspackPlugin.loader,
|
||||
'css-loader',
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
api: 'modern-compiler',
|
||||
implementation: 'sass-embedded',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg)$/,
|
||||
oneOf: [
|
||||
{
|
||||
issuer: /\.(s)?css$/,
|
||||
type: 'asset/inline',
|
||||
},
|
||||
{
|
||||
type: 'asset/resource',
|
||||
},
|
||||
],
|
||||
generator: {
|
||||
filename: '[name][ext]',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.svg$/,
|
||||
oneOf: [
|
||||
{
|
||||
issuer: /\.(s)?css$/,
|
||||
type: 'asset/inline',
|
||||
},
|
||||
{
|
||||
type: 'asset/resource',
|
||||
},
|
||||
],
|
||||
generator: {
|
||||
filename: '[name][ext]',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
emitOnErrors: false,
|
||||
},
|
||||
output: {
|
||||
path: 'public',
|
||||
filename: '[name].bundle.js',
|
||||
chunkFilename: '[name].bundle.js',
|
||||
chunkLoadTimeout: 15000,
|
||||
publicPath: '/',
|
||||
assetModuleFilename: '[name][ext]',
|
||||
},
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
plugins: [
|
||||
new rspack.CssExtractRspackPlugin({
|
||||
chunkFilename: '[name].bundle.css',
|
||||
filename: '[name].bundle.css',
|
||||
}),
|
||||
new rspack.EnvironmentPlugin({
|
||||
NODE_ENV: 'production',
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.js', '.jsx'],
|
||||
alias: {
|
||||
tgui: path.resolve(dirname, './packages/tgui'),
|
||||
'tgui-panel': path.resolve(dirname, './packages/tgui-panel'),
|
||||
'tgui-say': path.resolve(dirname, './packages/tgui-say'),
|
||||
'tgui-dev-server': path.resolve(dirname, './packages/tgui-dev-server'),
|
||||
},
|
||||
},
|
||||
stats: createStats(true),
|
||||
target: ['web', 'browserslist:edge >= 123'],
|
||||
});
|
||||
@@ -1,148 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
* @copyright 2020 Aleksej Komarov
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
const webpack = require('webpack');
|
||||
const path = require('path');
|
||||
const ExtractCssPlugin = require('mini-css-extract-plugin');
|
||||
|
||||
const createStats = (verbose) => ({
|
||||
assets: verbose,
|
||||
builtAt: verbose,
|
||||
cached: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
colors: true,
|
||||
entrypoints: true,
|
||||
hash: false,
|
||||
modules: false,
|
||||
performance: false,
|
||||
timings: verbose,
|
||||
version: verbose,
|
||||
});
|
||||
|
||||
module.exports = (env = {}, argv) => {
|
||||
const mode = argv.mode || 'production';
|
||||
const config = {
|
||||
mode,
|
||||
context: path.resolve(__dirname),
|
||||
target: ['web', 'browserslist:edge>=123'],
|
||||
entry: {
|
||||
tgui: ['./packages/tgui'],
|
||||
'tgui-panel': ['./packages/tgui-panel'],
|
||||
'tgui-say': ['./packages/tgui-say'],
|
||||
},
|
||||
output: {
|
||||
path:
|
||||
mode !== 'production'
|
||||
? path.resolve(__dirname, './public/.tmp')
|
||||
: path.resolve(__dirname, './public'),
|
||||
filename: '[name].bundle.js',
|
||||
chunkFilename: '[name].bundle.js',
|
||||
chunkLoadTimeout: 15000,
|
||||
publicPath: '/',
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.js', '.jsx'],
|
||||
alias: {
|
||||
tgui: path.resolve(__dirname, './packages/tgui'),
|
||||
'tgui-panel': path.resolve(__dirname, './packages/tgui-panel'),
|
||||
'tgui-say': path.resolve(__dirname, './packages/tgui-say'),
|
||||
'tgui-dev-server': path.resolve(
|
||||
__dirname,
|
||||
'./packages/tgui-dev-server',
|
||||
),
|
||||
},
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.([tj]s(x)?|cjs)$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: require.resolve('swc-loader'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(s)?css$/,
|
||||
use: [
|
||||
ExtractCssPlugin.loader,
|
||||
require.resolve('css-loader'),
|
||||
require.resolve('sass-loader'),
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.(cur|png|jpg)$/,
|
||||
type: 'asset/resource',
|
||||
},
|
||||
{
|
||||
test: /.svg$/,
|
||||
oneOf: [
|
||||
{
|
||||
issuer: /\.(s)?css$/,
|
||||
type: 'asset/inline',
|
||||
},
|
||||
{
|
||||
type: 'asset/resource',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
emitOnErrors: false,
|
||||
},
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
devtool: false,
|
||||
cache: {
|
||||
type: 'filesystem',
|
||||
cacheLocation: path.resolve(
|
||||
__dirname,
|
||||
`node_modules/.cache/webpack/${mode}`,
|
||||
),
|
||||
buildDependencies: {
|
||||
config: [__filename],
|
||||
},
|
||||
},
|
||||
stats: createStats(true),
|
||||
plugins: [
|
||||
new webpack.EnvironmentPlugin({
|
||||
NODE_ENV: mode,
|
||||
}),
|
||||
new ExtractCssPlugin({
|
||||
filename: '[name].bundle.css',
|
||||
chunkFilename: '[name].bundle.css',
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
// Production build specific options
|
||||
if (mode === 'production') {
|
||||
const { EsbuildPlugin } = require('esbuild-loader');
|
||||
config.optimization.minimizer = [
|
||||
new EsbuildPlugin({
|
||||
css: true,
|
||||
legalComments: 'none',
|
||||
}),
|
||||
];
|
||||
} else {
|
||||
config.devServer = {
|
||||
clientLogLevel: 'silent',
|
||||
hot: true,
|
||||
noInfo: false,
|
||||
progress: false,
|
||||
quiet: false,
|
||||
stats: createStats(false),
|
||||
};
|
||||
config.devtool = 'cheap-module-source-map';
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
@@ -26,7 +26,7 @@ const dependencies: Record<string, any> = await Bun.file("dependencies.sh")
|
||||
.then(formatDeps)
|
||||
.catch((err) => {
|
||||
Juke.logger.error(
|
||||
"Failed to read dependencies.sh, please ensure it exists and is formatted correctly."
|
||||
"Failed to read dependencies.sh, please ensure it exists and is formatted correctly.",
|
||||
);
|
||||
Juke.logger.error(err);
|
||||
throw new Juke.ExitCode(1);
|
||||
@@ -82,7 +82,7 @@ export const NoWarningParameter = new Juke.Parameter({
|
||||
export const CutterTarget = new Juke.Target({
|
||||
onlyWhen: () => {
|
||||
const files = Juke.glob(cutter_path);
|
||||
return files.length == 0;
|
||||
return files.length === 0;
|
||||
},
|
||||
executes: async () => {
|
||||
const repo = dependencies.CUTTER_REPO;
|
||||
@@ -104,7 +104,6 @@ export const IconCutterTarget = new Juke.Target({
|
||||
`icons/**/*.png.toml`,
|
||||
`icons/**/*.dmi.toml`,
|
||||
`cutter_templates/**/*.toml`,
|
||||
"tgui/public/tgui.html",
|
||||
cutter_path,
|
||||
];
|
||||
// Alright we're gonna search out any existing toml files and convert
|
||||
@@ -226,7 +225,7 @@ export const DmTestTarget = new Juke.Target({
|
||||
"-trusted",
|
||||
"-verbose",
|
||||
"-params",
|
||||
"log-directory=ci"
|
||||
"log-directory=ci",
|
||||
);
|
||||
Juke.rm("*.test.*");
|
||||
try {
|
||||
@@ -273,7 +272,7 @@ export const AutowikiTarget = new Juke.Target({
|
||||
"-trusted",
|
||||
"-verbose",
|
||||
"-params",
|
||||
"log-directory=ci"
|
||||
"log-directory=ci",
|
||||
);
|
||||
Juke.rm("*.test.*");
|
||||
if (!fs.existsSync("data/autowiki_edits.txt")) {
|
||||
@@ -306,11 +305,11 @@ export const TgFontTarget = new Juke.Target({
|
||||
fs.mkdirSync("tgui/packages/tgfont/static", { recursive: true });
|
||||
fs.copyFileSync(
|
||||
"tgui/packages/tgfont/dist/tgfont.css",
|
||||
"tgui/packages/tgfont/static/tgfont.css"
|
||||
"tgui/packages/tgfont/static/tgfont.css",
|
||||
);
|
||||
fs.copyFileSync(
|
||||
"tgui/packages/tgfont/dist/tgfont.woff2",
|
||||
"tgui/packages/tgfont/static/tgfont.woff2"
|
||||
"tgui/packages/tgfont/static/tgfont.woff2",
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -318,7 +317,7 @@ export const TgFontTarget = new Juke.Target({
|
||||
export const TguiTarget = new Juke.Target({
|
||||
dependsOn: [BunTarget],
|
||||
inputs: [
|
||||
"tgui/webpack.config.js",
|
||||
"tgui/rspack.config.ts",
|
||||
"tgui/**/package.json",
|
||||
"tgui/packages/**/*.+(js|cjs|ts|tsx|jsx|scss)",
|
||||
],
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.2.16"
|
||||
"@types/bun": "^1.2.18"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user