@haibun/web-server-express 1.28.19 → 1.29.0
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/build/defs.d.ts +20 -0
- package/build/defs.js +3 -0
- package/build/defs.js.map +1 -0
- package/build/server-express.d.ts +29 -0
- package/build/server-express.js +114 -0
- package/build/server-express.js.map +1 -0
- package/build/server-express.test.d.ts +1 -0
- package/build/server-express.test.js +17 -0
- package/build/server-express.test.js.map +1 -0
- package/build/web-server-stepper-route.test.d.ts +1 -0
- package/build/web-server-stepper-route.test.js +35 -0
- package/build/web-server-stepper-route.test.js.map +1 -0
- package/build/web-server-stepper.d.ts +65 -0
- package/build/web-server-stepper.js +103 -0
- package/build/web-server-stepper.js.map +1 -0
- package/build/web-server-stepper.test.d.ts +1 -0
- package/build/web-server-stepper.test.js +39 -0
- package/build/web-server-stepper.test.js.map +1 -0
- package/package.json +4 -4
package/build/defs.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const WEBSERVER = "webserver";
|
|
2
|
+
export declare const CHECK_LISTENER = "CHECK_LISTENER";
|
|
3
|
+
import * as express from 'express';
|
|
4
|
+
export interface IWebServer {
|
|
5
|
+
checkAddStaticFolder(subdir: string, loc: string): undefined | string;
|
|
6
|
+
checkAddIndexFolder(subdir: string, loc: string): undefined | string;
|
|
7
|
+
addKnownStaticFolder(subdir: string, mountAt?: string): undefined | string;
|
|
8
|
+
listen(): Promise<unknown>;
|
|
9
|
+
close(): Promise<void>;
|
|
10
|
+
mounted: {
|
|
11
|
+
get: object;
|
|
12
|
+
post: object;
|
|
13
|
+
};
|
|
14
|
+
addRoute(type: TRouteTypes, path: string, route: TRequestHandler): void;
|
|
15
|
+
use(middleware: express.RequestHandler): void;
|
|
16
|
+
}
|
|
17
|
+
export type TRouteTypes = 'get' | 'post';
|
|
18
|
+
export type IRequest = typeof express.request;
|
|
19
|
+
export type IResponse = typeof express.response;
|
|
20
|
+
export type TRequestHandler = (req: IRequest, res: IResponse) => void;
|
package/build/defs.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defs.js","sourceRoot":"","sources":["../src/defs.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAC;AACrC,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import http from 'http';
|
|
3
|
+
import { RequestHandler } from 'express';
|
|
4
|
+
import { IWebServer, TRouteTypes } from './defs.js';
|
|
5
|
+
import { ILogger } from '@haibun/core/build/lib/interfaces/logger.js';
|
|
6
|
+
export declare const DEFAULT_PORT = 8123;
|
|
7
|
+
export declare class ServerExpress implements IWebServer {
|
|
8
|
+
logger: ILogger;
|
|
9
|
+
static listening: boolean;
|
|
10
|
+
listener?: http.Server;
|
|
11
|
+
app: import("express-serve-static-core").Express;
|
|
12
|
+
mounted: {
|
|
13
|
+
get: {};
|
|
14
|
+
post: {};
|
|
15
|
+
};
|
|
16
|
+
base: string;
|
|
17
|
+
port: number;
|
|
18
|
+
constructor(logger: ILogger, base: string, port?: number);
|
|
19
|
+
use(middleware: RequestHandler): void;
|
|
20
|
+
listen(): Promise<unknown>;
|
|
21
|
+
addRoute(type: TRouteTypes, path: string, route: RequestHandler): void;
|
|
22
|
+
private addMounted;
|
|
23
|
+
checkAddStaticFolder(relativeFolder: string, mountAt?: string): string;
|
|
24
|
+
checkAddIndexFolder(relativeFolder: string, mountAt?: string): string;
|
|
25
|
+
addKnownStaticFolder(folder: string, mountAt?: string): string;
|
|
26
|
+
private doAddStaticFolder;
|
|
27
|
+
checkMountBadOrMounted(type: string, loc: string, what: string): string;
|
|
28
|
+
close(): Promise<void>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { statSync, existsSync } from 'fs';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import serveIndex from 'serve-index';
|
|
4
|
+
import cookieParser from 'cookie-parser';
|
|
5
|
+
export const DEFAULT_PORT = 8123;
|
|
6
|
+
export class ServerExpress {
|
|
7
|
+
logger;
|
|
8
|
+
static listening = false;
|
|
9
|
+
listener;
|
|
10
|
+
app = express();
|
|
11
|
+
mounted = { get: {}, post: {} };
|
|
12
|
+
base;
|
|
13
|
+
port;
|
|
14
|
+
constructor(logger, base, port = DEFAULT_PORT) {
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
this.base = base;
|
|
17
|
+
this.port = port;
|
|
18
|
+
this.app.use(cookieParser());
|
|
19
|
+
this.app.use(express.json({ limit: '50mb' }));
|
|
20
|
+
}
|
|
21
|
+
use(middleware) {
|
|
22
|
+
this.app.use(middleware);
|
|
23
|
+
}
|
|
24
|
+
listen() {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
if (!ServerExpress.listening) {
|
|
27
|
+
try {
|
|
28
|
+
this.listener = this.app.listen(this.port, () => {
|
|
29
|
+
this.logger.log(`Server listening on port: ${this.port}`);
|
|
30
|
+
ServerExpress.listening = true;
|
|
31
|
+
this.logger.log('express listening');
|
|
32
|
+
resolve('started');
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
reject(e);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
this.logger.log('express already listening');
|
|
41
|
+
resolve('already listening');
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
addRoute(type, path, route) {
|
|
46
|
+
if (type !== 'get' && type !== 'post') {
|
|
47
|
+
throw Error(`invalid route type ${type}`);
|
|
48
|
+
}
|
|
49
|
+
const bad = this.checkMountBadOrMounted('get', path, route.toString());
|
|
50
|
+
if (bad) {
|
|
51
|
+
throw Error(bad);
|
|
52
|
+
}
|
|
53
|
+
this.logger.log(`adding ${type} route from ${path}`);
|
|
54
|
+
this.app[type](path, route);
|
|
55
|
+
this.addMounted(type, path, route.toString());
|
|
56
|
+
}
|
|
57
|
+
addMounted(type, path, what) {
|
|
58
|
+
this.mounted[type][path] = what;
|
|
59
|
+
}
|
|
60
|
+
// add a static folder restricted to relative paths from files
|
|
61
|
+
checkAddStaticFolder(relativeFolder, mountAt = '/') {
|
|
62
|
+
const folder = [this.base, relativeFolder].join('/');
|
|
63
|
+
return this.doAddStaticFolder(folder, mountAt);
|
|
64
|
+
}
|
|
65
|
+
// add a index folder restricted to relative paths from files
|
|
66
|
+
checkAddIndexFolder(relativeFolder, mountAt = '/') {
|
|
67
|
+
const folder = [this.base, relativeFolder].join('/');
|
|
68
|
+
const bad = this.checkMountBadOrMounted('get', folder, mountAt);
|
|
69
|
+
if (bad) {
|
|
70
|
+
return bad;
|
|
71
|
+
}
|
|
72
|
+
this.logger.info(`serving index from ${folder} at ${mountAt}`);
|
|
73
|
+
this.app.use(mountAt, serveIndex(folder), express.static(folder));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// add a static folder at any path
|
|
77
|
+
addKnownStaticFolder(folder, mountAt = '/') {
|
|
78
|
+
return this.doAddStaticFolder(folder, mountAt);
|
|
79
|
+
}
|
|
80
|
+
doAddStaticFolder(folder, mountAt = '/') {
|
|
81
|
+
const bad = this.checkMountBadOrMounted('get', mountAt, folder);
|
|
82
|
+
if (bad) {
|
|
83
|
+
return bad;
|
|
84
|
+
}
|
|
85
|
+
if (!existsSync(folder)) {
|
|
86
|
+
return `"${folder}" doesn't exist`;
|
|
87
|
+
}
|
|
88
|
+
const stat = statSync(folder);
|
|
89
|
+
if (!stat.isDirectory()) {
|
|
90
|
+
return `"${folder}" is not a directory`;
|
|
91
|
+
}
|
|
92
|
+
this.app.use(mountAt, express.static(folder));
|
|
93
|
+
this.addMounted('get', mountAt, folder);
|
|
94
|
+
this.logger.info(`serving files from ${folder} at ${mountAt}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
checkMountBadOrMounted(type, loc, what) {
|
|
98
|
+
if (loc !== loc.replace(/[^a-zA-Z-0-9/\-_]/g, '')) {
|
|
99
|
+
return `mount folder ${loc} has illegal characters`;
|
|
100
|
+
}
|
|
101
|
+
const alreadyMounted = this.mounted[type][loc] || Object.keys(this.mounted[type]).find((m) => m.startsWith(`${loc}/`));
|
|
102
|
+
if (alreadyMounted) {
|
|
103
|
+
return `cannot mount ${type} ${what} at ${loc}, ${alreadyMounted} is already mounted}`;
|
|
104
|
+
}
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
async close() {
|
|
108
|
+
this.logger.info(`closing server ${this.port}`);
|
|
109
|
+
await this.listener?.close();
|
|
110
|
+
this.mounted = { get: {}, post: {} };
|
|
111
|
+
ServerExpress.listening = false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=server-express.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-express.js","sourceRoot":"","sources":["../src/server-express.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ServerExpress } from "./server-express.js";
|
|
2
|
+
import TestLogger from '@haibun/core/build/lib/TestLogger.js';
|
|
3
|
+
describe('mounts', () => {
|
|
4
|
+
it('mounts a route', () => {
|
|
5
|
+
const tl = new TestLogger();
|
|
6
|
+
const se = new ServerExpress(tl, '/', 8999);
|
|
7
|
+
se.listen = async () => 'started';
|
|
8
|
+
expect(() => se.addRoute('get', '/', () => undefined)).not.toThrow();
|
|
9
|
+
});
|
|
10
|
+
it.skip('throws instead of double mounting a route', () => {
|
|
11
|
+
const tl = new TestLogger();
|
|
12
|
+
const se = new ServerExpress(tl, '/', 8999);
|
|
13
|
+
se.listen = async () => 'started';
|
|
14
|
+
expect(async () => await se.addRoute('get', '/', () => undefined)).rejects.toThrow();
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=server-express.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-express.test.js","sourceRoot":"","sources":["../src/server-express.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,UAAU,MAAM,sCAAsC,CAAC;AAE9D,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACpB,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;QACtB,MAAM,EAAE,GAAG,IAAI,UAAU,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5C,EAAE,CAAC,MAAM,GAAG,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC;QAClC,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IACzE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,IAAI,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACtD,MAAM,EAAE,GAAG,IAAI,UAAU,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5C,EAAE,CAAC,MAAM,GAAG,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC;QAClC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACzF,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import WebHttp from '@haibun/web-http/build/web-http.js';
|
|
2
|
+
import { actionOK, getFromRuntime, getStepperOptionName } from '@haibun/core/build/lib/util/index.js';
|
|
3
|
+
import { DEFAULT_DEST } from '@haibun/core/build/lib/defs.js';
|
|
4
|
+
import { WEBSERVER } from './defs.js';
|
|
5
|
+
import Server from './web-server-stepper.js';
|
|
6
|
+
import { AStepper } from '@haibun/core/build/lib/defs.js';
|
|
7
|
+
import { testWithDefaults } from '@haibun/core/build/lib/test/lib.js';
|
|
8
|
+
import WebServerStepper from './web-server-stepper.js';
|
|
9
|
+
describe('route mount', () => {
|
|
10
|
+
it.skip('mounts a route', async () => {
|
|
11
|
+
const TestRoute = class TestRoute extends AStepper {
|
|
12
|
+
steps = {
|
|
13
|
+
addRoute: {
|
|
14
|
+
gwta: 'serve test route to {loc}',
|
|
15
|
+
action: async ({ loc }) => {
|
|
16
|
+
const route = (req, res) => res.status(200).send('ok');
|
|
17
|
+
const webserver = await getFromRuntime(this.getWorld().runtime, WEBSERVER);
|
|
18
|
+
await webserver.addRoute('get', loc, route);
|
|
19
|
+
return actionOK();
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
const wss = new WebServerStepper();
|
|
25
|
+
const feature = { path: '/features/test.feature', content: `serve test route to /test\nwebserver is listening\nfetch from http://localhost:8124/test is "ok"` };
|
|
26
|
+
const result = await testWithDefaults([feature], [Server, TestRoute, WebHttp], {
|
|
27
|
+
options: { DEST: DEFAULT_DEST, },
|
|
28
|
+
extraOptions: {
|
|
29
|
+
[getStepperOptionName(wss, 'PORT')]: '8124',
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
expect(result.ok).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=web-server-stepper-route.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-server-stepper-route.test.js","sourceRoot":"","sources":["../src/web-server-stepper-route.test.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,oCAAoC,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACtG,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAmC,SAAS,EAAE,MAAM,WAAW,CAAC;AAEvE,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAU,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AAEvD,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,SAAS,GAAG,MAAM,SAAU,SAAQ,QAAQ;YAChD,KAAK,GAAG;gBACN,QAAQ,EAAE;oBACR,IAAI,EAAE,2BAA2B;oBACjC,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,EAAU,EAAE,EAAE;wBAChC,MAAM,KAAK,GAAG,CAAC,GAAa,EAAE,GAAc,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC5E,MAAM,SAAS,GAAe,MAAM,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;wBACvF,MAAM,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;wBAC5C,OAAO,QAAQ,EAAE,CAAC;oBACpB,CAAC;iBACF;aACF,CAAC;SACH,CAAC;QACF,MAAM,GAAG,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,kGAAkG,EAAE,CAAC;QAChK,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE;YAC7E,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,GAAG;YAChC,YAAY,EAAE;gBACZ,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM;aAC5C;SACF,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { TWorld, TNamed, TOptions, AStepper, TVStep } from '@haibun/core/build/lib/defs.js';
|
|
2
|
+
import { IWebServer } from './defs.js';
|
|
3
|
+
import { ServerExpress } from './server-express.js';
|
|
4
|
+
declare const WebServerStepper: {
|
|
5
|
+
new (): {
|
|
6
|
+
webserver: ServerExpress | undefined;
|
|
7
|
+
options: {
|
|
8
|
+
PORT: {
|
|
9
|
+
desc: string;
|
|
10
|
+
parse: (port: string) => {
|
|
11
|
+
error: string;
|
|
12
|
+
result?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
result: number;
|
|
15
|
+
error?: undefined;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
setWorld(world: TWorld, steppers: AStepper[]): void;
|
|
20
|
+
close(): Promise<void>;
|
|
21
|
+
steps: {
|
|
22
|
+
thisURI: {
|
|
23
|
+
gwta: string;
|
|
24
|
+
action: ({ where }: TNamed, vstep: TVStep) => Promise<import("@haibun/core/build/lib/defs.js").TOKActionResult>;
|
|
25
|
+
};
|
|
26
|
+
isListening: {
|
|
27
|
+
gwta: string;
|
|
28
|
+
action: () => Promise<import("@haibun/core/build/lib/defs.js").TOKActionResult>;
|
|
29
|
+
};
|
|
30
|
+
showMounts: {
|
|
31
|
+
gwta: string;
|
|
32
|
+
action: () => Promise<import("@haibun/core/build/lib/defs.js").TOKActionResult>;
|
|
33
|
+
};
|
|
34
|
+
serveFilesAt: {
|
|
35
|
+
gwta: string;
|
|
36
|
+
action: ({ where, loc }: TNamed) => Promise<import("@haibun/core/build/lib/defs.js").TOKActionResult>;
|
|
37
|
+
};
|
|
38
|
+
serveFiles: {
|
|
39
|
+
gwta: string;
|
|
40
|
+
action: ({ loc }: TNamed) => Promise<import("@haibun/core/build/lib/defs.js").TOKActionResult | import("@haibun/core/build/lib/defs.js").TNotOKActionResult>;
|
|
41
|
+
};
|
|
42
|
+
indexFiles: {
|
|
43
|
+
gwta: string;
|
|
44
|
+
action: ({ loc }: TNamed) => Promise<import("@haibun/core/build/lib/defs.js").TOKActionResult | import("@haibun/core/build/lib/defs.js").TNotOKActionResult>;
|
|
45
|
+
};
|
|
46
|
+
indexFilesAt: {
|
|
47
|
+
gwta: string;
|
|
48
|
+
action: ({ where, loc }: TNamed) => Promise<import("@haibun/core/build/lib/defs.js").TOKActionResult | import("@haibun/core/build/lib/defs.js").TNotOKActionResult>;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
doServeIndex(where: any, loc: any): Promise<import("@haibun/core/build/lib/defs.js").TOKActionResult>;
|
|
52
|
+
doServeFiles(where: any, loc: any): Promise<import("@haibun/core/build/lib/defs.js").TOKActionResult>;
|
|
53
|
+
listen(): Promise<void>;
|
|
54
|
+
world?: TWorld;
|
|
55
|
+
endFeature?(): void;
|
|
56
|
+
onFailure?(result: import("@haibun/core/build/lib/defs.js").TStepResult): void;
|
|
57
|
+
getWorld(): TWorld;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
export default WebServerStepper;
|
|
61
|
+
export type ICheckListener = (options: TOptions, webserver: IWebServer) => void;
|
|
62
|
+
export interface IWebServerStepper {
|
|
63
|
+
webserver: IWebServer;
|
|
64
|
+
close: () => void;
|
|
65
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { OK, AStepper, } from '@haibun/core/build/lib/defs.js';
|
|
2
|
+
import { actionNotOK, getFromRuntime, getStepperOption, intOrError } from '@haibun/core/build/lib/util/index.js';
|
|
3
|
+
import { WEBSERVER, } from './defs.js';
|
|
4
|
+
import { ServerExpress, DEFAULT_PORT } from './server-express.js';
|
|
5
|
+
import { WEB_PAGE } from '@haibun/domain-webpage/build/domain-webpage.js';
|
|
6
|
+
const WebServerStepper = class WebServerStepper extends AStepper {
|
|
7
|
+
webserver;
|
|
8
|
+
options = {
|
|
9
|
+
PORT: {
|
|
10
|
+
desc: `change web server port from ${DEFAULT_PORT}`,
|
|
11
|
+
parse: (port) => intOrError(port)
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
setWorld(world, steppers) {
|
|
15
|
+
super.setWorld(world, steppers);
|
|
16
|
+
// this.world.runtime[CHECK_LISTENER] = WebServerStepper.checkListener;
|
|
17
|
+
const port = parseInt(getStepperOption(this, 'PORT', world.extraOptions)) || DEFAULT_PORT;
|
|
18
|
+
this.webserver = new ServerExpress(world.logger, [process.cwd(), 'files'].join('/'), port);
|
|
19
|
+
world.runtime[WEBSERVER] = this.webserver;
|
|
20
|
+
}
|
|
21
|
+
async close() {
|
|
22
|
+
await this.webserver?.close();
|
|
23
|
+
}
|
|
24
|
+
steps = {
|
|
25
|
+
thisURI: {
|
|
26
|
+
gwta: `a ${WEB_PAGE} at {where}`,
|
|
27
|
+
action: async ({ where }, vstep) => {
|
|
28
|
+
const page = vstep.source.name;
|
|
29
|
+
const webserver = getFromRuntime(this.getWorld().runtime, WEBSERVER);
|
|
30
|
+
await webserver.checkAddStaticFolder(page, where);
|
|
31
|
+
return OK;
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
/// generator
|
|
35
|
+
isListening: {
|
|
36
|
+
gwta: 'webserver is listening',
|
|
37
|
+
action: async () => {
|
|
38
|
+
await this.listen();
|
|
39
|
+
return OK;
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
showMounts: {
|
|
43
|
+
gwta: 'show mounts',
|
|
44
|
+
action: async () => {
|
|
45
|
+
const webserver = getFromRuntime(this.getWorld().runtime, WEBSERVER);
|
|
46
|
+
const mounts = webserver.mounted;
|
|
47
|
+
this.getWorld().logger.info(`mounts: ${JSON.stringify(mounts)}`);
|
|
48
|
+
return OK;
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
serveFilesAt: {
|
|
52
|
+
gwta: 'serve files at {where} from {loc}',
|
|
53
|
+
action: async ({ where, loc }) => {
|
|
54
|
+
await this.doServeFiles(where, loc).catch((e) => actionNotOK(e));
|
|
55
|
+
return OK;
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
serveFiles: {
|
|
59
|
+
gwta: 'serve files from {loc}',
|
|
60
|
+
action: async ({ loc }) => {
|
|
61
|
+
const r = await this.doServeFiles('/', loc).catch((e) => actionNotOK(e));
|
|
62
|
+
return r;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
indexFiles: {
|
|
66
|
+
gwta: 'index files from {loc}',
|
|
67
|
+
action: async ({ loc }) => {
|
|
68
|
+
const r = await this.doServeIndex('/', loc).catch((e) => actionNotOK(e));
|
|
69
|
+
return r;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
indexFilesAt: {
|
|
73
|
+
gwta: 'index files at {where} from {loc}',
|
|
74
|
+
action: async ({ where, loc }) => {
|
|
75
|
+
const r = await this.doServeIndex(where, loc).catch((e) => actionNotOK(e));
|
|
76
|
+
return r;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
async doServeIndex(where, loc) {
|
|
81
|
+
const ws = getFromRuntime(this.getWorld().runtime, WEBSERVER);
|
|
82
|
+
const res = ws.checkAddIndexFolder(loc, where);
|
|
83
|
+
if (res) {
|
|
84
|
+
throw Error(`failed to add index folder ${loc} at ${where}`);
|
|
85
|
+
}
|
|
86
|
+
await this.listen();
|
|
87
|
+
return OK;
|
|
88
|
+
}
|
|
89
|
+
async doServeFiles(where, loc) {
|
|
90
|
+
const ws = getFromRuntime(this.getWorld().runtime, WEBSERVER);
|
|
91
|
+
const res = ws.checkAddStaticFolder(loc, where);
|
|
92
|
+
if (res) {
|
|
93
|
+
throw Error(`failed to add static folder ${loc} at ${where}`);
|
|
94
|
+
}
|
|
95
|
+
await this.listen();
|
|
96
|
+
return OK;
|
|
97
|
+
}
|
|
98
|
+
async listen() {
|
|
99
|
+
await this.webserver.listen();
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
export default WebServerStepper;
|
|
103
|
+
//# sourceMappingURL=web-server-stepper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-server-stepper.js","sourceRoot":"","sources":["../src/web-server-stepper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { testWithDefaults } from '@haibun/core/build/lib/test/lib.js';
|
|
2
|
+
import WebHttp from '@haibun/web-http/build/web-http.js';
|
|
3
|
+
import server from './web-server-stepper.js';
|
|
4
|
+
describe('static mount', () => {
|
|
5
|
+
it('serves files', async () => {
|
|
6
|
+
const feature = { path: '/features/test.feature', content: `serve files from test\nfetch from http://localhost:8123/testfile matches "content"` };
|
|
7
|
+
const result = await testWithDefaults([feature], [server, WebHttp]);
|
|
8
|
+
expect(result.ok).toBe(true);
|
|
9
|
+
});
|
|
10
|
+
it('restricts characters used in static mount folder name', async () => {
|
|
11
|
+
const feature = { path: '/features/test.feature', content: `serve files from l*(*$\n` };
|
|
12
|
+
const result = await testWithDefaults([feature], [server]);
|
|
13
|
+
expect(result.ok).toBe(false);
|
|
14
|
+
});
|
|
15
|
+
it("doesn't re-mount same static mount", async () => {
|
|
16
|
+
const feature = { path: '/features/test.feature', content: `serve files from test\nserve files from test\n` };
|
|
17
|
+
const result = await testWithDefaults([feature], [server]);
|
|
18
|
+
expect(result.ok).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
it("doesn't permit different static mount", async () => {
|
|
21
|
+
const feature = { path: '/features/test.feature', content: `serve files from test\nserve files from fails\n` };
|
|
22
|
+
const result = await testWithDefaults([feature], [server]);
|
|
23
|
+
expect(result.ok).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe.skip('index mount', () => {
|
|
27
|
+
// FIXME: This fails when both tests are run
|
|
28
|
+
it('index files at', async () => {
|
|
29
|
+
const feature = { path: '/features/test.feature', content: `index files at /test from test\nfetch from http://localhost:8123/test/ contains href="/test/testfile"\nfetch from http://localhost:8123/test/testfile matches "content"` };
|
|
30
|
+
const result = await testWithDefaults([feature], [server, WebHttp]);
|
|
31
|
+
expect(result.ok).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
it('index files', async () => {
|
|
34
|
+
const feature = { path: '/features/test.feature', content: `index files from test\nfetch from http://localhost:8123/ contains href="/testfile"\nfetch from http://localhost:8123/testfile matches "content"` };
|
|
35
|
+
const result = await testWithDefaults([feature], [server, WebHttp]);
|
|
36
|
+
expect(result.ok).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=web-server-stepper.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-server-stepper.test.js","sourceRoot":"","sources":["../src/web-server-stepper.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,OAAO,MAAM,oCAAoC,CAAC;AAEzD,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAE7C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE;QAC5B,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,oFAAoF,EAAE,CAAC;QAClJ,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAA;QACvF,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,gDAAgD,EAAE,CAAA;QAC7G,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAA;QAC9G,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,EAAE;IAChC,4CAA4C;IAC5C,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,yKAAyK,EAAE,CAAC;QACvO,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,aAAa,EAAE,KAAK,IAAI,EAAE;QAC3B,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,iJAAiJ,EAAE,CAAC;QAC/M,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haibun/web-server-express",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.29.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "build/web-server-stepper.js",
|
|
7
7
|
"files": [
|
|
@@ -20,14 +20,14 @@
|
|
|
20
20
|
"author": "",
|
|
21
21
|
"license": "ISC",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@haibun/core": "1.
|
|
24
|
-
"@haibun/domain-webpage": "1.
|
|
23
|
+
"@haibun/core": "1.29.0",
|
|
24
|
+
"@haibun/domain-webpage": "1.29.0",
|
|
25
25
|
"cookie-parser": "^1.4.5",
|
|
26
26
|
"express": "^4.17.1",
|
|
27
27
|
"serve-index": "^1.9.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@haibun/web-http": "1.
|
|
30
|
+
"@haibun/web-http": "1.29.0",
|
|
31
31
|
"@types/cookie-parser": "^1.4.2",
|
|
32
32
|
"@types/express": "^4.17.15"
|
|
33
33
|
},
|