From a3bfaf4d930f79813cfefda765ec06fe7ebba294 Mon Sep 17 00:00:00 2001 From: Jo Date: Mon, 18 Mar 2024 02:18:45 +0100 Subject: [PATCH] feat: create starter TS setup with express feat: add CSS examples feat: add img example feat: add views example feat: add .env example feat: add example interface feat: add logger util --- .gitignore | 175 ++++++++++++++++++++++++++ .idea/.gitignore | 8 ++ bun.lockb | Bin 0 -> 52843 bytes example.env | 1 + package.json | 22 ++++ src/app.ts | 42 +++++++ src/public/css/_components/button.css | 3 + src/public/css/_modules/home.css | 3 + src/public/css/_variables/colours.css | 6 + src/public/css/all.css | 11 ++ src/public/css/base.css | 12 ++ src/public/css/typography.css | 3 + src/public/img/logo.png | Bin 0 -> 4466 bytes src/types/LoggerInterface.ts | 7 ++ src/utils/logger.ts | 45 +++++++ src/views/home.ejs | 8 ++ src/views/partials/head.ejs | 5 + tsconfig.json | 27 ++++ 18 files changed, 378 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100755 bun.lockb create mode 100644 example.env create mode 100644 package.json create mode 100644 src/app.ts create mode 100644 src/public/css/_components/button.css create mode 100644 src/public/css/_modules/home.css create mode 100644 src/public/css/_variables/colours.css create mode 100644 src/public/css/all.css create mode 100644 src/public/css/base.css create mode 100644 src/public/css/typography.css create mode 100644 src/public/img/logo.png create mode 100644 src/types/LoggerInterface.ts create mode 100644 src/utils/logger.ts create mode 100644 src/views/home.ejs create mode 100644 src/views/partials/head.ejs create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b1ee42 --- /dev/null +++ b/.gitignore @@ -0,0 +1,175 @@ +# 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 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..5d1a7f51a93c9b0fa40fa52b34746d0b0a0cfd6f GIT binary patch literal 52843 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 literal 0 HcmV?d00001 diff --git a/example.env b/example.env new file mode 100644 index 0000000..1381285 --- /dev/null +++ b/example.env @@ -0,0 +1 @@ +EXPRESS_PORT=4300 \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..c5c19b5 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "ts_expressstarter", + "module": "src/app.ts", + "type": "module", + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "@types/dotenv": "^8.2.0", + "@types/express": "^4.17.21", + "body-parser": "^1.20.2", + "dotenv": "^16.4.5", + "ejs": "^3.1.9", + "express": "^4.18.3", + "express-session": "^1.18.0", + "mongoose": "^8.2.2", + "socket.io": "^4.7.5" + } +} \ No newline at end of file diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 0000000..815385b --- /dev/null +++ b/src/app.ts @@ -0,0 +1,42 @@ +//-----------------------------------------------> +// Imports +//-----------------------------------------------> + +// Dependencies +import express, { type Express, type Request, type Response } from "express"; +import dotenv from "dotenv"; +dotenv.config(); + +// Utils +import log from "./utils/logger.ts"; +import * as path from "path"; + +//-----------------------------------------------> +// Express - setup & configuration +//-----------------------------------------------> + +// Declare app as a new instance of express +const app: Express = express(); + +// Set static assets directory +app.use(express.static(path.join(import.meta.dirname, "public"))); + +// Set views directory and view engine +app.set("views", path.join(import.meta.dirname, "views")); +app.set("view engine", "ejs"); + +//-----------------------------------------------> +// Express - routing setup +//-----------------------------------------------> + +app.get("/", (req: Request, res: Response) => { + res.render("home", { page: { title: "ExpressStarter: Home" } }); +}) + +//-----------------------------------------------> +// Express - listen on specified port +//-----------------------------------------------> + +app.listen(process.env.EXPRESS_PORT, (): void => { + log.info("Initialization", `Listening on http://localhost:${process.env.EXPRESS_PORT}`); +}) \ No newline at end of file diff --git a/src/public/css/_components/button.css b/src/public/css/_components/button.css new file mode 100644 index 0000000..8349db3 --- /dev/null +++ b/src/public/css/_components/button.css @@ -0,0 +1,3 @@ +.button { + background-color: var(--color-primary); +} \ No newline at end of file diff --git a/src/public/css/_modules/home.css b/src/public/css/_modules/home.css new file mode 100644 index 0000000..84d36e7 --- /dev/null +++ b/src/public/css/_modules/home.css @@ -0,0 +1,3 @@ +body { + background-color: var(--color-background); +} \ No newline at end of file diff --git a/src/public/css/_variables/colours.css b/src/public/css/_variables/colours.css new file mode 100644 index 0000000..2578d30 --- /dev/null +++ b/src/public/css/_variables/colours.css @@ -0,0 +1,6 @@ +:root { + --color-text: rgb(221, 221, 221); + --color-background: rgb(27, 27, 27); + --color-primary: rgb(204, 234, 174); + --color-secondary: rgb(164, 137, 198); +} \ No newline at end of file diff --git a/src/public/css/all.css b/src/public/css/all.css new file mode 100644 index 0000000..b81d1d4 --- /dev/null +++ b/src/public/css/all.css @@ -0,0 +1,11 @@ +/* Variables */ +@import "_variables/colours.css"; + +/* Base/Overrides */ +@import "base.css"; + +/* Typography */ +@import "typography.css"; + +/* Components */ +@import "_components/button.css"; \ No newline at end of file diff --git a/src/public/css/base.css b/src/public/css/base.css new file mode 100644 index 0000000..f7ba01f --- /dev/null +++ b/src/public/css/base.css @@ -0,0 +1,12 @@ +* { + padding: 0; + margin: 0; + box-sizing: border-box; + position: relative; +} + +body { + min-width: 100vw; + background-color: var(--color-background); + color: var(--color-text); +} \ No newline at end of file diff --git a/src/public/css/typography.css b/src/public/css/typography.css new file mode 100644 index 0000000..991ff6f --- /dev/null +++ b/src/public/css/typography.css @@ -0,0 +1,3 @@ +h1, h2, h3, h4, h5, h6 { + font-weight: 400; +} \ No newline at end of file diff --git a/src/public/img/logo.png b/src/public/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..69935afe93f58e8be56995ca1d146895f17f06b1 GIT binary patch literal 4466 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 literal 0 HcmV?d00001 diff --git a/src/types/LoggerInterface.ts b/src/types/LoggerInterface.ts new file mode 100644 index 0000000..6a1ea45 --- /dev/null +++ b/src/types/LoggerInterface.ts @@ -0,0 +1,7 @@ +export interface LoggerInterface { + history: Array, + constructLog(serviceName: string, message: string): string, + info(serviceName: string, content: string): void, + warn(serviceName: string, content: string): void, + error(serviceName: string, content: string): void +} \ No newline at end of file diff --git a/src/utils/logger.ts b/src/utils/logger.ts new file mode 100644 index 0000000..78e90e4 --- /dev/null +++ b/src/utils/logger.ts @@ -0,0 +1,45 @@ +//-----------------------------------------------> +// Imports +//-----------------------------------------------> + +import type {LoggerInterface} from "../types/LoggerInterface.ts"; + +//-----------------------------------------------> +// Logger class +//-----------------------------------------------> + +class Logger implements LoggerInterface { + public history: Array; + private colors: { warn: string; reset: string; error: string; info: string }; + + constructor() { + this.history = []; + + this.colors = { + error: '\x1b[31m', // Red + warn: '\x1b[33m', // Yellow + info: '\x1b[36m', // Cyan + reset: '\x1b[0m', // Reset color + }; + } + + constructLog(serviceName: string, message: string): string { + const timestamp: string = new Date().toISOString(); + return `[${serviceName}/${timestamp}] ${message}`; + } + + info(serviceName: string, content: string): void { + console.log(`${this.colors.info}${this.constructLog(serviceName, content)}${this.colors.reset}`); + } + + error(serviceName: string, content: string): void { + console.log(`${this.colors.error}${this.constructLog(serviceName, content)}${this.colors.reset}`); + } + + warn(serviceName: string, content: string): void { + console.log(`${this.colors.warn}${this.constructLog(serviceName, content)}${this.colors.reset}`); + } +} + +const log: LoggerInterface = new Logger(); +export default log; \ No newline at end of file diff --git a/src/views/home.ejs b/src/views/home.ejs new file mode 100644 index 0000000..338afb4 --- /dev/null +++ b/src/views/home.ejs @@ -0,0 +1,8 @@ + + + +<%- include("partials/head.ejs", { page }) %> + +

Home!

+ + \ No newline at end of file diff --git a/src/views/partials/head.ejs b/src/views/partials/head.ejs new file mode 100644 index 0000000..42b6501 --- /dev/null +++ b/src/views/partials/head.ejs @@ -0,0 +1,5 @@ + + <%- page.title %> + + + \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ae88302 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext"], + "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 + } +} \ No newline at end of file