@teamscale/javascript-instrumenter 0.1.0-beta.8 → 1.0.0-beta.2
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/dist/package.json +28 -30
- package/dist/src/App.d.ts +10 -9
- package/dist/src/App.d.ts.map +1 -1
- package/dist/src/App.js +75 -75
- package/dist/src/instrumenter/FileSystem.d.ts +4 -0
- package/dist/src/instrumenter/FileSystem.d.ts.map +1 -1
- package/dist/src/instrumenter/FileSystem.js +34 -15
- package/dist/src/instrumenter/Instrumenter.d.ts +4 -2
- package/dist/src/instrumenter/Instrumenter.d.ts.map +1 -1
- package/dist/src/instrumenter/Instrumenter.js +29 -15
- package/dist/src/instrumenter/InstrumenterConfig.d.ts +36 -0
- package/dist/src/instrumenter/InstrumenterConfig.d.ts.map +1 -0
- package/dist/src/instrumenter/InstrumenterConfig.js +137 -0
- package/dist/src/instrumenter/Task.d.ts +6 -2
- package/dist/src/instrumenter/Task.d.ts.map +1 -1
- package/dist/src/instrumenter/Task.js +4 -3
- package/dist/src/instrumenter/TaskBuilder.d.ts +12 -16
- package/dist/src/instrumenter/TaskBuilder.d.ts.map +1 -1
- package/dist/src/instrumenter/TaskBuilder.js +51 -19
- package/dist/src/instrumenter/WebToolkit.js +5 -6
- package/dist/src/main.js +43 -1
- package/dist/src/vaccine/types.d.ts +21 -5
- package/dist/src/vaccine/types.d.ts.map +1 -1
- package/dist/vaccine.js +1 -1
- package/package.json +29 -31
package/dist/package.json
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teamscale/javascript-instrumenter",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"description": "JavaScript coverage instrumenter with coverage forwarding to a collector process",
|
|
5
5
|
"main": "dist/src/main.js",
|
|
6
6
|
"bin": "dist/src/main.js",
|
|
7
7
|
"types": "dist/src/main.d.ts",
|
|
8
8
|
"author": "CQSE GmbH",
|
|
9
9
|
"license": "Apache-2.0",
|
|
10
|
-
"
|
|
11
|
-
"type": "git",
|
|
12
|
-
"url": "https://github.com/cqse/teamscale-javascript-profiler.git"
|
|
13
|
-
},
|
|
10
|
+
"homepage": "https://docs.teamscale.com/howto/setting-up-profiler-tga/javascript/",
|
|
14
11
|
"scripts": {
|
|
15
12
|
"prepublishOnly": "pnpm clean && pnpm build",
|
|
16
13
|
"clean": "rimraf dist tsconfig.tsbuildinfo",
|
|
@@ -23,50 +20,51 @@
|
|
|
23
20
|
"dist/**/*"
|
|
24
21
|
],
|
|
25
22
|
"devDependencies": {
|
|
26
|
-
"@babel/core": "^7.
|
|
27
|
-
"@babel/plugin-transform-modules-commonjs": "^7.
|
|
28
|
-
"@babel/preset-env": "^7.
|
|
29
|
-
"@types/argparse": "^2.0.
|
|
23
|
+
"@babel/core": "^7.26.8",
|
|
24
|
+
"@babel/plugin-transform-modules-commonjs": "^7.26.3",
|
|
25
|
+
"@babel/preset-env": "^7.26.8",
|
|
26
|
+
"@types/argparse": "^2.0.17",
|
|
30
27
|
"@types/async": "^3.2.24",
|
|
31
28
|
"@types/babel__generator": "^7.6.8",
|
|
32
|
-
"@types/babel__traverse": "^7.20.
|
|
29
|
+
"@types/babel__traverse": "^7.20.6",
|
|
33
30
|
"@types/bunyan": "^1.8.11",
|
|
34
31
|
"@types/convert-source-map": "^2.0.3",
|
|
35
32
|
"@types/glob": "^8.1.0",
|
|
36
|
-
"@types/
|
|
37
|
-
"@types/
|
|
38
|
-
"@types/
|
|
39
|
-
"@types/
|
|
33
|
+
"@types/jest": "^29.5.14",
|
|
34
|
+
"@types/node": "^22.13.4",
|
|
35
|
+
"@types/ws": "^8.5.14",
|
|
36
|
+
"@types/uuid": "^10.0.0",
|
|
40
37
|
"babel-jest": "^29.7.0",
|
|
41
|
-
"esbuild": "^0.
|
|
38
|
+
"esbuild": "^0.25.0",
|
|
42
39
|
"esbuild-plugin-inline-worker": "^0.1.1",
|
|
43
40
|
"jest": "^29.7.0",
|
|
44
|
-
"rimraf": "^
|
|
45
|
-
"ts-jest": "^29.
|
|
41
|
+
"rimraf": "^6.0.1",
|
|
42
|
+
"ts-jest": "^29.2.5",
|
|
46
43
|
"ts-node": "^10.9.2",
|
|
47
|
-
"tslib": "^2.
|
|
48
|
-
"typescript": "^5.
|
|
44
|
+
"tslib": "^2.8.1",
|
|
45
|
+
"typescript": "^5.7.3"
|
|
49
46
|
},
|
|
50
47
|
"dependencies": {
|
|
51
|
-
"@cqse/commons": "
|
|
48
|
+
"@cqse/commons": "workspace:../cqse-commons",
|
|
52
49
|
"@teamscale/lib-instrument": "workspace:../lib-instrument",
|
|
53
|
-
"@babel/generator": "^7.
|
|
54
|
-
"@babel/parser": "^7.
|
|
55
|
-
"@babel/traverse": "^7.
|
|
56
|
-
"@babel/types": "^7.
|
|
57
|
-
"@types/micromatch": "^4.0.
|
|
50
|
+
"@babel/generator": "^7.26.8",
|
|
51
|
+
"@babel/parser": "^7.26.8",
|
|
52
|
+
"@babel/traverse": "^7.26.8",
|
|
53
|
+
"@babel/types": "^7.26.8",
|
|
54
|
+
"@types/micromatch": "^4.0.9",
|
|
58
55
|
"argparse": "^2.0.1",
|
|
59
|
-
"async": "^3.2.
|
|
56
|
+
"async": "^3.2.6",
|
|
60
57
|
"bunyan": "^1.8.15",
|
|
61
58
|
"convert-source-map": "^2.0.0",
|
|
62
|
-
"foreground-child": "^3.
|
|
63
|
-
"glob": "^
|
|
64
|
-
"micromatch": "4.0.
|
|
59
|
+
"foreground-child": "^3.3.0",
|
|
60
|
+
"glob": "^11.0.1",
|
|
61
|
+
"micromatch": "4.0.8",
|
|
65
62
|
"mkdirp": "^3.0.1",
|
|
66
63
|
"source-map": "0.7.4",
|
|
67
64
|
"typescript-optional": "^2.0.1",
|
|
68
65
|
"unload": "^2.4.1",
|
|
69
|
-
"
|
|
66
|
+
"uuid": "^11.1.0",
|
|
67
|
+
"web-worker": "^1.5.0"
|
|
70
68
|
},
|
|
71
69
|
"publishConfig": {
|
|
72
70
|
"access": "public"
|
package/dist/src/App.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TaskResult } from './instrumenter/Task';
|
|
2
|
-
import { ConfigurationParameters } from './instrumenter/TaskBuilder';
|
|
3
2
|
import Logger from 'bunyan';
|
|
3
|
+
import { InstrumenterOptions } from './instrumenter/InstrumenterConfig';
|
|
4
4
|
/**
|
|
5
5
|
* Entry points of the instrumenter, including command line argument parsing.
|
|
6
6
|
*/
|
|
@@ -10,22 +10,23 @@ export declare class App {
|
|
|
10
10
|
* Parses the command line options and the instrumentation accordingly.
|
|
11
11
|
*/
|
|
12
12
|
static run(): Promise<TaskResult>;
|
|
13
|
+
/**
|
|
14
|
+
* Runs the application with for the given command line arguments. Visible for testing.
|
|
15
|
+
*/
|
|
16
|
+
static runForArgv(argv: string[]): Promise<TaskResult>;
|
|
13
17
|
/**
|
|
14
18
|
* Parses the command-line arguments.
|
|
15
19
|
*
|
|
16
|
-
* @param args Optional. For testing. If given, uses this as the arguments to parse and does not exit the process on errors.
|
|
20
|
+
* @param args - Optional. For testing. If given, uses this as the arguments to parse and does not exit the process on errors.
|
|
17
21
|
* If not given, uses the NodeJS process's arguments and exits on errors.
|
|
22
|
+
* @param beforeArgumentCheckCallback - To be executed before the arguments are checked for validity.
|
|
18
23
|
*/
|
|
19
|
-
static parseCommandLine(args?: string[]):
|
|
24
|
+
static parseCommandLine(args?: string[], beforeArgumentCheckCallback?: (options: InstrumenterOptions) => void): InstrumenterOptions;
|
|
20
25
|
/**
|
|
21
26
|
* Sometimes we get inputs from shell environments where the strings are
|
|
22
27
|
* still quoted. We remove those here.
|
|
23
28
|
*/
|
|
24
|
-
static postprocessConfig(config:
|
|
25
|
-
/**
|
|
26
|
-
* Build the command line argument parser.
|
|
27
|
-
*/
|
|
28
|
-
private static buildParser;
|
|
29
|
+
static postprocessConfig(config: InstrumenterOptions): void;
|
|
29
30
|
/**
|
|
30
31
|
* Construct the logger.
|
|
31
32
|
*/
|
|
@@ -40,7 +41,7 @@ export declare class App {
|
|
|
40
41
|
* @param config - The dictionary with all configuration arguments.
|
|
41
42
|
* @param logger - The logger to use.
|
|
42
43
|
*/
|
|
43
|
-
static runForConfigArguments(config:
|
|
44
|
+
static runForConfigArguments(config: InstrumenterOptions, logger?: Logger): Promise<TaskResult>;
|
|
44
45
|
private static createInstrumentationTask;
|
|
45
46
|
private static createInstrumenter;
|
|
46
47
|
}
|
package/dist/src/App.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/App.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/App.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAYtE,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAA4C,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAGlH;;GAEG;AACH,qBAAa,GAAG;IACf;;;OAGG;WACiB,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;IAI9C;;OAEG;WACiB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IA2BnE;;;;;;OAMG;WACW,gBAAgB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,2BAA2B,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,GAAG,mBAAmB;IAM1I;;;OAGG;WACW,iBAAiB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAwClE;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IA+B1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAI/B;;;;;OAKG;WACW,qBAAqB,CAAC,MAAM,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAoCtG,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAIxC,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAajC"}
|
package/dist/src/App.js
CHANGED
|
@@ -15,19 +15,28 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
39
|
exports.App = void 0;
|
|
30
|
-
const argparse_1 = require("argparse");
|
|
31
40
|
const Instrumenter_1 = require("./instrumenter/Instrumenter");
|
|
32
41
|
const commons_1 = require("@cqse/commons");
|
|
33
42
|
const TaskBuilder_1 = require("./instrumenter/TaskBuilder");
|
|
@@ -36,6 +45,8 @@ const package_json_1 = require("../package.json");
|
|
|
36
45
|
const fs_1 = require("fs");
|
|
37
46
|
const mkdirp_1 = require("mkdirp");
|
|
38
47
|
const bunyan_1 = __importDefault(require("bunyan"));
|
|
48
|
+
const InstrumenterConfig_1 = require("./instrumenter/InstrumenterConfig");
|
|
49
|
+
const process = __importStar(require("node:process"));
|
|
39
50
|
/**
|
|
40
51
|
* Entry points of the instrumenter, including command line argument parsing.
|
|
41
52
|
*/
|
|
@@ -45,7 +56,25 @@ class App {
|
|
|
45
56
|
* Parses the command line options and the instrumentation accordingly.
|
|
46
57
|
*/
|
|
47
58
|
static async run() {
|
|
48
|
-
|
|
59
|
+
return this.runForArgv(process.argv);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Runs the application with for the given command line arguments. Visible for testing.
|
|
63
|
+
*/
|
|
64
|
+
static async runForArgv(argv) {
|
|
65
|
+
const config = this.parseCommandLine(argv.slice(2), options => {
|
|
66
|
+
if (options.collectorOptionsList) {
|
|
67
|
+
const collectorParameters = (0, commons_1.buildReconfigurableCollectorParameters)();
|
|
68
|
+
(0, commons_1.printHelp)(collectorParameters, undefined, true);
|
|
69
|
+
console.log("");
|
|
70
|
+
console.log("ATTENTION:\n" +
|
|
71
|
+
"When specifying credentials of Teamscale or other services via --collector-config-file or --collector-option,\n" +
|
|
72
|
+
"the credentials will be included in the instrumented source code and are thus visible\n" +
|
|
73
|
+
"to anyone that can access your deployed application.\n" +
|
|
74
|
+
"We recommend you instead give these credentials to the collector directly when launching it.\n");
|
|
75
|
+
process.exit(0);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
49
78
|
// Build the logger
|
|
50
79
|
const logger = this.buildLogger(config);
|
|
51
80
|
logger.trace('Retrieved arguments', process.argv);
|
|
@@ -56,12 +85,14 @@ class App {
|
|
|
56
85
|
/**
|
|
57
86
|
* Parses the command-line arguments.
|
|
58
87
|
*
|
|
59
|
-
* @param args Optional. For testing. If given, uses this as the arguments to parse and does not exit the process on errors.
|
|
88
|
+
* @param args - Optional. For testing. If given, uses this as the arguments to parse and does not exit the process on errors.
|
|
60
89
|
* If not given, uses the NodeJS process's arguments and exits on errors.
|
|
90
|
+
* @param beforeArgumentCheckCallback - To be executed before the arguments are checked for validity.
|
|
61
91
|
*/
|
|
62
|
-
static parseCommandLine(args) {
|
|
63
|
-
const
|
|
64
|
-
|
|
92
|
+
static parseCommandLine(args, beforeArgumentCheckCallback) {
|
|
93
|
+
const configParameters = (0, InstrumenterConfig_1.buildInstrumenterConfigurationParameters)();
|
|
94
|
+
const appInfos = { about: package_json_1.description, version: package_json_1.version, name: package_json_1.name };
|
|
95
|
+
return (0, commons_1.processCommandLine)(configParameters, appInfos, args, beforeArgumentCheckCallback);
|
|
65
96
|
}
|
|
66
97
|
/**
|
|
67
98
|
* Sometimes we get inputs from shell environments where the strings are
|
|
@@ -107,70 +138,14 @@ class App {
|
|
|
107
138
|
}
|
|
108
139
|
}
|
|
109
140
|
}
|
|
110
|
-
/**
|
|
111
|
-
* Build the command line argument parser.
|
|
112
|
-
*/
|
|
113
|
-
static buildParser() {
|
|
114
|
-
const parser = new argparse_1.ArgumentParser({
|
|
115
|
-
description: 'Instrumenter of the Teamscale JavaScript Profiler',
|
|
116
|
-
});
|
|
117
|
-
parser.add_argument('-v', '--version', { action: 'version', version: package_json_1.version });
|
|
118
|
-
parser.add_argument('-i', '--in-place', {
|
|
119
|
-
action: 'store_true',
|
|
120
|
-
help: 'If set, the original files to instrument are replaced by their instrumented counterparts.'
|
|
121
|
-
});
|
|
122
|
-
parser.add_argument('-d', '--debug', { action: 'store_true' });
|
|
123
|
-
parser.add_argument('-o', '--to', {
|
|
124
|
-
help: 'Path (directory or file name) to write the instrumented version to.'
|
|
125
|
-
});
|
|
126
|
-
parser.add_argument('-s', '--source-map', {
|
|
127
|
-
help: 'External location of source-map files to consider.'
|
|
128
|
-
});
|
|
129
|
-
parser.add_argument('-c', '--collector', {
|
|
130
|
-
help: 'The collector (`host:port` or `wss://host:port/` or `ws://host:port/`) to send coverage information to.',
|
|
131
|
-
default: 'ws://localhost:54678'
|
|
132
|
-
});
|
|
133
|
-
parser.add_argument('--relative-collector', {
|
|
134
|
-
help: 'Pattern used to determine the collector URL from the application hostname.'
|
|
135
|
-
+ ' Useful for Kubernetes deployments where the collector URL is not known at instrumentation time.'
|
|
136
|
-
+ ' Example: `replace-in-host:app collector,scheme:wss`.'
|
|
137
|
-
+ ' This causes the first occurrence of `app` in the application hostname to be replaced with `collector`'
|
|
138
|
-
+ ' and the URL scheme changed to wss.'
|
|
139
|
-
+ ' Available operations:'
|
|
140
|
-
+ ' `replace-in-host:SEARCH REPLACE` replaces the literal term SEARCH once in the hostname with REPLACE.'
|
|
141
|
-
+ ' `port:NUMBER` changes the port to NUMBER.'
|
|
142
|
-
+ ' `port:keep` keeps the port of the application (instead of using the chosen scheme\'s default port).'
|
|
143
|
-
+ ' `scheme:SCHEME` changes the URL scheme to one of ws, wss, http or https.'
|
|
144
|
-
+ ' `path:PATH` uses the URL path PATH (instead of no path).'
|
|
145
|
-
});
|
|
146
|
-
parser.add_argument('-x', '--exclude-origin', {
|
|
147
|
-
nargs: '*',
|
|
148
|
-
help: 'Glob pattern(s) of files in the source origin to not produce coverage for. Multiple patterns can be separated by space.'
|
|
149
|
-
});
|
|
150
|
-
parser.add_argument('-k', '--include-origin', {
|
|
151
|
-
nargs: '*',
|
|
152
|
-
help: 'Glob pattern(s) of files in the source origin to produce coverage for. Multiple patterns can be separated by space.'
|
|
153
|
-
});
|
|
154
|
-
parser.add_argument('-e', '--exclude-bundle', {
|
|
155
|
-
nargs: '*',
|
|
156
|
-
help: 'Glob pattern(s) of input (bundle) files to keep unchanged (to not instrument).'
|
|
157
|
-
});
|
|
158
|
-
parser.add_argument('-p', '--dump-origins-to', {
|
|
159
|
-
help: 'Path specifying where to dump source origins file names, based on the source maps, as a JSON file.'
|
|
160
|
-
});
|
|
161
|
-
parser.add_argument('-m', '--dump-origin-matches-to', {
|
|
162
|
-
help: 'Path specifying where to dump a JSON with the names of the files that have matched the origin include/exclude patterns.'
|
|
163
|
-
});
|
|
164
|
-
parser.add_argument('inputs', { nargs: '+', help: 'The input file(s) to instrument.' });
|
|
165
|
-
return parser;
|
|
166
|
-
}
|
|
167
141
|
/**
|
|
168
142
|
* Construct the logger.
|
|
169
143
|
*/
|
|
170
144
|
static buildLogger(config) {
|
|
145
|
+
var _a;
|
|
171
146
|
const logfilePath = 'logs/instrumenter.log';
|
|
172
147
|
mkdirp_1.mkdirp.sync(path.dirname(logfilePath));
|
|
173
|
-
const logLevel = config.
|
|
148
|
+
const logLevel = (_a = config.logLevel) !== null && _a !== void 0 ? _a : 'info';
|
|
174
149
|
return bunyan_1.default.createLogger({
|
|
175
150
|
name: 'Instrumenter',
|
|
176
151
|
streams: [
|
|
@@ -205,14 +180,39 @@ class App {
|
|
|
205
180
|
*/
|
|
206
181
|
static runForConfigArguments(config, logger) {
|
|
207
182
|
this.postprocessConfig(config);
|
|
183
|
+
if (config.collectorConfigFile) {
|
|
184
|
+
if (!(0, fs_1.existsSync)(config.collectorConfigFile)) {
|
|
185
|
+
throw new commons_1.InvalidConfigurationException(`The specified collector configuration file '${config.collectorConfigFile}' does not exist.`);
|
|
186
|
+
}
|
|
187
|
+
config.collectorConfigFileContent = (0, fs_1.readFileSync)(config.collectorConfigFile, 'utf8');
|
|
188
|
+
}
|
|
189
|
+
if (Array.isArray(config.collectorOption)) {
|
|
190
|
+
if (!config.collectorConfigFileContent) {
|
|
191
|
+
config.collectorConfigFileContent = "";
|
|
192
|
+
}
|
|
193
|
+
config.collectorConfigFileContent += `\n${config.collectorOption.join("\n")}`;
|
|
194
|
+
}
|
|
195
|
+
if (config.collectorConfigFileContent) {
|
|
196
|
+
try {
|
|
197
|
+
// We parse the collector config file once, to see if it is valid.
|
|
198
|
+
const collectorParameters = (0, commons_1.buildReconfigurableCollectorParameters)();
|
|
199
|
+
const { options } = (0, commons_1.parseConfigFile)(config.collectorConfigFileContent, collectorParameters);
|
|
200
|
+
if (!(0, commons_1.checkArguments)(collectorParameters, options)) {
|
|
201
|
+
throw new commons_1.InvalidConfigurationException(`Not all required configuration options are specified correctly.`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
throw new commons_1.InvalidConfigurationException(`The specified collector configuration is invalid: ${e.message}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
208
|
const task = this.createInstrumentationTask(config);
|
|
209
209
|
commons_1.Contract.require(task.elements.length > 0, 'The instrumentation task must not be empty.');
|
|
210
|
-
return this.createInstrumenter(logger !== null && logger !== void 0 ? logger : this.buildDummyLogger(), task.collector).instrument(task);
|
|
210
|
+
return this.createInstrumenter(logger !== null && logger !== void 0 ? logger : this.buildDummyLogger(), task.collector, task.targetBucket).instrument(task);
|
|
211
211
|
}
|
|
212
212
|
static createInstrumentationTask(config) {
|
|
213
213
|
return new TaskBuilder_1.TaskBuilder().addFromConfig(config).build();
|
|
214
214
|
}
|
|
215
|
-
static createInstrumenter(logger, collector) {
|
|
215
|
+
static createInstrumenter(logger, collector, targetBucket) {
|
|
216
216
|
// We have to deal with two different `__dirname` versions,
|
|
217
217
|
// which depends on whether we run from within the IDE or from
|
|
218
218
|
// the command line:
|
|
@@ -220,10 +220,10 @@ class App {
|
|
|
220
220
|
const pathVariant1 = path.join(__dirname, '../vaccine.js');
|
|
221
221
|
const pathVariant2 = path.join(__dirname, '../dist/vaccine.js');
|
|
222
222
|
if ((0, fs_1.existsSync)(pathVariant1)) {
|
|
223
|
-
return new Instrumenter_1.IstanbulInstrumenter(pathVariant1, logger, collector);
|
|
223
|
+
return new Instrumenter_1.IstanbulInstrumenter(pathVariant1, logger, collector, targetBucket);
|
|
224
224
|
}
|
|
225
225
|
else {
|
|
226
|
-
return new Instrumenter_1.IstanbulInstrumenter(pathVariant2, logger, collector);
|
|
226
|
+
return new Instrumenter_1.IstanbulInstrumenter(pathVariant2, logger, collector, targetBucket);
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
}
|
|
@@ -31,4 +31,8 @@ export declare function expandToFileSet(toExpand: string): string[];
|
|
|
31
31
|
* @param mapFilePath
|
|
32
32
|
*/
|
|
33
33
|
export declare function sourceMapFromMapFile(mapFilePath: string): RawSourceMap | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Ensure that the given name works as a file or folder name.
|
|
36
|
+
*/
|
|
37
|
+
export declare function replaceNonFilesystemCharacters(name: string): string;
|
|
34
38
|
//# sourceMappingURL=FileSystem.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSystem.d.ts","sourceRoot":"","sources":["../../../src/instrumenter/FileSystem.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAU1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBpF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAc1D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAGlF"}
|
|
1
|
+
{"version":3,"file":"FileSystem.d.ts","sourceRoot":"","sources":["../../../src/instrumenter/FileSystem.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAU1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBpF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAc1D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAGlF;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKnE"}
|
|
@@ -15,18 +15,35 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
39
|
+
exports.isExistingFile = isExistingFile;
|
|
40
|
+
exports.isExistingDirectory = isExistingDirectory;
|
|
41
|
+
exports.ensureExistingDirectory = ensureExistingDirectory;
|
|
42
|
+
exports.findSubFolders = findSubFolders;
|
|
43
|
+
exports.isDirectoryEmpty = isDirectoryEmpty;
|
|
44
|
+
exports.expandToFileSet = expandToFileSet;
|
|
45
|
+
exports.sourceMapFromMapFile = sourceMapFromMapFile;
|
|
46
|
+
exports.replaceNonFilesystemCharacters = replaceNonFilesystemCharacters;
|
|
30
47
|
const commons_1 = require("@cqse/commons");
|
|
31
48
|
const fs = __importStar(require("fs"));
|
|
32
49
|
const mkdirp = __importStar(require("mkdirp"));
|
|
@@ -38,14 +55,12 @@ const glob_1 = require("glob");
|
|
|
38
55
|
function isExistingFile(path) {
|
|
39
56
|
return fs.existsSync(path) && fs.lstatSync(path).isFile();
|
|
40
57
|
}
|
|
41
|
-
exports.isExistingFile = isExistingFile;
|
|
42
58
|
/**
|
|
43
59
|
* Does the given `path` point to an existing directory?
|
|
44
60
|
*/
|
|
45
61
|
function isExistingDirectory(path) {
|
|
46
62
|
return fs.existsSync(path) && fs.lstatSync(path).isDirectory();
|
|
47
63
|
}
|
|
48
|
-
exports.isExistingDirectory = isExistingDirectory;
|
|
49
64
|
/**
|
|
50
65
|
* Ensure that the given directory `path` exists.
|
|
51
66
|
*/
|
|
@@ -57,7 +72,6 @@ function ensureExistingDirectory(path) {
|
|
|
57
72
|
throw new commons_1.InvalidConfigurationException(`The specified path '${path}' does not point to an existing directory!`);
|
|
58
73
|
}
|
|
59
74
|
}
|
|
60
|
-
exports.ensureExistingDirectory = ensureExistingDirectory;
|
|
61
75
|
/**
|
|
62
76
|
* Given a root folder find a folder with a given name.
|
|
63
77
|
*/
|
|
@@ -76,14 +90,12 @@ function findSubFolders(startFromFolder, folderName) {
|
|
|
76
90
|
}
|
|
77
91
|
return matches;
|
|
78
92
|
}
|
|
79
|
-
exports.findSubFolders = findSubFolders;
|
|
80
93
|
/**
|
|
81
94
|
* Is the given directory empty?
|
|
82
95
|
*/
|
|
83
96
|
function isDirectoryEmpty(path) {
|
|
84
97
|
return !isExistingDirectory(path) || fs.readdirSync(path).length > 0;
|
|
85
98
|
}
|
|
86
|
-
exports.isDirectoryEmpty = isDirectoryEmpty;
|
|
87
99
|
/**
|
|
88
100
|
* Expand a given Glob pattern to a list of files.
|
|
89
101
|
*
|
|
@@ -102,7 +114,6 @@ function expandToFileSet(toExpand) {
|
|
|
102
114
|
}
|
|
103
115
|
return glob_1.glob.sync(globPattern, { nodir: true });
|
|
104
116
|
}
|
|
105
|
-
exports.expandToFileSet = expandToFileSet;
|
|
106
117
|
/**
|
|
107
118
|
* Read a source map from a source map file.
|
|
108
119
|
*
|
|
@@ -112,4 +123,12 @@ function sourceMapFromMapFile(mapFilePath) {
|
|
|
112
123
|
const content = fs.readFileSync(mapFilePath, 'utf8');
|
|
113
124
|
return JSON.parse(content);
|
|
114
125
|
}
|
|
115
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Ensure that the given name works as a file or folder name.
|
|
128
|
+
*/
|
|
129
|
+
function replaceNonFilesystemCharacters(name) {
|
|
130
|
+
// Replace undesired characters by underscore chars.
|
|
131
|
+
const result = name.replace(/[^a-zA-Z0-9_\-.\\/]/g, '_');
|
|
132
|
+
// Remove repeated underscores (_) from `result.
|
|
133
|
+
return result.replace(/_+/g, '_');
|
|
134
|
+
}
|
|
@@ -2,7 +2,7 @@ import { FileExcludePattern, InstrumentationTask, OriginSourcePattern, SourceMap
|
|
|
2
2
|
import { RawSourceMap, SourceMapConsumer } from 'source-map';
|
|
3
3
|
import { Optional } from 'typescript-optional';
|
|
4
4
|
import Logger from 'bunyan';
|
|
5
|
-
import { CollectorSpecifier } from '@src/vaccine/types';
|
|
5
|
+
import { CollectorSpecifier, CoverageBucketSpecifier } from '@src/vaccine/types';
|
|
6
6
|
export declare const IS_INSTRUMENTED_TOKEN = "$IS_JS_PROFILER_INSTRUMENTED=true";
|
|
7
7
|
/**
|
|
8
8
|
* An instrumenter that can conduct a {@code InstrumentationTask}.
|
|
@@ -29,7 +29,7 @@ export declare class IstanbulInstrumenter implements IInstrumenter {
|
|
|
29
29
|
* The logger instance to log to.
|
|
30
30
|
*/
|
|
31
31
|
private logger;
|
|
32
|
-
constructor(vaccineFilePath: string, logger: Logger, collector: CollectorSpecifier);
|
|
32
|
+
constructor(vaccineFilePath: string, logger: Logger, collector: CollectorSpecifier, targetBucket: CoverageBucketSpecifier);
|
|
33
33
|
/**
|
|
34
34
|
* {@inheritDoc #IInstrumenter.instrument}
|
|
35
35
|
*/
|
|
@@ -49,7 +49,9 @@ export declare class IstanbulInstrumenter implements IInstrumenter {
|
|
|
49
49
|
/**
|
|
50
50
|
* Loads the vaccine from the vaccine file and adjusts some template parameters.
|
|
51
51
|
*
|
|
52
|
+
* @param filePath - The path to the vaccine file.
|
|
52
53
|
* @param collector - The collector to send coverage information to.
|
|
54
|
+
* @param targetBucket - The bucket within the collector to put the coverage into.
|
|
53
55
|
*/
|
|
54
56
|
private loadVaccine;
|
|
55
57
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Instrumenter.d.ts","sourceRoot":"","sources":["../../../src/instrumenter/Instrumenter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,kBAAkB,EAElB,mBAAmB,EACnB,mBAAmB,EAEnB,kBAAkB,EAElB,WAAW,EACX,UAAU,EACV,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAM7D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,MAAM,MAAM,QAAQ,CAAC;AAO5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"Instrumenter.d.ts","sourceRoot":"","sources":["../../../src/instrumenter/Instrumenter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,kBAAkB,EAElB,mBAAmB,EACnB,mBAAmB,EAEnB,kBAAkB,EAElB,WAAW,EACX,UAAU,EACV,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAM7D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,MAAM,MAAM,QAAQ,CAAC;AAO5B,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAEjF,eAAO,MAAM,qBAAqB,sCAAsC,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC3D;AA0BD;;GAEG;AACH,qBAAa,oBAAqB,YAAW,aAAa;IACzD;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAS;gBAEX,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,EAAE,uBAAuB;IAUzH;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IA2BhE;;;;;;;;OAQG;IACG,aAAa,CAClB,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,kBAAkB,EAClC,aAAa,EAAE,mBAAmB,EAClC,eAAe,EAAE,MAAM,GAAG,SAAS,GACjC,OAAO,CAAC,UAAU,CAAC;YAsER,gBAAgB;IA8C9B,OAAO,CAAC,eAAe;IA0BvB;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAgBpC,+EAA+E;IAC/E,OAAO,CAAC,SAAS;IAUjB,+EAA+E;IAC/E,OAAO,CAAC,UAAU;CAYlB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAClC,kBAAkB,EAAE,MAAM,EAC1B,0BAA0B,EAAE,MAAM,GAChC,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAUxC;AAsBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CACjC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,qBAAqB,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GACjD,YAAY,GAAG,SAAS,CAU1B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAwC7G"}
|
|
@@ -15,18 +15,31 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
39
|
+
exports.IstanbulInstrumenter = exports.IS_INSTRUMENTED_TOKEN = void 0;
|
|
40
|
+
exports.loadSourceMap = loadSourceMap;
|
|
41
|
+
exports.loadInputSourceMap = loadInputSourceMap;
|
|
42
|
+
exports.sourceMapFromCodeComment = sourceMapFromCodeComment;
|
|
30
43
|
const Task_1 = require("./Task");
|
|
31
44
|
const commons_1 = require("@cqse/commons");
|
|
32
45
|
const source_map_1 = require("source-map");
|
|
@@ -66,9 +79,9 @@ function readBundle(bundleContent, taskElement) {
|
|
|
66
79
|
* An instrumenter based on the IstanbulJs instrumentation and coverage framework.
|
|
67
80
|
*/
|
|
68
81
|
class IstanbulInstrumenter {
|
|
69
|
-
constructor(vaccineFilePath, logger, collector) {
|
|
82
|
+
constructor(vaccineFilePath, logger, collector, targetBucket) {
|
|
70
83
|
commons_1.Contract.require(fs.existsSync(vaccineFilePath), `The vaccine file to inject "${vaccineFilePath}" must exist!\nCWD:${process.cwd()}`);
|
|
71
|
-
this.vaccineSource = this.loadVaccine(commons_1.Contract.requireNonEmpty(vaccineFilePath), collector);
|
|
84
|
+
this.vaccineSource = this.loadVaccine(commons_1.Contract.requireNonEmpty(vaccineFilePath), collector, targetBucket);
|
|
72
85
|
this.logger = logger;
|
|
73
86
|
}
|
|
74
87
|
/**
|
|
@@ -199,12 +212,16 @@ class IstanbulInstrumenter {
|
|
|
199
212
|
/**
|
|
200
213
|
* Loads the vaccine from the vaccine file and adjusts some template parameters.
|
|
201
214
|
*
|
|
215
|
+
* @param filePath - The path to the vaccine file.
|
|
202
216
|
* @param collector - The collector to send coverage information to.
|
|
217
|
+
* @param targetBucket - The bucket within the collector to put the coverage into.
|
|
203
218
|
*/
|
|
204
|
-
loadVaccine(filePath, collector) {
|
|
219
|
+
loadVaccine(filePath, collector, targetBucket) {
|
|
205
220
|
// We first replace parameters in the file with the
|
|
206
221
|
// actual values, for example, the collector to send the coverage information to.
|
|
207
|
-
return fs.readFileSync(filePath, 'utf8')
|
|
222
|
+
return fs.readFileSync(filePath, 'utf8')
|
|
223
|
+
.replace(/\$COLLECTOR_SPECIFIER/g, JSON.stringify(collector))
|
|
224
|
+
.replace(/\$BUCKET_SPECIFIER/g, Buffer.from(JSON.stringify(targetBucket)).toString('base64'));
|
|
208
225
|
}
|
|
209
226
|
/**
|
|
210
227
|
* @returns whether the given file is supported for instrumentation.
|
|
@@ -272,7 +289,6 @@ async function loadSourceMap(instrumentedSource, instrumentedSourceFileName) {
|
|
|
272
289
|
}
|
|
273
290
|
return undefined;
|
|
274
291
|
}
|
|
275
|
-
exports.loadSourceMap = loadSourceMap;
|
|
276
292
|
function loadInputSourceMaps(taskFile, bundleFile, externalSourceMapFile) {
|
|
277
293
|
if ((0, WebToolkit_1.isGwtBundle)(bundleFile)) {
|
|
278
294
|
return (0, WebToolkit_1.loadInputSourceMapsGwt)(taskFile, bundleFile);
|
|
@@ -303,7 +319,6 @@ function loadInputSourceMap(inputSource, taskFile, externalSourceMapFile) {
|
|
|
303
319
|
return sourceMapFromCodeComment(inputSource, taskFile);
|
|
304
320
|
}
|
|
305
321
|
}
|
|
306
|
-
exports.loadInputSourceMap = loadInputSourceMap;
|
|
307
322
|
/**
|
|
308
323
|
* Extract a sourcemap for a given code comment.
|
|
309
324
|
*
|
|
@@ -351,7 +366,6 @@ function sourceMapFromCodeComment(sourcecode, sourceFilePath) {
|
|
|
351
366
|
return undefined;
|
|
352
367
|
}
|
|
353
368
|
}
|
|
354
|
-
exports.sourceMapFromCodeComment = sourceMapFromCodeComment;
|
|
355
369
|
function writeToFile(filePath, fileContent) {
|
|
356
370
|
mkdirp.sync(path.dirname(filePath));
|
|
357
371
|
fs.writeFileSync(filePath, fileContent);
|