@teamscale/coverage-collector 0.0.1-beta.54 → 0.0.1-beta.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -19,12 +19,12 @@ 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 are needed as prerequisites.
22
+ NodeJs (>= v16) and pnpm are needed as prerequisites.
23
23
 
24
24
  ```
25
- yarn clean
26
- yarn install
27
- yarn build
25
+ pnpm clean
26
+ pnpm install
27
+ pnpm build
28
28
  ```
29
29
 
30
30
  ## Running the Collector
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamscale/coverage-collector",
3
- "version": "0.0.1-beta.54",
3
+ "version": "0.0.1-beta.55",
4
4
  "description": "Collector for JavaScript code coverage information",
5
5
  "main": "dist/src/main.js",
6
6
  "bin": "dist/src/main.js",
@@ -12,53 +12,51 @@
12
12
  "url": "https://github.com/cqse/teamscale-javascript-profiler.git"
13
13
  },
14
14
  "scripts": {
15
- "prepublishOnly": "yarn clean && yarn build",
15
+ "prepublishOnly": "pnpm clean && pnpm build",
16
16
  "clean": "rimraf dist tsconfig.tsbuildinfo",
17
17
  "build": "tsc",
18
18
  "collector": "node dist/src/main.js",
19
- "test": "yarn build && NODE_OPTIONS='--experimental-vm-modules' jest --coverage --silent=true"
19
+ "test": "pnpm build && NODE_OPTIONS='--experimental-vm-modules' jest --coverage --silent=true --detectOpenHandles --forceExit"
20
20
  },
21
21
  "files": [
22
22
  "dist/**/*"
23
23
  ],
24
24
  "dependencies": {
25
- "@cqse/commons": "^0.0.1-beta.45",
25
+ "@cqse/commons": "^0.0.1-beta.54",
26
26
  "argparse": "^2.0.1",
27
27
  "async": "^3.2.4",
28
- "axios": "^0.24.0",
28
+ "axios": "^1.4.0",
29
29
  "bunyan": "^1.8.15",
30
- "date-and-time": "^2.3.1",
31
- "dotenv": "^14.1.0",
32
- "express": "^4.18.1",
30
+ "date-and-time": "^3.0.2",
31
+ "dotenv": "^16.3.1",
32
+ "express": "^4.18.2",
33
33
  "form-data": "^4.0.0",
34
- "mkdirp": "^1.0.4",
35
- "rxjs": "^7.1.0",
34
+ "mkdirp": "^3.0.1",
35
+ "rxjs": "^7.8.1",
36
36
  "source-map": "^0.7.4",
37
37
  "tmp": "^0.2.1",
38
38
  "typescript-optional": "^2.0.1",
39
- "ws": "^7.4.5"
39
+ "ws": "^8.13.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@babel/core": "^7.21.8",
43
- "@babel/preset-env": "^7.21.5",
44
- "@types/argparse": "^2.0.5",
45
- "@types/async": "^3.2.6",
42
+ "@babel/core": "^7.22.8",
43
+ "@babel/preset-env": "^7.22.7",
44
+ "@types/argparse": "^2.0.10",
45
+ "@types/async": "^3.2.20",
46
46
  "@types/bunyan": "^1.8.8",
47
- "@types/express": "^4.17.13",
48
- "@types/jest": "^29.5.1",
49
- "@types/mkdirp": "^1.0.2",
50
- "@types/node": "^15.0.1",
51
- "@types/source-map": "^0.5.7",
47
+ "@types/express": "^4.17.17",
48
+ "@types/jest": "^29.5.3",
49
+ "@types/node": "^20.4.1",
52
50
  "@types/tmp": "^0.2.3",
53
- "@types/ws": "^7.4.2",
54
- "babel-jest": "^29.5.0",
55
- "esbuild": "^0.13.4",
56
- "jest": "^29.5.0",
57
- "mockttp": "^3.7.5",
58
- "rimraf": "^3.0.2",
59
- "ts-jest": "^29.1.0",
60
- "ts-node": "^10.2.1",
61
- "typescript": "^4.4.3"
51
+ "@types/ws": "^8.5.5",
52
+ "babel-jest": "^29.6.1",
53
+ "esbuild": "^0.18.11",
54
+ "jest": "^29.6.1",
55
+ "mockttp": "^3.7.6",
56
+ "rimraf": "^5.0.1",
57
+ "ts-jest": "^29.1.1",
58
+ "ts-node": "^10.9.1",
59
+ "typescript": "^5.1.6"
62
60
  },
