@teamscale/coverage-collector 0.0.1-alpha.20 → 0.0.1-beta.22

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/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ We use [Semantic Versioning](https://semver.org/).
2
+
3
+ # New Release
4
+
5
+ # 0.0.1-beta.22
6
+
7
+ - [feature] Logging of the status text in case of an error when uploading to Teamscale added.
8
+
9
+ # 0.0.1-beta.20
10
+
11
+ - [feature] Docker image of the Coverage Collector now available.
12
+ - [fix] The version of collector and instrumenter are kept in sync from now on.
13
+
14
+ # 0.0.1-beta.8
15
+
16
+ - [fix] Reduced the collectors dump interval from 2 minutes to 6 hours.
package/README.md CHANGED
@@ -9,7 +9,7 @@ files in the [Teamscale Simple Coverage Format](https://docs.teamscale.com/refer
9
9
  The Teamscale JavaScript Profiler consists of this Coverage Collector and the
10
10
  [JavaScript Instrumenter](https://www.npmjs.com/package/@teamscale/javascript-instrumenter).
11
11
  More details on using them (in combination) can be found
12
- on the projects' [Github page](https://github.com/cqse/teamscale-javascript-profiler/).
12
+ in the [Teamscale Documentation](https://docs.teamscale.com/howto/recording-test-coverage-for-javascript/).
13
13
 
14
14
  The JavaScript Coverage Collector starts a server process that listens for
15
15
  code coverage information from manually or automatically exercised (tested)
@@ -19,9 +19,10 @@ information back to the original source code.
19
19
  ## Building
20
20
 
21
21
  The Collector is written in TypeScript/JavaScript. For building and running it,
22
- NodeJs (>= v14) and Yarn (>= v3) are needed as prerequisites.
22
+ NodeJs (>= v14) and Yarn are needed as prerequisites.
23
23
 
24
24
  ```
25
+ yarn clean
25
26
  yarn install
26
27
  yarn build
27
28
  ```
@@ -31,7 +32,7 @@ yarn build
31
32
  There are several options to run the Collector. For example, via `yarn` by running
32
33
 
33
34
  ```
34
- yarn serve --port 54678 --dump-to-file=./coverage.simple
35
+ yarn collector --port 54678 --dump-to-file=./coverage.simple
35
36
  ```
36
37
 
37
38
  or via `npx` by running
@@ -48,8 +49,3 @@ for example, by setting a corresponding environment variable.
48
49
  export NODE_OPTIONS="$NODE_OPTIONS --max-old-space-size=8192"
49
50
  ```
50
51
 
51
- ## Publishing
52
-
53
- The list of files to publish is defined by the `files` attribute in `package.json`.
54
- The actual files packed by npm can be listed by running `npx npm-packlist`.
55
-
package/dist/package.json CHANGED
@@ -1,27 +1,35 @@
1
1
  {
2
2
  "name": "@teamscale/coverage-collector",
3
- "version": "0.0.1-alpha.18",
3
+ "version": "0.0.1-beta.21",
4
4
  "description": "Collector for JavaScript code coverage information",
5
- "main": "dist/main.js",
6
- "bin": "dist/main.js",
7
- "types": "dist/main.d.ts",
5
+ "main": "dist/src/main.js",
6
+ "bin": "dist/src/main.js",
7
+ "types": "dist/src/main.d.ts",
8
8
  "author": "CQSE GmbH",
9
9
  "license": "Apache-2.0",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/cqse/teamscale-javascript-profiler.git"
13
+ },
10
14
  "scripts": {
11
- "clean": "npx rimraf dist tsconfig.tsbuildinfo",
15
+ "clean": "rimraf dist tsconfig.tsbuildinfo",
12
16
  "build": "tsc",
13
- "serve": "node dist/main.js",
14
- "test": "yarn build && jest --forceExit --coverage --silent=true"
17
+ "collector": "node dist/src/main.js",
18
+ "test": "yarn build && NODE_OPTIONS='--experimental-vm-modules' jest --forceExit --coverage --silent=true --detectOpenHandles"
15
19
  },
16
20
  "files": [
17
21
  "dist/**/*"
18
22
  ],
19
23
  "dependencies": {
20
- "@cqse/commons": "workspace:*",
24
+ "@cqse/commons": "^0.0.1-beta.1",
21
25
  "argparse": "^2.0.1",
22
26
  "async": "^3.2.0",
27
+ "axios": "^0.24.0",
28
+ "dotenv": "^14.1.0",
29
+ "form-data": "^4.0.0",
23
30
  "rxjs": "^7.1.0",
24
31
  "source-map": "^0.7.3",
32
+ "tmp": "^0.2.1",
25
33
  "typescript-optional": "^2.0.1",
26
34
  "winston": "^3.3.3",
27
35
  "ws": "^7.4.5"
@@ -34,10 +42,13 @@
34
42
  "@types/jest": "^27.0.1",
35
43
  "@types/node": "^15.0.1",
36
44
  "@types/source-map": "^0.5.7",
45
+ "@types/tmp": "^0.2.3",
37
46
  "@types/winston": "^2.4.4",
38
47
  "@types/ws": "^7.4.2",
39
48
  "babel-jest": "^27.2.0",
49
+ "esbuild": "^0.13.4",
40
50
  "jest": "^27.2.0",
51
+ "rimraf": "^3.0.2",
41
52
  "ts-jest": "^27.0.5",
42
53
  "ts-node": "^10.2.1",
43
54
  "typescript": "^4.4.3"
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
+ import 'dotenv/config';
2
3
  /**
3
4
  * The main class of the Teamscale JavaScript Collector.
4
- * Used to start-up the collector for with a given configuration.
5
+ * Used to start the collector for with a given configuration.
5
6
  */
6
7
  export declare class Main {
7
8
  /**
@@ -23,9 +24,10 @@ export declare class Main {
23
24
  /**
24
25
  * Start a timer for dumping the data, depending on the configuration.
25
26
  *
26
- * @param config - The config that determines whether or not to do the timed dump.
27
+ * @param config - The config that determines whether to do the timed dump or not.
27
28
  * @param storage - The storage with the information to dump.
28
29
  * @param logger - The logger to use.
29
30
  */
30
31
  private static maybeStartDumpTimer;
32
+ private static dumpCoverage;
31
33
  }
package/dist/src/main.js CHANGED
@@ -1,33 +1,104 @@
1
1
  #!/usr/bin/env node
2
- import { version } from '../package.json';
3
- import { ArgumentParser } from 'argparse';
4
- import winston from 'winston';
5
- import { DataStorage } from './storage/DataStorage';
6
- import { WebSocketCollectingServer } from './receiver/CollectingServer';
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
6
+ }) : (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ o[k2] = m[k];
9
+ }));
10
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
11
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
12
+ }) : function(o, v) {
13
+ o["default"] = v;
14
+ });
15
+ var __importStar = (this && this.__importStar) || function (mod) {
16
+ if (mod && mod.__esModule) return mod;
17
+ var result = {};
18
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
19
+ __setModuleDefault(result, mod);
20
+ return result;
21
+ };
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.Main = void 0;
27
+ const package_json_1 = require("../package.json");
28
+ const argparse_1 = require("argparse");
29
+ const winston_1 = __importDefault(require("winston"));
30
+ const DataStorage_1 = require("./storage/DataStorage");
31
+ const CollectingServer_1 = require("./receiver/CollectingServer");
32
+ require("dotenv/config");
33
+ const fs = __importStar(require("fs"));
34
+ const axios_1 = __importDefault(require("axios"));
35
+ const form_data_1 = __importDefault(require("form-data"));
36
+ const QueryParameters_1 = __importDefault(require("./utils/QueryParameters"));
37
+ const tmp_1 = __importDefault(require("tmp"));
7
38
  /**
8
39
  * The main class of the Teamscale JavaScript Collector.
9
- * Used to start-up the collector for with a given configuration.
40
+ * Used to start the collector for with a given configuration.
10
41
  */
11
- export class Main {
42
+ class Main {
12
43
  /**
13
44
  * Construct the object for parsing the command line arguments.
14
45
  */
15
46
  static buildParser() {
16
- const parser = new ArgumentParser({
47
+ var _a;
48
+ const parser = new argparse_1.ArgumentParser({
17
49
  description: 'Collector of the Teamscale JavaScript Profiler. Collects coverage information from a' +
18
50
  '(headless) Web browser that executes code instrumented with our instrumenter.'
19
51
  });
20
- parser.add_argument('-v', '--version', { action: 'version', version });
52
+ parser.add_argument('-v', '--version', { action: 'version', version: package_json_1.version });
21
53
  parser.add_argument('-p', '--port', { help: 'The port to receive coverage information on.', default: 54678 });
22
- parser.add_argument('-f', '--dump-to-file', { help: 'Target file', default: './coverage.simple' });
23
- parser.add_argument('-s', '--dump-after-secs', {
24
- help: 'Dump the coverage information to the target file every N seconds.',
25
- default: 120
54
+ parser.add_argument('-f', '--dump-to-file', { help: 'Target file to write coverage to.' });
55
+ parser.add_argument('-l', '--log-to-file', { help: 'Log file', default: 'logs/collector-combined.log' });
56
+ parser.add_argument('-e', '--log-level', { help: 'Log level', default: 'info' });
57
+ parser.add_argument('-t', '--dump-after-mins', {
58
+ help: 'Dump the coverage information to the target file every N minutes.',
59
+ default: 360
26
60
  });
27
61
  parser.add_argument('-d', '--debug', {
28
62
  help: 'Print received coverage information to the terminal?',
29
63
  default: false
30
64
  });
65
+ // Parameters for the upload to Teamscale
66
+ parser.add_argument('-u', '--teamscale-server-url', {
67
+ help: 'Upload the coverage to the given Teamscale server URL, for example, https://teamscale.dev.example.com:8080/production.',
68
+ default: process.env.TEAMSCALE_SERVER_URL
69
+ });
70
+ parser.add_argument('--teamscale-access-token', {
71
+ help: 'The API key to use for uploading to Teamscale.',
72
+ default: process.env.TEAMSCALE_ACCESS_TOKEN
73
+ });
74
+ parser.add_argument('--teamscale-project', {
75
+ help: 'The project ID to upload coverage to.',
76
+ default: process.env.TEAMSCALE_PROJECT
77
+ });
78
+ parser.add_argument('--teamscale-user', {
79
+ help: 'The user for uploading coverage to Teamscale.',
80
+ default: process.env.TEAMSCALE_USER
81
+ });
82
+ parser.add_argument('--teamscale-partition', {
83
+ help: 'The partition to upload coverage to.',
84
+ default: process.env.TEAMSCALE_PARTITION
85
+ });
86
+ parser.add_argument('--teamscale-revision', {
87
+ help: 'The revision (commit hash, version id) to upload coverage for.',
88
+ default: process.env.TEAMSCALE_REVISION
89
+ });
90
+ parser.add_argument('--teamscale-commit', {
91
+ help: 'The branch and timestamp to upload coverage for, separated by colon.',
92
+ default: process.env.TEAMSCALE_COMMIT
93
+ });
94
+ parser.add_argument('--teamscale-repository', {
95
+ help: 'The repository to upload coverage for. Optional: Only needed when uploading via revision to a project that has more than one connector.',
96
+ default: process.env.TEAMSCALE_REPOSITORY
97
+ });
98
+ parser.add_argument('--teamscale-message', {
99
+ help: 'The commit message shown within Teamscale for the coverage upload. Default is "JavaScript coverage upload".',
100
+ default: (_a = process.env.TEAMSCALE_MESSAGE) !== null && _a !== void 0 ? _a : 'JavaScript coverage upload'
101
+ });
31
102
  return parser;
32
103
  }
33
104
  /**
@@ -40,15 +111,15 @@ export class Main {
40
111
  /**
41
112
  * Construct the logger.
42
113
  */
43
- static buildLogger() {
44
- return winston.createLogger({
45
- level: 'info',
46
- format: winston.format.json(),
114
+ static buildLogger(config) {
115
+ return winston_1.default.createLogger({
116
+ level: config.log_level,
117
+ format: winston_1.default.format.json(),
47
118
  defaultMeta: {},
48
119
  transports: [
49
- new winston.transports.File({ filename: 'logs/collector-error.log', level: 'error' }),
50
- new winston.transports.File({ filename: 'logs/collector-combined.log' }),
51
- new winston.transports.Console({ format: winston.format.simple(), level: 'info' })
120
+ new winston_1.default.transports.File({ filename: 'logs/collector-error.log', level: 'error' }),
121
+ new winston_1.default.transports.File({ filename: config.log_to_file.trim() }),
122
+ new winston_1.default.transports.Console({ format: winston_1.default.format.simple(), level: config.log_level })
52
123
  ]
53
124
  });
54
125
  }
@@ -56,20 +127,29 @@ export class Main {
56
127
  * Entry point of the Teamscale JavaScript Profiler.
57
128
  */
58
129
  static run() {
59
- const logger = this.buildLogger();
60
- logger.info(`Starting collector in working directory "${process.cwd()}".`);
61
130
  // Parse the command line arguments
62
131
  const config = this.parseArguments();
132
+ // Build the logger
133
+ const logger = this.buildLogger(config);
134
+ logger.info(`Starting collector in working directory "${process.cwd()}".`);
135
+ logger.info(`Logging "${config.log_level}" to "${config.log_to_file}".`);
136
+ // Check the command line arguments
137
+ if (!config.dump_to_file && !config.teamscale_server_url) {
138
+ logger.error('The Collector must be configured to either dump to a file or upload to Teamscale.');
139
+ process.exit(1);
140
+ }
63
141
  // Prepare the storage and the server
64
- const storage = new DataStorage(logger);
65
- const server = new WebSocketCollectingServer(config.port, storage, logger);
142
+ const storage = new DataStorage_1.DataStorage(logger);
143
+ const server = new CollectingServer_1.WebSocketCollectingServer(config.port, storage, logger);
66
144
  // Start the server socket.
67
145
  // ATTENTION: The server is executed asynchronously
68
146
  server.start();
69
147
  // Optionally, start a timer that dumps the coverage after a N seconds
70
148
  this.maybeStartDumpTimer(config, storage, logger);
71
149
  // Say bye bye on CTRL+C and exit the process
72
- process.on('SIGINT', () => {
150
+ process.on('SIGINT', async () => {
151
+ // ... and do a final dump before.
152
+ await this.dumpCoverage(config, storage, logger).then();
73
153
  logger.info('Bye bye.');
74
154
  process.exit();
75
155
  });
@@ -77,31 +157,82 @@ export class Main {
77
157
  /**
78
158
  * Start a timer for dumping the data, depending on the configuration.
79
159
  *
80
- * @param config - The config that determines whether or not to do the timed dump.
160
+ * @param config - The config that determines whether to do the timed dump or not.
81
161
  * @param storage - The storage with the information to dump.
82
162
  * @param logger - The logger to use.
83
163
  */
84
164
  static maybeStartDumpTimer(config, storage, logger) {
85
- if (config.dump_after_secs > 0) {
165
+ if (config.dump_after_mins > 0) {
166
+ logger.info(`Will dump coverage information every ${config.dump_after_mins} minute(s).`);
86
167
  const timer = setInterval(() => {
87
- try {
88
- const lines = storage.dumpToSimpleCoverageFile(config.dump_to_file);
89
- logger.info(`Conducted periodic coverage dump with ${lines} lines to ${config.dump_to_file}.`);
90
- }
91
- catch (e) {
92
- logger.error('Timed coverage dump failed.', e);
93
- }
94
- }, config.dump_after_secs * 1000);
168
+ this.dumpCoverage(config, storage, logger).then();
169
+ }, config.dump_after_mins * 1000 * 60);
95
170
  process.on('SIGINT', () => {
96
171
  // Stop the timed file dump
97
172
  if (timer) {
98
173
  clearInterval(timer);
99
174
  }
100
- // ... and do a final dump
101
- logger.info('\nCaught interrupt signal. Writing latest coverage.');
102
- storage.dumpToSimpleCoverageFile(config.dump_to_file);
103
175
  });
104
176
  }
105
177
  }
178
+ static async dumpCoverage(config, storage, logger) {
179
+ var _a;
180
+ try {
181
+ const deleteCoverageFileAfterUpload = !config.dump_to_file;
182
+ const coverageFile = (_a = config.dump_to_file) !== null && _a !== void 0 ? _a : tmp_1.default.tmpNameSync();
183
+ try {
184
+ // 1. Write coverage to a file
185
+ const lines = storage.dumpToSimpleCoverageFile(coverageFile);
186
+ logger.info(`Dumped ${lines} lines of coverage to ${coverageFile}.`);
187
+ // 2. Upload to Teamscale if configured
188
+ if (!config.teamscale_server_url) {
189
+ logger.info('Upload to Teamscale not configured.');
190
+ }
191
+ else if (lines === 0) {
192
+ // Nothing to upload
193
+ }
194
+ else if (config.teamscale_access_token && config.teamscale_user) {
195
+ logger.info('Preparing upload to Teamscale');
196
+ const form = new form_data_1.default();
197
+ form.append('report', fs.createReadStream(coverageFile), 'coverage.simple');
198
+ const parameters = new QueryParameters_1.default();
199
+ parameters.addIfDefined('format', 'SIMPLE');
200
+ parameters.addIfDefined('message', config.teamscale_message);
201
+ parameters.addIfDefined('repository', config.teamscale_repository);
202
+ parameters.addIfDefined('t', config.teamscale_commit);
203
+ parameters.addIfDefined('revision', config.teamscale_revision);
204
+ parameters.addIfDefined('partition', config.teamscale_partition);
205
+ const response = await axios_1.default.post(`${config.teamscale_server_url.replace(/\/$/, '')}/api/projects/${config.teamscale_project}/external-analysis/session/auto-create/report?${parameters.toString()}`, form, {
206
+ auth: {
207
+ username: config.teamscale_user,
208
+ password: config.teamscale_access_token
209
+ },
210
+ headers: {
211
+ Accept: '*/*',
212
+ 'Content-Type': `multipart/form-data; boundary=${form.getBoundary()}`
213
+ }
214
+ });
215
+ if (response.status >= 400) {
216
+ logger.error(`Upload failed with code ${response.status}: ${response.statusText}`);
217
+ }
218
+ else {
219
+ logger.info(`Upload with status code ${response.status} finished.`);
220
+ }
221
+ }
222
+ else {
223
+ logger.error('Cannot upload to Teamscale: API key and user name must be configured!');
224
+ }
225
+ }
226
+ finally {
227
+ if (deleteCoverageFileAfterUpload) {
228
+ fs.unlinkSync(coverageFile);
229
+ }
230
+ }
231
+ }
232
+ catch (e) {
233
+ logger.error('Coverage dump failed.', e);
234
+ }
235
+ }
106
236
  }
237
+ exports.Main = Main;
107
238
  Main.run();
@@ -1,17 +1,39 @@
1
- import * as WebSocket from 'ws';
2
- import { Contract } from '@cqse/commons';
3
- import { Session } from './Session';
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.WebSocketCollectingServer = exports.ProtocolMessageTypes = void 0;
23
+ const WebSocket = __importStar(require("ws"));
24
+ const commons_1 = require("@cqse/commons");
25
+ const Session_1 = require("./Session");
4
26
  /**
5
27
  * Various constants that are used to exchange data between
6
28
  * the instrumented application and the coverage collector.
7
29
  */
8
- export var ProtocolMessageTypes;
30
+ var ProtocolMessageTypes;
9
31
  (function (ProtocolMessageTypes) {
10
32
  /** A message that provides a source map */
11
33
  ProtocolMessageTypes["TYPE_SOURCEMAP"] = "s";
12
34
  /** A message that provides coverage information */
13
35
  ProtocolMessageTypes["TYPE_COVERAGE"] = "c";
14
- })(ProtocolMessageTypes || (ProtocolMessageTypes = {}));
36
+ })(ProtocolMessageTypes = exports.ProtocolMessageTypes || (exports.ProtocolMessageTypes = {}));
15
37
  /**
16
38
  * Separates the instrumentation subject from the coverage information.
17
39
  */
@@ -20,7 +42,7 @@ const INSTRUMENTATION_SUBJECT_SEPARATOR = ':';
20
42
  * A WebSocket based implementation of a coverage receiver.
21
43
  * Receives coverage from instrumented JavaScript code.
22
44
  */
23
- export class WebSocketCollectingServer {
45
+ class WebSocketCollectingServer {
24
46
  /**
25
47
  * Constructor.
26
48
  *
@@ -29,9 +51,9 @@ export class WebSocketCollectingServer {
29
51
  * @param logger - The logger to use.
30
52
  */
31
53
  constructor(port, storage, logger) {
32
- Contract.require(port > 0 && port < 65536, 'Port must be valid (range).');
33
- this.storage = Contract.requireDefined(storage);
34
- this.logger = Contract.requireDefined(logger);
54
+ commons_1.Contract.require(port > 0 && port < 65536, 'Port must be valid (range).');
55
+ this.storage = commons_1.Contract.requireDefined(storage);
56
+ this.logger = commons_1.Contract.requireDefined(logger);
35
57
  this.server = new WebSocket.Server({ port: port });
36
58
  }
37
59
  /**
@@ -41,7 +63,7 @@ export class WebSocketCollectingServer {
41
63
  this.logger.info(`Starting server on port ${this.server.options.port}.`);
42
64
  // Handle new connections from clients
43
65
  this.server.on('connection', (webSocket, req) => {
44
- let session = new Session(req.socket, this.storage, this.logger);
66
+ let session = new Session_1.Session(req.socket, this.storage, this.logger);
45
67
  this.logger.debug(`Connection from: ${req.socket.remoteAddress}`);
46
68
  // Handle disconnecting clients
47
69
  webSocket.on('close', code => {
@@ -94,6 +116,7 @@ export class WebSocketCollectingServer {
94
116
  const fileIdSeparatorPosition = body.indexOf(INSTRUMENTATION_SUBJECT_SEPARATOR);
95
117
  if (fileIdSeparatorPosition > -1) {
96
118
  const fileId = body.substring(0, fileIdSeparatorPosition).trim();
119
+ this.logger.debug(`Received source map information for ${fileId}`);
97
120
  const sourcemap = body.substring(fileIdSeparatorPosition + 1);
98
121
  session.putSourcemap(fileId, sourcemap);
99
122
  }
@@ -118,3 +141,4 @@ export class WebSocketCollectingServer {
118
141
  }
119
142
  }
120
143
  }
144
+ exports.WebSocketCollectingServer = WebSocketCollectingServer;
@@ -1,11 +1,33 @@
1
- import * as sourceMap from 'source-map';
2
- import { Contract } from '@cqse/commons';
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.Session = void 0;
23
+ const sourceMap = __importStar(require("source-map"));
24
+ const commons_1 = require("@cqse/commons");
3
25
  /**
4
26
  * The session maintains the relevant information for a client.
5
27
  * One session is created for each client.
6
28
  * The mapping based on sourcemaps is conducted here.
7
29
  */
8
- export class Session {
30
+ class Session {
9
31
  /**
10
32
  * Constructor
11
33
  *
@@ -14,9 +36,9 @@ export class Session {
14
36
  * @param logger - The logger to use.
15
37
  */
16
38
  constructor(socket, storage, logger) {
17
- this.socket = Contract.requireDefined(socket);
18
- this.storage = Contract.requireDefined(storage);
19
- this.logger = Contract.requireDefined(logger);
39
+ this.socket = commons_1.Contract.requireDefined(socket);
40
+ this.storage = commons_1.Contract.requireDefined(storage);
41
+ this.logger = commons_1.Contract.requireDefined(logger);
20
42
  this.sourceMaps = new Map();
21
43
  this.projectId = ''; // We currently only support coverage for one project.
22
44
  }
@@ -84,3 +106,4 @@ export class Session {
84
106
  }
85
107
  }
86
108
  }
109
+ exports.Session = Session;
@@ -94,6 +94,10 @@ export declare class DataStorage implements IDataStorage {
94
94
  * Logger to use.
95
95
  */
96
96
  private readonly logger;
97
+ /**
98
+ * Times unmapped coverage received.
99
+ */
100
+ private timesUnmappedCoverage;
97
101
  /**
98
102
  * Constructs the data storage.
99
103
  *