Skip to content

Commit 44b0f64

Browse files
authored
Merge pull request #22 from web-tech-tw/refactor-node-24-ts-9728651109116575249
Refactor to Node.js 24 erasableSyntaxOnly TypeScript
2 parents 236d67f + f59335d commit 44b0f64

File tree

22 files changed

+604
-198
lines changed

22 files changed

+604
-198
lines changed

app.js renamed to app.ts

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,28 @@
1-
"use strict";
2-
31
// Import config
4-
const {
2+
import {
53
runLoader,
64
getEnvironmentOverview,
7-
} = require("./src/config");
5+
} from "./src/config.ts";
86

97
// Load config
108
runLoader();
119

1210
// Import constants
13-
const constant = require("./src/init/const");
11+
import * as constant from "./src/init/const.ts";
1412

1513
// Import useApp
16-
const {useApp} = require("./src/init/express");
14+
import {useApp} from "./src/init/express.ts";
1715

1816
// Initialize application
1917
const app = useApp();
2018

2119
// Initialize prepare handlers
22-
const {
23-
prepare: prepareDatabase,
24-
} = require("./src/init/database");
25-
const {
26-
prepare: prepareListener,
27-
} = require("./src/init/listener");
20+
import {
21+
prepare as prepareDatabase,
22+
} from "./src/init/database.ts";
23+
import {
24+
prepare as prepareListener,
25+
} from "./src/init/listener.ts";
2826

2927
const prepareHandlers = [
3028
prepareDatabase,
@@ -42,7 +40,7 @@ app.get("/robots.txt", (_, res) => {
4240
});
4341

4442
// Load router dispatcher
45-
const routerDispatcher = require("./src/routes");
43+
import * as routerDispatcher from "./src/routes/index.ts";
4644
routerDispatcher.load();
4745

4846
// Show banner message
@@ -54,7 +52,8 @@ routerDispatcher.load();
5452
})();
5553

