ng-talkback 21.0.31 → 21.0.34

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.
Files changed (137) hide show
  1. package/VERIFIED-BUILD-DATA.jsonc +3 -3
  2. package/bin/ng-talkback +5 -0
  3. package/bin/ng-talkback-debug +5 -0
  4. package/bin/ng-talkback-debug-brk +4 -0
  5. package/browser/fesm2022/ng-talkback-browser.mjs +9 -2
  6. package/browser/fesm2022/ng-talkback-browser.mjs.map +1 -1
  7. package/browser/package.json +1 -1
  8. package/browser/types/ng-talkback-browser.d.ts +2 -2
  9. package/browser-prod/fesm2022/ng-talkback-browser-prod.mjs +9 -2
  10. package/browser-prod/fesm2022/ng-talkback-browser-prod.mjs.map +1 -1
  11. package/browser-prod/package.json +1 -1
  12. package/browser-prod/types/ng-talkback-browser-prod.d.ts +2 -2
  13. package/html/assets/generated/pwa/html-pwa.html +60 -0
  14. package/lib/build-info._auto-generated_.d.ts +1 -1
  15. package/lib/build-info._auto-generated_.js +1 -1
  16. package/lib/index.d.ts +1 -1
  17. package/lib/index.js +7 -3
  18. package/lib/index.js.map +1 -1
  19. package/lib/package.json +1 -1
  20. package/lib-esm/app.d.ts +0 -0
  21. package/lib-esm/app.electron.d.ts +2 -0
  22. package/lib-esm/app.electron.js +83 -0
  23. package/lib-esm/app.electron.js.map +1 -0
  24. package/lib-esm/app.hosts.d.ts +3 -0
  25. package/lib-esm/app.hosts.js +48 -0
  26. package/lib-esm/app.hosts.js.map +1 -0
  27. package/lib-esm/app.js +49 -0
  28. package/lib-esm/app.js.map +1 -0
  29. package/lib-esm/app.vscode.d.ts +9 -0
  30. package/lib-esm/app.vscode.js +31 -0
  31. package/lib-esm/app.vscode.js.map +1 -0
  32. package/lib-esm/index.d.ts +1 -0
  33. package/lib-esm/index.js +2 -0
  34. package/lib-esm/index.js.map +1 -0
  35. package/lib-esm/lib/build-info._auto-generated_.d.ts +24 -0
  36. package/lib-esm/lib/build-info._auto-generated_.js +27 -0
  37. package/lib-esm/lib/build-info._auto-generated_.js.map +1 -0
  38. package/lib-esm/lib/env/env.angular-node-app.d.ts +66 -0
  39. package/lib-esm/lib/env/env.angular-node-app.js +135 -0
  40. package/lib-esm/lib/env/env.angular-node-app.js.map +1 -0
  41. package/lib-esm/lib/env/env.docs-webapp.d.ts +66 -0
  42. package/lib-esm/lib/env/env.docs-webapp.js +135 -0
  43. package/lib-esm/lib/env/env.docs-webapp.js.map +1 -0
  44. package/lib-esm/lib/env/env.electron-app.d.ts +66 -0
  45. package/lib-esm/lib/env/env.electron-app.js +135 -0
  46. package/lib-esm/lib/env/env.electron-app.js.map +1 -0
  47. package/lib-esm/lib/env/env.mobile-app.d.ts +66 -0
  48. package/lib-esm/lib/env/env.mobile-app.js +135 -0
  49. package/lib-esm/lib/env/env.mobile-app.js.map +1 -0
  50. package/lib-esm/lib/env/env.npm-lib-and-cli-tool.d.ts +66 -0
  51. package/lib-esm/lib/env/env.npm-lib-and-cli-tool.js +135 -0
  52. package/lib-esm/lib/env/env.npm-lib-and-cli-tool.js.map +1 -0
  53. package/lib-esm/lib/env/env.vscode-plugin.d.ts +66 -0
  54. package/lib-esm/lib/env/env.vscode-plugin.js +135 -0
  55. package/lib-esm/lib/env/env.vscode-plugin.js.map +1 -0
  56. package/lib-esm/lib/env/index.d.ts +6 -0
  57. package/lib-esm/lib/env/index.js +7 -0
  58. package/lib-esm/lib/env/index.js.map +1 -0
  59. package/lib-esm/lib/es6.backend.d.ts +2 -0
  60. package/lib-esm/lib/es6.backend.js +3 -0
  61. package/lib-esm/lib/es6.backend.js.map +1 -0
  62. package/lib-esm/lib/features/error-rate.backend.d.ts +9 -0
  63. package/lib-esm/lib/features/error-rate.backend.js +23 -0
  64. package/lib-esm/lib/features/error-rate.backend.js.map +1 -0
  65. package/lib-esm/lib/features/latency.backend.d.ts +8 -0
  66. package/lib-esm/lib/features/latency.backend.js +30 -0
  67. package/lib-esm/lib/features/latency.backend.js.map +1 -0
  68. package/lib-esm/lib/index._auto-generated_.d.ts +0 -0
  69. package/lib-esm/lib/index._auto-generated_.js +6 -0
  70. package/lib-esm/lib/index._auto-generated_.js.map +1 -0
  71. package/lib-esm/lib/index.d.ts +41 -0
  72. package/lib-esm/lib/index.js +24 -0
  73. package/lib-esm/lib/index.js.map +1 -0
  74. package/lib-esm/lib/logger.backend.d.ts +7 -0
  75. package/lib-esm/lib/logger.backend.js +23 -0
  76. package/lib-esm/lib/logger.backend.js.map +1 -0
  77. package/lib-esm/lib/migrations/index.d.ts +1 -0
  78. package/lib-esm/lib/migrations/index.js +3 -0
  79. package/lib-esm/lib/migrations/index.js.map +1 -0
  80. package/lib-esm/lib/migrations/migrations_index._auto-generated_.d.ts +0 -0
  81. package/lib-esm/lib/migrations/migrations_index._auto-generated_.js +4 -0
  82. package/lib-esm/lib/migrations/migrations_index._auto-generated_.js.map +1 -0
  83. package/lib-esm/lib/options.backend.d.ts +52 -0
  84. package/lib-esm/lib/options.backend.js +87 -0
  85. package/lib-esm/lib/options.backend.js.map +1 -0
  86. package/lib-esm/lib/request-handler.backend.d.ts +13 -0
  87. package/lib-esm/lib/request-handler.backend.js +142 -0
  88. package/lib-esm/lib/request-handler.backend.js.map +1 -0
  89. package/lib-esm/lib/server.backend.d.ts +17 -0
  90. package/lib-esm/lib/server.backend.js +85 -0
  91. package/lib-esm/lib/server.backend.js.map +1 -0
  92. package/lib-esm/lib/summary.backend.d.ts +8 -0
  93. package/lib-esm/lib/summary.backend.js +22 -0
  94. package/lib-esm/lib/summary.backend.js.map +1 -0
  95. package/lib-esm/lib/talkback-factory.backend.d.ts +7 -0
  96. package/lib-esm/lib/talkback-factory.backend.js +17 -0
  97. package/lib-esm/lib/talkback-factory.backend.js.map +1 -0
  98. package/lib-esm/lib/tape-matcher.backend.d.ts +12 -0
  99. package/lib-esm/lib/tape-matcher.backend.js +94 -0
  100. package/lib-esm/lib/tape-matcher.backend.js.map +1 -0
  101. package/lib-esm/lib/tape-renderer.backend.d.ts +24 -0
  102. package/lib-esm/lib/tape-renderer.backend.js +96 -0
  103. package/lib-esm/lib/tape-renderer.backend.js.map +1 -0
  104. package/lib-esm/lib/tape-store.backend.d.ts +16 -0
  105. package/lib-esm/lib/tape-store.backend.js +96 -0
  106. package/lib-esm/lib/tape-store.backend.js.map +1 -0
  107. package/lib-esm/lib/tape.backend.d.ts +19 -0
  108. package/lib-esm/lib/tape.backend.js +76 -0
  109. package/lib-esm/lib/tape.backend.js.map +1 -0
  110. package/lib-esm/lib/types.backend.d.ts +43 -0
  111. package/lib-esm/lib/types.backend.js +2 -0
  112. package/lib-esm/lib/types.backend.js.map +1 -0
  113. package/lib-esm/lib/utils/content-encoding.backend.d.ts +10 -0
  114. package/lib-esm/lib/utils/content-encoding.backend.js +38 -0
  115. package/lib-esm/lib/utils/content-encoding.backend.js.map +1 -0
  116. package/lib-esm/lib/utils/headers.backend.d.ts +4 -0
  117. package/lib-esm/lib/utils/headers.backend.js +15 -0
  118. package/lib-esm/lib/utils/headers.backend.js.map +1 -0
  119. package/lib-esm/lib/utils/media-type.backend.d.ts +10 -0
  120. package/lib-esm/lib/utils/media-type.backend.js +51 -0
  121. package/lib-esm/lib/utils/media-type.backend.js.map +1 -0
  122. package/lib-prod/build-info._auto-generated_.d.ts +1 -1
  123. package/lib-prod/build-info._auto-generated_.js +1 -1
  124. package/lib-prod/index.d.ts +1 -1
  125. package/lib-prod/index.js +8 -4
  126. package/lib-prod/index.js.map +1 -1
  127. package/lib-prod/package.json +1 -1
  128. package/package.json +6 -2
  129. package/src.js +4 -20
  130. package/websql/fesm2022/ng-talkback-websql.mjs +9 -2
  131. package/websql/fesm2022/ng-talkback-websql.mjs.map +1 -1
  132. package/websql/package.json +1 -1
  133. package/websql/types/ng-talkback-websql.d.ts +2 -2
  134. package/websql-prod/fesm2022/ng-talkback-websql-prod.mjs +9 -2
  135. package/websql-prod/fesm2022/ng-talkback-websql-prod.mjs.map +1 -1
  136. package/websql-prod/package.json +1 -1
  137. package/websql-prod/types/ng-talkback-websql-prod.d.ts +2 -2
@@ -0,0 +1,85 @@
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';
6
+ export default class TalkbackServer {
7
+ options;
8
+ tapeStore;
9
+ requestHandler;
10
+ closeSignalHandler;
11
+ server;
12
+ closed = false;
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
+ // console.log(`rawReq: ${rawReq.url}`)
21
+ let reqBody = [];
22
+ rawReq.on("data", (chunk) => {
23
+ reqBody.push(chunk);
24
+ }).on("end", async () => {
25
+ try {
26
+ const req = {
27
+ headers: rawReq.headers,
28
+ url: rawReq.url,
29
+ method: rawReq.method,
30
+ body: Buffer.concat(reqBody)
31
+ };
32
+ const fRes = await this.requestHandler.handle(req);
33
+ res.writeHead(fRes.status, fRes.headers);
34
+ res.end(fRes.body);
35
+ }
36
+ catch (ex) {
37
+ console.error("Error handling request", ex);
38
+ res.statusCode = 500;
39
+ res.end();
40
+ }
41
+ });
42
+ }
43
+ async start(callback) {
44
+ await this.tapeStore.load();
45
+ const handleRequest = this.handleRequest.bind(this);
46
+ const serverFactory = this.options.https.enabled ? () => {
47
+ const httpsOpts = {
48
+ key: fse.readFileSync(this.options.https.keyPath),
49
+ cert: fse.readFileSync(this.options.https.certPath)
50
+ };
51
+ return https.createServer(httpsOpts, handleRequest);
52
+ } : () => http.createServer(handleRequest);
53
+ this.server = serverFactory();
54
+ console.log(`Starting talkback on ${this.options.port}`);
55
+ this.server.listen(this.options.port, callback);
56
+ process.on("exit", this.closeSignalHandler);
57
+ process.on("SIGINT", this.closeSignalHandler);
58
+ process.on("SIGTERM", this.closeSignalHandler);
59
+ return this.server;
60
+ }
61
+ hasTapeBeenUsed(tapeName) {
62
+ return this.tapeStore.hasTapeBeenUsed(tapeName);
63
+ }
64
+ resetTapeUsage() {
65
+ this.tapeStore.resetTapeUsage();
66
+ }
67
+ close(callback) {
68
+ if (this.closed) {
69
+ return;
70
+ }
71
+ this.closed = true;
72
+ this.server.close(callback);
73
+ // @ts-ignore
74
+ process.removeListener("exit", this.closeSignalHandler);
75
+ // @ts-ignore
76
+ process.removeListener("SIGINT", this.closeSignalHandler);
77
+ // @ts-ignore
78
+ process.removeListener("SIGTERM", this.closeSignalHandler);
79
+ if (this.options.summary) {
80
+ const summary = new Summary(this.tapeStore.tapes, this.options);
81
+ summary.print();
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=server.backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.backend.js","sourceRoot":"","sources":[""],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import Tape from './tape.backend';
2
+ import { Options } from './options.backend';
3
+ export default class Summary {
4
+ private tapes;
5
+ private opts;
6
+ constructor(tapes: Tape[], opts: Options);
7
+ print(): void;
8
+ }
@@ -0,0 +1,22 @@
1
+ export default class Summary {
2
+ tapes;
3
+ opts;
4
+ constructor(tapes, opts) {
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}`));
14
+ }
15
+ const unusedTapes = this.tapes.filter(t => !t.used);
16
+ if (unusedTapes.length > 0) {
17
+ console.log("Unused tapes:");
18
+ unusedTapes.forEach(t => console.log(`- ${t.path}`));
19
+ }
20
+ }
21
+ }
22
+ //# sourceMappingURL=summary.backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.backend.js","sourceRoot":"","sources":[""],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,OAAO,OAAO;IAClB,KAAK,CAAQ;IACb,IAAI,CAAS;IAErB,YAAY,KAAa,EAAE,IAAa;QACtC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,KAAK;QACH,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,CAAA;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC9C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YACzB,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACnD,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACnD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;YAC5B,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACtD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import Options from './options.backend';
2
+ import TalkbackServer from './server.backend';
3
+ import RequestHandler from './request-handler.backend';
4
+ export default class TalkbackFactory {
5
+ static server(options: Partial<Options>): TalkbackServer;
6
+ static requestHandler(options: Partial<Options>): Promise<RequestHandler>;
7
+ }
@@ -0,0 +1,17 @@
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
+ }
17
+ //# sourceMappingURL=talkback-factory.backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"talkback-factory.backend.js","sourceRoot":"","sources":[""],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,mBAAmB,CAAC;AACxC,OAAO,SAAS,MAAM,sBAAsB,CAAC;AAC7C,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,cAAc,MAAM,2BAA2B,CAAC;AAEvD,MAAM,CAAC,OAAO,OAAO,eAAe;IAClC,MAAM,CAAC,MAAM,CAAC,OAAyB;QACrC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC5C,OAAO,IAAI,cAAc,CAAC,WAAW,CAAC,CAAA;IACxC,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,OAAyB;QACnD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC5C,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,WAAW,CAAC,CAAA;QAC5C,MAAM,SAAS,CAAC,IAAI,EAAE,CAAA;QACtB,OAAO,IAAI,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IACnD,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import { Options } from './options.backend';
2
+ import Tape from './tape.backend';
3
+ export default class TapeMatcher {
4
+ private readonly tape;
5
+ private readonly options;
6
+ constructor(tape: Tape, options: Options);
7
+ sameAs(otherTape: Tape): boolean;
8
+ private isSameBody;
9
+ private isSameHeaders;
10
+ private isSameMethod;
11
+ private isSameUrl;
12
+ }
@@ -0,0 +1,94 @@
1
+ import ContentEncoding from './utils/content-encoding.backend';
2
+ import MediaType from './utils/media-type.backend';
3
+ import { _ } from 'tnp-core/lib';
4
+ export default class TapeMatcher {
5
+ tape;
6
+ options;
7
+ constructor(tape, options) {
8
+ this.tape = tape;
9
+ this.options = options;
10
+ }
11
+ sameAs(otherTape) {
12
+ const otherReq = otherTape.req;
13
+ const req = this.tape.req;
14
+ if (!this.isSameUrl(req, otherReq)) {
15
+ return false;
16
+ }
17
+ if (!this.isSameMethod(req, otherReq)) {
18
+ return false;
19
+ }
20
+ if (!this.isSameHeaders(req, otherReq)) {
21
+ return false;
22
+ }
23
+ return this.options.ignoreBody || this.isSameBody(req, otherReq);
24
+ }
25
+ isSameBody(req, otherReq) {
26
+ const mediaType = new MediaType(req);
27
+ const contentEncoding = new ContentEncoding(req);
28
+ let sameBody;
29
+ if (contentEncoding.isUncompressed() && mediaType.isJSON() && req.body.length > 0 && otherReq.body.length > 0) {
30
+ const parsedReqBody = JSON.parse(req.body.toString());
31
+ const parsedOtherReqBody = JSON.parse(otherReq.body.toString());
32
+ sameBody = _.isEqual(parsedReqBody, parsedOtherReqBody);
33
+ }
34
+ else {
35
+ sameBody = req.body.equals(otherReq.body);
36
+ }
37
+ if (!sameBody) {
38
+ if (!this.options.bodyMatcher) {
39
+ this.options.logger.debug(`Not same BODY ${req.body} vs ${otherReq.body}`);
40
+ return false;
41
+ }
42
+ const bodyMatches = this.options.bodyMatcher(this.tape, otherReq);
43
+ if (!bodyMatches) {
44
+ this.options.logger.debug(`Not same bodyMatcher ${req.body} vs ${otherReq.body}`);
45
+ return false;
46
+ }
47
+ }
48
+ return true;
49
+ }
50
+ isSameHeaders(req, otherReq) {
51
+ const currentHeadersLength = Object.keys(req.headers).length;
52
+ const otherHeadersLength = Object.keys(otherReq.headers).length;
53
+ const sameNumberOfHeaders = currentHeadersLength === otherHeadersLength;
54
+ if (!sameNumberOfHeaders) {
55
+ this.options.logger.debug(`Not same #HEADERS ${JSON.stringify(req.headers)} vs ${JSON.stringify(otherReq.headers)}`);
56
+ return false;
57
+ }
58
+ let headersSame = true;
59
+ Object.keys(req.headers).forEach(k => {
60
+ const entryHeader = req.headers[k];
61
+ const header = otherReq.headers[k];
62
+ headersSame = headersSame && entryHeader === header;
63
+ });
64
+ if (!headersSame) {
65
+ this.options.logger.debug(`Not same HEADERS values ${JSON.stringify(req.headers)} vs ${JSON.stringify(otherReq.headers)}`);
66
+ return false;
67
+ }
68
+ return true;
69
+ }
70
+ isSameMethod(req, otherReq) {
71
+ const sameMethod = req.method === otherReq.method;
72
+ if (!sameMethod) {
73
+ this.options.logger.debug(`Not same METHOD ${req.method} vs ${otherReq.method}`);
74
+ return false;
75
+ }
76
+ return true;
77
+ }
78
+ isSameUrl(req, otherReq) {
79
+ const sameURL = req.url === otherReq.url;
80
+ if (!sameURL) {
81
+ if (!this.options.urlMatcher) {
82
+ this.options.logger.debug(`Not same URL ${req.url} vs ${otherReq.url}`);
83
+ return false;
84
+ }
85
+ const urlMatches = this.options.urlMatcher(this.tape, otherReq);
86
+ if (!urlMatches) {
87
+ this.options.logger.debug(`Not same urlMatcher ${req.url} vs ${otherReq.url}`);
88
+ return false;
89
+ }
90
+ }
91
+ return true;
92
+ }
93
+ }
94
+ //# sourceMappingURL=tape-matcher.backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tape-matcher.backend.js","sourceRoot":"","sources":[""],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import Tape from './tape.backend';
2
+ import { Options } from './options.backend';
3
+ import { ReqRes } from './types.backend';
4
+ export default class TapeRenderer {
5
+ private tape;
6
+ constructor(tape: Tape);
7
+ static fromStore(raw: any, options: Options): Promise<Tape>;
8
+ static prepareBody(tape: Tape, reqResObj: ReqRes, rawBody: string, metaPrefix: "res" | "req"): Promise<any>;
9
+ render(): Promise<{
10
+ meta: import("./types.backend").Metadata;
11
+ req: {
12
+ body: any;
13
+ url: string;
14
+ method: string;
15
+ headers: any;
16
+ };
17
+ res: {
18
+ body: any;
19
+ status: number;
20
+ headers: any;
21
+ };
22
+ }>;
23
+ bodyFor(reqResObj: ReqRes, metaPrefix: "req" | "res"): Promise<any>;
24
+ }
@@ -0,0 +1,96 @@
1
+ import Headers from './utils/headers.backend';
2
+ import MediaType from './utils/media-type.backend';
3
+ import Tape from './tape.backend';
4
+ import ContentEncoding from './utils/content-encoding.backend';
5
+ import * as bufferShim from 'buffer-shims';
6
+ // const bufferShim = require('buffer-shims')/
7
+ export default class TapeRenderer {
8
+ tape;
9
+ constructor(tape) {
10
+ this.tape = tape;
11
+ }
12
+ static async fromStore(raw, options) {
13
+ const req = { ...raw.req };
14
+ req.body = await this.prepareBody(raw, req, req.body, "req");
15
+ const tape = new Tape(req, options);
16
+ tape.meta = { ...raw.meta };
17
+ const baseRes = { ...raw.res };
18
+ const resBody = await this.prepareBody(tape, baseRes, baseRes.body, "res");
19
+ tape.res = {
20
+ ...baseRes,
21
+ body: resBody
22
+ };
23
+ return tape;
24
+ }
25
+ static async prepareBody(tape, reqResObj, rawBody, metaPrefix) {
26
+ const contentEncoding = new ContentEncoding(reqResObj);
27
+ const isTapeUncompressed = tape.meta[metaPrefix + "Uncompressed"];
28
+ const isTapeHumanReadable = tape.meta[metaPrefix + "HumanReadable"];
29
+ const isTapeInPlainText = isTapeUncompressed || contentEncoding.isUncompressed();
30
+ if (isTapeHumanReadable && isTapeInPlainText) {
31
+ const mediaType = new MediaType(reqResObj);
32
+ let bufferContent = rawBody;
33
+ const isResAnObject = typeof (bufferContent) === "object";
34
+ if (isResAnObject && mediaType.isJSON()) {
35
+ bufferContent = JSON.stringify(bufferContent, null, 2);
36
+ }
37
+ if (Headers.read(reqResObj.headers, "content-length")) {
38
+ Headers.write(reqResObj.headers, "content-length", Buffer.byteLength(bufferContent).toString(), metaPrefix);
39
+ }
40
+ if (isTapeUncompressed) {
41
+ return await contentEncoding.compressedBody(bufferContent);
42
+ }
43
+ return bufferShim.from(bufferContent);
44
+ }
45
+ else {
46
+ return bufferShim.from(rawBody, "base64");
47
+ }
48
+ }
49
+ async render() {
50
+ const reqBody = await this.bodyFor(this.tape.req, "req");
51
+ const resBody = await this.bodyFor(this.tape.res, "res");
52
+ return {
53
+ meta: this.tape.meta,
54
+ req: {
55
+ ...this.tape.req,
56
+ body: reqBody
57
+ },
58
+ res: {
59
+ ...this.tape.res,
60
+ body: resBody
61
+ }
62
+ };
63
+ }
64
+ async bodyFor(reqResObj, metaPrefix) {
65
+ const mediaType = new MediaType(reqResObj);
66
+ const contentEncoding = new ContentEncoding(reqResObj);
67
+ const bodyLength = reqResObj.body.length;
68
+ const isUncompressed = contentEncoding.isUncompressed();
69
+ const contentEncodingSupported = isUncompressed || contentEncoding.supportedAlgorithm();
70
+ if (mediaType.isHumanReadable() && contentEncodingSupported && bodyLength > 0) {
71
+ this.tape.meta[metaPrefix + "HumanReadable"] = true;
72
+ let body = reqResObj.body;
73
+ if (!isUncompressed) {
74
+ this.tape.meta[metaPrefix + "Uncompressed"] = true;
75
+ body = await contentEncoding.uncompressedBody(body);
76
+ }
77
+ const rawBody = body.toString("utf8");
78
+ if (mediaType.isJSON()) {
79
+ try { // TODO handle this better in future not based on mediaType.isJSON
80
+ const parsed = JSON.parse(rawBody);
81
+ return parsed;
82
+ }
83
+ catch (error) {
84
+ return rawBody;
85
+ }
86
+ }
87
+ else {
88
+ return rawBody;
89
+ }
90
+ }
91
+ else {
92
+ return reqResObj.body.toString("base64");
93
+ }
94
+ }
95
+ }
96
+ //# sourceMappingURL=tape-renderer.backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tape-renderer.backend.js","sourceRoot":"","sources":[""],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { Options } from './options.backend';
2
+ import Tape from './tape.backend';
3
+ export default class TapeStore {
4
+ private readonly path;
5
+ private readonly options;
6
+ tapes: Tape[];
7
+ constructor(options: Options);
8
+ load(): Promise<void>;
9
+ loadTapesAtDir(directory: string): Promise<void>;
10
+ find(newTape: Tape): Tape;
11
+ save(tape: Tape): Promise<void>;
12
+ currentTapeId(): number;
13
+ hasTapeBeenUsed(tapeName: string): boolean;
14
+ resetTapeUsage(): void;
15
+ createTapePath(tape: Tape): string;
16
+ }
@@ -0,0 +1,96 @@
1
+ import { fse, path, json5, mkdirp } from 'tnp-core/lib';
2
+ import Tape from './tape.backend';
3
+ import TapeMatcher from './tape-matcher.backend';
4
+ import TapeRenderer from './tape-renderer.backend';
5
+ export default class TapeStore {
6
+ path;
7
+ options;
8
+ tapes;
9
+ constructor(options) {
10
+ this.path = path.normalize(options.path + "/");
11
+ this.options = options;
12
+ this.tapes = [];
13
+ }
14
+ async load() {
15
+ mkdirp.sync(this.path);
16
+ await this.loadTapesAtDir(this.path);
17
+ console.log(`Loaded ${this.tapes.length} tapes`);
18
+ }
19
+ async loadTapesAtDir(directory) {
20
+ const items = fse.readdirSync(directory);
21
+ for (let i = 0; i < items.length; i++) {
22
+ const filename = items[i];
23
+ const fullPath = `${directory}${filename}`;
24
+ const stat = fse.statSync(fullPath);
25
+ if (!stat.isDirectory()) {
26
+ try {
27
+ const data = fse.readFileSync(fullPath, "utf8");
28
+ const raw = json5.parse(data);
29
+ const tape = await Tape.fromStore(raw, this.options);
30
+ tape.path = filename;
31
+ this.tapes.push(tape);
32
+ }
33
+ catch (e) {
34
+ console.log(`Error reading tape ${fullPath}`, e.message);
35
+ }
36
+ }
37
+ else {
38
+ this.loadTapesAtDir(fullPath + "/");
39
+ }
40
+ }
41
+ }
42
+ find(newTape) {
43
+ const foundTape = this.tapes.find(t => {
44
+ this.options.logger.debug(`Comparing against tape ${t.path}`);
45
+ return new TapeMatcher(t, this.options).sameAs(newTape);
46
+ });
47
+ if (foundTape) {
48
+ foundTape.used = true;
49
+ this.options.logger.log(`Found matching tape for ${newTape.req.url} at ${foundTape.path}`);
50
+ return foundTape;
51
+ }
52
+ }
53
+ async save(tape) {
54
+ tape.new = true;
55
+ tape.used = true;
56
+ const tapePath = tape.path;
57
+ let fullFilename;
58
+ if (tapePath) {
59
+ fullFilename = path.join(this.path, tapePath);
60
+ }
61
+ else {
62
+ // If the tape doesn't have a path then it's new
63
+ this.tapes.push(tape);
64
+ fullFilename = this.createTapePath(tape);
65
+ tape.path = path.relative(this.path, fullFilename);
66
+ }
67
+ this.options.logger.log(`Saving request ${tape.req.url} at ${tape.path}`);
68
+ const tapeRenderer = new TapeRenderer(tape);
69
+ const toSave = await tapeRenderer.render();
70
+ fse.writeFileSync(fullFilename, json5.stringify(toSave, null, 4));
71
+ }
72
+ currentTapeId() {
73
+ return this.tapes.length;
74
+ }
75
+ hasTapeBeenUsed(tapeName) {
76
+ return this.tapes.some(t => t.used && t.path === tapeName);
77
+ }
78
+ resetTapeUsage() {
79
+ return this.tapes.forEach(t => t.used = false);
80
+ }
81
+ createTapePath(tape) {
82
+ const currentTapeId = this.currentTapeId();
83
+ let tapePath = `unnamed-${currentTapeId}.json5`;
84
+ if (this.options.tapeNameGenerator) {
85
+ tapePath = this.options.tapeNameGenerator(currentTapeId, tape);
86
+ }
87
+ let result = path.normalize(path.join(this.options.path, tapePath));
88
+ if (!result.endsWith(".json5")) {
89
+ result = `${result}.json5`;
90
+ }
91
+ const dir = path.dirname(result);
92
+ mkdirp.sync(dir);
93
+ return result;
94
+ }
95
+ }
96
+ //# sourceMappingURL=tape-store.backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tape-store.backend.js","sourceRoot":"","sources":[""],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { Options } from './options.backend';
2
+ import { Metadata, Req, Res } from './types.backend';
3
+ export declare class Tape {
4
+ req: Req;
5
+ res?: Res;
6
+ options: Options;
7
+ queryParamsToIgnore: string[];
8
+ meta: Metadata;
9
+ path?: string;
10
+ new: boolean;
11
+ used: boolean;
12
+ constructor(req: Req, options: Options);
13
+ static fromStore(raw: any, options: Options): Promise<Tape>;
14
+ cleanupHeaders(): void;
15
+ cleanupQueryParams(): void;
16
+ normalizeBody(): void;
17
+ clone(): Promise<Tape>;
18
+ }
19
+ export default Tape;
@@ -0,0 +1,76 @@
1
+ import MediaType from './utils/media-type.backend';
2
+ import TapeRenderer from './tape-renderer.backend';
3
+ import ContentEncoding from './utils/content-encoding.backend';
4
+ import * as URL from 'url';
5
+ import * as querystring from 'querystring';
6
+ // const URL = require('url')
7
+ // const querystring = require('querystring')
8
+ export class Tape {
9
+ req;
10
+ res;
11
+ options;
12
+ queryParamsToIgnore;
13
+ meta;
14
+ path;
15
+ new = false;
16
+ used = false;
17
+ constructor(req, options) {
18
+ this.req = { ...req };
19
+ this.options = options;
20
+ // This needs to happen before we erase headers since we could lose information
21
+ this.normalizeBody();
22
+ this.cleanupHeaders();
23
+ this.queryParamsToIgnore = this.options.ignoreQueryParams;
24
+ this.cleanupQueryParams();
25
+ this.meta = {
26
+ createdAt: new Date(),
27
+ host: this.options.host
28
+ };
29
+ }
30
+ static async fromStore(raw, options) {
31
+ return TapeRenderer.fromStore(raw, options);
32
+ }
33
+ cleanupHeaders() {
34
+ const newHeaders = { ...this.req.headers };
35
+ this.options.ignoreHeaders.forEach(h => delete newHeaders[h]);
36
+ this.req = {
37
+ ...this.req,
38
+ headers: newHeaders
39
+ };
40
+ }
41
+ cleanupQueryParams() {
42
+ if (this.queryParamsToIgnore.length === 0) {
43
+ return;
44
+ }
45
+ const url = URL.parse(this.req.url, true);
46
+ if (!url.search) {
47
+ return;
48
+ }
49
+ const query = { ...url.query };
50
+ this.queryParamsToIgnore.forEach(q => delete query[q]);
51
+ const newQuery = querystring.stringify(query);
52
+ if (newQuery) {
53
+ url.query = query;
54
+ url.search = "?" + newQuery;
55
+ }
56
+ else {
57
+ url.query = null;
58
+ url.search = null;
59
+ }
60
+ this.req.url = URL.format(url);
61
+ }
62
+ normalizeBody() {
63
+ const mediaType = new MediaType(this.req);
64
+ const contentEncoding = new ContentEncoding(this.req);
65
+ if (contentEncoding.isUncompressed() && mediaType.isJSON() && this.req.body.length > 0) {
66
+ this.req.body = Buffer.from(JSON.stringify(JSON.parse(this.req.body.toString()), null, 2));
67
+ }
68
+ }
69
+ async clone() {
70
+ const tapeRenderer = new TapeRenderer(this);
71
+ const raw = await tapeRenderer.render();
72
+ return Tape.fromStore(raw, this.options);
73
+ }
74
+ }
75
+ export default Tape;
76
+ //# sourceMappingURL=tape.backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tape.backend.js","sourceRoot":"","sources":[""],"names":[],"mappings":"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"}