initial comit
This commit is contained in:
commit
8f843dc27d
13 changed files with 674 additions and 0 deletions
176
.gitignore
vendored
Normal file
176
.gitignore
vendored
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
# 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
|
||||||
|
/.vscode
|
21
LICENCE
Normal file
21
LICENCE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Creation's // [creations@creations.works]
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
20
README.md
Normal file
20
README.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# TS Fastify Example
|
||||||
|
|
||||||
|
This is just an example/template to get you started with Fastify and TypeScript. It starts off using EJS, but you can use something else if you'd like.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
To start the project, you can run either `start.bat` or `start.sh`.
|
||||||
|
|
||||||
|
## Cleanup
|
||||||
|
|
||||||
|
You can clean up your project with the following commands:
|
||||||
|
|
||||||
|
- **Windows:** `start.bat clean`
|
||||||
|
- **Unix/Linux:** `start.sh clean`
|
||||||
|
|
||||||
|
Have fun - **Creations** // **creations@creations.works**
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
43
config/environment.ts
Normal file
43
config/environment.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { dirname, join } from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
|
export interface IEnvironment {
|
||||||
|
development: boolean;
|
||||||
|
|
||||||
|
fastify: {
|
||||||
|
host: string;
|
||||||
|
port: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
paths: {
|
||||||
|
src: string;
|
||||||
|
www: {
|
||||||
|
root: string;
|
||||||
|
views: string;
|
||||||
|
public: string;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const __dirname : string = join(dirname(fileURLToPath(import.meta.url)), "..");
|
||||||
|
|
||||||
|
const environment : IEnvironment = {
|
||||||
|
development: process.argv.includes("--development"),
|
||||||
|
|
||||||
|
fastify: {
|
||||||
|
host: "0.0.0.0",
|
||||||
|
port: 7788
|
||||||
|
},
|
||||||
|
|
||||||
|
paths: {
|
||||||
|
src: __dirname,
|
||||||
|
www: {
|
||||||
|
root: join(__dirname, "src", "www"),
|
||||||
|
views: join(__dirname, "src", "www", "views"),
|
||||||
|
public: join(__dirname, "src", "www", "public")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default environment;
|
||||||
|
export { environment };
|
21
package.json
Normal file
21
package.json
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "ts_fastify_example",
|
||||||
|
"module": "src/index.ts",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "bun run --watch src/index.ts --development"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest",
|
||||||
|
"@types/ejs": "^3.1.5"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fastify/static": "^7.0.4",
|
||||||
|
"@fastify/view": "^9.1.0",
|
||||||
|
"ejs": "^3.1.10",
|
||||||
|
"fastify": "^4.28.1"
|
||||||
|
}
|
||||||
|
}
|
135
src/fastify/manager.ts
Normal file
135
src/fastify/manager.ts
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
import Fastify from "fastify";
|
||||||
|
import ejs from "ejs";
|
||||||
|
|
||||||
|
import { IncomingMessage, Server, ServerResponse } from "http";
|
||||||
|
import { readdir, stat } from "fs/promises";
|
||||||
|
import { join } from "path";
|
||||||
|
|
||||||
|
import { environment } from "../../config/environment";
|
||||||
|
|
||||||
|
// types
|
||||||
|
import type { FastifyInstance, FastifyReply, FastifyRequest, RouteShorthandMethod } from "fastify";
|
||||||
|
import type { Stats } from "fs";
|
||||||
|
import type { AddressInfo } from "net";
|
||||||
|
|
||||||
|
// official plugins
|
||||||
|
import { fastifyView } from "@fastify/view";
|
||||||
|
import { fastifyStatic } from "@fastify/static";
|
||||||
|
|
||||||
|
//custom plugins
|
||||||
|
import faviconPlugin from "./plugins/favicon";
|
||||||
|
|
||||||
|
class FastifyManager {
|
||||||
|
private readonly port : number = environment.fastify.port;
|
||||||
|
private readonly server : FastifyInstance<Server, IncomingMessage, ServerResponse>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.server = Fastify({
|
||||||
|
logger: false,
|
||||||
|
trustProxy: !environment.development,
|
||||||
|
ignoreTrailingSlash: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private async registerPlugins() : Promise<void> {
|
||||||
|
console.log(environment.paths.www.views);
|
||||||
|
|
||||||
|
// official plugins
|
||||||
|
this.server.register(fastifyView, {
|
||||||
|
engine: {
|
||||||
|
ejs
|
||||||
|
},
|
||||||
|
root: environment.paths.www.views,
|
||||||
|
includeViewExtension: true
|
||||||
|
});
|
||||||
|
|
||||||
|
this.server.register(fastifyStatic, {
|
||||||
|
root: environment.paths.www.public,
|
||||||
|
prefix: "/public/",
|
||||||
|
prefixAvoidTrailingSlash: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// custom plugins
|
||||||
|
this.server.register(faviconPlugin, { path: join(environment.paths.www.public, "assets", "favicon.ico") });
|
||||||
|
}
|
||||||
|
|
||||||
|
// dynamic route loading
|
||||||
|
private async loadRoutes(): Promise<void> {
|
||||||
|
// you can specify a route path, prefix, and whether to load routes recursively e.g. ["routes", "/", true] will load all routes in the /routes directory with the prefix / and recursively load all routes in subdirectories
|
||||||
|
|
||||||
|
const routePaths: [string, string, boolean][] = [
|
||||||
|
["routes", '/', false]
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const [routePath, prefix, recursive] of routePaths) {
|
||||||
|
const modifiedRoutePath = join(environment.paths.www.root, routePath);
|
||||||
|
|
||||||
|
let files: string[];
|
||||||
|
try {
|
||||||
|
files = await this.readDirRecursive(modifiedRoutePath, recursive);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to read route directory", modifiedRoutePath, "error:", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
try {
|
||||||
|
const route = await import(file);
|
||||||
|
if (route.default) {
|
||||||
|
this.server.register(route.default, { prefix });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to load route", file, "error:", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async readDirRecursive(dir: string, recursive: boolean): Promise<string[]> {
|
||||||
|
let results: string[] = [];
|
||||||
|
const list : string[] = await readdir(dir);
|
||||||
|
|
||||||
|
for (const file of list) {
|
||||||
|
const filePath : string = join(dir, file);
|
||||||
|
const statObj : Stats = await stat(filePath);
|
||||||
|
if (statObj && statObj.isDirectory()) {
|
||||||
|
if (recursive) {
|
||||||
|
results = results.concat(await this.readDirRecursive(filePath, recursive));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
results.push(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async start() : Promise<void> {
|
||||||
|
try {
|
||||||
|
await this.registerPlugins();
|
||||||
|
await this.loadRoutes();
|
||||||
|
|
||||||
|
await this.server.listen({
|
||||||
|
port: environment.fastify.port,
|
||||||
|
host: environment.fastify.host
|
||||||
|
});
|
||||||
|
|
||||||
|
const [_address, _port, scheme]: [string, number, string] = (() : [string, number, string] => {
|
||||||
|
const address: string | AddressInfo | null = this.server.server.address();
|
||||||
|
const resolvedAddress: [string, number] = (address && typeof address === 'object') ? [( address.address.startsWith("::") || address.address === "0.0.0.0") ? "localhost" : address.address, address.port] : ["localhost", this.port];
|
||||||
|
const resolvedScheme: string = resolvedAddress[0] === "localhost" ? "http" : "https";
|
||||||
|
|
||||||
|
return [...resolvedAddress, resolvedScheme];
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
console.info("Started Listening on", `${scheme}://${_address}:${_port}`);
|
||||||
|
console.info("Registered routes: ", "\n", this.server.printRoutes());
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to start Fastify server", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fastifyManager = new FastifyManager();
|
||||||
|
export default fastifyManager;
|
||||||
|
export { fastifyManager };
|
35
src/fastify/plugins/favicon.ts
Normal file
35
src/fastify/plugins/favicon.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { readFile } from 'fs/promises';
|
||||||
|
|
||||||
|
import type { FastifyInstance, FastifyPluginAsync } from 'fastify';
|
||||||
|
import type { FastifyRequest } from "fastify/types/request";
|
||||||
|
import type { FastifyReply } from "fastify/types/reply";
|
||||||
|
|
||||||
|
interface FaviconOptions {
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const faviconPlugin: FastifyPluginAsync<FaviconOptions> = async (fastify: FastifyInstance, options: FaviconOptions): Promise<void> => {
|
||||||
|
let faviconData: Buffer | null = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
faviconData = await readFile(options.path);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error reading favicon:", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
fastify.get('/favicon.ico', async (_request: FastifyRequest, reply: FastifyReply): Promise<void> => {
|
||||||
|
if (faviconData) {
|
||||||
|
reply.header('Content-Type', 'image/x-icon')
|
||||||
|
.header('Cache-Control', 'public, max-age=86400') // 1 day
|
||||||
|
.send(faviconData);
|
||||||
|
} else {
|
||||||
|
reply.status(404).send({
|
||||||
|
code: 404,
|
||||||
|
error: 'FILE_NOT_FOUND',
|
||||||
|
message: 'Favicon not found'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default faviconPlugin as FastifyPluginAsync<FaviconOptions>;
|
15
src/index.ts
Normal file
15
src/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { environment } from "../config/environment";
|
||||||
|
import { fastifyManager } from "./fastify/manager";
|
||||||
|
|
||||||
|
class Index {
|
||||||
|
public static async main() : Promise<void> {
|
||||||
|
const main = new Index();
|
||||||
|
await main.start();
|
||||||
|
};
|
||||||
|
|
||||||
|
public async start() : Promise<void> {
|
||||||
|
await fastifyManager.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const index : Promise<void> = Index.main();
|
BIN
src/www/public/assets/favicon.ico
Normal file
BIN
src/www/public/assets/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 567 B |
17
src/www/routes/index.ts
Normal file
17
src/www/routes/index.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||||
|
|
||||||
|
const route : (fastify: FastifyInstance) => Promise<void> = async (fastify: FastifyInstance) : Promise<void> => {
|
||||||
|
const handleRequest: (request : FastifyRequest, reply : FastifyReply) => Promise<void> = async (request : FastifyRequest, reply : FastifyReply) : Promise<void> => {
|
||||||
|
|
||||||
|
return reply.view("index.ejs", {
|
||||||
|
h1: "Hello, World!",
|
||||||
|
p: "This is a placeholder page.",
|
||||||
|
discord: "https://discord.gg/DxFhhbr2pm",
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fastify.get("/", handleRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default route as (fastify: FastifyInstance) => Promise<void>;
|
14
src/www/views/index.ejs
Normal file
14
src/www/views/index.ejs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1><%= h1 %></h1>
|
||||||
|
<p><%= p %></p>
|
||||||
|
|
||||||
|
<p>join this cool discord: <a href="<%= discord %>">click here</a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
150
start.bat
Normal file
150
start.bat
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
@echo off
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
for %%I in ("%~dp0.") do set "SCRIPT_DIR=%%~fI"
|
||||||
|
cd /d "!SCRIPT_DIR!"
|
||||||
|
|
||||||
|
if not exist package.json (
|
||||||
|
echo package.json not found in !SCRIPT_DIR!
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
set "PKG_MANAGER=bun"
|
||||||
|
set "MODE=dev"
|
||||||
|
|
||||||
|
set "next_is_value=0"
|
||||||
|
set "last_key="
|
||||||
|
|
||||||
|
for %%a in (%*) do (
|
||||||
|
set "arg=%%a"
|
||||||
|
|
||||||
|
if "!next_is_value!"=="1" (
|
||||||
|
if "!last_key!"=="manager" (
|
||||||
|
set "PKG_MANAGER=%%a"
|
||||||
|
)
|
||||||
|
if "!last_key!"=="mode" (
|
||||||
|
set "MODE=%%a"
|
||||||
|
)
|
||||||
|
set "next_is_value=0"
|
||||||
|
)
|
||||||
|
|
||||||
|
if "!arg!"=="clean" (
|
||||||
|
goto cleanup
|
||||||
|
)
|
||||||
|
|
||||||
|
if "!arg!"=="cleanup" (
|
||||||
|
goto cleanup
|
||||||
|
)
|
||||||
|
|
||||||
|
if "!arg!"=="manager" (
|
||||||
|
set "last_key=manager"
|
||||||
|
set "next_is_value=1"
|
||||||
|
)
|
||||||
|
|
||||||
|
if "!arg!"=="mode" (
|
||||||
|
set "last_key=mode"
|
||||||
|
set "next_is_value=1"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
set "ALLOWED_MANAGERS=bun npm yarn pnpm"
|
||||||
|
set "ALLOWED_MODES=dev prod development production"
|
||||||
|
|
||||||
|
set "manager_allowed=0"
|
||||||
|
for %%a in (!ALLOWED_MANAGERS!) do (
|
||||||
|
if "!PKG_MANAGER!"=="%%a" (
|
||||||
|
set "manager_allowed=1"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
set "mode_allowed=0"
|
||||||
|
for %%a in (!ALLOWED_MODES!) do (
|
||||||
|
if "!MODE!"=="%%a" (
|
||||||
|
set "mode_allowed=1"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if "!manager_allowed!"=="0" (
|
||||||
|
echo !PKG_MANAGER! is not a valid package manager, please use one of the following: !ALLOWED_MANAGERS!
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
if "!mode_allowed!"=="0" (
|
||||||
|
echo !MODE! is not a valid mode, please use one of the following: !ALLOWED_MODES!
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo Using package manager: !PKG_MANAGER!
|
||||||
|
echo Mode: !MODE!
|
||||||
|
|
||||||
|
set "NPM_MARKER=node_modules/.npm_used"
|
||||||
|
set "YARN_MARKER=node_modules/.yarn_used"
|
||||||
|
set "PNPM_MARKER=node_modules/.pnpm_used"
|
||||||
|
set "BUN_MARKER=node_modules/.bun_used"
|
||||||
|
|
||||||
|
if "!PKG_MANAGER!"=="npm" (
|
||||||
|
set "INSTALL_CMD=npm install"
|
||||||
|
set "RUN_CMD=npm run !MODE!"
|
||||||
|
set "CURRENT_MARKER=!NPM_MARKER!"
|
||||||
|
) else if "!PKG_MANAGER!"=="yarn" (
|
||||||
|
set "INSTALL_CMD=yarn"
|
||||||
|
set "RUN_CMD=yarn !MODE!"
|
||||||
|
set "CURRENT_MARKER=!YARN_MARKER!"
|
||||||
|
) else if "!PKG_MANAGER!"=="pnpm" (
|
||||||
|
set "INSTALL_CMD=pnpm install"
|
||||||
|
set "RUN_CMD=pnpm !MODE!"
|
||||||
|
set "CURRENT_MARKER=!PNPM_MARKER!"
|
||||||
|
) else if "!PKG_MANAGER!"=="bun" (
|
||||||
|
set "INSTALL_CMD=bun install"
|
||||||
|
set "RUN_CMD=bun !MODE!"
|
||||||
|
set "CURRENT_MARKER=!BUN_MARKER!"
|
||||||
|
)
|
||||||
|
|
||||||
|
if exist "!NPM_MARKER!" if not "!CURRENT_MARKER!"=="!NPM_MARKER!" goto cleanup
|
||||||
|
if exist "!YARN_MARKER!" if not "!CURRENT_MARKER!"=="!YARN_MARKER!" goto cleanup
|
||||||
|
if exist "!PNPM_MARKER!" if not "!CURRENT_MARKER!"=="!PNPM_MARKER!" goto cleanup
|
||||||
|
if exist "!BUN_MARKER!" if not "!CURRENT_MARKER!"=="!BUN_MARKER!" goto cleanup
|
||||||
|
|
||||||
|
goto run
|
||||||
|
|
||||||
|
:cleanup
|
||||||
|
set "files_to_delete=package-lock.json yarn.lock pnpm-lock.yaml bun.lockb"
|
||||||
|
set "folders_to_delete=node_modules dist logs"
|
||||||
|
set "markers_to_delete=node_modules/.npm_used node_modules/.yarn_used node_modules/.pnpm_used node_modules/.bun_used"
|
||||||
|
|
||||||
|
echo Cleaning up files and folders...
|
||||||
|
|
||||||
|
for %%a in (!files_to_delete!) do (
|
||||||
|
if exist "%%a" (
|
||||||
|
echo Found %%a in !SCRIPT_DIR! - deleting...
|
||||||
|
del "%%a"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for %%a in (!folders_to_delete!) do (
|
||||||
|
if exist "%%a" (
|
||||||
|
echo Found %%a in !SCRIPT_DIR! - deleting...
|
||||||
|
rmdir /s /q "%%a"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for %%a in (!markers_to_delete!) do (
|
||||||
|
if exist "%%a" del "%%a"
|
||||||
|
)
|
||||||
|
|
||||||
|
if defined RUN_CMD (
|
||||||
|
goto run
|
||||||
|
)
|
||||||
|
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:run
|
||||||
|
if defined RUN_CMD (
|
||||||
|
echo Running !RUN_CMD!...
|
||||||
|
!INSTALL_CMD!
|
||||||
|
!RUN_CMD!
|
||||||
|
) else (
|
||||||
|
echo No run command set, exiting...
|
||||||
|
)
|
||||||
|
|
||||||
|
exit /b 0
|
27
tsconfig.json
Normal file
27
tsconfig.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// Enable latest features
|
||||||
|
"lib": ["ESNext", "DOM"],
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"allowJs": true,
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
"noPropertyAccessFromIndexSignature": false
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue