@t8/serve 0.1.37 → 0.1.39
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/README.md +26 -17
- package/dist/index.cjs +127 -0
- package/dist/index.d.ts +15 -6
- package/dist/{index.js → index.mjs} +31 -47
- package/package.json +8 -9
- package/src/serve.ts +7 -0
- package/tsconfig.json +1 -1
- /package/dist/{run.js → run.mjs} +0 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Simple static file server + bundler, primarily for demo apps and tests, manual or automated
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Use cases:
|
|
6
6
|
|
|
7
7
|
- Use the CLI-based server to launch a demo or test app with a single CLI command.
|
|
8
8
|
- Use the code-based setup to launch an own server from multiple tests, each with its own app.
|
|
@@ -12,19 +12,29 @@ Simple static file server + bundler, primarily for demo apps and tests, manual o
|
|
|
12
12
|
```sh
|
|
13
13
|
npx @t8/serve [url|port] [*] [app_dir] [...assets_dirs] [-b [bundle_input_path] [bundle_output_path] [bundle_output_dir]] [--watch] [--minify]
|
|
14
14
|
# * = SPA mode: serve all unmatched paths as "/"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
15
18
|
|
|
19
|
+
```sh
|
|
16
20
|
npx @t8/serve 3000 app
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
# - serve files from './app' at 'localhost:3000'
|
|
22
|
+
|
|
19
23
|
npx @t8/serve 3000 * app -b
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
npx @t8/serve 3000 app
|
|
24
|
+
# - bundle './app/index.ts' to './app/dist/index.js' [-b]
|
|
25
|
+
# - serve files from './app' at 'localhost:3000' in the SPA mode [*] (handling all unmatched paths as "/")
|
|
26
|
+
|
|
27
|
+
npx @t8/serve 3000 * app -b src/index.ts
|
|
28
|
+
# - bundle './app/src/index.ts' to './app/dist/index.js'
|
|
29
|
+
# - serve files from './app' at 'localhost:3000' in the SPA mode
|
|
30
|
+
|
|
31
|
+
npx @t8/serve 127.0.0.1:3000 app public dist -b
|
|
32
|
+
# - bundle './app/index.ts' to './app/dist/index.js'
|
|
33
|
+
# - serve files from './app/public' and './app/dist' at '127.0.0.1:3000'
|
|
24
34
|
```
|
|
25
35
|
|
|
26
36
|
<details>
|
|
27
|
-
<summary>Example 1 (flat)</summary>
|
|
37
|
+
<summary>Example with Playwright #1 (flat)</summary>
|
|
28
38
|
|
|
29
39
|
```
|
|
30
40
|
// package.json
|
|
@@ -47,7 +57,6 @@ npm run play
|
|
|
47
57
|
```
|
|
48
58
|
|
|
49
59
|
```
|
|
50
|
-
// With Playwright:
|
|
51
60
|
// playwright.config.ts
|
|
52
61
|
...
|
|
53
62
|
use: {
|
|
@@ -62,7 +71,7 @@ webServer: {
|
|
|
62
71
|
</details>
|
|
63
72
|
|
|
64
73
|
<details>
|
|
65
|
-
<summary>Example 2 (nested)</summary>
|
|
74
|
+
<summary>Example with Playwright #2 (nested)</summary>
|
|
66
75
|
|
|
67
76
|
```
|
|
68
77
|
// package.json
|
|
@@ -87,7 +96,6 @@ npm run play
|
|
|
87
96
|
```
|
|
88
97
|
|
|
89
98
|
```
|
|
90
|
-
// With Playwright:
|
|
91
99
|
// playwright.config.ts
|
|
92
100
|
...
|
|
93
101
|
use: {
|
|
@@ -102,7 +110,7 @@ webServer: {
|
|
|
102
110
|
</details>
|
|
103
111
|
|
|
104
112
|
<details>
|
|
105
|
-
<summary>Example
|
|
113
|
+
<summary>Example with the watch mode</summary>
|
|
106
114
|
|
|
107
115
|
```
|
|
108
116
|
/app
|
|
@@ -137,9 +145,10 @@ import { serve } from "@t8/serve";
|
|
|
137
145
|
|
|
138
146
|
// Start
|
|
139
147
|
let server = await serve({
|
|
140
|
-
|
|
148
|
+
host: "localhost", // default
|
|
149
|
+
port: 3000, // default
|
|
141
150
|
path: "app",
|
|
142
|
-
bundle: true, // or input path, or
|
|
151
|
+
bundle: true, // or input path, or { input, output, dir }
|
|
143
152
|
spa: true,
|
|
144
153
|
});
|
|
145
154
|
|
|
@@ -148,7 +157,7 @@ server.close();
|
|
|
148
157
|
```
|
|
149
158
|
|
|
150
159
|
<details>
|
|
151
|
-
<summary>Example 1 (flat)</summary>
|
|
160
|
+
<summary>Example with Playwright 1 (flat)</summary>
|
|
152
161
|
|
|
153
162
|
```
|
|
154
163
|
/playground
|
|
@@ -182,7 +191,7 @@ test.afterAll(() => {
|
|
|
182
191
|
</details>
|
|
183
192
|
|
|
184
193
|
<details>
|
|
185
|
-
<summary>Example 2 (nested)</summary>
|
|
194
|
+
<summary>Example with Playwright 2 (nested)</summary>
|
|
186
195
|
|
|
187
196
|
```
|
|
188
197
|
/tests/x
|
|
@@ -220,7 +229,7 @@ test.afterAll(() => {
|
|
|
220
229
|
</details>
|
|
221
230
|
|
|
222
231
|
<details>
|
|
223
|
-
<summary>Example
|
|
232
|
+
<summary>Example with an API mock</summary>
|
|
224
233
|
|
|
225
234
|
```ts
|
|
226
235
|
import { serve } from "@t8/serve";
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
let node_fs = require("node:fs");
|
|
2
|
+
let node_http = require("node:http");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
let node_fs_promises = require("node:fs/promises");
|
|
5
|
+
let esbuild = require("esbuild");
|
|
6
|
+
|
|
7
|
+
async function bundle({ path = "", bundle: options, watch, minify } = {}) {
|
|
8
|
+
if (!options) return;
|
|
9
|
+
let normalizedOptions;
|
|
10
|
+
if (typeof options === "boolean") normalizedOptions = {};
|
|
11
|
+
else if (typeof options === "string") normalizedOptions = { input: options };
|
|
12
|
+
else normalizedOptions = options;
|
|
13
|
+
let dir = normalizedOptions.dir ?? "dist";
|
|
14
|
+
let inputFile = (0, node_path.join)(path, normalizedOptions.input ?? "index.ts");
|
|
15
|
+
await (0, node_fs_promises.rm)((0, node_path.join)(path, dir), {
|
|
16
|
+
recursive: true,
|
|
17
|
+
force: true
|
|
18
|
+
});
|
|
19
|
+
let buildOptions = {
|
|
20
|
+
entryPoints: [inputFile],
|
|
21
|
+
bundle: true,
|
|
22
|
+
format: "esm",
|
|
23
|
+
platform: "browser",
|
|
24
|
+
logLevel: "warning",
|
|
25
|
+
minify
|
|
26
|
+
};
|
|
27
|
+
if (normalizedOptions.output) buildOptions.outfile = (0, node_path.join)(path, dir, normalizedOptions.output);
|
|
28
|
+
else {
|
|
29
|
+
buildOptions.outdir = (0, node_path.join)(path, dir);
|
|
30
|
+
buildOptions.splitting = true;
|
|
31
|
+
}
|
|
32
|
+
if (watch) {
|
|
33
|
+
let ctx = await (0, esbuild.context)(buildOptions);
|
|
34
|
+
await ctx.watch();
|
|
35
|
+
return async () => {
|
|
36
|
+
await ctx.dispose();
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
await (0, esbuild.build)(buildOptions);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function isValidFilePath(filePath, dirPath) {
|
|
43
|
+
if (!filePath.startsWith(dirPath)) return false;
|
|
44
|
+
try {
|
|
45
|
+
await (0, node_fs_promises.access)(filePath);
|
|
46
|
+
return !(await (0, node_fs_promises.lstat)(filePath)).isDirectory();
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const cwd = process.cwd();
|
|
53
|
+
async function getFilePath(url = "", { path = "", dirs = [], spa }) {
|
|
54
|
+
let urlPath = url.replace(/[?#].*$/, "");
|
|
55
|
+
for (let dir of dirs.length === 0 ? [""] : dirs) {
|
|
56
|
+
let dirPath = (0, node_path.join)(cwd, path, dir);
|
|
57
|
+
let filePath = (0, node_path.join)(dirPath, urlPath);
|
|
58
|
+
if (!urlPath.endsWith("/") && await isValidFilePath(filePath, dirPath)) return filePath;
|
|
59
|
+
filePath = (0, node_path.join)(dirPath, spa ? "" : urlPath, "index.html");
|
|
60
|
+
if (await isValidFilePath(filePath, dirPath)) return filePath;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const defaultHost = "localhost";
|
|
65
|
+
const defaultPort = 3e3;
|
|
66
|
+
function getTarget(config = {}) {
|
|
67
|
+
let { host, port, url } = config;
|
|
68
|
+
let [, , urlHost, , urlPort] = url?.match(/^(https?:\/\/)?([^:/]+)(:(\d+))?\/?/) ?? [];
|
|
69
|
+
if (!urlPort && /^\d+$/.test(urlHost)) {
|
|
70
|
+
urlPort = urlHost;
|
|
71
|
+
urlHost = "";
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
port: port || Number(urlPort) || defaultPort,
|
|
75
|
+
host: host || urlHost || defaultHost
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const mimeTypes = {
|
|
80
|
+
html: "text/html; charset=utf-8",
|
|
81
|
+
js: "text/javascript",
|
|
82
|
+
json: "application/json",
|
|
83
|
+
css: "text/css",
|
|
84
|
+
svg: "image/svg+xml",
|
|
85
|
+
png: "image/png",
|
|
86
|
+
jpg: "image/jpeg",
|
|
87
|
+
gif: "image/gif",
|
|
88
|
+
ico: "image/x-icon",
|
|
89
|
+
txt: "text/plain",
|
|
90
|
+
md: "text/markdown"
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Starts a static server as configured by the `config` parameter and
|
|
95
|
+
* returns the `Server` object.
|
|
96
|
+
*
|
|
97
|
+
* Bundles the code before starting the server, if configured with
|
|
98
|
+
* `config.bundle` to do so.
|
|
99
|
+
*/
|
|
100
|
+
async function serve(config = {}) {
|
|
101
|
+
let stop = await bundle(config);
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
let server = (0, node_http.createServer)(async (req, res) => {
|
|
104
|
+
await config.onRequest?.(req, res);
|
|
105
|
+
if (res.headersSent) return;
|
|
106
|
+
let filePath = await getFilePath(req.url, config);
|
|
107
|
+
if (filePath === void 0) {
|
|
108
|
+
res.writeHead(404, { "content-type": "text/plain" });
|
|
109
|
+
res.end("Not found");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
let mimeType = mimeTypes[(0, node_path.extname)(filePath).slice(1).toLowerCase()] ?? "application/octet-stream";
|
|
113
|
+
res.writeHead(200, { "content-type": mimeType });
|
|
114
|
+
(0, node_fs.createReadStream)(filePath).pipe(res);
|
|
115
|
+
});
|
|
116
|
+
if (stop) server.on("close", async () => {
|
|
117
|
+
await stop();
|
|
118
|
+
});
|
|
119
|
+
let { host, port } = getTarget(config);
|
|
120
|
+
server.listen(port, host, () => {
|
|
121
|
+
if (config.log) console.log(`Server running at http://${host}:${port}`);
|
|
122
|
+
resolve(server);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
exports.serve = serve;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { IncomingMessage, ServerResponse, createServer } from "node:http";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
type BundleConfig = {
|
|
4
4
|
/**
|
|
5
5
|
* Output directory path relative to the server config `path`.
|
|
6
6
|
*
|
|
@@ -20,7 +20,8 @@ export type BundleConfig = {
|
|
|
20
20
|
*/
|
|
21
21
|
output?: string | undefined;
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
type Config = {
|
|
24
25
|
/** Server URL. */
|
|
25
26
|
url?: string;
|
|
26
27
|
/**
|
|
@@ -65,7 +66,15 @@ export type Config = {
|
|
|
65
66
|
/** Custom request handler. */
|
|
66
67
|
onRequest?: (req?: IncomingMessage, res?: ServerResponse<IncomingMessage>) => void | Promise<void>;
|
|
67
68
|
};
|
|
68
|
-
export type Server = ReturnType<typeof createServer>;
|
|
69
|
-
export declare function serve(config?: Config): Promise<Server>;
|
|
70
69
|
|
|
71
|
-
|
|
70
|
+
type Server = ReturnType<typeof createServer>;
|
|
71
|
+
/**
|
|
72
|
+
* Starts a static server as configured by the `config` parameter and
|
|
73
|
+
* returns the `Server` object.
|
|
74
|
+
*
|
|
75
|
+
* Bundles the code before starting the server, if configured with
|
|
76
|
+
* `config.bundle` to do so.
|
|
77
|
+
*/
|
|
78
|
+
declare function serve(config?: Config): Promise<Server>;
|
|
79
|
+
|
|
80
|
+
export { BundleConfig, Config, Server, serve };
|
|
@@ -1,29 +1,21 @@
|
|
|
1
|
-
// src/serve.ts
|
|
2
1
|
import { createReadStream } from "node:fs";
|
|
3
2
|
import { createServer } from "node:http";
|
|
4
|
-
import { extname } from "node:path";
|
|
5
|
-
|
|
6
|
-
// src/bundle.ts
|
|
7
|
-
import { rm } from "node:fs/promises";
|
|
8
|
-
import { join } from "node:path";
|
|
3
|
+
import { extname, join } from "node:path";
|
|
4
|
+
import { access, lstat, rm } from "node:fs/promises";
|
|
9
5
|
import { build, context } from "esbuild";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
bundle: options,
|
|
13
|
-
watch,
|
|
14
|
-
minify
|
|
15
|
-
} = {}) {
|
|
6
|
+
|
|
7
|
+
async function bundle({ path = "", bundle: options, watch, minify } = {}) {
|
|
16
8
|
if (!options) return;
|
|
17
9
|
let normalizedOptions;
|
|
18
10
|
if (typeof options === "boolean") normalizedOptions = {};
|
|
19
|
-
else if (typeof options === "string")
|
|
20
|
-
normalizedOptions = {
|
|
21
|
-
input: options
|
|
22
|
-
};
|
|
11
|
+
else if (typeof options === "string") normalizedOptions = { input: options };
|
|
23
12
|
else normalizedOptions = options;
|
|
24
13
|
let dir = normalizedOptions.dir ?? "dist";
|
|
25
14
|
let inputFile = join(path, normalizedOptions.input ?? "index.ts");
|
|
26
|
-
await rm(join(path, dir), {
|
|
15
|
+
await rm(join(path, dir), {
|
|
16
|
+
recursive: true,
|
|
17
|
+
force: true
|
|
18
|
+
});
|
|
27
19
|
let buildOptions = {
|
|
28
20
|
entryPoints: [inputFile],
|
|
29
21
|
bundle: true,
|
|
@@ -32,8 +24,7 @@ async function bundle({
|
|
|
32
24
|
logLevel: "warning",
|
|
33
25
|
minify
|
|
34
26
|
};
|
|
35
|
-
if (normalizedOptions.output)
|
|
36
|
-
buildOptions.outfile = join(path, dir, normalizedOptions.output);
|
|
27
|
+
if (normalizedOptions.output) buildOptions.outfile = join(path, dir, normalizedOptions.output);
|
|
37
28
|
else {
|
|
38
29
|
buildOptions.outdir = join(path, dir);
|
|
39
30
|
buildOptions.splitting = true;
|
|
@@ -48,11 +39,6 @@ async function bundle({
|
|
|
48
39
|
await build(buildOptions);
|
|
49
40
|
}
|
|
50
41
|
|
|
51
|
-
// src/getFilePath.ts
|
|
52
|
-
import { join as join2 } from "node:path";
|
|
53
|
-
|
|
54
|
-
// src/isValidFilePath.ts
|
|
55
|
-
import { access, lstat } from "node:fs/promises";
|
|
56
42
|
async function isValidFilePath(filePath, dirPath) {
|
|
57
43
|
if (!filePath.startsWith(dirPath)) return false;
|
|
58
44
|
try {
|
|
@@ -63,23 +49,20 @@ async function isValidFilePath(filePath, dirPath) {
|
|
|
63
49
|
}
|
|
64
50
|
}
|
|
65
51
|
|
|
66
|
-
|
|
67
|
-
var cwd = process.cwd();
|
|
52
|
+
const cwd = process.cwd();
|
|
68
53
|
async function getFilePath(url = "", { path = "", dirs = [], spa }) {
|
|
69
54
|
let urlPath = url.replace(/[?#].*$/, "");
|
|
70
55
|
for (let dir of dirs.length === 0 ? [""] : dirs) {
|
|
71
|
-
let dirPath =
|
|
72
|
-
let filePath =
|
|
73
|
-
if (!urlPath.endsWith("/") && await isValidFilePath(filePath, dirPath))
|
|
74
|
-
|
|
75
|
-
filePath = join2(dirPath, spa ? "" : urlPath, "index.html");
|
|
56
|
+
let dirPath = join(cwd, path, dir);
|
|
57
|
+
let filePath = join(dirPath, urlPath);
|
|
58
|
+
if (!urlPath.endsWith("/") && await isValidFilePath(filePath, dirPath)) return filePath;
|
|
59
|
+
filePath = join(dirPath, spa ? "" : urlPath, "index.html");
|
|
76
60
|
if (await isValidFilePath(filePath, dirPath)) return filePath;
|
|
77
61
|
}
|
|
78
62
|
}
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
var defaultPort = 3e3;
|
|
64
|
+
const defaultHost = "localhost";
|
|
65
|
+
const defaultPort = 3e3;
|
|
83
66
|
function getTarget(config = {}) {
|
|
84
67
|
let { host, port, url } = config;
|
|
85
68
|
let [, , urlHost, , urlPort] = url?.match(/^(https?:\/\/)?([^:/]+)(:(\d+))?\/?/) ?? [];
|
|
@@ -93,8 +76,7 @@ function getTarget(config = {}) {
|
|
|
93
76
|
};
|
|
94
77
|
}
|
|
95
78
|
|
|
96
|
-
|
|
97
|
-
var mimeTypes = {
|
|
79
|
+
const mimeTypes = {
|
|
98
80
|
html: "text/html; charset=utf-8",
|
|
99
81
|
js: "text/javascript",
|
|
100
82
|
json: "application/json",
|
|
@@ -108,7 +90,13 @@ var mimeTypes = {
|
|
|
108
90
|
md: "text/markdown"
|
|
109
91
|
};
|
|
110
92
|
|
|
111
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Starts a static server as configured by the `config` parameter and
|
|
95
|
+
* returns the `Server` object.
|
|
96
|
+
*
|
|
97
|
+
* Bundles the code before starting the server, if configured with
|
|
98
|
+
* `config.bundle` to do so.
|
|
99
|
+
*/
|
|
112
100
|
async function serve(config = {}) {
|
|
113
101
|
let stop = await bundle(config);
|
|
114
102
|
return new Promise((resolve) => {
|
|
@@ -121,16 +109,13 @@ async function serve(config = {}) {
|
|
|
121
109
|
res.end("Not found");
|
|
122
110
|
return;
|
|
123
111
|
}
|
|
124
|
-
let
|
|
125
|
-
let mimeType = mimeTypes[ext] ?? "application/octet-stream";
|
|
112
|
+
let mimeType = mimeTypes[extname(filePath).slice(1).toLowerCase()] ?? "application/octet-stream";
|
|
126
113
|
res.writeHead(200, { "content-type": mimeType });
|
|
127
114
|
createReadStream(filePath).pipe(res);
|
|
128
115
|
});
|
|
129
|
-
if (stop) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
});
|
|
133
|
-
}
|
|
116
|
+
if (stop) server.on("close", async () => {
|
|
117
|
+
await stop();
|
|
118
|
+
});
|
|
134
119
|
let { host, port } = getTarget(config);
|
|
135
120
|
server.listen(port, host, () => {
|
|
136
121
|
if (config.log) console.log(`Server running at http://${host}:${port}`);
|
|
@@ -138,6 +123,5 @@ async function serve(config = {}) {
|
|
|
138
123
|
});
|
|
139
124
|
});
|
|
140
125
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
};
|
|
126
|
+
|
|
127
|
+
export { serve };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t8/serve",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"description": "Simple static file server + bundler, primarily for demo apps and tests, manual or automated",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"bundler"
|
|
10
10
|
],
|
|
11
11
|
"bin": {
|
|
12
|
-
"serve": "dist/run.
|
|
12
|
+
"serve": "./dist/run.mjs"
|
|
13
13
|
},
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
@@ -18,14 +18,13 @@
|
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"author": "axtk",
|
|
20
20
|
"type": "module",
|
|
21
|
-
"main": "dist/index.
|
|
22
|
-
"
|
|
21
|
+
"main": "./dist/index.cjs",
|
|
22
|
+
"module": "./dist/index.mjs",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
23
24
|
"scripts": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"preversion": "npx npm-run-all clean shape -p compile compile-bin",
|
|
28
|
-
"shape": "npx codeshape --typecheck --emit-types"
|
|
25
|
+
"compile-bin": "npx esbuild src/run.ts --bundle --outfile=dist/run.mjs --platform=node --format=esm --external:esbuild",
|
|
26
|
+
"preversion": "npx npm-run-all shape compile-bin",
|
|
27
|
+
"shape": "npx codeshape"
|
|
29
28
|
},
|
|
30
29
|
"devDependencies": {
|
|
31
30
|
"@types/node": "^24.5.2"
|
package/src/serve.ts
CHANGED
|
@@ -9,6 +9,13 @@ import { mimeTypes } from "./mimeTypes.ts";
|
|
|
9
9
|
|
|
10
10
|
export type Server = ReturnType<typeof createServer>;
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Starts a static server as configured by the `config` parameter and
|
|
14
|
+
* returns the `Server` object.
|
|
15
|
+
*
|
|
16
|
+
* Bundles the code before starting the server, if configured with
|
|
17
|
+
* `config.bundle` to do so.
|
|
18
|
+
*/
|
|
12
19
|
export async function serve(config: Config = {}): Promise<Server> {
|
|
13
20
|
let stop = await bundle(config);
|
|
14
21
|
|
package/tsconfig.json
CHANGED
/package/dist/{run.js → run.mjs}
RENAMED
|
File without changes
|