diff --git a/package.json b/package.json index b2ad77c..974fdf4 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "publishConfig": { "access": "public" }, - "type": "commonjs", + "type": "module", "main": "./dist/servor.js", "bin": "./dist/cli.js", "keywords": [ @@ -20,7 +20,7 @@ "src/**/*" ], "scripts": { - "start": "SWC_NODE_PROJECT=./tsconfig.json node -r @swc-node/register src/cli.ts tests/example index.html 8081 --reload --browse", + "start": "SWC_NODE_PROJECT=./tsconfig.json node --import @swc-node/register/esm-register src/cli.ts tests/example index.html 8081 --reload --browse", "build": "tsc", "cleanup": "rm -f servor.key servor.crt", "test": "npm run cleanup && cd tests && node index.js" @@ -28,13 +28,13 @@ "author": "Luke Jackson ", "license": "MIT", "devDependencies": { - "@swc-node/register": "^1.6.4", + "@swc-node/register": "^1.8.0", "@swc/core": "^1.3.53", "@types/http-proxy": "^1.17.10", "@types/node": "^18.14.6", "prettier": "^2.8.7", "puppeteer": "^3.0.4", - "typescript": "^4.9.5" + "typescript": "^5.4.0" }, "dependencies": { "chokidar": "^3.5.3", diff --git a/src/cli.ts b/src/cli.ts index e54dc65..8d66ece 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,18 +1,19 @@ #!/usr/bin/env node import fs from 'node:fs'; -import path from 'node:path'; -import { servor } from './servor'; -import openBrowser from './utils/openBrowser'; +import { servor } from './servor.ts'; +import openBrowser from './utils/openBrowser.ts'; import { program } from 'commander'; +import { fileURLToPath } from "node:url"; +import process from "node:process"; const readCredentials = () => ({ - cert: fs.readFileSync(__dirname + '/servor.crt'), - key: fs.readFileSync(__dirname + '/servor.key'), + cert: fs.readFileSync(new URL('servor.crt', import.meta.url)), + key: fs.readFileSync(new URL('servor.key', import.meta.url)), }); const certify = () => - require('child_process').execSync(path.resolve(__dirname, '../certify.sh'), { - cwd: __dirname, + require('child_process').execSync(new URL('../certify.sh', import.meta.url), { + cwd: fileURLToPath(import.meta.url), }); (async () => { diff --git a/src/servor.ts b/src/servor.ts index 03e5965..57d4a19 100644 --- a/src/servor.ts +++ b/src/servor.ts @@ -7,13 +7,14 @@ import https from 'node:https'; import zlib from 'node:zlib'; import { promisify } from 'node:util'; import httpProxy from 'http-proxy'; +import process from "node:process"; const gzip = promisify(zlib.gzip); -import mimeTypes from './utils/mimeTypes'; -import directoryListing from './utils/directoryListing'; +import mimeTypes from './utils/mimeTypes.ts'; +import directoryListing from './utils/directoryListing.ts'; -import { fileWatch, usePort, networkIps } from './utils/common'; +import { fileWatch, usePort, networkIps } from './utils/common.ts'; import { existsSync } from 'node:fs'; import Server from 'http-proxy'; @@ -108,9 +109,6 @@ export const servor = async ({ const isRouteRequest = (pathname: string) => !~pathname.split('/').pop()!.indexOf('.'); const isDir = async (pathname: string) => existsSync(pathname.split('/').pop()!) && (await fs.lstat(pathname.split('/').pop()!)).isDirectory(); - const utf8 = (file: WithImplicitCoercion | { [Symbol.toPrimitive](hint: 'string'): string }) => - Buffer.from(file, 'binary').toString('utf8'); - const baseDoc = (pathname = '', base = path.join('/', pathname, '/')) => ``; @@ -123,7 +121,7 @@ export const servor = async ({ const _sendFile = ( res: http2.Http2ServerResponse, status: number, - file: any, + file: string | Uint8Array, ext: string, encoding: BufferEncoding ) => { @@ -132,10 +130,10 @@ export const servor = async ({ res.end(); }; - const sendFile = async (res: http2.Http2ServerResponse, status: number, file: any, ext: string) => { - if (['js', 'css', 'html', 'json', 'xml', 'svg'].includes(ext)) { + const sendFile = async (res: http2.Http2ServerResponse, status: number, file: string | Uint8Array, ext: string) => { + if ([ 'js', 'css', 'html', 'json', 'xml', 'svg' ].includes(ext)) { res.setHeader('content-encoding', 'gzip'); - const content = await gzip(utf8(file)); + const content = await gzip(file); _sendFile(res, status, content, ext, 'utf-8'); } else { _sendFile(res, status, file, ext, 'binary'); @@ -174,7 +172,8 @@ export const servor = async ({ } else { await sendFile(res, 200, file, ext); } - } catch { + } catch (err) { + console.error(err); return sendError(res, 500); } }; @@ -201,7 +200,8 @@ export const servor = async ({ return await sendFile(res, status, baseDoc(pathname) + file, 'html'); } return await sendFile(res, status, file + inject + livereload, 'html'); - } catch { + } catch (err) { + console.error(err); return sendError(res, 500); } }; diff --git a/src/utils/common.ts b/src/utils/common.ts index 817fd72..4227bda 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -1,6 +1,6 @@ -import fs from 'fs'; -import os, { NetworkInterfaceInfo } from 'os'; -import net from 'net'; +import fs from 'node:fs'; +import os, { NetworkInterfaceInfo } from 'node:os'; +import net from 'node:net'; import chokidar from 'chokidar'; // recursive function that checks if a file is still changing @@ -19,13 +19,17 @@ const awaitWriteFinish = (path: fs.PathLike, prev: { mtimeNs: bigint }, cb: () = export const fileWatch = ( x: string | readonly string[], - cb: ( - eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', - path: string, - stats?: fs.Stats | undefined - ) => void + cb: () => void ) => { - chokidar.watch(x).on('all', cb); + if ('Deno' in globalThis) { + (async () => { + for await (const iterator of (globalThis as any).Deno.watchFs(x, { recursive: true })) { + cb(); + } + })(); + } else { + chokidar.watch(x).on('all', cb); + } }; export const usePort = (port?: number, host?: string) => diff --git a/src/utils/openBrowser.ts b/src/utils/openBrowser.ts index bc0635f..34c59e9 100644 --- a/src/utils/openBrowser.ts +++ b/src/utils/openBrowser.ts @@ -1,4 +1,4 @@ -import childProcess from 'child_process'; +import childProcess from 'node:child_process'; export default (url: string) => { let cmd; diff --git a/tsconfig.json b/tsconfig.json index 20bb537..c159762 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ @@ -25,9 +25,9 @@ "moduleDetection": "force" /* Control what method is used to detect module-format JS files. */, /* Modules */ - "module": "CommonJS" /* Specify what module code is generated. */, + "module": "ESNext" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, + "moduleResolution": "Bundler" /* Specify how TypeScript looks up a file from a given module specifier. */, // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ @@ -98,7 +98,8 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */, + "allowImportingTsExtensions": true }, "include": ["src"] } diff --git a/yarn.lock b/yarn.lock index 8e5942c..b3620d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,7 +16,7 @@ __metadata: version: 0.0.0-use.local resolution: "@mayflower-tech/servor@workspace:." dependencies: - "@swc-node/register": ^1.6.4 + "@swc-node/register": ^1.8.0 "@swc/core": ^1.3.53 "@types/http-proxy": ^1.17.10 "@types/node": ^18.14.6 @@ -25,7 +25,7 @@ __metadata: http-proxy: ^1.18.1 prettier: ^2.8.7 puppeteer: ^3.0.4 - typescript: ^4.9.5 + typescript: ^5.4.0 bin: servor: ./dist/cli.js languageName: unknown @@ -51,39 +51,40 @@ __metadata: languageName: node linkType: hard -"@swc-node/core@npm:^1.10.3": - version: 1.10.3 - resolution: "@swc-node/core@npm:1.10.3" +"@swc-node/core@npm:^1.13.0": + version: 1.13.0 + resolution: "@swc-node/core@npm:1.13.0" peerDependencies: "@swc/core": ">= 1.3" - checksum: 6e3e50a44d7a1c1aa62599d83c58f21568c1da03422124b46634488aba02747939063eeb1a2710aab0ab9f14f347386226a017ed72e6ba608d4a26532cd426af + "@swc/types": ">= 0.1" + checksum: 12056f1458c535c54c889aafbe969feef9329210657e1d22235b7d795856ec88e4a8e2116572371698ff2c0b184ebe7935ec857748262d5fcf0bd5b1563649b7 languageName: node linkType: hard -"@swc-node/register@npm:^1.6.4": - version: 1.6.4 - resolution: "@swc-node/register@npm:1.6.4" +"@swc-node/register@npm:^1.8.0": + version: 1.9.0 + resolution: "@swc-node/register@npm:1.9.0" dependencies: - "@swc-node/core": ^1.10.3 - "@swc-node/sourcemap-support": ^0.3.0 - colorette: ^2.0.19 + "@swc-node/core": ^1.13.0 + "@swc-node/sourcemap-support": ^0.5.0 + colorette: ^2.0.20 debug: ^4.3.4 - pirates: ^4.0.5 - tslib: ^2.5.0 + pirates: ^4.0.6 + tslib: ^2.6.2 peerDependencies: "@swc/core": ">= 1.3" typescript: ">= 4.3" - checksum: 9112d10e1ef69a84d9043087ae09600b1d34d1901cef67b69329ddc642b9200ee8aabc5bdc419678e76b3f4e950a1ab13bac3999b92c9ec2fc9c8ce6a33943f2 + checksum: 5e08ece47a4a69deaa6594dfab2c018212d61bacb3bb8ba35875a319188eb83bbc14d58b8843cf424954fc0cbfd3e03a44956b8cfc81eed3d1b7c06b6f90a904 languageName: node linkType: hard -"@swc-node/sourcemap-support@npm:^0.3.0": - version: 0.3.0 - resolution: "@swc-node/sourcemap-support@npm:0.3.0" +"@swc-node/sourcemap-support@npm:^0.5.0": + version: 0.5.0 + resolution: "@swc-node/sourcemap-support@npm:0.5.0" dependencies: source-map-support: ^0.5.21 - tslib: ^2.5.0 - checksum: a3c837ed790238ef88682eb342b75d756eba5eb3b6cfe6cf14a597bd78dfc9a9797f1e54a4977c1297e5324fba2e33bd76ab8aa9c396ad463693de2001180c9e + tslib: ^2.6.2 + checksum: 2163f2ae337dafa07f62492a78d1e7b272207c91f1f7b5a9ab95ba929b7dfa93a4db1188dbafde117dae7219805ba9aac9693fd2066563992dba2239295181ee languageName: node linkType: hard @@ -477,7 +478,7 @@ __metadata: languageName: node linkType: hard -"colorette@npm:^2.0.19": +"colorette@npm:^2.0.20": version: 2.0.20 resolution: "colorette@npm:2.0.20" checksum: 0c016fea2b91b733eb9f4bcdb580018f52c0bc0979443dad930e5037a968237ac53d9beb98e218d2e9235834f8eebce7f8e080422d6194e957454255bde71d3d @@ -1181,10 +1182,10 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.5": - version: 4.0.5 - resolution: "pirates@npm:4.0.5" - checksum: c9994e61b85260bec6c4fc0307016340d9b0c4f4b6550a957afaaff0c9b1ad58fbbea5cfcf083860a25cb27a375442e2b0edf52e2e1e40e69934e08dcc52d227 +"pirates@npm:^4.0.6": + version: 4.0.6 + resolution: "pirates@npm:4.0.6" + checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6 languageName: node linkType: hard @@ -1478,30 +1479,30 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.5.0": - version: 2.5.0 - resolution: "tslib@npm:2.5.0" - checksum: ae3ed5f9ce29932d049908ebfdf21b3a003a85653a9a140d614da6b767a93ef94f460e52c3d787f0e4f383546981713f165037dc2274df212ea9f8a4541004e1 +"tslib@npm:^2.6.2": + version: 2.6.2 + resolution: "tslib@npm:2.6.2" + checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad languageName: node linkType: hard -"typescript@npm:^4.9.5": - version: 4.9.5 - resolution: "typescript@npm:4.9.5" +"typescript@npm:^5.4.0": + version: 5.4.2 + resolution: "typescript@npm:5.4.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: ee000bc26848147ad423b581bd250075662a354d84f0e06eb76d3b892328d8d4440b7487b5a83e851b12b255f55d71835b008a66cbf8f255a11e4400159237db + checksum: 96d80fde25a09bcb04d399082fb27a808a9e17c2111e43849d2aafbd642d835e4f4ef0de09b0ba795ec2a700be6c4c2c3f62bf4660c05404c948727b5bbfb32a languageName: node linkType: hard -"typescript@patch:typescript@^4.9.5#~builtin": - version: 4.9.5 - resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=23ec76" +"typescript@patch:typescript@^5.4.0#~builtin": + version: 5.4.2 + resolution: "typescript@patch:typescript@npm%3A5.4.2#~builtin::version=5.4.2&hash=1f5320" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: ab417a2f398380c90a6cf5a5f74badd17866adf57f1165617d6a551f059c3ba0a3e4da0d147b3ac5681db9ac76a303c5876394b13b3de75fdd5b1eaa06181c9d + checksum: c1b669146bca5529873aae60870e243fa8140c85f57ca32c42f898f586d73ce4a6b4f6bb02ae312729e214d7f5859a0c70da3e527a116fdf5ad00c9fc733ecc6 languageName: node linkType: hard