5654
// Mount application and execute it
57-
require("./src/execute")(app, prepareHandlers,
55+
import execute from "./src/execute.ts";
56+
execute(app, prepareHandlers,
5857
({protocol, hostname, port}) => {
5958
console.info(`Protocol "${protocol}" is listening at`);
6059
console.info(`${protocol}://${hostname}:${port}`);

package.json

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55
"author": "Taiwan Web Technology Promotion Organization",
66
"homepage": "https://web-tech.tw",
77
"license": "MIT",
8-
"main": "app.js",
8+
"type": "module",
9+
"main": "app.ts",
910
"scripts": {
10-
"export-openapi": "node export_openapi.js",
11-
"dev": "nodemon app.js",
12-
"start": "node app.js",
13-
"lint": "npx lint-staged",
14-
"lint:es": "eslint \"*.js\" \"src/**/*.js\"",
15-
"lint:es:fix": "eslint \"*.js\" \"src/**/*.js\" --fix",
11+
"export-openapi": "node export_openapi.ts",
12+
"dev": "node --watch app.ts",
13+
"start": "node app.ts",
14+
"lint": "eslint .",
15+
"type-check": "npx tsc --noEmit",
1616
"prepare": "husky install"
1717
},
1818
"lint-staged": {
19-
"*.js": "eslint"
19+
"*.ts": "eslint"
2020
},
2121
"dependencies": {
2222
"@discordjs/rest": "^2.4.0",
@@ -54,13 +54,27 @@
5454
"devDependencies": {
5555
"@commitlint/cli": "^17.4.4",
5656
"@commitlint/config-conventional": "^17.4.4",
57+
"@eslint/js": "^9.21.0",
58+
"@types/cors": "^2.8.17",
59+
"@types/ejs": "^3.1.5",
60+
"@types/express": "^5.0.0",
61+
"@types/jsonwebtoken": "^9.0.8",
62+
"@types/mongoose": "^5.11.97",
63+
"@types/node": "^22.13.5",
64+
"@types/node-cache": "^4.2.5",
65+
"@types/request-ip": "^0.0.41",
66+
"@types/swagger-jsdoc": "^6.0.4",
67+
"@types/swagger-ui-express": "^4.1.7",
68+
"@types/ua-parser-js": "^0.7.39",
5769
"cz-conventional-changelog": "^3.3.0",
58-
"eslint": "^8.17.0",
70+
"eslint": "^9.21.0",
5971
"eslint-config-google": "^0.14.0",
60-
"eslint-plugin-jsdoc": "^48.2.3",
72+
"eslint-plugin-jsdoc": "^50.6.3",
6173
"husky": "^8.0.3",
6274
"lint-staged": "^13.2.0",
63-
"nodemon": "^2.0.13"
75+
"nodemon": "^2.0.13",
76+
"typescript": "^5.7.3",
77+
"typescript-eslint": "^8.24.1"
6478
},
6579
"config": {
6680
"commitizen": {

src/config.js renamed to src/config.ts

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
"use strict";
21

32
// Import modules
4-
const {join: pathJoin} = require("node:path");
5-
const {existsSync} = require("node:fs");
3+
import {join as pathJoin} from "node:path";
4+
import {existsSync} from "node:fs";
5+
import { fileURLToPath } from 'node:url';
6+
import dotenv from "dotenv";
67

78
/**
89
* Load configs from system environment variables.
910
*/
10-
function runLoader() {
11-
const dotenvPath = pathJoin(__dirname, "..", ".env");
11+
export function runLoader(): void {
12+
// ESM doesn't have __dirname, need to construct it
13+
const __filename = fileURLToPath(import.meta.url);
14+
const __dirname = pathJoin(__filename, ".."); // src/config.ts -> src/
15+
const dotenvPath = pathJoin(__dirname, "..", ".env"); // src/../.env -> .env
1216

1317
const isDotEnvFileExists = existsSync(dotenvPath);
1418
const isCustomDefined = get("APP_CONFIGURED") === "1";
@@ -23,7 +27,7 @@ function runLoader() {
2327
throw new Error(".env not exists");
2428
}
2529

26-
require("dotenv").config();
30+
dotenv.config();
2731
}
2832

2933
/**
@@ -32,7 +36,7 @@ function runLoader() {
3236
* @function
3337
* @return {boolean} true if production
3438
*/
35-
function isProduction() {
39+
export function isProduction(): boolean {
3640
return getMust("NODE_ENV") === "production";
3741
}
3842

@@ -42,7 +46,7 @@ function isProduction() {
4246
* @function
4347
* @return {object}
4448
*/
45-
function getEnvironmentOverview() {
49+
export function getEnvironmentOverview(): {node: string, runtime: string} {
4650
return {
4751
node: getFallback("NODE_ENV", "development"),
4852
runtime: getFallback("RUNTIME_ENV", "native"),
@@ -56,7 +60,7 @@ function getEnvironmentOverview() {
5660
* @param {string} key the key
5761
* @return {string} the value
5862
*/
59-
function get(key) {
63+
export function get(key: string): string | undefined {
6064
return process.env[key];
6165
}
6266

@@ -67,7 +71,7 @@ function get(key) {
6771
* @param {string} key the key
6872
* @return {bool} the bool value
6973
*/
70-
function getEnabled(key) {
74+
export function getEnabled(key: string): boolean {
7175
return getMust(key) === "yes";
7276
}
7377

@@ -79,7 +83,7 @@ function getEnabled(key) {
7983
* @param {string} [separator=,] the separator.
8084
* @return {array} the array value
8185
*/
82-
function getSplited(key, separator=",") {
86+
export function getSplited(key: string, separator: string = ","): string[] {
8387
return getMust(key).
8488
split(separator).
8589
filter((s) => s).
@@ -94,7 +98,7 @@ function getSplited(key, separator=",") {
9498
* @return {string} the expected value
9599
* @throws {Error} if value is undefined, throw an error
96100
*/
97-
function getMust(key) {
101+
export function getMust(key: string): string {
98102
const value = get(key);
99103
if (value === undefined) {
100104
throw new Error(`config key ${key} is undefined`);
@@ -110,17 +114,6 @@ function getMust(key) {
110114
* @param {string} fallback the fallback value
111115
* @return {string} the expected value
112116
*/
113-
function getFallback(key, fallback) {
117+
export function getFallback(key: string, fallback: string): string {
114118
return get(key) || fallback;
115119
}
116-
117-
module.exports = {
118-
runLoader,
119-
isProduction,
120-
getEnvironmentOverview,
121-
get,
122-
getEnabled,
123-
getSplited,
124-
getMust,
125-
getFallback,
126-
};

src/execute.js renamed to src/execute.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
1-
"use strict";
2-
31
// Import config
4-
const {getMust, getSplited} = require("./config");
2+
import {getMust, getSplited} from "./config.ts";
53

64
// Import modules
7-
const fs = require("node:fs");
8-
const http = require("node:http");
9-
const https = require("node:https");
5+
import fs from "node:fs";
6+
import http from "node:http";
7+
import https from "node:https";
8+
import type { Express } from "express";
109

1110
// Import event listener
12-
const {
13-
listen: startListenEvents,
14-
} = require("./init/listener");
11+
import {
12+
listen as startListenEvents,
13+
} from "./init/listener.ts";
14+
15+
interface ProtocolInfo {
16+
protocol: string;
17+
hostname: string;
18+
port: number;
19+
}
1520

1621
/**
1722
* Setup protocol - http
1823
* @param {object} app
1924
* @param {function} callback
2025
*/
21-
function setupHttpProtocol(app, callback) {
26+
function setupHttpProtocol(app: Express, callback: (info: ProtocolInfo) => void) {
2227
const options = {};
2328
const httpServer = http.createServer(options, app);
2429
const port = parseInt(getMust("HTTP_PORT"));
@@ -31,7 +36,7 @@ function setupHttpProtocol(app, callback) {
3136
* @param {object} app
3237
* @param {function} callback
3338
*/
34-
function setupHttpsProtocol(app, callback) {
39+
function setupHttpsProtocol(app: Express, callback: (info: ProtocolInfo) => void) {
3540
const options = {
3641
key: fs.readFileSync(getMust("HTTPS_KEY_PATH")),
3742
cert: fs.readFileSync(getMust("HTTPS_CERT_PATH")),
@@ -43,7 +48,7 @@ function setupHttpsProtocol(app, callback) {
4348
}
4449

4550
// Prepare application and detect protocols automatically
46-
module.exports = async function(app, prepareHandlers, callback) {
51+
export default async function(app: Express, prepareHandlers: (() => Promise<void>)[], callback: (info: ProtocolInfo) => void) {
4752
// Waiting for prepare handlers
4853
if (prepareHandlers.length > 0) {
4954
const preparingPromises = prepareHandlers.map((c) => c());
@@ -65,4 +70,4 @@ module.exports = async function(app, prepareHandlers, callback) {
6570

6671
// Start event listener
6772
startListenEvents();
68-
};
73+
}

src/init/const.js

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/init/const.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Constants
2+
3+
export const APP_NAME = "Nymph";
4+
export const APP_DESCRIPTION = "The artificial intelligence powered by opensource.";
5+
6+
export const APP_VERSION = "latest";
7+
8+
export const APP_AUTHOR_NAME = "Taiwan Web Technology Promotion Organization";
9+
export const APP_AUTHOR_URL = "https://web-tech.tw";
10+
11+
export const OPENAPI_EXPORTED_FILENAME = "openapi_exported.json";
12+
export const PUBLIC_KEY_FILENAME = "keypair_public.pem";
13+
14+
export const PLATFORM_LINE = "LINE";
15+
export const PLATFORM_MATRIX = "Matrix";
16+
export const PLATFORM_DISCORD = "Discord";
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
"use strict";
21
// mongoose is an ODM library for MongoDB.
32

43
// Import config
5-
const {getMust} = require("../config");
4+
import {getMust} from "../config.ts";
65

76
// Import mongoose
8-
const database = require("mongoose");
7+
import database, { Mongoose } from "mongoose";
98

109
// Configure mongose
1110
database.set("strictQuery", true);
1211

1312
// Connect to MongoDB
14-
exports.prepare = () =>
13+
export const prepare = () =>
1514
database.connect(getMust("MONGODB_URI"));
1615

1716
// Export as useFunction
18-
exports.useDatabase = () => database;
17+
export const useDatabase = (): Mongoose => database;

0 commit comments

Comments
 (0)