63
61
  "publishConfig": {
64
62
  "access": "public"
package/dist/src/App.js CHANGED
@@ -33,7 +33,7 @@ const CollectingServer_1 = require("./receiver/CollectingServer");
33
33
  require("dotenv/config");
34
34
  const fs = __importStar(require("fs"));
35
35
  const ConfigParameters_1 = require("./utils/ConfigParameters");
36
- const mkdirp_1 = __importDefault(require("mkdirp"));
36
+ const mkdirp_1 = require("mkdirp");
37
37
  const path_1 = __importDefault(require("path"));
38
38
  const StdConsoleLogger_1 = require("./utils/StdConsoleLogger");
39
39
  const PrettyFileLogger_1 = require("./utils/PrettyFileLogger");
@@ -58,7 +58,7 @@ class App {
58
58
  */
59
59
  static buildLogger(config) {
60
60
  const logfilePath = config.log_to_file.trim();
61
- mkdirp_1.default.sync(path_1.default.dirname(logfilePath));
61
+ mkdirp_1.mkdirp.sync(path_1.default.dirname(logfilePath));
62
62
  const logLevel = config.log_level;
63
63
  const logger = bunyan_1.default.createLogger({
64
64
  name: 'Collector',
@@ -37,7 +37,7 @@ var ProtocolMessageTypes;
37
37
  ProtocolMessageTypes["TYPE_SOURCEMAP"] = "s";
38
38
  /** A message that provides coverage information */
39
39
  ProtocolMessageTypes["TYPE_COVERAGE"] = "c";
40
- })(ProtocolMessageTypes = exports.ProtocolMessageTypes || (exports.ProtocolMessageTypes = {}));
40
+ })(ProtocolMessageTypes || (exports.ProtocolMessageTypes = ProtocolMessageTypes = {}));
41
41
  /**
42
42
  * Separates the instrumentation subject from the coverage information.
43
43
  */
@@ -58,7 +58,7 @@ class WebSocketCollectingServer {
58
58
  commons_1.Contract.require(port > 0 && port < 65536, 'Port must be valid (range).');
59
59
  this.storage = commons_1.Contract.requireDefined(storage);
60
60
  this.logger = commons_1.Contract.requireDefined(logger);
61
- this.server = new WebSocket.Server({ port: port });
61
+ this.server = new WebSocket.Server({ port });
62
62
  }
63
63
  /**
64
64
  * Start the server socket, handle sessions and dispatch messages.
@@ -80,9 +80,9 @@ class WebSocketCollectingServer {
80
80
  }
81
81
  });
82
82
  // Handle incoming messages
83
- webSocket.on('message', async (message) => {
84
- if (session && typeof message === 'string') {
85
- await this.handleMessage(session, message);
83
+ webSocket.on('message', (message) => {
84
+ if (session && Buffer.isBuffer(message)) {
85
+ void this.handleMessage(session, message);
86
86
  }
87
87
  });
88
88
  // Handle errors
@@ -106,15 +106,16 @@ class WebSocketCollectingServer {
106
106
  */
107
107
  async handleMessage(session, message) {
108
108
  try {
109
- if (message.startsWith(ProtocolMessageTypes.TYPE_SOURCEMAP)) {
110
- await this.handleSourcemapMessage(session, message.substring(1));
109
+ const messageType = message.toString('utf8', 0, 1);
110
+ if (messageType.startsWith(ProtocolMessageTypes.TYPE_SOURCEMAP)) {
111
+ await this.handleSourcemapMessage(session, message.subarray(1));
111
112
  }
112
- else if (message.startsWith(ProtocolMessageTypes.TYPE_COVERAGE)) {
113
- await this.handleCoverageMessage(session, message.substring(1));
113
+ else if (messageType.startsWith(ProtocolMessageTypes.TYPE_COVERAGE)) {
114
+ await this.handleCoverageMessage(session, message.subarray(1));
114
115
  }
115
116
  }
116
117
  catch (e) {
117
- this.logger.error(`Error while processing message starting with ${message.substring(0, Math.min(50, message.length))}`);
118
+ this.logger.error(`Error while processing message starting with ${message.toString('utf8', 0, Math.min(50, message.length))}`);
118
119
  this.logger.error(e.message);
119
120
  }
120
121
  }
@@ -125,11 +126,11 @@ class WebSocketCollectingServer {
125
126
  * @param body - The body of the message (to be parsed).
126
127
  */
127
128
  async handleSourcemapMessage(session, body) {
128
- const fileIdSeparatorPosition = body.indexOf(INSTRUMENTATION_SUBJECT_SEPARATOR);
129
+ const fileIdSeparatorPosition = body.indexOf(INSTRUMENTATION_SUBJECT_SEPARATOR.charCodeAt(0));
129
130
  if (fileIdSeparatorPosition > -1) {
130
- const fileId = body.substring(0, fileIdSeparatorPosition).trim();
131
+ const fileId = body.toString('utf8', 0, fileIdSeparatorPosition).trim();
131
132
  this.logger.debug(`Received source map information for ${fileId}`);
132
- const sourcemap = body.substring(fileIdSeparatorPosition + 1);
133
+ const sourcemap = body.subarray(fileIdSeparatorPosition + 1);
133
134
  await session.putSourcemap(fileId, sourcemap);
134
135
  }
135
136
  }
@@ -142,7 +143,7 @@ class WebSocketCollectingServer {
142
143
  async handleCoverageMessage(session, body) {
143
144
  var _a;
144
145
  const bodyPattern = /(?<fileId>\S+) (?<positions>((\d+:\d+(:\d+:\d+)?\s+)*(\d+:\d+(:\d+:\d+)?)))/;
145
- const matches = bodyPattern.exec(body);
146
+ const matches = bodyPattern.exec(body.toString());
146
147
  if (matches === null || matches === void 0 ? void 0 : matches.groups) {
147
148
  const fileId = matches.groups.fileId;
148
149
  const positions = ((_a = matches.groups.positions) !== null && _a !== void 0 ? _a : '').split(/\s+/);
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { Socket } from 'net';
3
4
  import { IDataStorage } from '../storage/DataStorage';
4
5
  import Logger from 'bunyan';
@@ -78,7 +79,7 @@ export declare class Session {
78
79
  * @param fileId - The identifier of the file bundle.
79
80
  * @param sourceMapText - The actual source map.
80
81
  */
81
- putSourcemap(fileId: string, sourceMapText: string): Promise<void>;
82
+ putSourcemap(fileId: string, sourceMapText: Buffer): Promise<void>;
82
83
  private processUnmappedCoverageOf;
83
84
  /**
84
85
  * Destroy the session and free the memory it allocates.
@@ -137,7 +137,7 @@ class Session {
137
137
  * @param sourceMapText - The actual source map.
138
138
  */
139
139
  async putSourcemap(fileId, sourceMapText) {
140
- const rawSourceMap = JSON.parse(sourceMapText);
140
+ const rawSourceMap = JSON.parse(sourceMapText.toString());
141
141
  try {
142
142
  const sourceMapConsumer = await new sourceMap.SourceMapConsumer(rawSourceMap);
143
143
  this.sourceMaps.set(fileId, sourceMapConsumer);
@@ -150,7 +150,7 @@ class Session {
150
150
  processUnmappedCoverageOf(fileId) {
151
151
  var _a;
152
152
  const unmapped = (_a = this.unmappedCoverage.get(fileId)) !== null && _a !== void 0 ? _a : [];
153
- unmapped.forEach((entry) => {
153
+ unmapped.forEach(entry => {
154
154
  if (!this.putCoverage(entry.fileId, entry.startLine, entry.startColumn, entry.endLine, entry.endColumn)) {
155
155
  this.storage.signalUnmappedCoverage(this.projectId);
156
156
  }
@@ -13,4 +13,4 @@ export declare function prepareFormData(coverageFile: string): FormData;
13
13
  /**
14
14
  * Uploads a coverage file with the provided configuration.
15
15
  */
16
- export declare function performUpload(url: string, form: FormData, config: AxiosRequestConfig<FormData>, uploadFunction: <T = any, R = AxiosResponse<T>, D = FormData>(url: string, data?: D, config?: AxiosRequestConfig<D>) => Promise<R>, logger: Logger): Promise<void>;
16
+ export declare function performUpload(url: string, form: FormData, config: AxiosRequestConfig<FormData>, uploadFunction: <T = unknown, R = AxiosResponse<T>, D = FormData>(url: string, data?: D, config?: AxiosRequestConfig<D>) => Promise<R>, logger: Logger): Promise<void>;
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.performUpload = exports.prepareFormData = exports.UploadError = void 0;
7
7
  const form_data_1 = __importDefault(require("form-data"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
+ const axios_1 = __importDefault(require("axios"));
9
10
  const util_1 = require("util");
10
11
  /**
11
12
  * Error that is thrown when the upload failed
@@ -31,25 +32,25 @@ async function performUpload(url, form, config, uploadFunction, logger) {
31
32
  logger.info(`Upload finished with code ${response.status}.`);
32
33
  }
33
34
  catch (error) {
34
- if (error.response) {
35
- const response = error.response;
36
- if (response.status >= 400) {
37
- throw new UploadError(`Upload failed with code ${response.status}: ${response.statusText}. Response Data: ${response.data}`);
35
+ if (axios_1.default.isAxiosError(error)) {
36
+ if (error.response) {
37
+ const response = error.response;
38
+ if (response.status >= 400) {
39
+ throw new UploadError(`Upload failed with code ${response.status}: ${response.statusText}. Response Data: ${response.data}`);
40
+ }
41
+ else {
42
+ logger.info(`Upload with status code ${response.status} finished.`);
43
+ }
38
44
  }
39
- else {
40
- logger.info(`Upload with status code ${response.status} finished.`);
45
+ else if (error.request) {
46
+ throw new UploadError(`Upload request did not receive a response.`);
47
+ }
48
+ if (error.message) {
49
+ logger.debug(`Something went wrong when uploading data: ${error.message}. Details of the error: ${(0, util_1.inspect)(error)}`);
50
+ throw new UploadError(`Something went wrong when uploading data: ${error.message}`);
41
51
  }
42
52
  }
43
- else if (error.request) {
44
- throw new UploadError(`Upload request did not receive a response.`);
45
- }
46
- if (error.message) {
47
- logger.debug(`Something went wrong when uploading data: ${error.message}. Details of the error: ${(0, util_1.inspect)(error)}`);
48
- throw new UploadError(`Something went wrong when uploading data: ${error.message}`);
49
- }
50
- else {
51
- throw new UploadError(`Something went wrong when uploading data: ${(0, util_1.inspect)(error)}`);
52
- }
53
+ throw new UploadError(`Something went wrong when uploading data: ${(0, util_1.inspect)(error)}`);
53
54
  }
54
55
  }
55
56
  exports.performUpload = performUpload;
@@ -8,6 +8,6 @@ import { WriteStream } from 'fs';
8
8
  export declare class PrettyFileLogger {
9
9
  outputStream: WriteStream;
10
10
  constructor(outputStream: WriteStream);
11
- write(rec: Record<any, any>): void;
11
+ write(rec: any): void;
12
12
  end(): void;
13
13
  }
@@ -14,6 +14,7 @@ class PrettyFileLogger {
14
14
  constructor(outputStream) {
15
15
  this.outputStream = outputStream;
16
16
  }
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
18
  write(rec) {
18
19
  this.outputStream.write(`[${rec.time.toISOString()}] ${bunyan_1.default.nameFromLevel[rec.level].toUpperCase()}: ${rec.msg}\n`);
19
20
  }
@@ -1,5 +1,5 @@
1
1
  import 'dotenv/config';
2
2
  /** Class for console logger. Doesn't print all information to ensure better readability. */
3
3
  export declare class StdConsoleLogger {
4
- write(rec: Record<any, any>): void;
4
+ write(rec: any): void;
5
5
  }
@@ -8,6 +8,7 @@ const bunyan_1 = __importDefault(require("bunyan"));
8
8
  require("dotenv/config");
9
9
  /** Class for console logger. Doesn't print all information to ensure better readability. */
10
10
  class StdConsoleLogger {
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
12
  write(rec) {
12
13
  console.log(`[${rec.time.toISOString()}] ${bunyan_1.default.nameFromLevel[rec.level].toUpperCase()}: ${rec.msg}`);
13
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamscale/coverage-collector",
3
- "version": "0.0.1-beta.54",
3
+ "version": "0.0.1-beta.55",
4
4
  "description": "Collector for JavaScript code coverage information",
5
5
  "main": "dist/src/main.js",
6
6
  "bin": "dist/src/main.js",
@@ -12,53 +12,51 @@
12
12
  "url": "https://github.com/cqse/teamscale-javascript-profiler.git"
13
13
  },
14
14
  "scripts": {
15
- "prepublishOnly": "yarn clean && yarn build",
15
+ "prepublishOnly": "pnpm clean && pnpm build",
16
16
  "clean": "rimraf dist tsconfig.tsbuildinfo",
17
17
  "build": "tsc",
18
18
  "collector": "node dist/src/main.js",
19
- "test": "yarn build && NODE_OPTIONS='--experimental-vm-modules' jest --coverage --silent=true"
19
+ "test": "pnpm build && NODE_OPTIONS='--experimental-vm-modules' jest --coverage --silent=true --detectOpenHandles --forceExit"
20
20
  },
21
21
  "files": [
22
22
  "dist/**/*"
23
23
  ],
24
24
  "dependencies": {
25
- "@cqse/commons": "^0.0.1-beta.45",
25
+ "@cqse/commons": "^0.0.1-beta.54",
26
26
  "argparse": "^2.0.1",
27
27
  "async": "^3.2.4",
28
- "axios": "^0.24.0",
28
+ "axios": "^1.4.0",
29
29
  "bunyan": "^1.8.15",
30
- "date-and-time": "^2.3.1",
31
- "dotenv": "^14.1.0",
32
- "express": "^4.18.1",
30
+ "date-and-time": "^3.0.2",
31
+ "dotenv": "^16.3.1",
32
+ "express": "^4.18.2",
33
33
  "form-data": "^4.0.0",
34
- "mkdirp": "^1.0.4",
35
- "rxjs": "^7.1.0",
34
+ "mkdirp": "^3.0.1",
35
+ "rxjs": "^7.8.1",
36
36
  "source-map": "^0.7.4",
37
37
  "tmp": "^0.2.1",
38
38
  "typescript-optional": "^2.0.1",
39
- "ws": "^7.4.5"
39
+ "ws": "^8.13.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@babel/core": "^7.21.8",
43
- "@babel/preset-env": "^7.21.5",
44
- "@types/argparse": "^2.0.5",
45
- "@types/async": "^3.2.6",
42
+ "@babel/core": "^7.22.8",
43
+ "@babel/preset-env": "^7.22.7",
44
+ "@types/argparse": "^2.0.10",
45
+ "@types/async": "^3.2.20",
46
46
  "@types/bunyan": "^1.8.8",
47
- "@types/express": "^4.17.13",
48
- "@types/jest": "^29.5.1",
49
- "@types/mkdirp": "^1.0.2",
50
- "@types/node": "^15.0.1",
51
- "@types/source-map": "^0.5.7",
47
+ "@types/express": "^4.17.17",
48
+ "@types/jest": "^29.5.3",
49
+ "@types/node": "^20.4.1",
52
50
  "@types/tmp": "^0.2.3",
53
- "@types/ws": "^7.4.2",
54
- "babel-jest": "^29.5.0",
55
- "esbuild": "^0.13.4",
56
- "jest": "^29.5.0",
57
- "mockttp": "^3.7.5",
58
- "rimraf": "^3.0.2",
59
- "ts-jest": "^29.1.0",
60
- "ts-node": "^10.2.1",
61
- "typescript": "^4.4.3"
51
+ "@types/ws": "^8.5.5",
52
+ "babel-jest": "^29.6.1",
53
+ "esbuild": "^0.18.11",
54
+ "jest": "^29.6.1",
55
+ "mockttp": "^3.7.6",
56
+ "rimraf": "^5.0.1",
57
+ "ts-jest": "^29.1.1",
58
+ "ts-node": "^10.9.1",
59
+ "typescript": "^5.1.6"
62
60
  },
63
61
  "publishConfig": {
64
62
  "access": "public"