Skip to content
This repository was archived by the owner on May 11, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ A simple Typescript Boilerplate that builds incredibly fast using the [SWC Libra
- Auto Download Resources
- Single Resource Code Support
- Fastest Auto Reconnect Time on Recompile
- Compile Multiple Resources at Once
- Built-in React for WebViews

# Installation
Expand Down Expand Up @@ -92,3 +93,7 @@ Use the key combination `ctrl + c` to kill your server in your terminal, command
## How to Add Mods, and New Resources

Always add your already compiled resources & mods into the `resources` folder.

## How to ignore specific resources from compiling

Add file name `.nocompile` to the resource folder you want to ignore from compiling.
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "altv-quickstart-ts",
"version": "5.0.1",
"version": "5.2.1",
"description": "TypeScript with alt:V Made Easy",
"scripts": {
"[-] Server Deployment Commands (They All Do Different Things)": "",
Expand Down Expand Up @@ -43,9 +43,11 @@
},
"type": "module",
"dependencies": {
"vite": "^4.3.1"
"vite": "^4.3.1",
"fkill": "^8.1.0",
"toml": "^3.0.0"
},
"engines": {
"node": ">=18"
}
}
}
34 changes: 20 additions & 14 deletions scripts/compiler.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'fs-extra'
import * as glob from 'glob';
import swc from '@swc/core'
import { normalizeFilePath } from './shared.js';
import { getResources, normalizeFilePath } from './shared.js';

