diff --git a/client/.babelrc b/client/.babelrc index 04ccccb..053488d 100644 --- a/client/.babelrc +++ b/client/.babelrc @@ -1,5 +1,8 @@ { - "presets": ["@babel/preset-env"], + "presets": [ + "@babel/preset-env", + "@babel/preset-react" + ], "plugins": [ [ "@babel/plugin-transform-react-jsx", diff --git a/client/jsconfig.json b/client/jsconfig.json deleted file mode 100644 index 59b3b19..0000000 --- a/client/jsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@/*": ["src/*"], - "@public/*": ["public/*"] - } - } -} diff --git a/client/package.json b/client/package.json index 2b57468..0bd1a9d 100644 --- a/client/package.json +++ b/client/package.json @@ -3,13 +3,13 @@ "private": true, "version": "1.0.0", "description": "tech tools hosted on cloudflare worker", - "main": "index.js", + "main": "src/index.ts", "scripts": { "build": "webpack", - "deploy": "wrangler deploy src/index.js", + "deploy": "wrangler deploy src/index.ts", "dev": "webpack-dev-server --config webpack-dev.config.js --open", "prepare": "husky", - "start": "wrangler dev src/index.js" + "start": "wrangler dev src/index.ts" }, "author": "", "license": "ISC", @@ -28,8 +28,12 @@ "@babel/core": "^7.24.8", "@babel/preset-env": "^7.24.8", "@babel/preset-react": "^7.24.7", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@types/react-router-dom": "^5.3.3", "autoprefixer": "^10.4.19", "babel-loader": "^9.1.3", + "babel-plugin-module-resolver": "^5.0.2", "compression-webpack-plugin": "^11.1.0", "copy-webpack-plugin": "^12.0.2", "css-loader": "^7.1.2", @@ -43,6 +47,8 @@ "style-loader": "^4.0.0", "tailwindcss": "^3.4.4", "terser-webpack-plugin": "^5.3.10", + "ts-loader": "^9.5.1", + "typescript": "^5.5.3", "webpack": "^5.93.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4" diff --git a/client/src/@types/html.d.ts b/client/src/@types/html.d.ts new file mode 100644 index 0000000..ac6187a --- /dev/null +++ b/client/src/@types/html.d.ts @@ -0,0 +1,4 @@ +declare module '*.html' { + const content: string; + export default content; +} diff --git a/client/src/@types/svg.d.ts b/client/src/@types/svg.d.ts new file mode 100644 index 0000000..f9b7acd --- /dev/null +++ b/client/src/@types/svg.d.ts @@ -0,0 +1,4 @@ +declare module '*.svg' { + const content: string; + export default content; +} diff --git a/client/src/App.jsx b/client/src/App.tsx similarity index 100% rename from client/src/App.jsx rename to client/src/App.tsx diff --git a/client/src/components/Footer/Footer.jsx b/client/src/components/Footer/Footer.tsx similarity index 100% rename from client/src/components/Footer/Footer.jsx rename to client/src/components/Footer/Footer.tsx diff --git a/client/src/components/Header/Header.jsx b/client/src/components/Header/Header.tsx similarity index 100% rename from client/src/components/Header/Header.jsx rename to client/src/components/Header/Header.tsx diff --git a/client/src/index.js b/client/src/index.ts similarity index 97% rename from client/src/index.js rename to client/src/index.ts index c5faf29..3637421 100644 --- a/client/src/index.js +++ b/client/src/index.ts @@ -41,6 +41,6 @@ router.all('*', rootHandler); * are called, and the response is sent. The routesAndAssetsHandler will map * assets and routes accordingly. */ -addEventListener('fetch', event => { +addEventListener('fetch', (event: any) => { event.respondWith(routesAndAssetsHandler(event, router)); }); diff --git a/client/src/main.js b/client/src/main.tsx similarity index 88% rename from client/src/main.js rename to client/src/main.tsx index 6795e2a..c87d6d0 100644 --- a/client/src/main.js +++ b/client/src/main.tsx @@ -24,7 +24,8 @@ const router = createBrowserRouter([ ]); // Render your React component instead +// @ts-ignore const root = createRoot(document.getElementById('root')); root.render( - + ); diff --git a/client/src/pages/Error.jsx b/client/src/pages/Error.tsx similarity index 100% rename from client/src/pages/Error.jsx rename to client/src/pages/Error.tsx diff --git a/client/src/pages/Home.jsx b/client/src/pages/Home.tsx similarity index 77% rename from client/src/pages/Home.jsx rename to client/src/pages/Home.tsx index 701f95f..6ef5431 100644 --- a/client/src/pages/Home.jsx +++ b/client/src/pages/Home.tsx @@ -12,14 +12,14 @@ const Home = () => {

This is a basic React page deployed on Cloudflare Workers.


-
Your name: { tester }
+
Your name: {tester}
-

Count: { count }

+

Count: {count}


diff --git a/client/src/routers/encoding/base64/router.js b/client/src/routers/encoding/base64/router.js deleted file mode 100644 index ba6949c..0000000 --- a/client/src/routers/encoding/base64/router.js +++ /dev/null @@ -1,26 +0,0 @@ -import { Buffer } from 'buffer'; - -export const base64Handler = async ({ params }) => { - // Decode text like "Hello%20world" into "Hello world" - let input = decodeURIComponent(params.text) - - // Construct a buffer from our input - let buffer = Buffer.from(input, "utf8") - - // Serialise the buffer into a base64 string - let base64 = buffer.toString("base64") - - const backendApi = 'https://6wkf624dt4.execute-api.us-east-1.amazonaws.com/prod/'; - const response = await fetch(backendApi) - const data = await response.json() - - // Return the HTML with the string to the client - return new Response(` -

Base64 encoding: ${base64}

-

${JSON.stringify(data, null, 2)}

-`, { - headers: { - "Content-Type": "text/html" - } - }) -}; \ No newline at end of file diff --git a/client/src/routers/encoding/base64/router.ts b/client/src/routers/encoding/base64/router.ts new file mode 100644 index 0000000..86d2325 --- /dev/null +++ b/client/src/routers/encoding/base64/router.ts @@ -0,0 +1,26 @@ +import { Buffer } from 'buffer'; + +export const base64Handler = async ({ params }: any) => { + // Decode text like "Hello%20world" into "Hello world" + let input = decodeURIComponent(params.text) + + // Construct a buffer from our input + let buffer = Buffer.from(input, "utf8") + + // Serialise the buffer into a base64 string + let base64 = buffer.toString("base64") + + const backendApi = 'https://6wkf624dt4.execute-api.us-east-1.amazonaws.com/prod/'; + const response = await fetch(backendApi) + const data = await response.json() + + // Return the HTML with the string to the client + return new Response(` +

Base64 encoding: ${base64}

+

${JSON.stringify(data, null, 2)}

+`, { + headers: { + "Content-Type": "text/html" + } + }) +}; \ No newline at end of file diff --git a/client/src/routers/handler.js b/client/src/routers/handler.ts similarity index 87% rename from client/src/routers/handler.js rename to client/src/routers/handler.ts index 945ef03..d32bc56 100644 --- a/client/src/routers/handler.js +++ b/client/src/routers/handler.ts @@ -9,7 +9,7 @@ import { getAssetFromKV } from "@cloudflare/kv-asset-handler"; * @param {Router} router - The router object responsible for handling non-static asset requests. * @returns {Response} A Response object containing the requested asset or routed content. */ -export const routesAndAssetsHandler = async (event, router) => { +export const routesAndAssetsHandler = async (event: any, router: any): Promise => { // Extract the request from the event const request = event.request; @@ -27,8 +27,8 @@ export const routesAndAssetsHandler = async (event, router) => { try { // Pass the entire event object to getAssetFromKV return await getAssetFromKV(event); - } catch (e) { - return new Response(`Bundle not found: ${ e.message }`, { + } catch (e: any) { + return new Response(`Bundle not found: ${e.message}`, { status: 404, statusText: 'Not Found', }); diff --git a/client/src/routers/health/router.js b/client/src/routers/health/router.ts similarity index 100% rename from client/src/routers/health/router.js rename to client/src/routers/health/router.ts diff --git a/client/src/routers/index.js b/client/src/routers/index.ts similarity index 100% rename from client/src/routers/index.js rename to client/src/routers/index.ts diff --git a/client/src/routers/post/router.js b/client/src/routers/post/router.js deleted file mode 100644 index 52cc4bd..0000000 --- a/client/src/routers/post/router.js +++ /dev/null @@ -1,30 +0,0 @@ -/* -This shows a different HTTP method, a POST. - -Try send a POST request using curl or another tool. - -Try the below curl command to send JSON: - -$ curl -X POST -H "Content-Type: application/json" -d '{"abc": "def"}' -*/ -export const postHandler = async request => { - // Create a base object with some fields. - let fields = { - "asn": request.cf.asn, - "colo": request.cf.colo - } - - // If the POST data is JSON then attach it to our response. - if (request.headers.get("Content-Type") === "application/json") { - fields["json"] = await request.json() - } - - // Serialise the JSON to a string. - const returnData = JSON.stringify(fields, null, 2); - - return new Response(returnData, { - headers: { - "Content-Type": "application/json" - } - }) -}; \ No newline at end of file diff --git a/client/src/routers/post/router.ts b/client/src/routers/post/router.ts new file mode 100644 index 0000000..53a7eed --- /dev/null +++ b/client/src/routers/post/router.ts @@ -0,0 +1,30 @@ +/* +This shows a different HTTP method, a POST. + +Try send a POST request using curl or another tool. + +Try the below curl command to send JSON: + +$ curl -X POST -H "Content-Type: application/json" -d '{"abc": "def"}' +*/ +export const postHandler = async (request: any) => { + // Create a base object with some fields. + let fields: any = { + "asn": request.cf.asn, + "colo": request.cf.colo + } + + // If the POST data is JSON then attach it to our response. + if (request.headers.get("Content-Type") === "application/json") { + fields["json"] = await request.json() + } + + // Serialise the JSON to a string. + const returnData = JSON.stringify(fields, null, 2); + + return new Response(returnData, { + headers: { + "Content-Type": "application/json" + } + }) +}; \ No newline at end of file diff --git a/client/src/routers/root/router.js b/client/src/routers/root/router.ts similarity index 80% rename from client/src/routers/root/router.js rename to client/src/routers/root/router.ts index bddfb5e..1fc4a10 100644 --- a/client/src/routers/root/router.js +++ b/client/src/routers/root/router.ts @@ -4,7 +4,7 @@ import indexHTML from '../../../dist/index.html'; * Handles requests to serve the index.html file. * Uses the indexHTML imported from the public directory. */ -export const rootHandler = async (request) => { +export const rootHandler = async (request: any) => { return new Response(indexHTML, { headers: { 'Content-Type': 'text/html', diff --git a/client/tsconfig.json b/client/tsconfig.json new file mode 100644 index 0000000..e5771ec --- /dev/null +++ b/client/tsconfig.json @@ -0,0 +1,40 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noImplicitAny": true, + "noEmit": false, + "outDir": "dist", + "esModuleInterop": true, + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "paths": { + "@/*": [ + "./src/*" + ], + "@public/*": [ + "./public/*" + ] + } + }, + "include": [ + "**/*.ts", + "**/*.tsx", + "src/@types/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/client/webpack.config.js b/client/webpack.config.js index 3bb6296..e80ea30 100644 --- a/client/webpack.config.js +++ b/client/webpack.config.js @@ -7,7 +7,7 @@ const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = { mode: 'production', - entry: './src/main.js', + entry: './src/main.tsx', output: { filename: 'bundle.[contenthash:8].js', // Use content hash for cache busting path: path.resolve(__dirname, 'dist'), @@ -17,14 +17,19 @@ module.exports = { module: { rules: [ { - test: /\.(js|jsx)$/, + test: /\.ts(x?)$/, exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - configFile: './.babelrc', + use: [ + { + loader: 'babel-loader', + options: { + configFile: './.babelrc', + }, }, - }, + { + loader: 'ts-loader' + } + ] }, { test: /\.[s]?css$/, @@ -59,7 +64,7 @@ module.exports = { new CompressionPlugin() ], resolve: { - extensions: ['.js', '.jsx'], + extensions: ['.ts', '.tsx', '.js', '.jsx'], alias: { '@': path.resolve(__dirname, 'src'), // Alias for src folder '@public': path.resolve(__dirname, 'public'), // Alias for public folder diff --git a/client/wrangler.toml b/client/wrangler.toml index daa0584..c8be6f8 100644 --- a/client/wrangler.toml +++ b/client/wrangler.toml @@ -2,7 +2,7 @@ name = "tech" account_id = "**********" workers_dev = true compatibility_date = "2024-07-11" -main = "index.js" +main = "src/index.ts" [site] bucket = "./dist"