@t8/serve 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +51 -31
- package/dist/run.cjs +64 -52
- package/dist/run.mjs +60 -48
- package/package.json +1 -1
- package/src/Config.ts +4 -0
- package/src/bundle.ts +19 -0
- package/src/getFilePath.ts +5 -8
- package/src/run.ts +13 -19
- package/src/serve.ts +26 -22
package/dist/index.js
CHANGED
|
@@ -27,18 +27,34 @@ module.exports = __toCommonJS(index_exports);
|
|
|
27
27
|
// src/serve.ts
|
|
28
28
|
var import_node_fs = require("node:fs");
|
|
29
29
|
var import_node_http = require("node:http");
|
|
30
|
-
var
|
|
30
|
+
var import_node_path3 = require("node:path");
|
|
31
31
|
|
|
32
|
-
// src/
|
|
32
|
+
// src/bundle.ts
|
|
33
|
+
var import_node_child_process = require("node:child_process");
|
|
34
|
+
var import_promises = require("node:fs/promises");
|
|
33
35
|
var import_node_path = require("node:path");
|
|
36
|
+
var import_node_util = require("node:util");
|
|
37
|
+
var exec = (0, import_node_util.promisify)(import_node_child_process.exec);
|
|
38
|
+
async function bundle({ path = "", bundle: options } = {}) {
|
|
39
|
+
if (!options) return;
|
|
40
|
+
let inputFile = (0, import_node_path.join)(path, options.input ?? "index.ts");
|
|
41
|
+
let outputFile = (0, import_node_path.join)(path, "dist", options.output ?? "index.js");
|
|
42
|
+
await (0, import_promises.rm)((0, import_node_path.join)(path, "dist"), { recursive: true, force: true });
|
|
43
|
+
await exec(
|
|
44
|
+
`npx esbuild ${inputFile} --outfile=${outputFile} --bundle --platform=neutral --log-level=warning`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/getFilePath.ts
|
|
49
|
+
var import_node_path2 = require("node:path");
|
|
34
50
|
|
|
35
51
|
// src/isValidFilePath.ts
|
|
36
|
-
var
|
|
52
|
+
var import_promises2 = require("node:fs/promises");
|
|
37
53
|
async function isValidFilePath(filePath, dirPath) {
|
|
38
54
|
if (!filePath.startsWith(dirPath)) return false;
|
|
39
55
|
try {
|
|
40
|
-
await (0,
|
|
41
|
-
return !(await (0,
|
|
56
|
+
await (0, import_promises2.access)(filePath);
|
|
57
|
+
return !(await (0, import_promises2.lstat)(filePath)).isDirectory();
|
|
42
58
|
} catch {
|
|
43
59
|
return false;
|
|
44
60
|
}
|
|
@@ -46,14 +62,14 @@ async function isValidFilePath(filePath, dirPath) {
|
|
|
46
62
|
|
|
47
63
|
// src/getFilePath.ts
|
|
48
64
|
var cwd = process.cwd();
|
|
49
|
-
async function getFilePath(
|
|
50
|
-
let
|
|
65
|
+
async function getFilePath(url = "", { path = "", dirs = [], spa }) {
|
|
66
|
+
let urlPath = url.replace(/[?#].*$/, "");
|
|
51
67
|
for (let dir of dirs.length === 0 ? [""] : dirs) {
|
|
52
|
-
let dirPath = (0,
|
|
53
|
-
let filePath = (0,
|
|
54
|
-
if (!
|
|
68
|
+
let dirPath = (0, import_node_path2.join)(cwd, path, dir);
|
|
69
|
+
let filePath = (0, import_node_path2.join)(dirPath, urlPath);
|
|
70
|
+
if (!urlPath.endsWith("/") && await isValidFilePath(filePath, dirPath))
|
|
55
71
|
return filePath;
|
|
56
|
-
filePath = (0,
|
|
72
|
+
filePath = (0, import_node_path2.join)(dirPath, spa ? "" : urlPath, "index.html");
|
|
57
73
|
if (await isValidFilePath(filePath, dirPath)) return filePath;
|
|
58
74
|
}
|
|
59
75
|
}
|
|
@@ -76,32 +92,36 @@ var mimeTypes = {
|
|
|
76
92
|
// src/serve.ts
|
|
77
93
|
var defaultHost = "localhost";
|
|
78
94
|
var defaultPort = 3e3;
|
|
79
|
-
function serve(config = {}) {
|
|
95
|
+
async function serve(config = {}) {
|
|
80
96
|
let [, , host, , port] = config.url?.match(/^(https?:\/\/)?([^:/]+)(:(\d+))?\/?/) ?? [];
|
|
81
97
|
if (!port && /^\d+$/.test(host)) {
|
|
82
98
|
port = host;
|
|
83
99
|
host = defaultHost;
|
|
84
100
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
await bundle(config);
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
let server = (0, import_node_http.createServer)(async (req, res) => {
|
|
104
|
+
let filePath = await getFilePath(req.url, config);
|
|
105
|
+
if (filePath === void 0) {
|
|
106
|
+
res.writeHead(404, { "content-type": "text/plain" });
|
|
107
|
+
res.end("Not found");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
let ext = (0, import_node_path3.extname)(filePath).slice(1).toLowerCase();
|
|
111
|
+
let mimeType = mimeTypes[ext] ?? "application/octet-stream";
|
|
112
|
+
res.writeHead(200, { "content-type": mimeType });
|
|
113
|
+
(0, import_node_fs.createReadStream)(filePath).pipe(res);
|
|
114
|
+
});
|
|
115
|
+
server.on("close", () => {
|
|
116
|
+
process.exit(0);
|
|
117
|
+
});
|
|
118
|
+
let serverPort = Number(port) || defaultPort;
|
|
119
|
+
let serverHost = host || defaultHost;
|
|
120
|
+
server.listen(serverPort, serverHost, () => {
|
|
121
|
+
console.log(`Server running at http://${serverHost}:${serverPort}`);
|
|
122
|
+
resolve(server);
|
|
123
|
+
});
|
|
99
124
|
});
|
|
100
|
-
let serverPort = Number(port) || defaultPort;
|
|
101
|
-
let serverHost = host || defaultHost;
|
|
102
|
-
server.listen(serverPort, serverHost);
|
|
103
|
-
console.log(`Server running at http://${serverHost}:${serverPort}`);
|
|
104
|
-
return server;
|
|
105
125
|
}
|
|
106
126
|
// Annotate the CommonJS export names for ESM import in node:
|
|
107
127
|
0 && (module.exports = {
|
package/dist/run.cjs
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
|
-
// src/run.ts
|
|
5
|
-
var import_node_child_process = require("node:child_process");
|
|
6
|
-
var import_promises2 = require("node:fs/promises");
|
|
7
|
-
var import_node_path3 = require("node:path");
|
|
8
|
-
var import_node_util = require("node:util");
|
|
9
|
-
|
|
10
4
|
// src/serve.ts
|
|
11
5
|
var import_node_fs = require("node:fs");
|
|
12
6
|
var import_node_http = require("node:http");
|
|
13
|
-
var
|
|
7
|
+
var import_node_path3 = require("node:path");
|
|
14
8
|
|
|
15
|
-
// src/
|
|
9
|
+
// src/bundle.ts
|
|
10
|
+
var import_node_child_process = require("node:child_process");
|
|
11
|
+
var import_promises = require("node:fs/promises");
|
|
16
12
|
var import_node_path = require("node:path");
|
|
13
|
+
var import_node_util = require("node:util");
|
|
14
|
+
var exec = (0, import_node_util.promisify)(import_node_child_process.exec);
|
|
15
|
+
async function bundle({ path = "", bundle: options } = {}) {
|
|
16
|
+
if (!options) return;
|
|
17
|
+
let inputFile = (0, import_node_path.join)(path, options.input ?? "index.ts");
|
|
18
|
+
let outputFile = (0, import_node_path.join)(path, "dist", options.output ?? "index.js");
|
|
19
|
+
await (0, import_promises.rm)((0, import_node_path.join)(path, "dist"), { recursive: true, force: true });
|
|
20
|
+
await exec(
|
|
21
|
+
`npx esbuild ${inputFile} --outfile=${outputFile} --bundle --platform=neutral --log-level=warning`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/getFilePath.ts
|
|
26
|
+
var import_node_path2 = require("node:path");
|
|
17
27
|
|
|
18
28
|
// src/isValidFilePath.ts
|
|
19
|
-
var
|
|
29
|
+
var import_promises2 = require("node:fs/promises");
|
|
20
30
|
async function isValidFilePath(filePath, dirPath) {
|
|
21
31
|
if (!filePath.startsWith(dirPath)) return false;
|
|
22
32
|
try {
|
|
23
|
-
await (0,
|
|
24
|
-
return !(await (0,
|
|
33
|
+
await (0, import_promises2.access)(filePath);
|
|
34
|
+
return !(await (0, import_promises2.lstat)(filePath)).isDirectory();
|
|
25
35
|
} catch {
|
|
26
36
|
return false;
|
|
27
37
|
}
|
|
@@ -29,14 +39,14 @@ async function isValidFilePath(filePath, dirPath) {
|
|
|
29
39
|
|
|
30
40
|
// src/getFilePath.ts
|
|
31
41
|
var cwd = process.cwd();
|
|
32
|
-
async function getFilePath(
|
|
33
|
-
let
|
|
42
|
+
async function getFilePath(url = "", { path = "", dirs = [], spa }) {
|
|
43
|
+
let urlPath = url.replace(/[?#].*$/, "");
|
|
34
44
|
for (let dir of dirs.length === 0 ? [""] : dirs) {
|
|
35
|
-
let dirPath = (0,
|
|
36
|
-
let filePath = (0,
|
|
37
|
-
if (!
|
|
45
|
+
let dirPath = (0, import_node_path2.join)(cwd, path, dir);
|
|
46
|
+
let filePath = (0, import_node_path2.join)(dirPath, urlPath);
|
|
47
|
+
if (!urlPath.endsWith("/") && await isValidFilePath(filePath, dirPath))
|
|
38
48
|
return filePath;
|
|
39
|
-
filePath = (0,
|
|
49
|
+
filePath = (0, import_node_path2.join)(dirPath, spa ? "" : urlPath, "index.html");
|
|
40
50
|
if (await isValidFilePath(filePath, dirPath)) return filePath;
|
|
41
51
|
}
|
|
42
52
|
}
|
|
@@ -59,36 +69,39 @@ var mimeTypes = {
|
|
|
59
69
|
// src/serve.ts
|
|
60
70
|
var defaultHost = "localhost";
|
|
61
71
|
var defaultPort = 3e3;
|
|
62
|
-
function serve(config = {}) {
|
|
72
|
+
async function serve(config = {}) {
|
|
63
73
|
let [, , host, , port] = config.url?.match(/^(https?:\/\/)?([^:/]+)(:(\d+))?\/?/) ?? [];
|
|
64
74
|
if (!port && /^\d+$/.test(host)) {
|
|
65
75
|
port = host;
|
|
66
76
|
host = defaultHost;
|
|
67
77
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
await bundle(config);
|
|
79
|
+
return new Promise((resolve) => {
|
|
80
|
+
let server = (0, import_node_http.createServer)(async (req, res) => {
|
|
81
|
+
let filePath = await getFilePath(req.url, config);
|
|
82
|
+
if (filePath === void 0) {
|
|
83
|
+
res.writeHead(404, { "content-type": "text/plain" });
|
|
84
|
+
res.end("Not found");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
let ext = (0, import_node_path3.extname)(filePath).slice(1).toLowerCase();
|
|
88
|
+
let mimeType = mimeTypes[ext] ?? "application/octet-stream";
|
|
89
|
+
res.writeHead(200, { "content-type": mimeType });
|
|
90
|
+
(0, import_node_fs.createReadStream)(filePath).pipe(res);
|
|
91
|
+
});
|
|
92
|
+
server.on("close", () => {
|
|
93
|
+
process.exit(0);
|
|
94
|
+
});
|
|
95
|
+
let serverPort = Number(port) || defaultPort;
|
|
96
|
+
let serverHost = host || defaultHost;
|
|
97
|
+
server.listen(serverPort, serverHost, () => {
|
|
98
|
+
console.log(`Server running at http://${serverHost}:${serverPort}`);
|
|
99
|
+
resolve(server);
|
|
100
|
+
});
|
|
82
101
|
});
|
|
83
|
-
let serverPort = Number(port) || defaultPort;
|
|
84
|
-
let serverHost = host || defaultHost;
|
|
85
|
-
server.listen(serverPort, serverHost);
|
|
86
|
-
console.log(`Server running at http://${serverHost}:${serverPort}`);
|
|
87
|
-
return server;
|
|
88
102
|
}
|
|
89
103
|
|
|
90
104
|
// src/run.ts
|
|
91
|
-
var exec = (0, import_node_util.promisify)(import_node_child_process.exec);
|
|
92
105
|
async function run() {
|
|
93
106
|
let [url, ...args] = process.argv.slice(2);
|
|
94
107
|
let spa = false;
|
|
@@ -96,25 +109,24 @@ async function run() {
|
|
|
96
109
|
spa = true;
|
|
97
110
|
args.shift();
|
|
98
111
|
}
|
|
99
|
-
let
|
|
112
|
+
let bundleFlagIndex = args.indexOf("-b");
|
|
100
113
|
let path = args[0];
|
|
101
|
-
let dirs
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
`npx esbuild ${inputFile} --outfile=${outputFile} --bundle --platform=neutral --log-level=warning`
|
|
111
|
-
);
|
|
114
|
+
let dirs;
|
|
115
|
+
let bundle2;
|
|
116
|
+
if (bundleFlagIndex === -1) dirs = args.slice(1);
|
|
117
|
+
else {
|
|
118
|
+
dirs = args.slice(1, bundleFlagIndex);
|
|
119
|
+
bundle2 = {
|
|
120
|
+
input: args[bundleFlagIndex + 1],
|
|
121
|
+
output: args[bundleFlagIndex + 2]
|
|
122
|
+
};
|
|
112
123
|
}
|
|
113
|
-
serve({
|
|
124
|
+
await serve({
|
|
114
125
|
url,
|
|
115
126
|
path,
|
|
116
127
|
dirs,
|
|
117
|
-
spa
|
|
128
|
+
spa,
|
|
129
|
+
bundle: bundle2
|
|
118
130
|
});
|
|
119
131
|
}
|
|
120
132
|
run();
|
package/dist/run.mjs
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// src/run.ts
|
|
4
|
-
import { exec as originalExec } from "node:child_process";
|
|
5
|
-
import { rm } from "node:fs/promises";
|
|
6
|
-
import { join as join2 } from "node:path";
|
|
7
|
-
import { promisify } from "node:util";
|
|
8
|
-
|
|
9
3
|
// src/serve.ts
|
|
10
4
|
import { createReadStream } from "node:fs";
|
|
11
5
|
import { createServer } from "node:http";
|
|
12
6
|
import { extname } from "node:path";
|
|
13
7
|
|
|
14
|
-
// src/
|
|
8
|
+
// src/bundle.ts
|
|
9
|
+
import { exec as originalExec } from "node:child_process";
|
|
10
|
+
import { rm } from "node:fs/promises";
|
|
15
11
|
import { join } from "node:path";
|
|
12
|
+
import { promisify } from "node:util";
|
|
13
|
+
var exec = promisify(originalExec);
|
|
14
|
+
async function bundle({ path = "", bundle: options } = {}) {
|
|
15
|
+
if (!options) return;
|
|
16
|
+
let inputFile = join(path, options.input ?? "index.ts");
|
|
17
|
+
let outputFile = join(path, "dist", options.output ?? "index.js");
|
|
18
|
+
await rm(join(path, "dist"), { recursive: true, force: true });
|
|
19
|
+
await exec(
|
|
20
|
+
`npx esbuild ${inputFile} --outfile=${outputFile} --bundle --platform=neutral --log-level=warning`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/getFilePath.ts
|
|
25
|
+
import { join as join2 } from "node:path";
|
|
16
26
|
|
|
17
27
|
// src/isValidFilePath.ts
|
|
18
28
|
import { access, lstat } from "node:fs/promises";
|
|
@@ -28,14 +38,14 @@ async function isValidFilePath(filePath, dirPath) {
|
|
|
28
38
|
|
|
29
39
|
// src/getFilePath.ts
|
|
30
40
|
var cwd = process.cwd();
|
|
31
|
-
async function getFilePath(
|
|
32
|
-
let
|
|
41
|
+
async function getFilePath(url = "", { path = "", dirs = [], spa }) {
|
|
42
|
+
let urlPath = url.replace(/[?#].*$/, "");
|
|
33
43
|
for (let dir of dirs.length === 0 ? [""] : dirs) {
|
|
34
|
-
let dirPath =
|
|
35
|
-
let filePath =
|
|
36
|
-
if (!
|
|
44
|
+
let dirPath = join2(cwd, path, dir);
|
|
45
|
+
let filePath = join2(dirPath, urlPath);
|
|
46
|
+
if (!urlPath.endsWith("/") && await isValidFilePath(filePath, dirPath))
|
|
37
47
|
return filePath;
|
|
38
|
-
filePath =
|
|
48
|
+
filePath = join2(dirPath, spa ? "" : urlPath, "index.html");
|
|
39
49
|
if (await isValidFilePath(filePath, dirPath)) return filePath;
|
|
40
50
|
}
|
|
41
51
|
}
|
|
@@ -58,36 +68,39 @@ var mimeTypes = {
|
|
|
58
68
|
// src/serve.ts
|
|
59
69
|
var defaultHost = "localhost";
|
|
60
70
|
var defaultPort = 3e3;
|
|
61
|
-
function serve(config = {}) {
|
|
71
|
+
async function serve(config = {}) {
|
|
62
72
|
let [, , host, , port] = config.url?.match(/^(https?:\/\/)?([^:/]+)(:(\d+))?\/?/) ?? [];
|
|
63
73
|
if (!port && /^\d+$/.test(host)) {
|
|
64
74
|
port = host;
|
|
65
75
|
host = defaultHost;
|
|
66
76
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
await bundle(config);
|
|
78
|
+
return new Promise((resolve) => {
|
|
79
|
+
let server = createServer(async (req, res) => {
|
|
80
|
+
let filePath = await getFilePath(req.url, config);
|
|
81
|
+
if (filePath === void 0) {
|
|
82
|
+
res.writeHead(404, { "content-type": "text/plain" });
|
|
83
|
+
res.end("Not found");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
let ext = extname(filePath).slice(1).toLowerCase();
|
|
87
|
+
let mimeType = mimeTypes[ext] ?? "application/octet-stream";
|
|
88
|
+
res.writeHead(200, { "content-type": mimeType });
|
|
89
|
+
createReadStream(filePath).pipe(res);
|
|
90
|
+
});
|
|
91
|
+
server.on("close", () => {
|
|
92
|
+
process.exit(0);
|
|
93
|
+
});
|
|
94
|
+
let serverPort = Number(port) || defaultPort;
|
|
95
|
+
let serverHost = host || defaultHost;
|
|
96
|
+
server.listen(serverPort, serverHost, () => {
|
|
97
|
+
console.log(`Server running at http://${serverHost}:${serverPort}`);
|
|
98
|
+
resolve(server);
|
|
99
|
+
});
|
|
81
100
|
});
|
|
82
|
-
let serverPort = Number(port) || defaultPort;
|
|
83
|
-
let serverHost = host || defaultHost;
|
|
84
|
-
server.listen(serverPort, serverHost);
|
|
85
|
-
console.log(`Server running at http://${serverHost}:${serverPort}`);
|
|
86
|
-
return server;
|
|
87
101
|
}
|
|
88
102
|
|
|
89
103
|
// src/run.ts
|
|
90
|
-
var exec = promisify(originalExec);
|
|
91
104
|
async function run() {
|
|
92
105
|
let [url, ...args] = process.argv.slice(2);
|
|
93
106
|
let spa = false;
|
|
@@ -95,25 +108,24 @@ async function run() {
|
|
|
95
108
|
spa = true;
|
|
96
109
|
args.shift();
|
|
97
110
|
}
|
|
98
|
-
let
|
|
111
|
+
let bundleFlagIndex = args.indexOf("-b");
|
|
99
112
|
let path = args[0];
|
|
100
|
-
let dirs
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
`npx esbuild ${inputFile} --outfile=${outputFile} --bundle --platform=neutral --log-level=warning`
|
|
110
|
-
);
|
|
113
|
+
let dirs;
|
|
114
|
+
let bundle2;
|
|
115
|
+
if (bundleFlagIndex === -1) dirs = args.slice(1);
|
|
116
|
+
else {
|
|
117
|
+
dirs = args.slice(1, bundleFlagIndex);
|
|
118
|
+
bundle2 = {
|
|
119
|
+
input: args[bundleFlagIndex + 1],
|
|
120
|
+
output: args[bundleFlagIndex + 2]
|
|
121
|
+
};
|
|
111
122
|
}
|
|
112
|
-
serve({
|
|
123
|
+
await serve({
|
|
113
124
|
url,
|
|
114
125
|
path,
|
|
115
126
|
dirs,
|
|
116
|
-
spa
|
|
127
|
+
spa,
|
|
128
|
+
bundle: bundle2
|
|
117
129
|
});
|
|
118
130
|
}
|
|
119
131
|
run();
|
package/package.json
CHANGED
package/src/Config.ts
CHANGED
package/src/bundle.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { exec as originalExec } from "node:child_process";
|
|
2
|
+
import { rm } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import type { Config } from "./Config";
|
|
6
|
+
|
|
7
|
+
const exec = promisify(originalExec);
|
|
8
|
+
|
|
9
|
+
export async function bundle({ path = "", bundle: options }: Config = {}) {
|
|
10
|
+
if (!options) return;
|
|
11
|
+
|
|
12
|
+
let inputFile = join(path, options.input ?? "index.ts");
|
|
13
|
+
let outputFile = join(path, "dist", options.output ?? "index.js");
|
|
14
|
+
|
|
15
|
+
await rm(join(path, "dist"), { recursive: true, force: true });
|
|
16
|
+
await exec(
|
|
17
|
+
`npx esbuild ${inputFile} --outfile=${outputFile} --bundle --platform=neutral --log-level=warning`,
|
|
18
|
+
);
|
|
19
|
+
}
|
package/src/getFilePath.ts
CHANGED
|
@@ -5,22 +5,19 @@ import { isValidFilePath } from "./isValidFilePath";
|
|
|
5
5
|
const cwd = process.cwd();
|
|
6
6
|
|
|
7
7
|
export async function getFilePath(
|
|
8
|
-
|
|
8
|
+
url = "",
|
|
9
9
|
{ path = "", dirs = [], spa }: Config,
|
|
10
10
|
) {
|
|
11
|
-
let
|
|
11
|
+
let urlPath = url.replace(/[?#].*$/, "");
|
|
12
12
|
|
|
13
13
|
for (let dir of dirs.length === 0 ? [""] : dirs) {
|
|
14
14
|
let dirPath = join(cwd, path, dir);
|
|
15
|
-
let filePath = join(dirPath,
|
|
15
|
+
let filePath = join(dirPath, urlPath);
|
|
16
16
|
|
|
17
|
-
if (
|
|
18
|
-
!effectiveURLPath.endsWith("/") &&
|
|
19
|
-
(await isValidFilePath(filePath, dirPath))
|
|
20
|
-
)
|
|
17
|
+
if (!urlPath.endsWith("/") && (await isValidFilePath(filePath, dirPath)))
|
|
21
18
|
return filePath;
|
|
22
19
|
|
|
23
|
-
filePath = join(dirPath,
|
|
20
|
+
filePath = join(dirPath, spa ? "" : urlPath, "index.html");
|
|
24
21
|
|
|
25
22
|
if (await isValidFilePath(filePath, dirPath)) return filePath;
|
|
26
23
|
}
|
package/src/run.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { rm } from "node:fs/promises";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { promisify } from "node:util";
|
|
2
|
+
import type { Config } from "./Config";
|
|
6
3
|
import { serve } from "./serve";
|
|
7
4
|
|
|
8
|
-
const exec = promisify(originalExec);
|
|
9
|
-
|
|
10
5
|
async function run() {
|
|
11
6
|
let [url, ...args] = process.argv.slice(2);
|
|
12
7
|
let spa = false;
|
|
@@ -16,28 +11,27 @@ async function run() {
|
|
|
16
11
|
args.shift();
|
|
17
12
|
}
|
|
18
13
|
|
|
19
|
-
let
|
|
14
|
+
let bundleFlagIndex = args.indexOf("-b");
|
|
20
15
|
let path = args[0];
|
|
21
|
-
let dirs = args.slice(
|
|
22
|
-
1,
|
|
23
|
-
buildFlagIndex === -1 ? args.length : buildFlagIndex,
|
|
24
|
-
);
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
let outputFile = join(path, "dist", args[buildFlagIndex + 2] ?? "index.js");
|
|
17
|
+
let dirs: string[];
|
|
18
|
+
let bundle: Config["bundle"];
|
|
29
19
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
if (bundleFlagIndex === -1) dirs = args.slice(1);
|
|
21
|
+
else {
|
|
22
|
+
dirs = args.slice(1, bundleFlagIndex);
|
|
23
|
+
bundle = {
|
|
24
|
+
input: args[bundleFlagIndex + 1],
|
|
25
|
+
output: args[bundleFlagIndex + 2],
|
|
26
|
+
};
|
|
34
27
|
}
|
|
35
28
|
|
|
36
|
-
serve({
|
|
29
|
+
await serve({
|
|
37
30
|
url,
|
|
38
31
|
path,
|
|
39
32
|
dirs,
|
|
40
33
|
spa,
|
|
34
|
+
bundle,
|
|
41
35
|
});
|
|
42
36
|
}
|
|
43
37
|
|
package/src/serve.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createReadStream } from "node:fs";
|
|
2
2
|
import { createServer } from "node:http";
|
|
3
3
|
import { extname } from "node:path";
|
|
4
|
+
import { bundle } from "./bundle";
|
|
4
5
|
import type { Config } from "./Config";
|
|
5
6
|
import { getFilePath } from "./getFilePath";
|
|
6
7
|
import { mimeTypes } from "./mimeTypes";
|
|
@@ -8,7 +9,7 @@ import { mimeTypes } from "./mimeTypes";
|
|
|
8
9
|
const defaultHost = "localhost";
|
|
9
10
|
const defaultPort = 3000;
|
|
10
11
|
|
|
11
|
-
export function serve(config: Config = {}) {
|
|
12
|
+
export async function serve(config: Config = {}) {
|
|
12
13
|
let [, , host, , port] =
|
|
13
14
|
config.url?.match(/^(https?:\/\/)?([^:/]+)(:(\d+))?\/?/) ?? [];
|
|
14
15
|
|
|
@@ -17,32 +18,35 @@ export function serve(config: Config = {}) {
|
|
|
17
18
|
host = defaultHost;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
let filePath = await getFilePath(req.url, config);
|
|
21
|
+
await bundle(config);
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
let server = createServer(async (req, res) => {
|
|
25
|
+
let filePath = await getFilePath(req.url, config);
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
if (filePath === undefined) {
|
|
28
|
+
res.writeHead(404, { "content-type": "text/plain" });
|
|
29
|
+
res.end("Not found");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
server.on("close", () => {
|
|
37
|
-
process.exit(0);
|
|
38
|
-
});
|
|
33
|
+
let ext = extname(filePath).slice(1).toLowerCase();
|
|
34
|
+
let mimeType = mimeTypes[ext] ?? "application/octet-stream";
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
res.writeHead(200, { "content-type": mimeType });
|
|
37
|
+
createReadStream(filePath).pipe(res);
|
|
38
|
+
});
|
|
42
39
|
|
|
43
|
-
|
|
40
|
+
server.on("close", () => {
|
|
41
|
+
process.exit(0);
|
|
42
|
+
});
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
let serverPort = Number(port) || defaultPort;
|
|
45
|
+
let serverHost = host || defaultHost;
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
server.listen(serverPort, serverHost, () => {
|
|
48
|
+
console.log(`Server running at http://${serverHost}:${serverPort}`);
|
|
49
|
+
resolve(server);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
48
52
|
}
|