const SWC_CONFIG = {
jsc: {
Expand All @@ -19,21 +19,27 @@ const SWC_CONFIG = {
sourceMaps: false,
};

const startTime = Date.now();
const filesToCompile = glob.sync('./src/core/**/*.ts');

if (fs.existsSync('resources/core')) {
fs.rmSync('resources/core', { force: true, recursive: true });
}
async function buildTargetResource(name) {
const startTime = Date.now();

if (fs.existsSync(`resources/${name}`)) {
fs.rmSync(`resources/${name}`, { force: true, recursive: true });
}

const filesToCompile = glob.sync(`./src/${name}/**/*.ts`);
let compileCount = 0;
for (let i = 0; i < filesToCompile.length; i++) {
const filePath = normalizeFilePath(filesToCompile[i]);
const finalPath = filePath.replace('src/', 'resources/').replace('.ts', '.js');
const compiled = swc.transformFileSync(filePath, SWC_CONFIG);
fs.outputFileSync(finalPath, compiled.code, { encoding: 'utf-8' });
compileCount += 1;
}

let compileCount = 0;
for (let i = 0; i < filesToCompile.length; i++) {
const filePath = normalizeFilePath(filesToCompile[i]);
const finalPath = filePath.replace('src/', 'resources/').replace('.ts', '.js');
const compiled = swc.transformFileSync(filePath, SWC_CONFIG);
fs.outputFileSync(finalPath, compiled.code, { encoding: 'utf-8' });
compileCount += 1;
console.log(`[${name}] Has built ${compileCount} files in ${Date.now() - startTime}ms`)
}

console.log(`${compileCount} Files Built | ${Date.now() - startTime}ms`);;
for (let resource of getResources()) {
buildTargetResource(resource);
}
36 changes: 21 additions & 15 deletions scripts/copy.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
import fs from 'fs-extra'
import * as glob from 'glob';
import { normalizeFilePath } from './shared.js';
import { getResources, normalizeFilePath } from './shared.js';

const startTime = Date.now();
const files = glob.sync(['src/core/**/*.!(ts)', 'src-webviews/**/*.toml'])
async function copyResourceAssets(name) {
const startTime = Date.now();
const files = glob.sync([`./src/${name}/**/*.!(ts)`, './src-webviews/**/*.toml']);

let filesCopied = 0;
for (let file of files) {
const filePath = normalizeFilePath(file);
let filesCopied = 0;
for (let file of files) {
const filePath = normalizeFilePath(file);

if (filePath.includes('src/')) {
const finalPath = filePath.replace('src/', 'resources/');
fs.copySync(filePath, finalPath, { overwrite: true });
}
if(filePath.includes('src/')) {
const finalPath = filePath.replace('src/', 'resources/');
fs.copySync(filePath, finalPath, {overwrite: true});
}

if (filePath.includes('src-webviews')) {
const finalPath = filePath.replace('src-webviews/', 'resources/webviews/');
fs.copySync(filePath, finalPath, { overwrite: true });
}

if (filePath.includes('src-webviews')) {
const finalPath = filePath.replace('src-webviews/', 'resources/webviews/');
fs.copySync(filePath, finalPath, { overwrite: true });
filesCopied += 1;
}

filesCopied += 1;
console.log(`[${name}] | ${filesCopied} Files Moved | ${Date.now() - startTime}ms`);
}

console.log(`${filesCopied} Files Moved | ${Date.now() - startTime}ms`);
for (let resource of getResources()) {
copyResourceAssets(resource);
}
23 changes: 22 additions & 1 deletion scripts/shared.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import fs from 'fs-extra';
import toml from 'toml';

export function normalizeFilePath(filePath) {
return filePath.replace(/\\/gm, '/');
Expand All @@ -12,4 +13,24 @@ export async function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
})
}
}

function shouldCompileResource(name) {
const path = `./src/${name}`;
if (!fs.existsSync(path)) {
return false;
}
return !fs.existsSync(`${path}/.nocompile`);
}

let serverConfigPath = './server.toml';
export function getResources() {
if (!fs.existsSync(serverConfigPath)) {
console.log('server.toml does not exist, please create one.');
return [];
}
const fileContents = fs.readFileSync(serverConfigPath, { encoding: 'utf-8' });
const serverConfig = toml.parse(fileContents);
serverConfig.resources = serverConfig.resources.filter(shouldCompileResource);
return serverConfig.resources;
}
101 changes: 54 additions & 47 deletions scripts/transform.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import path from 'path';
import * as glob from 'glob';
import fs from 'fs';
import { getResources } from './shared.js';

/**
* What does this do?
* Appends `.js` to the end of all imports that are not 'nodejs' imports.
* This is required for alt:V
*/

const resourcePath = path.join(process.cwd(), 'resources/core/**/*.js').replace(/\\/gm, '/');
const filePaths = glob.sync(resourcePath);

const funcsToIgnore = [
//
'export function',
Expand All @@ -20,63 +18,72 @@ const funcsToIgnore = [
'=>',
];

for (let filePath of filePaths) {
const fileContents = fs.readFileSync(filePath, { encoding: 'utf-8' });
const splitContents = fileContents.split(/\r?\n/);
async function transformResource(name) {
const resourcePath = path.join(process.cwd(), `resources/${name}/**/*.js`).replace(/\\/gm, '/');
const filePaths = glob.sync(resourcePath);

const filePathing = filePath.split('/');
filePathing.pop();
const directoryPath = filePathing.join('/');
for (let filePath of filePaths) {
const fileContents = fs.readFileSync(filePath, { encoding: 'utf-8' });
const splitContents = fileContents.split(/\r?\n/);

let wasModified = false;
for (let i = 0; i < splitContents.length; i++) {
if (!splitContents[i].includes('import') && !splitContents[i].includes('export')) {
continue;
}
const filePathing = filePath.split('/');
filePathing.pop();
const directoryPath = filePathing.join('/');

let shouldSkip = false;
for (let funcToIgnore of funcsToIgnore) {
if (splitContents[i].includes(funcToIgnore)) {
shouldSkip = true;
break;
let wasModified = false;
for (let i = 0; i < splitContents.length; i++) {
if (!splitContents[i].includes('import') && !splitContents[i].includes('export')) {
continue;
}
}

if (shouldSkip) {
continue;
}
let shouldSkip = false;
for (let funcToIgnore of funcsToIgnore) {
if (splitContents[i].includes(funcToIgnore)) {
shouldSkip = true;
break;
}
}

const filePathReg = new RegExp(/('|").*.('|")/g);
const extractions = splitContents[i].match(filePathReg);
if (extractions === null || !extractions) {
continue;
}
if (shouldSkip) {
continue;
}

const relativeFilePath = extractions[0].replace(/'/gm, '').replace(/"/gm, '');
if (relativeFilePath.charAt(0) !== '.' && relativeFilePath.charAt(0) !== '/') {
continue;
}
const filePathReg = new RegExp(/('|").*.('|")/g);
const extractions = splitContents[i].match(filePathReg);
if (extractions === null || !extractions) {
continue;
}

const actualFilePath = path.join(directoryPath, relativeFilePath).replace(/\\/gm, '/');
if (fs.existsSync(actualFilePath)) {
const barrelFileTest = fs.statSync(actualFilePath);
if (barrelFileTest.isDirectory()) {
splitContents[i] = splitContents[i].replace(relativeFilePath, `${relativeFilePath}/index.js`);
wasModified = true;
const relativeFilePath = extractions[0].replace(/'/gm, '').replace(/"/gm, '');
if (relativeFilePath.charAt(0) !== '.' && relativeFilePath.charAt(0) !== '/') {
continue;
}

const actualFilePath = path.join(directoryPath, relativeFilePath).replace(/\\/gm, '/');
if (fs.existsSync(actualFilePath)) {
const barrelFileTest = fs.statSync(actualFilePath);
if (barrelFileTest.isDirectory()) {
splitContents[i] = splitContents[i].replace(relativeFilePath, `${relativeFilePath}/index.js`);
wasModified = true;
continue;
}
}

if (!splitContents[i].includes('.js')) {
splitContents[i] = splitContents[i].replace(relativeFilePath, `${relativeFilePath}.js`);
wasModified = true;
}
}

if (!splitContents[i].includes('.js')) {
splitContents[i] = splitContents[i].replace(relativeFilePath, `${relativeFilePath}.js`);
wasModified = true;
if (!wasModified) {
continue;
}
}

if (!wasModified) {
continue;
const finalFile = splitContents.join('\r\n');
fs.writeFileSync(filePath, finalFile, { encoding: 'utf-8' });
}
}

const finalFile = splitContents.join('\r\n');
fs.writeFileSync(filePath, finalFile, { encoding: 'utf-8' });
}
for (let resource of getResources()) {
transformResource(resource);
}
31 changes: 8 additions & 23 deletions scripts/watch.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@

import { spawnSync, spawn, ChildProcess } from 'node:child_process'
import Watcher from 'watcher';
import { writeToIpc, sleep } from './shared.js';
import fkill from 'fkill'

const fileWatcher = new Watcher(['./src', './src-webviews'], { recursive: true, renameDetection: true });
const isWindows = process.platform === "win32";
const altvProcessName = isWindows ? './altv-server.exe' : './altv-server'

/** @type {ChildProcess} */
let childProcess = undefined
let rebootDebounce = Date.now() + 0;

async function compiler() {
console.log(`Starting Compile`)
Expand All @@ -27,30 +26,16 @@ async function compiler() {
}

async function reboot() {
if (rebootDebounce > Date.now()) {
return;
}

rebootDebounce = Date.now() + 1000;
writeToIpc('kick-all');
await sleep(250);
if (childProcess) {
try {
childProcess.kill();
} catch (err) { }

await new Promise((resolve) => {
const interval = setInterval(() => {
if (!childProcess.killed) {
childProcess.kill();
return;
}
await fkill(':7788')

childProcess = undefined
clearInterval(interval);
resolve();
}, 100);
})
if (!childProcess.killed) {
try {
childProcess.kill();
} catch (err) { }
}
}

await compiler();
Expand All @@ -62,4 +47,4 @@ function start() {
reboot();
}

start();
start();