ng-talkback 21.0.17 → 21.0.19
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/browser/package.json +1 -1
- package/browser-prod/package.json +1 -1
- package/lib/build-info._auto-generated_.d.ts +1 -1
- package/lib/build-info._auto-generated_.js +1 -1
- package/lib/package.json +1 -1
- package/lib-prod/build-info._auto-generated_.js +26 -14
- package/lib-prod/env/env.angular-node-app.js +66 -130
- package/lib-prod/env/env.docs-webapp.js +66 -130
- package/lib-prod/env/env.electron-app.js +66 -130
- package/lib-prod/env/env.mobile-app.js +66 -130
- package/lib-prod/env/env.npm-lib-and-cli-tool.js +66 -130
- package/lib-prod/env/env.vscode-plugin.js +66 -130
- package/lib-prod/env/index.js +6 -6
- package/lib-prod/es6.backend.js +2 -5
- package/lib-prod/features/error-rate.backend.js +20 -24
- package/lib-prod/features/latency.backend.js +25 -27
- package/lib-prod/index._auto-generated_.js +5 -0
- package/lib-prod/index.js +12 -14
- package/lib-prod/logger.backend.js +17 -21
- package/lib-prod/migrations/index.js +2 -1
- package/lib-prod/migrations/migrations_index._auto-generated_.js +3 -0
- package/lib-prod/options.backend.js +75 -85
- package/lib-prod/package.json +1 -1
- package/lib-prod/request-handler.backend.js +131 -125
- package/lib-prod/server.backend.js +76 -79
- package/lib-prod/summary.backend.js +16 -21
- package/lib-prod/talkback-factory.backend.js +15 -18
- package/lib-prod/tape-matcher.backend.js +84 -88
- package/lib-prod/tape-renderer.backend.js +90 -89
- package/lib-prod/tape-store.backend.js +85 -87
- package/lib-prod/tape.backend.js +64 -70
- package/lib-prod/types.backend.js +1 -0
- package/lib-prod/utils/content-encoding.backend.js +31 -35
- package/lib-prod/utils/headers.backend.js +12 -14
- package/lib-prod/utils/media-type.backend.js +41 -46
- package/package.json +1 -1
- package/websql/package.json +1 -1
- package/websql-prod/package.json +1 -1
|
@@ -1,131 +1,137 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from
|
|
2
|
-
import axios from
|
|
3
|
-
import Tape from
|
|
4
|
-
import OptionsFactory, { RecordMode, FallbackMode } from
|
|
5
|
-
import ErrorRate from
|
|
6
|
-
import Latency from
|
|
7
|
-
class RequestHandler {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this.tapeStore = tapeStore;
|
|
14
|
-
this.options = options;
|
|
15
|
-
this.errorRate = new ErrorRate(this.options);
|
|
16
|
-
this.latency = new Latency(this.options);
|
|
17
|
-
}
|
|
18
|
-
async handle(req) {
|
|
19
|
-
const matchingContext = {
|
|
20
|
-
id: uuidv4()
|
|
21
|
-
};
|
|
22
|
-
const recordMode = typeof this.options.record === "string" ? this.options.record : this.options.record(req);
|
|
23
|
-
OptionsFactory.validateRecord(recordMode);
|
|
24
|
-
if (this.options.requestDecorator) {
|
|
25
|
-
req = this.options.requestDecorator(req, matchingContext);
|
|
26
|
-
if (!req) {
|
|
27
|
-
throw new Error("requestDecorator didn't return a req object");
|
|
28
|
-
}
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import Tape from './tape.backend';
|
|
4
|
+
import OptionsFactory, { RecordMode, FallbackMode } from './options.backend';
|
|
5
|
+
import ErrorRate from './features/error-rate.backend';
|
|
6
|
+
import Latency from './features/latency.backend';
|
|
7
|
+
export default class RequestHandler {
|
|
8
|
+
constructor(tapeStore, options) {
|
|
9
|
+
this.tapeStore = tapeStore;
|
|
10
|
+
this.options = options;
|
|
11
|
+
this.errorRate = new ErrorRate(this.options);
|
|
12
|
+
this.latency = new Latency(this.options);
|
|
29
13
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
responseTape = matchingTape;
|
|
42
|
-
} else {
|
|
43
|
-
responseTape = newTape;
|
|
44
|
-
}
|
|
45
|
-
if (recordMode === RecordMode.NEW || recordMode === RecordMode.OVERWRITE) {
|
|
46
|
-
resObj = await this.makeRealRequest(req);
|
|
47
|
-
responseTape.res = { ...resObj };
|
|
48
|
-
if (this.options.tapeDecorator) {
|
|
49
|
-
responseTape = this.options.tapeDecorator(responseTape, matchingContext);
|
|
50
|
-
if (!responseTape) {
|
|
51
|
-
throw new Error("tapeDecorator didn't return a tape object");
|
|
52
|
-
}
|
|
14
|
+
async handle(req) {
|
|
15
|
+
const matchingContext = {
|
|
16
|
+
id: uuidv4()
|
|
17
|
+
};
|
|
18
|
+
const recordMode = typeof (this.options.record) === "string" ? this.options.record : this.options.record(req);
|
|
19
|
+
OptionsFactory.validateRecord(recordMode);
|
|
20
|
+
if (this.options.requestDecorator) {
|
|
21
|
+
req = this.options.requestDecorator(req, matchingContext);
|
|
22
|
+
if (!req) {
|
|
23
|
+
throw new Error("requestDecorator didn't return a req object");
|
|
24
|
+
}
|
|
53
25
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
resObj
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
26
|
+
let newTape = new Tape(req, this.options);
|
|
27
|
+
let matchingTape = this.tapeStore.find(newTape);
|
|
28
|
+
let resObj, responseTape;
|
|
29
|
+
if (recordMode !== RecordMode.OVERWRITE && matchingTape) {
|
|
30
|
+
responseTape = matchingTape;
|
|
31
|
+
if (this.errorRate.shouldSimulate(req, matchingTape)) {
|
|
32
|
+
return this.errorRate.simulate(req);
|
|
33
|
+
}
|
|
34
|
+
await this.latency.simulate(req, matchingTape);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
if (matchingTape) {
|
|
38
|
+
responseTape = matchingTape;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
responseTape = newTape;
|
|
42
|
+
}
|
|
43
|
+
if (recordMode === RecordMode.NEW || recordMode === RecordMode.OVERWRITE) {
|
|
44
|
+
resObj = await this.makeRealRequest(req);
|
|
45
|
+
responseTape.res = { ...resObj };
|
|
46
|
+
if (this.options.tapeDecorator) {
|
|
47
|
+
responseTape = this.options.tapeDecorator(responseTape, matchingContext);
|
|
48
|
+
if (!responseTape) {
|
|
49
|
+
throw new Error("tapeDecorator didn't return a tape object");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
await this.tapeStore.save(responseTape);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
resObj = await this.onNoRecord(req);
|
|
56
|
+
responseTape.res = { ...resObj };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
resObj = responseTape.res;
|
|
60
|
+
if (this.options.responseDecorator) {
|
|
61
|
+
const clonedTape = await responseTape.clone();
|
|
62
|
+
const resTape = this.options.responseDecorator(clonedTape, req, matchingContext);
|
|
63
|
+
if (!resTape) {
|
|
64
|
+
throw new Error("responseDecorator didn't return a tape object");
|
|
65
|
+
}
|
|
66
|
+
if (resTape.res.headers["content-length"]) {
|
|
67
|
+
resTape.res.headers["content-length"] = resTape.res.body.length;
|
|
68
|
+
}
|
|
69
|
+
resObj = resTape.res;
|
|
70
|
+
}
|
|
71
|
+
return resObj;
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
73
|
+
async onNoRecord(req) {
|
|
74
|
+
const fallbackMode = typeof (this.options.fallbackMode) === "string" ? this.options.fallbackMode : this.options.fallbackMode(req);
|
|
75
|
+
OptionsFactory.validateFallbackMode(fallbackMode);
|
|
76
|
+
this.options.logger.log(`Tape for ${req.url} not found and recording is disabled (fallbackMode: ${fallbackMode})`);
|
|
77
|
+
this.options.logger.log({
|
|
78
|
+
url: req.url,
|
|
79
|
+
headers: req.headers
|
|
80
|
+
});
|
|
81
|
+
if (fallbackMode === FallbackMode.PROXY) {
|
|
82
|
+
if (this.errorRate.shouldSimulate(req, undefined)) {
|
|
83
|
+
return this.errorRate.simulate(req);
|
|
84
|
+
}
|
|
85
|
+
await this.latency.simulate(req, undefined);
|
|
86
|
+
return await this.makeRealRequest(req);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
status: 404,
|
|
90
|
+
headers: { "content-type": ["text/plain"] },
|
|
91
|
+
body: Buffer.from("talkback - tape not found")
|
|
92
|
+
};
|
|
88
93
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
94
|
+
async makeRealRequest(req) {
|
|
95
|
+
// let fetchBody: Buffer | null
|
|
96
|
+
let { method, url, body } = req;
|
|
97
|
+
// fetchBody = body
|
|
98
|
+
const headers = { ...req.headers };
|
|
99
|
+
delete headers.host;
|
|
100
|
+
const host = this.options.host;
|
|
101
|
+
// this.options.logger.log(`Making real request to ${host}${url}`)
|
|
102
|
+
// if (method === "GET" || method === "HEAD") {
|
|
103
|
+
// fetchBody = null
|
|
104
|
+
// }
|
|
105
|
+
let urlToGetData = `${host}${url}`;
|
|
106
|
+
// console.log(`host: "${urlToGetData}"` )
|
|
107
|
+
// console.log(`url: "${url}"` )
|
|
108
|
+
var fRes = {
|
|
109
|
+
status: 400,
|
|
110
|
+
headers: {},
|
|
111
|
+
body: new Buffer('')
|
|
112
|
+
};
|
|
113
|
+
try {
|
|
114
|
+
// console.log(body.toString())
|
|
115
|
+
const r = await axios({
|
|
116
|
+
url: urlToGetData,
|
|
117
|
+
method,
|
|
118
|
+
headers,
|
|
119
|
+
data: body,
|
|
120
|
+
responseType: 'arraybuffer',
|
|
121
|
+
});
|
|
122
|
+
fRes = {
|
|
123
|
+
status: r.status,
|
|
124
|
+
headers: r.headers,
|
|
125
|
+
body: r.data
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
fRes = {
|
|
130
|
+
status: err?.response?.status,
|
|
131
|
+
headers: err?.response?.headers,
|
|
132
|
+
body: err?.response?.data
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return fRes;
|
|
125
136
|
}
|
|
126
|
-
return fRes;
|
|
127
|
-
}
|
|
128
137
|
}
|
|
129
|
-
export {
|
|
130
|
-
RequestHandler as default
|
|
131
|
-
};
|
|
@@ -1,82 +1,79 @@
|
|
|
1
|
-
import RequestHandler from
|
|
2
|
-
import Summary from
|
|
3
|
-
import TapeStore from
|
|
4
|
-
import * as http from
|
|
5
|
-
import { https, fse } from
|
|
6
|
-
class TalkbackServer {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
constructor(options) {
|
|
14
|
-
this.options = options;
|
|
15
|
-
this.tapeStore = new TapeStore(this.options);
|
|
16
|
-
this.requestHandler = new RequestHandler(this.tapeStore, this.options);
|
|
17
|
-
this.closeSignalHandler = this.close.bind(this);
|
|
18
|
-
}
|
|
19
|
-
handleRequest(rawReq, res) {
|
|
20
|
-
let reqBody = [];
|
|
21
|
-
rawReq.on("data", (chunk) => {
|
|
22
|
-
reqBody.push(chunk);
|
|
23
|
-
}).on("end", async () => {
|
|
24
|
-
try {
|
|
25
|
-
const req = {
|
|
26
|
-
headers: rawReq.headers,
|
|
27
|
-
url: rawReq.url,
|
|
28
|
-
method: rawReq.method,
|
|
29
|
-
body: Buffer.concat(reqBody)
|
|
30
|
-
};
|
|
31
|
-
const fRes = await this.requestHandler.handle(req);
|
|
32
|
-
res.writeHead(fRes.status, fRes.headers);
|
|
33
|
-
res.end(fRes.body);
|
|
34
|
-
} catch (ex) {
|
|
35
|
-
console.error("Error handling request", ex);
|
|
36
|
-
res.statusCode = 500;
|
|
37
|
-
res.end();
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
async start(callback) {
|
|
42
|
-
await this.tapeStore.load();
|
|
43
|
-
const handleRequest = this.handleRequest.bind(this);
|
|
44
|
-
const serverFactory = this.options.https.enabled ? () => {
|
|
45
|
-
const httpsOpts = {
|
|
46
|
-
key: fse.readFileSync(this.options.https.keyPath),
|
|
47
|
-
cert: fse.readFileSync(this.options.https.certPath)
|
|
48
|
-
};
|
|
49
|
-
return https.createServer(httpsOpts, handleRequest);
|
|
50
|
-
} : () => http.createServer(handleRequest);
|
|
51
|
-
this.server = serverFactory();
|
|
52
|
-
console.log(`Starting talkback on ${this.options.port}`);
|
|
53
|
-
this.server.listen(this.options.port, callback);
|
|
54
|
-
process.on("exit", this.closeSignalHandler);
|
|
55
|
-
process.on("SIGINT", this.closeSignalHandler);
|
|
56
|
-
process.on("SIGTERM", this.closeSignalHandler);
|
|
57
|
-
return this.server;
|
|
58
|
-
}
|
|
59
|
-
hasTapeBeenUsed(tapeName) {
|
|
60
|
-
return this.tapeStore.hasTapeBeenUsed(tapeName);
|
|
61
|
-
}
|
|
62
|
-
resetTapeUsage() {
|
|
63
|
-
this.tapeStore.resetTapeUsage();
|
|
64
|
-
}
|
|
65
|
-
close(callback) {
|
|
66
|
-
if (this.closed) {
|
|
67
|
-
return;
|
|
1
|
+
import RequestHandler from './request-handler.backend';
|
|
2
|
+
import Summary from './summary.backend';
|
|
3
|
+
import TapeStore from './tape-store.backend';
|
|
4
|
+
import * as http from 'http';
|
|
5
|
+
import { https, fse } from 'tnp-core/lib-prod';
|
|
6
|
+
export default class TalkbackServer {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.closed = false;
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.tapeStore = new TapeStore(this.options);
|
|
11
|
+
this.requestHandler = new RequestHandler(this.tapeStore, this.options);
|
|
12
|
+
this.closeSignalHandler = this.close.bind(this);
|
|
68
13
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
14
|
+
handleRequest(rawReq, res) {
|
|
15
|
+
// console.log(`rawReq: ${rawReq.url}`)
|
|
16
|
+
let reqBody = [];
|
|
17
|
+
rawReq.on("data", (chunk) => {
|
|
18
|
+
reqBody.push(chunk);
|
|
19
|
+
}).on("end", async () => {
|
|
20
|
+
try {
|
|
21
|
+
const req = {
|
|
22
|
+
headers: rawReq.headers,
|
|
23
|
+
url: rawReq.url,
|
|
24
|
+
method: rawReq.method,
|
|
25
|
+
body: Buffer.concat(reqBody)
|
|
26
|
+
};
|
|
27
|
+
const fRes = await this.requestHandler.handle(req);
|
|
28
|
+
res.writeHead(fRes.status, fRes.headers);
|
|
29
|
+
res.end(fRes.body);
|
|
30
|
+
}
|
|
31
|
+
catch (ex) {
|
|
32
|
+
console.error("Error handling request", ex);
|
|
33
|
+
res.statusCode = 500;
|
|
34
|
+
res.end();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async start(callback) {
|
|
39
|
+
await this.tapeStore.load();
|
|
40
|
+
const handleRequest = this.handleRequest.bind(this);
|
|
41
|
+
const serverFactory = this.options.https.enabled ? () => {
|
|
42
|
+
const httpsOpts = {
|
|
43
|
+
key: fse.readFileSync(this.options.https.keyPath),
|
|
44
|
+
cert: fse.readFileSync(this.options.https.certPath)
|
|
45
|
+
};
|
|
46
|
+
return https.createServer(httpsOpts, handleRequest);
|
|
47
|
+
} : () => http.createServer(handleRequest);
|
|
48
|
+
this.server = serverFactory();
|
|
49
|
+
console.log(`Starting talkback on ${this.options.port}`);
|
|
50
|
+
this.server.listen(this.options.port, callback);
|
|
51
|
+
process.on("exit", this.closeSignalHandler);
|
|
52
|
+
process.on("SIGINT", this.closeSignalHandler);
|
|
53
|
+
process.on("SIGTERM", this.closeSignalHandler);
|
|
54
|
+
return this.server;
|
|
55
|
+
}
|
|
56
|
+
hasTapeBeenUsed(tapeName) {
|
|
57
|
+
return this.tapeStore.hasTapeBeenUsed(tapeName);
|
|
58
|
+
}
|
|
59
|
+
resetTapeUsage() {
|
|
60
|
+
this.tapeStore.resetTapeUsage();
|
|
61
|
+
}
|
|
62
|
+
close(callback) {
|
|
63
|
+
if (this.closed) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.closed = true;
|
|
67
|
+
this.server.close(callback);
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
process.removeListener("exit", this.closeSignalHandler);
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
process.removeListener("SIGINT", this.closeSignalHandler);
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
process.removeListener("SIGTERM", this.closeSignalHandler);
|
|
74
|
+
if (this.options.summary) {
|
|
75
|
+
const summary = new Summary(this.tapeStore.tapes, this.options);
|
|
76
|
+
summary.print();
|
|
77
|
+
}
|
|
77
78
|
}
|
|
78
|
-
}
|
|
79
79
|
}
|
|
80
|
-
export {
|
|
81
|
-
TalkbackServer as default
|
|
82
|
-
};
|
|
@@ -1,24 +1,19 @@
|
|
|
1
|
-
class Summary {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
this.tapes = tapes;
|
|
6
|
-
this.opts = opts;
|
|
7
|
-
}
|
|
8
|
-
print() {
|
|
9
|
-
console.log(`===== SUMMARY (${this.opts.name}) =====`);
|
|
10
|
-
const newTapes = this.tapes.filter((t) => t.new);
|
|
11
|
-
if (newTapes.length > 0) {
|
|
12
|
-
console.log("New tapes:");
|
|
13
|
-
newTapes.forEach((t) => console.log(`- ${t.path}`));
|
|
1
|
+
export default class Summary {
|
|
2
|
+
constructor(tapes, opts) {
|
|
3
|
+
this.tapes = tapes;
|
|
4
|
+
this.opts = opts;
|
|
14
5
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
6
|
+
print() {
|
|
7
|
+
console.log(`===== SUMMARY (${this.opts.name}) =====`);
|
|
8
|
+
const newTapes = this.tapes.filter(t => t.new);
|
|
9
|
+
if (newTapes.length > 0) {
|
|
10
|
+
console.log("New tapes:");
|
|
11
|
+
newTapes.forEach(t => console.log(`- ${t.path}`));
|
|
12
|
+
}
|
|
13
|
+
const unusedTapes = this.tapes.filter(t => !t.used);
|
|
14
|
+
if (unusedTapes.length > 0) {
|
|
15
|
+
console.log("Unused tapes:");
|
|
16
|
+
unusedTapes.forEach(t => console.log(`- ${t.path}`));
|
|
17
|
+
}
|
|
19
18
|
}
|
|
20
|
-
}
|
|
21
19
|
}
|
|
22
|
-
export {
|
|
23
|
-
Summary as default
|
|
24
|
-
};
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import Options from
|
|
2
|
-
import TapeStore from
|
|
3
|
-
import TalkbackServer from
|
|
4
|
-
import RequestHandler from
|
|
5
|
-
class TalkbackFactory {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import Options from './options.backend';
|
|
2
|
+
import TapeStore from './tape-store.backend';
|
|
3
|
+
import TalkbackServer from './server.backend';
|
|
4
|
+
import RequestHandler from './request-handler.backend';
|
|
5
|
+
export default class TalkbackFactory {
|
|
6
|
+
static server(options) {
|
|
7
|
+
const fullOptions = Options.prepare(options);
|
|
8
|
+
return new TalkbackServer(fullOptions);
|
|
9
|
+
}
|
|
10
|
+
static async requestHandler(options) {
|
|
11
|
+
const fullOptions = Options.prepare(options);
|
|
12
|
+
const tapeStore = new TapeStore(fullOptions);
|
|
13
|
+
await tapeStore.load();
|
|
14
|
+
return new RequestHandler(tapeStore, fullOptions);
|
|
15
|
+
}
|
|
16
16
|
}
|
|
17
|
-
export {
|
|
18
|
-
TalkbackFactory as default
|
|
19
|
-
};
|