checkly 0.0.0-pr.686.4c0f5e3
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 +43 -0
- package/bin/dev +17 -0
- package/bin/run +5 -0
- package/bin/run.cmd +3 -0
- package/constructs.d.ts +1 -0
- package/constructs.js +1 -0
- package/dist/auth/index.d.ts +15 -0
- package/dist/auth/index.js +228 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/commands/authCommand.d.ts +5 -0
- package/dist/commands/authCommand.js +14 -0
- package/dist/commands/authCommand.js.map +1 -0
- package/dist/commands/baseCommand.d.ts +9 -0
- package/dist/commands/baseCommand.js +21 -0
- package/dist/commands/baseCommand.js.map +1 -0
- package/dist/commands/deploy.d.ts +13 -0
- package/dist/commands/deploy.js +171 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/destroy.d.ts +10 -0
- package/dist/commands/destroy.js +47 -0
- package/dist/commands/destroy.js.map +1 -0
- package/dist/commands/env/add.d.ts +13 -0
- package/dist/commands/env/add.js +54 -0
- package/dist/commands/env/add.js.map +1 -0
- package/dist/commands/env/ls.d.ts +6 -0
- package/dist/commands/env/ls.js +21 -0
- package/dist/commands/env/ls.js.map +1 -0
- package/dist/commands/env/pull.d.ts +12 -0
- package/dist/commands/env/pull.js +63 -0
- package/dist/commands/env/pull.js.map +1 -0
- package/dist/commands/env/rm.d.ts +12 -0
- package/dist/commands/env/rm.js +56 -0
- package/dist/commands/env/rm.js.map +1 -0
- package/dist/commands/env/update.d.ts +13 -0
- package/dist/commands/env/update.js +54 -0
- package/dist/commands/env/update.js.map +1 -0
- package/dist/commands/login.d.ts +13 -0
- package/dist/commands/login.js +129 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +9 -0
- package/dist/commands/logout.js +40 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/runtimes.d.ts +6 -0
- package/dist/commands/runtimes.js +26 -0
- package/dist/commands/runtimes.js.map +1 -0
- package/dist/commands/switch.d.ts +9 -0
- package/dist/commands/switch.js +59 -0
- package/dist/commands/switch.js.map +1 -0
- package/dist/commands/test.d.ts +36 -0
- package/dist/commands/test.js +237 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/trigger.d.ts +32 -0
- package/dist/commands/trigger.js +173 -0
- package/dist/commands/trigger.js.map +1 -0
- package/dist/commands/whoami.d.ts +6 -0
- package/dist/commands/whoami.js +16 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -0
- package/dist/constructs/alert-channel-subscription.d.ts +44 -0
- package/dist/constructs/alert-channel-subscription.js +39 -0
- package/dist/constructs/alert-channel-subscription.js.map +1 -0
- package/dist/constructs/alert-channel.d.ts +53 -0
- package/dist/constructs/alert-channel.js +55 -0
- package/dist/constructs/alert-channel.js.map +1 -0
- package/dist/constructs/api-check.d.ts +179 -0
- package/dist/constructs/api-check.js +248 -0
- package/dist/constructs/api-check.js.map +1 -0
- package/dist/constructs/browser-check.d.ts +59 -0
- package/dist/constructs/browser-check.js +102 -0
- package/dist/constructs/browser-check.js.map +1 -0
- package/dist/constructs/check-group.d.ts +116 -0
- package/dist/constructs/check-group.js +113 -0
- package/dist/constructs/check-group.js.map +1 -0
- package/dist/constructs/check.d.ts +111 -0
- package/dist/constructs/check.js +88 -0
- package/dist/constructs/check.js.map +1 -0
- package/dist/constructs/construct.d.ts +17 -0
- package/dist/constructs/construct.js +22 -0
- package/dist/constructs/construct.js.map +1 -0
- package/dist/constructs/email-alert-channel.d.ts +26 -0
- package/dist/constructs/email-alert-channel.js +37 -0
- package/dist/constructs/email-alert-channel.js.map +1 -0
- package/dist/constructs/environment-variable.d.ts +2 -0
- package/dist/constructs/environment-variable.js +3 -0
- package/dist/constructs/environment-variable.js.map +1 -0
- package/dist/constructs/frequency.d.ts +20 -0
- package/dist/constructs/frequency.js +26 -0
- package/dist/constructs/frequency.js.map +1 -0
- package/dist/constructs/http-header.d.ts +2 -0
- package/dist/constructs/http-header.js +3 -0
- package/dist/constructs/http-header.js.map +1 -0
- package/dist/constructs/index.d.ts +15 -0
- package/dist/constructs/index.js +32 -0
- package/dist/constructs/index.js.map +1 -0
- package/dist/constructs/key-value-pair.d.ts +5 -0
- package/dist/constructs/key-value-pair.js +3 -0
- package/dist/constructs/key-value-pair.js.map +1 -0
- package/dist/constructs/opsgenie-alert-channel.d.ts +45 -0
- package/dist/constructs/opsgenie-alert-channel.js +44 -0
- package/dist/constructs/opsgenie-alert-channel.js.map +1 -0
- package/dist/constructs/pagerduty-alert-channel.d.ts +39 -0
- package/dist/constructs/pagerduty-alert-channel.js +42 -0
- package/dist/constructs/pagerduty-alert-channel.js.map +1 -0
- package/dist/constructs/project.d.ts +57 -0
- package/dist/constructs/project.js +100 -0
- package/dist/constructs/project.js.map +1 -0
- package/dist/constructs/query-param.d.ts +2 -0
- package/dist/constructs/query-param.js +3 -0
- package/dist/constructs/query-param.js.map +1 -0
- package/dist/constructs/ref.d.ts +5 -0
- package/dist/constructs/ref.js +13 -0
- package/dist/constructs/ref.js.map +1 -0
- package/dist/constructs/slack-alert-channel.d.ts +26 -0
- package/dist/constructs/slack-alert-channel.js +40 -0
- package/dist/constructs/slack-alert-channel.js.map +1 -0
- package/dist/constructs/sms-alert-channel.d.ts +27 -0
- package/dist/constructs/sms-alert-channel.js +38 -0
- package/dist/constructs/sms-alert-channel.js.map +1 -0
- package/dist/constructs/validator-error.d.ts +2 -0
- package/dist/constructs/validator-error.js +7 -0
- package/dist/constructs/validator-error.js.map +1 -0
- package/dist/constructs/webhook-alert-channel.d.ts +59 -0
- package/dist/constructs/webhook-alert-channel.js +50 -0
- package/dist/constructs/webhook-alert-channel.js.map +1 -0
- package/dist/help/examples.d.ts +6 -0
- package/dist/help/examples.js +22 -0
- package/dist/help/examples.js.map +1 -0
- package/dist/help/help-extension.d.ts +4 -0
- package/dist/help/help-extension.js +41 -0
- package/dist/help/help-extension.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/messages/common-messages.d.ts +5 -0
- package/dist/messages/common-messages.js +9 -0
- package/dist/messages/common-messages.js.map +1 -0
- package/dist/reporters/abstract-list.d.ts +35 -0
- package/dist/reporters/abstract-list.js +135 -0
- package/dist/reporters/abstract-list.js.map +1 -0
- package/dist/reporters/ci.d.ts +12 -0
- package/dist/reporters/ci.js +29 -0
- package/dist/reporters/ci.js.map +1 -0
- package/dist/reporters/dot.d.ts +12 -0
- package/dist/reporters/dot.js +28 -0
- package/dist/reporters/dot.js.map +1 -0
- package/dist/reporters/github.d.ts +34 -0
- package/dist/reporters/github.js +95 -0
- package/dist/reporters/github.js.map +1 -0
- package/dist/reporters/list.d.ts +14 -0
- package/dist/reporters/list.js +56 -0
- package/dist/reporters/list.js.map +1 -0
- package/dist/reporters/reporter.d.ts +15 -0
- package/dist/reporters/reporter.js +23 -0
- package/dist/reporters/reporter.js.map +1 -0
- package/dist/reporters/util.d.ts +15 -0
- package/dist/reporters/util.js +283 -0
- package/dist/reporters/util.js.map +1 -0
- package/dist/rest/accounts.d.ts +12 -0
- package/dist/rest/accounts.js +15 -0
- package/dist/rest/accounts.js.map +1 -0
- package/dist/rest/api.d.ts +27 -0
- package/dist/rest/api.js +90 -0
- package/dist/rest/api.js.map +1 -0
- package/dist/rest/assets.d.ts +13 -0
- package/dist/rest/assets.js +30 -0
- package/dist/rest/assets.js.map +1 -0
- package/dist/rest/environment-variables.d.ts +16 -0
- package/dist/rest/environment-variables.js +25 -0
- package/dist/rest/environment-variables.js.map +1 -0
- package/dist/rest/locations.d.ts +11 -0
- package/dist/rest/locations.js +12 -0
- package/dist/rest/locations.js.map +1 -0
- package/dist/rest/private-locations.d.ts +11 -0
- package/dist/rest/private-locations.js +12 -0
- package/dist/rest/private-locations.js.map +1 -0
- package/dist/rest/projects.d.ts +43 -0
- package/dist/rest/projects.js +24 -0
- package/dist/rest/projects.js.map +1 -0
- package/dist/rest/runtimes.d.ts +15 -0
- package/dist/rest/runtimes.js +15 -0
- package/dist/rest/runtimes.js.map +1 -0
- package/dist/rest/test-sessions.d.ts +57 -0
- package/dist/rest/test-sessions.js +21 -0
- package/dist/rest/test-sessions.js.map +1 -0
- package/dist/rest/users.d.ts +12 -0
- package/dist/rest/users.js +12 -0
- package/dist/rest/users.js.map +1 -0
- package/dist/services/abstract-check-runner.d.ts +55 -0
- package/dist/services/abstract-check-runner.js +154 -0
- package/dist/services/abstract-check-runner.js.map +1 -0
- package/dist/services/check-parser/collector.d.ts +33 -0
- package/dist/services/check-parser/collector.js +48 -0
- package/dist/services/check-parser/collector.js.map +1 -0
- package/dist/services/check-parser/errors.d.ts +8 -0
- package/dist/services/check-parser/errors.js +45 -0
- package/dist/services/check-parser/errors.js.map +1 -0
- package/dist/services/check-parser/parser.d.ts +39 -0
- package/dist/services/check-parser/parser.js +296 -0
- package/dist/services/check-parser/parser.js.map +1 -0
- package/dist/services/checkly-config-loader.d.ts +54 -0
- package/dist/services/checkly-config-loader.js +55 -0
- package/dist/services/checkly-config-loader.js.map +1 -0
- package/dist/services/config.d.ts +24 -0
- package/dist/services/config.js +75 -0
- package/dist/services/config.js.map +1 -0
- package/dist/services/project-parser.d.ts +19 -0
- package/dist/services/project-parser.js +87 -0
- package/dist/services/project-parser.js.map +1 -0
- package/dist/services/socket-client.d.ts +4 -0
- package/dist/services/socket-client.js +20 -0
- package/dist/services/socket-client.js.map +1 -0
- package/dist/services/test-filters.d.ts +2 -0
- package/dist/services/test-filters.js +16 -0
- package/dist/services/test-filters.js.map +1 -0
- package/dist/services/test-runner.d.ts +21 -0
- package/dist/services/test-runner.js +50 -0
- package/dist/services/test-runner.js.map +1 -0
- package/dist/services/trigger-runner.d.ts +26 -0
- package/dist/services/trigger-runner.js +47 -0
- package/dist/services/trigger-runner.js.map +1 -0
- package/dist/services/util.d.ts +30 -0
- package/dist/services/util.js +157 -0
- package/dist/services/util.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/oclif.manifest.json +527 -0
- package/package.json +174 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Events = void 0;
|
|
4
|
+
const api_1 = require("../rest/api");
|
|
5
|
+
const socket_client_1 = require("./socket-client");
|
|
6
|
+
const p_queue_1 = require("p-queue");
|
|
7
|
+
const uuid = require("uuid");
|
|
8
|
+
const node_events_1 = require("node:events");
|
|
9
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
10
|
+
var Events;
|
|
11
|
+
(function (Events) {
|
|
12
|
+
Events["CHECK_REGISTERED"] = "CHECK_REGISTERED";
|
|
13
|
+
Events["CHECK_INPROGRESS"] = "CHECK_INPROGRESS";
|
|
14
|
+
Events["CHECK_FAILED"] = "CHECK_FAILED";
|
|
15
|
+
Events["CHECK_SUCCESSFUL"] = "CHECK_SUCCESSFUL";
|
|
16
|
+
Events["CHECK_FINISHED"] = "CHECK_FINISHED";
|
|
17
|
+
Events["RUN_STARTED"] = "RUN_STARTED";
|
|
18
|
+
Events["RUN_FINISHED"] = "RUN_FINISHED";
|
|
19
|
+
Events["ERROR"] = "ERROR";
|
|
20
|
+
})(Events = exports.Events || (exports.Events = {}));
|
|
21
|
+
class AbstractCheckRunner extends node_events_1.EventEmitter {
|
|
22
|
+
constructor(accountId, timeout, verbose) {
|
|
23
|
+
super();
|
|
24
|
+
this.checks = new Map();
|
|
25
|
+
this.timeouts = new Map();
|
|
26
|
+
this.queue = new p_queue_1.default({ autoStart: false, concurrency: 1 });
|
|
27
|
+
this.timeout = timeout;
|
|
28
|
+
this.verbose = verbose;
|
|
29
|
+
this.accountId = accountId;
|
|
30
|
+
}
|
|
31
|
+
async run() {
|
|
32
|
+
let socketClient = null;
|
|
33
|
+
try {
|
|
34
|
+
socketClient = await socket_client_1.SocketClient.connect();
|
|
35
|
+
const checkRunSuiteId = uuid.v4();
|
|
36
|
+
// Configure the socket listener and allChecksFinished listener before starting checks to avoid race conditions
|
|
37
|
+
await this.configureResultListener(checkRunSuiteId, socketClient);
|
|
38
|
+
const { testSessionId, checks } = await this.scheduleChecks(checkRunSuiteId);
|
|
39
|
+
this.testSessionId = testSessionId;
|
|
40
|
+
this.checks = new Map(checks.map(({ check, checkRunId, testResultId }) => [checkRunId, { check, testResultId }]));
|
|
41
|
+
// `processMessage()` assumes that `this.timeouts` always has an entry for non-timed-out checks.
|
|
42
|
+
// To ensure that this is the case, we call `setAllTimeouts()` before `queue.start()`.
|
|
43
|
+
// Otherwise, we risk a race condition where check results are received before the timeout is set.
|
|
44
|
+
// This would cause `processMessage()` to mistakenly skip check results and consider the checks timed-out.
|
|
45
|
+
this.setAllTimeouts();
|
|
46
|
+
// `allChecksFinished` should be started before processing check results in `queue.start()`.
|
|
47
|
+
// Otherwise, there could be a race condition causing check results to be missed by `allChecksFinished()`.
|
|
48
|
+
const allChecksFinished = this.allChecksFinished();
|
|
49
|
+
// Start the queue after the test session run rest call is completed to avoid race conditions
|
|
50
|
+
this.queue.start();
|
|
51
|
+
/// / Need to structure the checks depending on how it went
|
|
52
|
+
this.emit(Events.RUN_STARTED, checks, testSessionId);
|
|
53
|
+
await allChecksFinished;
|
|
54
|
+
this.emit(Events.RUN_FINISHED, testSessionId);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
this.disableAllTimeouts();
|
|
58
|
+
this.emit(Events.ERROR, err);
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
if (socketClient) {
|
|
62
|
+
await socketClient.end();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async configureResultListener(checkRunSuiteId, socketClient) {
|
|
67
|
+
socketClient.on('message', (topic, rawMessage) => {
|
|
68
|
+
const message = JSON.parse(rawMessage.toString('utf8'));
|
|
69
|
+
const topicComponents = topic.split('/');
|
|
70
|
+
const checkRunId = topicComponents[4];
|
|
71
|
+
const subtopic = topicComponents[5];
|
|
72
|
+
this.queue.add(() => this.processMessage(checkRunId, subtopic, message));
|
|
73
|
+
});
|
|
74
|
+
await socketClient.subscribe(`account/${this.accountId}/ad-hoc-check-results/${checkRunSuiteId}/+/+`);
|
|
75
|
+
}
|
|
76
|
+
async processMessage(checkRunId, subtopic, message) {
|
|
77
|
+
if (!this.timeouts.has(checkRunId)) {
|
|
78
|
+
// The check has already timed out. We return early to avoid reporting a duplicate result.
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (!this.checks.get(checkRunId)) {
|
|
82
|
+
// The check has no checkRunId associated.
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const { check, testResultId } = this.checks.get(checkRunId);
|
|
86
|
+
if (subtopic === 'run-start') {
|
|
87
|
+
this.emit(Events.CHECK_INPROGRESS, check);
|
|
88
|
+
}
|
|
89
|
+
else if (subtopic === 'run-end') {
|
|
90
|
+
this.disableTimeout(checkRunId);
|
|
91
|
+
const { result } = message;
|
|
92
|
+
const { region, logPath, checkRunDataPath, } = result.assets;
|
|
93
|
+
if (logPath && (this.verbose || result.hasFailures)) {
|
|
94
|
+
result.logs = await api_1.assets.getLogs(region, logPath);
|
|
95
|
+
}
|
|
96
|
+
if (checkRunDataPath && (this.verbose || result.hasFailures)) {
|
|
97
|
+
result.checkRunData = await api_1.assets.getCheckRunData(region, checkRunDataPath);
|
|
98
|
+
}
|
|
99
|
+
const links = testResultId && result.hasFailures && await this.getShortLinks(testResultId);
|
|
100
|
+
this.emit(Events.CHECK_SUCCESSFUL, checkRunId, check, result, links);
|
|
101
|
+
this.emit(Events.CHECK_FINISHED, check);
|
|
102
|
+
}
|
|
103
|
+
else if (subtopic === 'error') {
|
|
104
|
+
this.disableTimeout(checkRunId);
|
|
105
|
+
this.emit(Events.CHECK_FAILED, checkRunId, check, message);
|
|
106
|
+
this.emit(Events.CHECK_FINISHED, check);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
allChecksFinished() {
|
|
110
|
+
let finishedCheckCount = 0;
|
|
111
|
+
const numChecks = this.checks.size;
|
|
112
|
+
if (numChecks === 0) {
|
|
113
|
+
return Promise.resolve();
|
|
114
|
+
}
|
|
115
|
+
return new Promise((resolve) => {
|
|
116
|
+
this.on(Events.CHECK_FINISHED, () => {
|
|
117
|
+
finishedCheckCount++;
|
|
118
|
+
if (finishedCheckCount === numChecks)
|
|
119
|
+
resolve();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
setAllTimeouts() {
|
|
124
|
+
Array.from(this.checks.entries()).forEach(([checkRunId, { check }]) => this.timeouts.set(checkRunId, setTimeout(() => {
|
|
125
|
+
this.timeouts.delete(checkRunId);
|
|
126
|
+
this.emit(Events.CHECK_FAILED, check, `Reached timeout of ${this.timeout} seconds waiting for check result.`);
|
|
127
|
+
this.emit(Events.CHECK_FINISHED, check);
|
|
128
|
+
}, this.timeout * 1000)));
|
|
129
|
+
}
|
|
130
|
+
disableAllTimeouts() {
|
|
131
|
+
if (!this.checks) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
Array.from(this.checks.entries()).forEach(([checkRunId]) => this.disableTimeout(checkRunId));
|
|
135
|
+
}
|
|
136
|
+
disableTimeout(checkRunId) {
|
|
137
|
+
const timeout = this.timeouts.get(checkRunId);
|
|
138
|
+
clearTimeout(timeout);
|
|
139
|
+
this.timeouts.delete(checkRunId);
|
|
140
|
+
}
|
|
141
|
+
async getShortLinks(testResultId) {
|
|
142
|
+
try {
|
|
143
|
+
if (!this.testSessionId) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const { data: links } = await api_1.testSessions.getResultShortLinks(this.testSessionId, testResultId);
|
|
147
|
+
return links;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
exports.default = AbstractCheckRunner;
|
|
154
|
+
//# sourceMappingURL=abstract-check-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstract-check-runner.js","sourceRoot":"","sources":["../../src/services/abstract-check-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type UnsupportedNpmDependencies = {
|
|
2
|
+
file: string;
|
|
3
|
+
unsupportedDependencies: string[];
|
|
4
|
+
};
|
|
5
|
+
export type ParseError = {
|
|
6
|
+
file: string;
|
|
7
|
+
error: string;
|
|
8
|
+
};
|
|
9
|
+
export declare class Collector {
|
|
10
|
+
entrypoint: string;
|
|
11
|
+
entrypointContent: string;
|
|
12
|
+
missingFiles: string[];
|
|
13
|
+
parseErrors: ParseError[];
|
|
14
|
+
unsupportedNpmDependencies: UnsupportedNpmDependencies[];
|
|
15
|
+
dependencies: Map<string, string>;
|
|
16
|
+
constructor(entrypoint: string, entrypointContent: string);
|
|
17
|
+
hasDependency(path: string): boolean;
|
|
18
|
+
addDependency(path: string, content: string): void;
|
|
19
|
+
addUnsupportedNpmDependencies(file: string, unsupportedDependencies: string[]): void;
|
|
20
|
+
addParsingError(file: string, message: string): void;
|
|
21
|
+
addMissingFile(filePath: string): void;
|
|
22
|
+
validate(): void;
|
|
23
|
+
getItems(): {
|
|
24
|
+
entrypoint: {
|
|
25
|
+
filePath: string;
|
|
26
|
+
content: string;
|
|
27
|
+
};
|
|
28
|
+
dependencies: {
|
|
29
|
+
filePath: string;
|
|
30
|
+
content: string;
|
|
31
|
+
}[];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Collector = void 0;
|
|
4
|
+
const errors_1 = require("./errors");
|
|
5
|
+
class Collector {
|
|
6
|
+
constructor(entrypoint, entrypointContent) {
|
|
7
|
+
this.missingFiles = [];
|
|
8
|
+
this.parseErrors = [];
|
|
9
|
+
this.unsupportedNpmDependencies = [];
|
|
10
|
+
this.dependencies = new Map();
|
|
11
|
+
this.entrypoint = entrypoint;
|
|
12
|
+
this.entrypointContent = entrypointContent;
|
|
13
|
+
}
|
|
14
|
+
hasDependency(path) {
|
|
15
|
+
return this.dependencies.has(path);
|
|
16
|
+
}
|
|
17
|
+
addDependency(path, content) {
|
|
18
|
+
this.dependencies.set(path, content);
|
|
19
|
+
}
|
|
20
|
+
addUnsupportedNpmDependencies(file, unsupportedDependencies) {
|
|
21
|
+
this.unsupportedNpmDependencies.push({ file, unsupportedDependencies });
|
|
22
|
+
}
|
|
23
|
+
addParsingError(file, message) {
|
|
24
|
+
this.parseErrors.push({ file, error: message });
|
|
25
|
+
}
|
|
26
|
+
addMissingFile(filePath) {
|
|
27
|
+
this.missingFiles.push(filePath);
|
|
28
|
+
}
|
|
29
|
+
validate() {
|
|
30
|
+
if (this.missingFiles.length || this.parseErrors.length || this.unsupportedNpmDependencies.length) {
|
|
31
|
+
throw new errors_1.DependencyParseError(this.entrypoint, this.missingFiles, this.unsupportedNpmDependencies, this.parseErrors);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
getItems() {
|
|
35
|
+
return {
|
|
36
|
+
entrypoint: {
|
|
37
|
+
filePath: this.entrypoint,
|
|
38
|
+
content: this.entrypointContent,
|
|
39
|
+
},
|
|
40
|
+
dependencies: Array.from(this.dependencies.entries(), ([key, value]) => ({
|
|
41
|
+
filePath: key,
|
|
42
|
+
content: value,
|
|
43
|
+
})),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.Collector = Collector;
|
|
48
|
+
//# sourceMappingURL=collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector.js","sourceRoot":"","sources":["../../../src/services/check-parser/collector.ts"],"names":[],"mappings":";;;AAAA,qCAA+C;AAY/C,MAAa,SAAS;IAQpB,YAAa,UAAkB,EAAE,iBAAyB;QAL1D,iBAAY,GAAa,EAAE,CAAA;QAC3B,gBAAW,GAAiB,EAAE,CAAA;QAC9B,+BAA0B,GAAiC,EAAE,CAAA;QAC7D,iBAAY,GAAG,IAAI,GAAG,EAAkB,CAAA;QAGtC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAA;IAC5C,CAAC;IAED,aAAa,CAAE,IAAY;QACzB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,aAAa,CAAE,IAAY,EAAE,OAAe;QAC1C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACtC,CAAC;IAED,6BAA6B,CAAE,IAAY,EAAE,uBAAiC;QAC5E,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,eAAe,CAAE,IAAY,EAAE,OAAe;QAC5C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;IACjD,CAAC;IAED,cAAc,CAAE,QAAgB;QAC9B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAClC,CAAC;IAED,QAAQ;QACN,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE;YACjG,MAAM,IAAI,6BAAoB,CAC5B,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,0BAA0B,EAC/B,IAAI,CAAC,WAAW,CACjB,CAAA;SACF;IACH,CAAC;IAED,QAAQ;QACN,OAAO;YACL,UAAU,EAAE;gBACV,QAAQ,EAAE,IAAI,CAAC,UAAU;gBACzB,OAAO,EAAE,IAAI,CAAC,iBAAiB;aAChC;YACD,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;gBACvE,QAAQ,EAAE,GAAG;gBACb,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;CACF;AAxDD,8BAwDC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ParseError, UnsupportedNpmDependencies } from './collector';
|
|
2
|
+
export declare class DependencyParseError extends Error {
|
|
3
|
+
entrypoint: string;
|
|
4
|
+
missingFiles: string[];
|
|
5
|
+
unsupportedNpmDependencies: UnsupportedNpmDependencies[];
|
|
6
|
+
parseErrors: ParseError[];
|
|
7
|
+
constructor(entrypoint: string, missingFiles: string[], unsupportedNpmDependencies: UnsupportedNpmDependencies[], parseErrors: ParseError[]);
|
|
8
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DependencyParseError = void 0;
|
|
4
|
+
class DependencyParseError extends Error {
|
|
5
|
+
constructor(entrypoint, missingFiles, unsupportedNpmDependencies, parseErrors) {
|
|
6
|
+
let message = `Encountered an error parsing check files for ${entrypoint}.`;
|
|
7
|
+
if (missingFiles.length) {
|
|
8
|
+
message += '\n\nThe following dependencies weren\'t found:\n';
|
|
9
|
+
for (const missingFile of missingFiles) {
|
|
10
|
+
message += `\t${missingFile}\n`;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (unsupportedNpmDependencies.length) {
|
|
14
|
+
if (unsupportedNpmDependencies.some(d => d.unsupportedDependencies.some(ud => ud === 'checkly/constructs'))) {
|
|
15
|
+
message += '\n\nIt looks like you\'re trying to use checkly/constructs in a browser check file. ' +
|
|
16
|
+
'checkly/constructs should only be used in check files: files ending in .check.ts and .check.js, ' +
|
|
17
|
+
'or the checkMatch pattern set in your configuration. For more information see on the difference between ' +
|
|
18
|
+
'test files and check files, see https://www.checklyhq.com/docs/cli/\n';
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
message += '\n\nThe following NPM dependencies were used, but aren\'t supported in the runtimes.\n';
|
|
22
|
+
message += 'For more information, see https://www.checklyhq.com/docs/runtimes/.\n';
|
|
23
|
+
for (const { file, unsupportedDependencies } of unsupportedNpmDependencies) {
|
|
24
|
+
message += `\t${file} imports unsupported dependencies:\n`;
|
|
25
|
+
for (const unsupportedDependency of unsupportedDependencies) {
|
|
26
|
+
message += `\t\t${unsupportedDependency}\n`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (parseErrors.length) {
|
|
32
|
+
message += '\n\nThe following files couldn\'t be parsed:\n';
|
|
33
|
+
for (const { file, error } of parseErrors) {
|
|
34
|
+
message += `\t${file} - ${error}\n`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
super(message);
|
|
38
|
+
this.entrypoint = entrypoint;
|
|
39
|
+
this.missingFiles = missingFiles;
|
|
40
|
+
this.unsupportedNpmDependencies = unsupportedNpmDependencies;
|
|
41
|
+
this.parseErrors = parseErrors;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.DependencyParseError = DependencyParseError;
|
|
45
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/services/check-parser/errors.ts"],"names":[],"mappings":";;;AAEA,MAAa,oBAAqB,SAAQ,KAAK;IAK7C,YACE,UAAkB,EAClB,YAAsB,EACtB,0BAAwD,EACxD,WAAyB;QAEzB,IAAI,OAAO,GAAG,gDAAgD,UAAU,GAAG,CAAA;QAC3E,IAAI,YAAY,CAAC,MAAM,EAAE;YACvB,OAAO,IAAI,kDAAkD,CAAA;YAC7D,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE;gBACtC,OAAO,IAAI,KAAK,WAAW,IAAI,CAAA;aAChC;SACF;QACD,IAAI,0BAA0B,CAAC,MAAM,EAAE;YACrC,IAAI,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,EAAE;gBAC3G,OAAO,IAAI,sFAAsF;oBAC/F,kGAAkG;oBAClG,0GAA0G;oBAC1G,uEAAuE,CAAA;aAC1E;iBAAM;gBACL,OAAO,IAAI,wFAAwF,CAAA;gBACnG,OAAO,IAAI,uEAAuE,CAAA;gBAClF,KAAK,MAAM,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,0BAA0B,EAAE;oBAC1E,OAAO,IAAI,KAAK,IAAI,sCAAsC,CAAA;oBAC1D,KAAK,MAAM,qBAAqB,IAAI,uBAAuB,EAAE;wBAC3D,OAAO,IAAI,OAAO,qBAAqB,IAAI,CAAA;qBAC5C;iBACF;aACF;SACF;QACD,IAAI,WAAW,CAAC,MAAM,EAAE;YACtB,OAAO,IAAI,gDAAgD,CAAA;YAC3D,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,WAAW,EAAE;gBACzC,OAAO,IAAI,KAAK,IAAI,MAAM,KAAK,IAAI,CAAA;aACpC;SACF;QACD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;QAChC,IAAI,CAAC,0BAA0B,GAAG,0BAA0B,CAAA;QAC5D,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;IAChC,CAAC;CACF;AA/CD,oDA+CC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
type Module = {
|
|
2
|
+
localDependencies: Array<string>;
|
|
3
|
+
npmDependencies: Array<string>;
|
|
4
|
+
};
|
|
5
|
+
type SupportedFileExtension = '.js' | '.ts';
|
|
6
|
+
declare const JS_RESOLVE_ORDER: string[];
|
|
7
|
+
declare const TS_RESOLVE_ORDER: string[];
|
|
8
|
+
export declare class Parser {
|
|
9
|
+
supportedModules: Set<string>;
|
|
10
|
+
constructor(supportedNpmModules: Array<string>);
|
|
11
|
+
parse(entrypoint: string): {
|
|
12
|
+
entrypoint: {
|
|
13
|
+
filePath: string;
|
|
14
|
+
content: string;
|
|
15
|
+
};
|
|
16
|
+
dependencies: {
|
|
17
|
+
filePath: string;
|
|
18
|
+
content: string;
|
|
19
|
+
}[];
|
|
20
|
+
};
|
|
21
|
+
static readDependency(filePath: string, preferedExtenstion: SupportedFileExtension): {
|
|
22
|
+
filePath: string;
|
|
23
|
+
content: string;
|
|
24
|
+
}[];
|
|
25
|
+
static tryReadFileExt(filePath: string, exts: typeof JS_RESOLVE_ORDER | typeof TS_RESOLVE_ORDER): {
|
|
26
|
+
filePath: string;
|
|
27
|
+
content: string;
|
|
28
|
+
}[];
|
|
29
|
+
static parseDependencies(filePath: string, contents: string): {
|
|
30
|
+
module: Module;
|
|
31
|
+
error?: any;
|
|
32
|
+
};
|
|
33
|
+
static jsNodeVisitor(localDependencies: Set<string>, npmDependencies: Set<string>): any;
|
|
34
|
+
static tsNodeVisitor(tsParser: any, localDependencies: Set<string>, npmDependencies: Set<string>): any;
|
|
35
|
+
static isRequireExpression(node: any): boolean;
|
|
36
|
+
static getRequireStringArg(node: any): string | null;
|
|
37
|
+
static registerDependency(importArg: string | null, localDependencies: Set<string>, npmDependencies: Set<string>): void;
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Parser = void 0;
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const acorn = require("acorn");
|
|
7
|
+
const walk = require("acorn-walk");
|
|
8
|
+
const collector_1 = require("./collector");
|
|
9
|
+
const errors_1 = require("./errors");
|
|
10
|
+
// Our custom configuration to handle walking errors
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
12
|
+
const ignore = (_node, _st, _c) => { };
|
|
13
|
+
const PACKAGE_EXTENSION = `${path.sep}package.json`;
|
|
14
|
+
const JS_RESOLVE_ORDER = [
|
|
15
|
+
'.js',
|
|
16
|
+
PACKAGE_EXTENSION,
|
|
17
|
+
`${path.sep}index.js`,
|
|
18
|
+
];
|
|
19
|
+
const TS_RESOLVE_ORDER = [
|
|
20
|
+
'.ts',
|
|
21
|
+
'.js',
|
|
22
|
+
PACKAGE_EXTENSION,
|
|
23
|
+
`${path.sep}index.ts`,
|
|
24
|
+
`${path.sep}index.js`,
|
|
25
|
+
];
|
|
26
|
+
const supportedBuiltinModules = [
|
|
27
|
+
'assert', 'buffer', 'crypto', 'dns', 'fs', 'path', 'querystring', 'readline ', 'stream', 'string_decoder',
|
|
28
|
+
'timers', 'tls', 'url', 'util', 'zlib',
|
|
29
|
+
];
|
|
30
|
+
function validateEntrypoint(entrypoint) {
|
|
31
|
+
const extension = path.extname(entrypoint);
|
|
32
|
+
if (extension !== '.js' && extension !== '.ts') {
|
|
33
|
+
throw new Error(`Unsupported file extension for ${entrypoint}`);
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const content = fs.readFileSync(entrypoint, { encoding: 'utf-8' });
|
|
37
|
+
return { extension, content };
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
throw new errors_1.DependencyParseError(entrypoint, [entrypoint], [], []);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
let tsParser;
|
|
44
|
+
function getTsParser() {
|
|
45
|
+
if (tsParser) {
|
|
46
|
+
return tsParser;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
tsParser = require('@typescript-eslint/typescript-estree');
|
|
50
|
+
const AST_NODE_TYPES = tsParser.AST_NODE_TYPES;
|
|
51
|
+
// Our custom configuration to handle walking errors
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
53
|
+
Object.values(AST_NODE_TYPES).forEach((astType) => {
|
|
54
|
+
var _a;
|
|
55
|
+
// Only handle the TS specific ones
|
|
56
|
+
if (!astType.startsWith('TS')) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
walk.base[astType] = (_a = walk.base[astType]) !== null && _a !== void 0 ? _a : ignore;
|
|
60
|
+
});
|
|
61
|
+
return tsParser;
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (err.code === 'ERR_MODULE_NOT_FOUND' || err.code === 'MODULE_NOT_FOUND') {
|
|
65
|
+
throw new Error('Please install "typescript" to use TypeScript-code in check files');
|
|
66
|
+
}
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
class Parser {
|
|
71
|
+
// TODO: pass a npm matrix of supported npm modules
|
|
72
|
+
// Maybe pass a cache so we don't have to fetch files separately all the time
|
|
73
|
+
constructor(supportedNpmModules) {
|
|
74
|
+
this.supportedModules = new Set([...supportedBuiltinModules, ...supportedNpmModules]);
|
|
75
|
+
}
|
|
76
|
+
parse(entrypoint) {
|
|
77
|
+
const { extension, content } = validateEntrypoint(entrypoint);
|
|
78
|
+
/*
|
|
79
|
+
* The importing of files forms a directed graph.
|
|
80
|
+
* Vertices are source files and edges are from importing other files.
|
|
81
|
+
* We can find all of the files we need to run the check by traversing this graph.
|
|
82
|
+
* In this implementation, we use breadth first search.
|
|
83
|
+
*/
|
|
84
|
+
const collector = new collector_1.Collector(entrypoint, content);
|
|
85
|
+
const bfsQueue = [{ filePath: entrypoint, content }];
|
|
86
|
+
while (bfsQueue.length > 0) {
|
|
87
|
+
// Since we just checked the length, shift() will never return undefined.
|
|
88
|
+
// We can add a not-null assertion operator (!).
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
90
|
+
const item = bfsQueue.shift();
|
|
91
|
+
if (item.filePath.endsWith(PACKAGE_EXTENSION)) {
|
|
92
|
+
// Holds info about the main file and doesn't need to be parsed
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const { module, error } = Parser.parseDependencies(item.filePath, item.content);
|
|
96
|
+
if (error) {
|
|
97
|
+
collector.addParsingError(item.filePath, error.message);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const unsupportedDependencies = module.npmDependencies.filter((dep) => !this.supportedModules.has(dep));
|
|
101
|
+
if (unsupportedDependencies.length) {
|
|
102
|
+
collector.addUnsupportedNpmDependencies(item.filePath, unsupportedDependencies);
|
|
103
|
+
}
|
|
104
|
+
const localDependenciesResolvedPaths = [];
|
|
105
|
+
module.localDependencies.forEach((localDependency) => {
|
|
106
|
+
const filePath = path.join(path.dirname(item.filePath), localDependency);
|
|
107
|
+
try {
|
|
108
|
+
const deps = Parser.readDependency(filePath, extension);
|
|
109
|
+
localDependenciesResolvedPaths.push(...deps);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
collector.addMissingFile(filePath);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
localDependenciesResolvedPaths.forEach(({ filePath, content }) => {
|
|
116
|
+
if (collector.hasDependency(filePath)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
collector.addDependency(filePath, content);
|
|
120
|
+
bfsQueue.push({ filePath, content });
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
collector.validate();
|
|
124
|
+
return collector.getItems();
|
|
125
|
+
}
|
|
126
|
+
static readDependency(filePath, preferedExtenstion) {
|
|
127
|
+
// Read the specific file if it has an extension
|
|
128
|
+
if (preferedExtenstion === '.js') {
|
|
129
|
+
return Parser.tryReadFileExt(filePath, JS_RESOLVE_ORDER);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
return Parser.tryReadFileExt(filePath, TS_RESOLVE_ORDER);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
static tryReadFileExt(filePath, exts) {
|
|
136
|
+
for (const extension of ['', ...exts]) {
|
|
137
|
+
try {
|
|
138
|
+
const deps = [];
|
|
139
|
+
const fullPath = filePath + extension;
|
|
140
|
+
const content = fs.readFileSync(fullPath, { encoding: 'utf-8' });
|
|
141
|
+
deps.push({ filePath: fullPath, content });
|
|
142
|
+
if (extension === PACKAGE_EXTENSION) {
|
|
143
|
+
const { main } = JSON.parse(content);
|
|
144
|
+
if (!main || !main.length) {
|
|
145
|
+
// No main is defined. This means package.json doesn't have a specific entry
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const mainFile = path.join(filePath, main);
|
|
149
|
+
deps.push({
|
|
150
|
+
filePath: mainFile, content: fs.readFileSync(mainFile, { encoding: 'utf-8' }),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return deps;
|
|
154
|
+
}
|
|
155
|
+
catch (err) { }
|
|
156
|
+
}
|
|
157
|
+
throw new Error(`Cannot find file ${filePath}`);
|
|
158
|
+
}
|
|
159
|
+
static parseDependencies(filePath, contents) {
|
|
160
|
+
const localDependencies = new Set();
|
|
161
|
+
const npmDependencies = new Set();
|
|
162
|
+
const extension = path.extname(filePath);
|
|
163
|
+
try {
|
|
164
|
+
if (extension === '.js') {
|
|
165
|
+
const ast = acorn.parse(contents, {
|
|
166
|
+
allowReturnOutsideFunction: true,
|
|
167
|
+
ecmaVersion: 'latest',
|
|
168
|
+
allowImportExportEverywhere: true,
|
|
169
|
+
});
|
|
170
|
+
walk.simple(ast, Parser.jsNodeVisitor(localDependencies, npmDependencies));
|
|
171
|
+
}
|
|
172
|
+
else if (extension === '.ts') {
|
|
173
|
+
const tsParser = getTsParser();
|
|
174
|
+
const ast = tsParser.parse(contents, {});
|
|
175
|
+
// The AST from typescript-estree is slightly different from the type used by acorn-walk.
|
|
176
|
+
// This doesn't actually cause problems (both are "ESTree's"), but we need to ignore type errors here.
|
|
177
|
+
// @ts-ignore
|
|
178
|
+
walk.simple(ast, Parser.tsNodeVisitor(tsParser, localDependencies, npmDependencies));
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
throw new Error(`Unsupported file extension for ${filePath}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
return {
|
|
186
|
+
module: {
|
|
187
|
+
localDependencies: Array.from(localDependencies),
|
|
188
|
+
npmDependencies: Array.from(npmDependencies),
|
|
189
|
+
},
|
|
190
|
+
error: err,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
module: {
|
|
195
|
+
localDependencies: Array.from(localDependencies),
|
|
196
|
+
npmDependencies: Array.from(npmDependencies),
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
static jsNodeVisitor(localDependencies, npmDependencies) {
|
|
201
|
+
return {
|
|
202
|
+
CallExpression(node) {
|
|
203
|
+
if (!Parser.isRequireExpression(node))
|
|
204
|
+
return;
|
|
205
|
+
const requireStringArg = Parser.getRequireStringArg(node);
|
|
206
|
+
Parser.registerDependency(requireStringArg, localDependencies, npmDependencies);
|
|
207
|
+
},
|
|
208
|
+
ImportDeclaration(node) {
|
|
209
|
+
if (node.source.type !== 'Literal')
|
|
210
|
+
return;
|
|
211
|
+
Parser.registerDependency(node.source.value, localDependencies, npmDependencies);
|
|
212
|
+
},
|
|
213
|
+
ExportNamedDeclaration(node) {
|
|
214
|
+
if (node.source === null)
|
|
215
|
+
return;
|
|
216
|
+
if (node.source.type !== 'Literal')
|
|
217
|
+
return;
|
|
218
|
+
Parser.registerDependency(node.source.value, localDependencies, npmDependencies);
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
static tsNodeVisitor(tsParser, localDependencies, npmDependencies) {
|
|
223
|
+
return {
|
|
224
|
+
ImportDeclaration(node) {
|
|
225
|
+
// For now, we only support literal strings in the import statement
|
|
226
|
+
if (node.source.type !== tsParser.TSESTree.AST_NODE_TYPES.Literal)
|
|
227
|
+
return;
|
|
228
|
+
Parser.registerDependency(node.source.value, localDependencies, npmDependencies);
|
|
229
|
+
},
|
|
230
|
+
ExportNamedDeclaration(node) {
|
|
231
|
+
// The statement isn't importing another dependency
|
|
232
|
+
if (node.source === null)
|
|
233
|
+
return;
|
|
234
|
+
// For now, we only support literal strings in the import statement
|
|
235
|
+
if (node.source.type !== tsParser.TSESTree.AST_NODE_TYPES.Literal)
|
|
236
|
+
return;
|
|
237
|
+
Parser.registerDependency(node.source.value, localDependencies, npmDependencies);
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
static isRequireExpression(node) {
|
|
242
|
+
if (node.type !== 'CallExpression') {
|
|
243
|
+
// Ignore AST nodes that aren't call expressions
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
else if (node.arguments.length === 0) {
|
|
247
|
+
// Weird case of `require()` or `module.require()` without arguments
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
else if (node.callee.type === 'Identifier') {
|
|
251
|
+
// Handle the case of a simple call to `require('dependency')`
|
|
252
|
+
return node.callee.name === 'require';
|
|
253
|
+
}
|
|
254
|
+
else if (node.callee.type === 'MemberExpression') {
|
|
255
|
+
// Handle calls to `module.require('dependency')`
|
|
256
|
+
const { object, property } = node.callee;
|
|
257
|
+
return object.type === 'Identifier' &&
|
|
258
|
+
object.name === 'module' &&
|
|
259
|
+
property.type === 'Identifier' &&
|
|
260
|
+
property.name === 'require';
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
static getRequireStringArg(node) {
|
|
267
|
+
if (node.arguments[0].type === 'Literal') {
|
|
268
|
+
return node.arguments[0].value;
|
|
269
|
+
}
|
|
270
|
+
else if (node.arguments[0].type === 'TemplateLiteral') {
|
|
271
|
+
return node.arguments[0].quasis[0].value.cooked;
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
/*
|
|
275
|
+
* It might be that `require` is called with a variable - `require(myPackage)`.
|
|
276
|
+
* Unfortunately supporting that case would be complicated.
|
|
277
|
+
* We just skip the dependency and hope that the check still works.
|
|
278
|
+
*/
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
static registerDependency(importArg, localDependencies, npmDependencies) {
|
|
283
|
+
// TODO: We currently don't support import path aliases, f.ex: `import { Something } from '@services/my-service'`
|
|
284
|
+
if (!importArg) {
|
|
285
|
+
// If there's no importArg, don't register a dependency
|
|
286
|
+
}
|
|
287
|
+
else if (importArg.startsWith('/') || importArg.startsWith('./') || importArg.startsWith('../')) {
|
|
288
|
+
localDependencies.add(importArg);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
npmDependencies.add(importArg);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
exports.Parser = Parser;
|
|
296
|
+
//# sourceMappingURL=parser.js.map
|