diff --git a/dist/index.js b/dist/index.js
index 593d2f07..fb2f2b16 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -47,10 +47,10 @@ const annotations_1 = __nccwpck_require__(31058);
async function decorateAction(analysisResult, analysis) {
let summaryBody;
if (analysisResult) {
- summaryBody = (0, summary_1.createSummaryBody)(analysisResult);
+ summaryBody = await (0, summary_1.createSummaryBody)(analysisResult);
}
else {
- summaryBody = (0, summary_1.createErrorSummaryBody)(analysis.errorList, analysis.warningList);
+ summaryBody = await (0, summary_1.createErrorSummaryBody)(analysis.errorList, analysis.warningList);
}
if (config_1.githubConfig.event.isPullRequest) {
await (0, pull_request_1.decoratePullRequest)(analysisResult?.passed ?? false, summaryBody);
@@ -71,6 +71,8 @@ async function decorateAction(analysisResult, analysis) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.generateStatusMarkdown = generateStatusMarkdown;
exports.generateExpandableAreaMarkdown = generateExpandableAreaMarkdown;
+exports.generateItalic = generateItalic;
+exports.generateComment = generateComment;
const os_1 = __nccwpck_require__(22037);
const enums_1 = __nccwpck_require__(31655);
/**
@@ -101,6 +103,20 @@ function generateStatusMarkdown(status, hasSuffix = false) {
function generateExpandableAreaMarkdown(header, body) {
return `${header}
${os_1.EOL}${body} ${os_1.EOL}${os_1.EOL}`;
}
+/**
+ * Generates italic text for markdown.
+ * @param text The text to make italic.
+ */
+function generateItalic(text, title) {
+ return `${text}`;
+}
+/**
+ * Generates a hidden comment for markdown.
+ * @param comment The text of the comment.
+ */
+function generateComment(comment) {
+ return ``;
+}
/***/ }),
@@ -201,11 +217,11 @@ const logger_1 = __nccwpck_require__(26440);
const url_1 = __nccwpck_require__(76259);
const markdown_1 = __nccwpck_require__(60517);
const config_1 = __nccwpck_require__(86444);
+const runs_1 = __nccwpck_require__(50046);
const capitalize = (s) => s && String(s[0]).toUpperCase() + String(s).slice(1);
-function createSummaryBody(analysisResult) {
+async function createSummaryBody(analysisResult) {
logger_1.logger.header('Creating summary.');
- core_1.summary.addHeading('TICS Quality Gate');
- core_1.summary.addHeading((0, markdown_1.generateStatusMarkdown)(getStatus(analysisResult.passed, analysisResult.passedWithWarning), true), 3);
+ setSummaryHeader(getStatus(analysisResult.passed, analysisResult.passedWithWarning));
analysisResult.projectResults.forEach(projectResult => {
if (projectResult.qualityGate) {
const failedOrWarnConditions = extractFailedOrWarningConditions(projectResult.qualityGate.gates);
@@ -231,6 +247,7 @@ function createSummaryBody(analysisResult) {
core_1.summary.addRaw(createFilesSummary(projectResult.analyzedFiles));
}
});
+ await setSummaryFooter();
logger_1.logger.info('Created summary.');
return core_1.summary.stringify();
}
@@ -240,10 +257,9 @@ function createSummaryBody(analysisResult) {
* @param warningList list containing all the warnings found in the TICS run.
* @returns string containing the error summary.
*/
-function createErrorSummaryBody(errorList, warningList) {
+async function createErrorSummaryBody(errorList, warningList) {
logger_1.logger.header('Creating summary.');
- core_1.summary.addHeading('TICS Quality Gate');
- core_1.summary.addHeading((0, markdown_1.generateStatusMarkdown)(enums_1.Status.FAILED, true), 3);
+ setSummaryHeader(enums_1.Status.FAILED);
if (errorList.length > 0) {
core_1.summary.addHeading('The following errors have occurred during analysis:', 2);
for (const error of errorList) {
@@ -257,6 +273,7 @@ function createErrorSummaryBody(errorList, warningList) {
core_1.summary.addRaw(`:warning: ${warning}${os_1.EOL}${os_1.EOL}`);
}
}
+ await setSummaryFooter();
logger_1.logger.info('Created summary.');
return core_1.summary.stringify();
}
@@ -265,14 +282,24 @@ function createErrorSummaryBody(errorList, warningList) {
* @param message Message to display in the body of the comment.
* @returns string containing the error summary.
*/
-function createNothingAnalyzedSummaryBody(message) {
+async function createNothingAnalyzedSummaryBody(message) {
logger_1.logger.header('Creating summary.');
- core_1.summary.addHeading('TICS Quality Gate');
- core_1.summary.addHeading((0, markdown_1.generateStatusMarkdown)(enums_1.Status.PASSED, true), 3);
+ setSummaryHeader(enums_1.Status.PASSED);
core_1.summary.addRaw(message);
+ await setSummaryFooter();
logger_1.logger.info('Created summary.');
return core_1.summary.stringify();
}
+function setSummaryHeader(status) {
+ core_1.summary.addHeading('TICS Quality Gate');
+ core_1.summary.addHeading((0, markdown_1.generateStatusMarkdown)(status, true), 3);
+}
+async function setSummaryFooter() {
+ core_1.summary.addEOL();
+ core_1.summary.addRaw('
');
+ core_1.summary.addRaw((0, markdown_1.generateItalic)(await (0, runs_1.getCurrentStepPath)(), 'Workflow / Job / Step'), true);
+ core_1.summary.addRaw((0, markdown_1.generateComment)(config_1.githubConfig.getCommentIdentifier()));
+}
function getConditionHeading(failedOrWarnConditions) {
const countFailedConditions = failedOrWarnConditions.filter(c => !c.passed).length;
const countWarnConditions = failedOrWarnConditions.filter(c => c.passed && c.passedWithWarning).length;
@@ -519,6 +546,7 @@ function findAnnotationInList(list, annotation) {
* @param unpostableReviewComments Review comments that could not be posted.
* @returns Summary of all the review comments that could not be posted.
*/
+// Exported for testing
function createUnpostableAnnotationsDetails(unpostableReviewComments) {
const label = 'Quality gate failures that cannot be annotated in Files Changed';
let body = '';
@@ -674,14 +702,14 @@ async function processIncompleteAnalysis(analysis) {
let summaryBody;
if (!analysis.completed) {
failedMessage = 'Failed to complete TICS analysis.';
- summaryBody = (0, summary_1.createErrorSummaryBody)(analysis.errorList, analysis.warningList);
+ summaryBody = await (0, summary_1.createErrorSummaryBody)(analysis.errorList, analysis.warningList);
}
else if (analysis.warningList.find(w => w.includes('[WARNING 5057]'))) {
- summaryBody = (0, summary_1.createNothingAnalyzedSummaryBody)('No changed files applicable for TICS analysis quality gating.');
+ summaryBody = await (0, summary_1.createNothingAnalyzedSummaryBody)('No changed files applicable for TICS analysis quality gating.');
}
else {
failedMessage = 'Explorer URL not returned from TICS analysis.';
- summaryBody = (0, summary_1.createErrorSummaryBody)(analysis.errorList, analysis.warningList);
+ summaryBody = await (0, summary_1.createErrorSummaryBody)(analysis.errorList, analysis.warningList);
}
if (config_1.githubConfig.event.isPullRequest) {
await (0, pull_request_1.postToConversation)(false, summaryBody);
@@ -808,13 +836,13 @@ async function qServerAnalysis() {
};
if (!verdict.passed) {
verdict.message = 'Failed to complete TICSQServer analysis.';
- const summaryBody = (0, summary_1.createErrorSummaryBody)(analysis.errorList, analysis.warningList);
+ const summaryBody = await (0, summary_1.createErrorSummaryBody)(analysis.errorList, analysis.warningList);
if (config_1.githubConfig.event.isPullRequest) {
await (0, pull_request_1.postToConversation)(false, summaryBody);
}
}
else if (analysis.warningList.find(w => w.includes('[WARNING 5057]'))) {
- const summaryBody = (0, summary_1.createNothingAnalyzedSummaryBody)('No changed files applicable for TICS analysis quality gating.');
+ const summaryBody = await (0, summary_1.createNothingAnalyzedSummaryBody)('No changed files applicable for TICS analysis quality gating.');
if (config_1.githubConfig.event.isPullRequest) {
await (0, pull_request_1.postToConversation)(false, summaryBody);
}
@@ -1024,17 +1052,29 @@ class GithubConfig {
event;
job;
action;
- id;
+ workflow;
+ runId;
+ runNumber;
+ runAttempt;
pullRequestNumber;
debugger;
+ runnerName;
+ id;
constructor() {
this.apiUrl = github_1.context.apiUrl;
this.owner = github_1.context.repo.owner;
this.reponame = github_1.context.repo.repo;
this.commitSha = github_1.context.sha;
this.event = this.getGithubEvent();
- this.job = github_1.context.job;
+ this.job = github_1.context.job.replace(/[\s|_]+/g, '-');
this.action = github_1.context.action.replace('__tiobe_', '');
+ this.workflow = github_1.context.workflow.replace(/[\s|_]+/g, '-');
+ this.runId = github_1.context.runId;
+ this.runNumber = github_1.context.runNumber;
+ this.runAttempt = parseInt(process.env.GITHUB_RUN_ATTEMPT ?? '0', 10);
+ this.pullRequestNumber = this.getPullRequestNumber();
+ this.debugger = (0, core_1.isDebug)();
+ this.runnerName = process.env.RUNNER_NAME ?? '';
/**
* Construct the id to use for storing tmpdirs. The action name will
* be appended with a number if there are multiple runs within a job.
@@ -1045,10 +1085,7 @@ class GithubConfig {
* include a suffix that consists of the sequence number preceded by an underscore.
* https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables
*/
- const runAttempt = process.env.GITHUB_RUN_ATTEMPT ?? '0';
- this.id = `${github_1.context.runId.toString()}_${runAttempt}_${this.job}_${this.action}`;
- this.pullRequestNumber = this.getPullRequestNumber();
- this.debugger = (0, core_1.isDebug)();
+ this.id = `${this.runId.toString()}_${this.runAttempt.toString()}_${this.job}_${this.action}`;
this.removeWarningListener();
}
getPullRequestNumber() {
@@ -1080,6 +1117,9 @@ class GithubConfig {
return github_event_1.GithubEvent.PUSH;
}
}
+ getCommentIdentifier() {
+ return [this.workflow, this.job, this.runNumber, this.runAttempt].join('_');
+ }
removeWarningListener() {
process.removeAllListeners('warning');
process.on('warning', warning => {
@@ -1627,7 +1667,7 @@ async function postComment(body) {
async function deletePreviousComments(comments) {
logger_1.logger.header('Deleting comments of previous runs.');
for (const comment of comments) {
- if (commentIncludesTicsTitle(comment.body)) {
+ if (shouldCommentBeDeleted(comment.body)) {
try {
const params = {
owner: config_1.githubConfig.owner,
@@ -1644,16 +1684,47 @@ async function deletePreviousComments(comments) {
}
logger_1.logger.info('Deleted review comments of previous runs.');
}
-function commentIncludesTicsTitle(body) {
- const titles = ['TICS Quality Gate
', '## TICS Quality Gate', '## TICS Analysis'];
+function shouldCommentBeDeleted(body) {
if (!body)
return false;
+ const titles = ['TICS Quality Gate
', '## TICS Quality Gate', '## TICS Analysis'];
let includesTitle = false;
- titles.forEach(title => {
- if (body.startsWith(title))
+ for (const title of titles) {
+ if (body.startsWith(title)) {
includesTitle = true;
- });
- return includesTitle;
+ }
+ }
+ if (includesTitle) {
+ return isWorkflowAndJobInAnotherRun(body);
+ }
+ return false;
+}
+function isWorkflowAndJobInAnotherRun(body) {
+ const regex = //g;
+ let identifier = '';
+ // Get the last match of the tag.
+ let match = null;
+ while ((match = regex.exec(body))) {
+ if (match[1] !== '') {
+ identifier = match[1];
+ }
+ }
+ // If no identifier is found, the comment is
+ // of the old format and should be replaced.
+ if (identifier === '')
+ return true;
+ const split = identifier.split('_');
+ // If the identifier does not match the correct format, do not replace.
+ if (split.length !== 4) {
+ logger_1.logger.debug(`Identifier is not of the correct format: ${identifier}`);
+ return false;
+ }
+ // If the workflow or job are different, do not replace.
+ if (split[0] !== config_1.githubConfig.workflow || split[1] !== config_1.githubConfig.job) {
+ return false;
+ }
+ // Only replace if the run number or run attempt are different.
+ return parseInt(split[2], 10) !== config_1.githubConfig.runNumber || parseInt(split[3], 10) !== config_1.githubConfig.runAttempt;
}
@@ -1882,6 +1953,54 @@ async function postReview(body, event) {
}
+/***/ }),
+
+/***/ 50046:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.getCurrentStepPath = getCurrentStepPath;
+const logger_1 = __nccwpck_require__(26440);
+const response_1 = __nccwpck_require__(81934);
+const config_1 = __nccwpck_require__(86444);
+const octokit_1 = __nccwpck_require__(10775);
+/**
+ * Create review on the pull request from the analysis given.
+ * @param body Body containing the summary of the review
+ * @param event Either approve or request changes in the review.
+ */
+async function getCurrentStepPath() {
+ const params = {
+ owner: config_1.githubConfig.owner,
+ repo: config_1.githubConfig.reponame,
+ run_id: config_1.githubConfig.runId,
+ attempt_number: config_1.githubConfig.runAttempt
+ };
+ const stepname = [config_1.githubConfig.workflow, config_1.githubConfig.job, config_1.githubConfig.action];
+ try {
+ logger_1.logger.debug('Retrieving step name for current step...');
+ const response = await octokit_1.octokit.rest.actions.listJobsForWorkflowRunAttempt(params);
+ logger_1.logger.debug(JSON.stringify(response.data));
+ const jobs = response.data.jobs.filter(j => j.status === 'in_progress' && j.runner_name === config_1.githubConfig.runnerName);
+ if (jobs.length === 1) {
+ const job = jobs[0];
+ stepname[1] = job.name;
+ const steps = job.steps?.filter(s => s.status === 'in_progress');
+ if (steps?.length === 1) {
+ stepname[2] = steps[0].name;
+ }
+ }
+ }
+ catch (error) {
+ const message = (0, response_1.handleOctokitError)(error);
+ logger_1.logger.notice(`Retrieving the step name failed: ${message}`);
+ }
+ return stepname.join(' / ');
+}
+
+
/***/ }),
/***/ 31655:
@@ -62212,427 +62331,427 @@ module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS;
/***/ 4351:
/***/ ((module) => {
-/******************************************************************************
-Copyright (c) Microsoft Corporation.
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-***************************************************************************** */
-/* global global, define, Symbol, Reflect, Promise, SuppressedError */
-var __extends;
-var __assign;
-var __rest;
-var __decorate;
-var __param;
-var __esDecorate;
-var __runInitializers;
-var __propKey;
-var __setFunctionName;
-var __metadata;
-var __awaiter;
-var __generator;
-var __exportStar;
-var __values;
-var __read;
-var __spread;
-var __spreadArrays;
-var __spreadArray;
-var __await;
-var __asyncGenerator;
-var __asyncDelegator;
-var __asyncValues;
-var __makeTemplateObject;
-var __importStar;
-var __importDefault;
-var __classPrivateFieldGet;
-var __classPrivateFieldSet;
-var __classPrivateFieldIn;
-var __createBinding;
-var __addDisposableResource;
-var __disposeResources;
-(function (factory) {
- var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
- if (typeof define === "function" && define.amd) {
- define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); });
- }
- else if ( true && typeof module.exports === "object") {
- factory(createExporter(root, createExporter(module.exports)));
- }
- else {
- factory(createExporter(root));
- }
- function createExporter(exports, previous) {
- if (exports !== root) {
- if (typeof Object.create === "function") {
- Object.defineProperty(exports, "__esModule", { value: true });
- }
- else {
- exports.__esModule = true;
- }
- }
- return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };
- }
-})
-(function (exporter) {
- var extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
-
- __extends = function (d, b) {
- if (typeof b !== "function" && b !== null)
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- };
-
- __assign = Object.assign || function (t) {
- for (var s, i = 1, n = arguments.length; i < n; i++) {
- s = arguments[i];
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
- }
- return t;
- };
-
- __rest = function (s, e) {
- var t = {};
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
- t[p] = s[p];
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
- t[p[i]] = s[p[i]];
- }
- return t;
- };
-
- __decorate = function (decorators, target, key, desc) {
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
- return c > 3 && r && Object.defineProperty(target, key, r), r;
- };
-
- __param = function (paramIndex, decorator) {
- return function (target, key) { decorator(target, key, paramIndex); }
- };
-
- __esDecorate = function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
- function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
- var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
- var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
- var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
- var _, done = false;
- for (var i = decorators.length - 1; i >= 0; i--) {
- var context = {};
- for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
- for (var p in contextIn.access) context.access[p] = contextIn.access[p];
- context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
- var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
- if (kind === "accessor") {
- if (result === void 0) continue;
- if (result === null || typeof result !== "object") throw new TypeError("Object expected");
- if (_ = accept(result.get)) descriptor.get = _;
- if (_ = accept(result.set)) descriptor.set = _;
- if (_ = accept(result.init)) initializers.unshift(_);
- }
- else if (_ = accept(result)) {
- if (kind === "field") initializers.unshift(_);
- else descriptor[key] = _;
- }
- }
- if (target) Object.defineProperty(target, contextIn.name, descriptor);
- done = true;
- };
-
- __runInitializers = function (thisArg, initializers, value) {
- var useValue = arguments.length > 2;
- for (var i = 0; i < initializers.length; i++) {
- value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
- }
- return useValue ? value : void 0;
- };
-
- __propKey = function (x) {
- return typeof x === "symbol" ? x : "".concat(x);
- };
-
- __setFunctionName = function (f, name, prefix) {
- if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
- return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
- };
-
- __metadata = function (metadataKey, metadataValue) {
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
- };
-
- __awaiter = function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- };
-
- __generator = function (thisArg, body) {
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
- function verb(n) { return function (v) { return step([n, v]); }; }
- function step(op) {
- if (f) throw new TypeError("Generator is already executing.");
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
- if (y = 0, t) op = [op[0] & 2, t.value];
- switch (op[0]) {
- case 0: case 1: t = op; break;
- case 4: _.label++; return { value: op[1], done: false };
- case 5: _.label++; y = op[1]; op = [0]; continue;
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
- default:
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
- if (t[2]) _.ops.pop();
- _.trys.pop(); continue;
- }
- op = body.call(thisArg, _);
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
- }
- };
-
- __exportStar = function(m, o) {
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
- };
-
- __createBinding = Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- var desc = Object.getOwnPropertyDescriptor(m, k);
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
- desc = { enumerable: true, get: function() { return m[k]; } };
- }
- Object.defineProperty(o, k2, desc);
- }) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
- });
-
- __values = function (o) {
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
- if (m) return m.call(o);
- if (o && typeof o.length === "number") return {
- next: function () {
- if (o && i >= o.length) o = void 0;
- return { value: o && o[i++], done: !o };
- }
- };
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
- };
-
- __read = function (o, n) {
- var m = typeof Symbol === "function" && o[Symbol.iterator];
- if (!m) return o;
- var i = m.call(o), r, ar = [], e;
- try {
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
- }
- catch (error) { e = { error: error }; }
- finally {
- try {
- if (r && !r.done && (m = i["return"])) m.call(i);
- }
- finally { if (e) throw e.error; }
- }
- return ar;
- };
-
- /** @deprecated */
- __spread = function () {
- for (var ar = [], i = 0; i < arguments.length; i++)
- ar = ar.concat(__read(arguments[i]));
- return ar;
- };
-
- /** @deprecated */
- __spreadArrays = function () {
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
- for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
- r[k] = a[j];
- return r;
- };
-
- __spreadArray = function (to, from, pack) {
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
- if (ar || !(i in from)) {
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
- ar[i] = from[i];
- }
- }
- return to.concat(ar || Array.prototype.slice.call(from));
- };
-
- __await = function (v) {
- return this instanceof __await ? (this.v = v, this) : new __await(v);
- };
-
- __asyncGenerator = function (thisArg, _arguments, generator) {
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
- function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
- function fulfill(value) { resume("next", value); }
- function reject(value) { resume("throw", value); }
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
- };
-
- __asyncDelegator = function (o) {
- var i, p;
- return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
- function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }
- };
-
- __asyncValues = function (o) {
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
- var m = o[Symbol.asyncIterator], i;
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
- };
-
- __makeTemplateObject = function (cooked, raw) {
- if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
- return cooked;
- };
-
- var __setModuleDefault = Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
- }) : function(o, v) {
- o["default"] = v;
- };
-
- __importStar = function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
- };
-
- __importDefault = function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
-
- __classPrivateFieldGet = function (receiver, state, kind, f) {
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
- };
-
- __classPrivateFieldSet = function (receiver, state, value, kind, f) {
- if (kind === "m") throw new TypeError("Private method is not writable");
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
- };
-
- __classPrivateFieldIn = function (state, receiver) {
- if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object");
- return typeof state === "function" ? receiver === state : state.has(receiver);
- };
-
- __addDisposableResource = function (env, value, async) {
- if (value !== null && value !== void 0) {
- if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
- var dispose;
- if (async) {
- if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
- dispose = value[Symbol.asyncDispose];
- }
- if (dispose === void 0) {
- if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
- dispose = value[Symbol.dispose];
- }
- if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
- env.stack.push({ value: value, dispose: dispose, async: async });
- }
- else if (async) {
- env.stack.push({ async: true });
- }
- return value;
- };
-
- var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
- var e = new Error(message);
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
- };
-
- __disposeResources = function (env) {
- function fail(e) {
- env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
- env.hasError = true;
- }
- function next() {
- while (env.stack.length) {
- var rec = env.stack.pop();
- try {
- var result = rec.dispose && rec.dispose.call(rec.value);
- if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
- }
- catch (e) {
- fail(e);
- }
- }
- if (env.hasError) throw env.error;
- }
- return next();
- };
-
- exporter("__extends", __extends);
- exporter("__assign", __assign);
- exporter("__rest", __rest);
- exporter("__decorate", __decorate);
- exporter("__param", __param);
- exporter("__esDecorate", __esDecorate);
- exporter("__runInitializers", __runInitializers);
- exporter("__propKey", __propKey);
- exporter("__setFunctionName", __setFunctionName);
- exporter("__metadata", __metadata);
- exporter("__awaiter", __awaiter);
- exporter("__generator", __generator);
- exporter("__exportStar", __exportStar);
- exporter("__createBinding", __createBinding);
- exporter("__values", __values);
- exporter("__read", __read);
- exporter("__spread", __spread);
- exporter("__spreadArrays", __spreadArrays);
- exporter("__spreadArray", __spreadArray);
- exporter("__await", __await);
- exporter("__asyncGenerator", __asyncGenerator);
- exporter("__asyncDelegator", __asyncDelegator);
- exporter("__asyncValues", __asyncValues);
- exporter("__makeTemplateObject", __makeTemplateObject);
- exporter("__importStar", __importStar);
- exporter("__importDefault", __importDefault);
- exporter("__classPrivateFieldGet", __classPrivateFieldGet);
- exporter("__classPrivateFieldSet", __classPrivateFieldSet);
- exporter("__classPrivateFieldIn", __classPrivateFieldIn);
- exporter("__addDisposableResource", __addDisposableResource);
- exporter("__disposeResources", __disposeResources);
-});
+/******************************************************************************
+Copyright (c) Microsoft Corporation.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+***************************************************************************** */
+/* global global, define, Symbol, Reflect, Promise, SuppressedError */
+var __extends;
+var __assign;
+var __rest;
+var __decorate;
+var __param;
+var __esDecorate;
+var __runInitializers;
+var __propKey;
+var __setFunctionName;
+var __metadata;
+var __awaiter;
+var __generator;
+var __exportStar;
+var __values;
+var __read;
+var __spread;
+var __spreadArrays;
+var __spreadArray;
+var __await;
+var __asyncGenerator;
+var __asyncDelegator;
+var __asyncValues;
+var __makeTemplateObject;
+var __importStar;
+var __importDefault;
+var __classPrivateFieldGet;
+var __classPrivateFieldSet;
+var __classPrivateFieldIn;
+var __createBinding;
+var __addDisposableResource;
+var __disposeResources;
+(function (factory) {
+ var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
+ if (typeof define === "function" && define.amd) {
+ define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); });
+ }
+ else if ( true && typeof module.exports === "object") {
+ factory(createExporter(root, createExporter(module.exports)));
+ }
+ else {
+ factory(createExporter(root));
+ }
+ function createExporter(exports, previous) {
+ if (exports !== root) {
+ if (typeof Object.create === "function") {
+ Object.defineProperty(exports, "__esModule", { value: true });
+ }
+ else {
+ exports.__esModule = true;
+ }
+ }
+ return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };
+ }
+})
+(function (exporter) {
+ var extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
+
+ __extends = function (d, b) {
+ if (typeof b !== "function" && b !== null)
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+
+ __assign = Object.assign || function (t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+
+ __rest = function (s, e) {
+ var t = {};
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
+ t[p] = s[p];
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
+ t[p[i]] = s[p[i]];
+ }
+ return t;
+ };
+
+ __decorate = function (decorators, target, key, desc) {
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
+ };
+
+ __param = function (paramIndex, decorator) {
+ return function (target, key) { decorator(target, key, paramIndex); }
+ };
+
+ __esDecorate = function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
+ var _, done = false;
+ for (var i = decorators.length - 1; i >= 0; i--) {
+ var context = {};
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
+ if (kind === "accessor") {
+ if (result === void 0) continue;
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
+ if (_ = accept(result.get)) descriptor.get = _;
+ if (_ = accept(result.set)) descriptor.set = _;
+ if (_ = accept(result.init)) initializers.unshift(_);
+ }
+ else if (_ = accept(result)) {
+ if (kind === "field") initializers.unshift(_);
+ else descriptor[key] = _;
+ }
+ }
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
+ done = true;
+ };
+
+ __runInitializers = function (thisArg, initializers, value) {
+ var useValue = arguments.length > 2;
+ for (var i = 0; i < initializers.length; i++) {
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
+ }
+ return useValue ? value : void 0;
+ };
+
+ __propKey = function (x) {
+ return typeof x === "symbol" ? x : "".concat(x);
+ };
+
+ __setFunctionName = function (f, name, prefix) {
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
+ };
+
+ __metadata = function (metadataKey, metadataValue) {
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
+ };
+
+ __awaiter = function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+ };
+
+ __generator = function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+ };
+
+ __exportStar = function(m, o) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
+ };
+
+ __createBinding = Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+ }) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+ });
+
+ __values = function (o) {
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
+ if (m) return m.call(o);
+ if (o && typeof o.length === "number") return {
+ next: function () {
+ if (o && i >= o.length) o = void 0;
+ return { value: o && o[i++], done: !o };
+ }
+ };
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
+ };
+
+ __read = function (o, n) {
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
+ if (!m) return o;
+ var i = m.call(o), r, ar = [], e;
+ try {
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
+ }
+ catch (error) { e = { error: error }; }
+ finally {
+ try {
+ if (r && !r.done && (m = i["return"])) m.call(i);
+ }
+ finally { if (e) throw e.error; }
+ }
+ return ar;
+ };
+
+ /** @deprecated */
+ __spread = function () {
+ for (var ar = [], i = 0; i < arguments.length; i++)
+ ar = ar.concat(__read(arguments[i]));
+ return ar;
+ };
+
+ /** @deprecated */
+ __spreadArrays = function () {
+ for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+ for (var r = Array(s), k = 0, i = 0; i < il; i++)
+ for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+ r[k] = a[j];
+ return r;
+ };
+
+ __spreadArray = function (to, from, pack) {
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+ if (ar || !(i in from)) {
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+ ar[i] = from[i];
+ }
+ }
+ return to.concat(ar || Array.prototype.slice.call(from));
+ };
+
+ __await = function (v) {
+ return this instanceof __await ? (this.v = v, this) : new __await(v);
+ };
+
+ __asyncGenerator = function (thisArg, _arguments, generator) {
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
+ return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
+ function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
+ function fulfill(value) { resume("next", value); }
+ function reject(value) { resume("throw", value); }
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
+ };
+
+ __asyncDelegator = function (o) {
+ var i, p;
+ return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
+ function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }
+ };
+
+ __asyncValues = function (o) {
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
+ var m = o[Symbol.asyncIterator], i;
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
+ };
+
+ __makeTemplateObject = function (cooked, raw) {
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
+ return cooked;
+ };
+
+ var __setModuleDefault = Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+ }) : function(o, v) {
+ o["default"] = v;
+ };
+
+ __importStar = function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+ };
+
+ __importDefault = function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+ };
+
+ __classPrivateFieldGet = function (receiver, state, kind, f) {
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
+ };
+
+ __classPrivateFieldSet = function (receiver, state, value, kind, f) {
+ if (kind === "m") throw new TypeError("Private method is not writable");
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
+ };
+
+ __classPrivateFieldIn = function (state, receiver) {
+ if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object");
+ return typeof state === "function" ? receiver === state : state.has(receiver);
+ };
+
+ __addDisposableResource = function (env, value, async) {
+ if (value !== null && value !== void 0) {
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
+ var dispose;
+ if (async) {
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
+ dispose = value[Symbol.asyncDispose];
+ }
+ if (dispose === void 0) {
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
+ dispose = value[Symbol.dispose];
+ }
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
+ env.stack.push({ value: value, dispose: dispose, async: async });
+ }
+ else if (async) {
+ env.stack.push({ async: true });
+ }
+ return value;
+ };
+
+ var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
+ var e = new Error(message);
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
+ };
+
+ __disposeResources = function (env) {
+ function fail(e) {
+ env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
+ env.hasError = true;
+ }
+ function next() {
+ while (env.stack.length) {
+ var rec = env.stack.pop();
+ try {
+ var result = rec.dispose && rec.dispose.call(rec.value);
+ if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
+ }
+ catch (e) {
+ fail(e);
+ }
+ }
+ if (env.hasError) throw env.error;
+ }
+ return next();
+ };
+
+ exporter("__extends", __extends);
+ exporter("__assign", __assign);
+ exporter("__rest", __rest);
+ exporter("__decorate", __decorate);
+ exporter("__param", __param);
+ exporter("__esDecorate", __esDecorate);
+ exporter("__runInitializers", __runInitializers);
+ exporter("__propKey", __propKey);
+ exporter("__setFunctionName", __setFunctionName);
+ exporter("__metadata", __metadata);
+ exporter("__awaiter", __awaiter);
+ exporter("__generator", __generator);
+ exporter("__exportStar", __exportStar);
+ exporter("__createBinding", __createBinding);
+ exporter("__values", __values);
+ exporter("__read", __read);
+ exporter("__spread", __spread);
+ exporter("__spreadArrays", __spreadArrays);
+ exporter("__spreadArray", __spreadArray);
+ exporter("__await", __await);
+ exporter("__asyncGenerator", __asyncGenerator);
+ exporter("__asyncDelegator", __asyncDelegator);
+ exporter("__asyncValues", __asyncValues);
+ exporter("__makeTemplateObject", __makeTemplateObject);
+ exporter("__importStar", __importStar);
+ exporter("__importDefault", __importDefault);
+ exporter("__classPrivateFieldGet", __classPrivateFieldGet);
+ exporter("__classPrivateFieldSet", __classPrivateFieldSet);
+ exporter("__classPrivateFieldIn", __classPrivateFieldIn);
+ exporter("__addDisposableResource", __addDisposableResource);
+ exporter("__disposeResources", __disposeResources);
+});
/***/ }),
@@ -85768,1303 +85887,1303 @@ exports.parseURL = __nccwpck_require__(2158).parseURL;
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
"use strict";
-
-const punycode = __nccwpck_require__(85477);
-const tr46 = __nccwpck_require__(84256);
-
-const specialSchemes = {
- ftp: 21,
- file: null,
- gopher: 70,
- http: 80,
- https: 443,
- ws: 80,
- wss: 443
-};
-
-const failure = Symbol("failure");
-
-function countSymbols(str) {
- return punycode.ucs2.decode(str).length;
-}
-
-function at(input, idx) {
- const c = input[idx];
- return isNaN(c) ? undefined : String.fromCodePoint(c);
-}
-
-function isASCIIDigit(c) {
- return c >= 0x30 && c <= 0x39;
-}
-
-function isASCIIAlpha(c) {
- return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A);
-}
-
-function isASCIIAlphanumeric(c) {
- return isASCIIAlpha(c) || isASCIIDigit(c);
-}
-
-function isASCIIHex(c) {
- return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66);
-}
-
-function isSingleDot(buffer) {
- return buffer === "." || buffer.toLowerCase() === "%2e";
-}
-
-function isDoubleDot(buffer) {
- buffer = buffer.toLowerCase();
- return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e";
-}
-
-function isWindowsDriveLetterCodePoints(cp1, cp2) {
- return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124);
-}
-
-function isWindowsDriveLetterString(string) {
- return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|");
-}
-
-function isNormalizedWindowsDriveLetterString(string) {
- return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":";
-}
-
-function containsForbiddenHostCodePoint(string) {
- return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1;
-}
-
-function containsForbiddenHostCodePointExcludingPercent(string) {
- return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1;
-}
-
-function isSpecialScheme(scheme) {
- return specialSchemes[scheme] !== undefined;
-}
-
-function isSpecial(url) {
- return isSpecialScheme(url.scheme);
-}
-
-function defaultPort(scheme) {
- return specialSchemes[scheme];
-}
-
-function percentEncode(c) {
- let hex = c.toString(16).toUpperCase();
- if (hex.length === 1) {
- hex = "0" + hex;
- }
-
- return "%" + hex;
-}
-
-function utf8PercentEncode(c) {
- const buf = new Buffer(c);
-
- let str = "";
-
- for (let i = 0; i < buf.length; ++i) {
- str += percentEncode(buf[i]);
- }
-
- return str;
-}
-
-function utf8PercentDecode(str) {
- const input = new Buffer(str);
- const output = [];
- for (let i = 0; i < input.length; ++i) {
- if (input[i] !== 37) {
- output.push(input[i]);
- } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) {
- output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16));
- i += 2;
- } else {
- output.push(input[i]);
- }
- }
- return new Buffer(output).toString();
-}
-
-function isC0ControlPercentEncode(c) {
- return c <= 0x1F || c > 0x7E;
-}
-
-const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]);
-function isPathPercentEncode(c) {
- return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c);
-}
-
-const extraUserinfoPercentEncodeSet =
- new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]);
-function isUserinfoPercentEncode(c) {
- return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c);
-}
-
-function percentEncodeChar(c, encodeSetPredicate) {
- const cStr = String.fromCodePoint(c);
-
- if (encodeSetPredicate(c)) {
- return utf8PercentEncode(cStr);
- }
-
- return cStr;
-}
-
-function parseIPv4Number(input) {
- let R = 10;
-
- if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") {
- input = input.substring(2);
- R = 16;
- } else if (input.length >= 2 && input.charAt(0) === "0") {
- input = input.substring(1);
- R = 8;
- }
-
- if (input === "") {
- return 0;
- }
-
- const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/);
- if (regex.test(input)) {
- return failure;
- }
-
- return parseInt(input, R);
-}
-
-function parseIPv4(input) {
- const parts = input.split(".");
- if (parts[parts.length - 1] === "") {
- if (parts.length > 1) {
- parts.pop();
- }
- }
-
- if (parts.length > 4) {
- return input;
- }
-
- const numbers = [];
- for (const part of parts) {
- if (part === "") {
- return input;
- }
- const n = parseIPv4Number(part);
- if (n === failure) {
- return input;
- }
-
- numbers.push(n);
- }
-
- for (let i = 0; i < numbers.length - 1; ++i) {
- if (numbers[i] > 255) {
- return failure;
- }
- }
- if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) {
- return failure;
- }
-
- let ipv4 = numbers.pop();
- let counter = 0;
-
- for (const n of numbers) {
- ipv4 += n * Math.pow(256, 3 - counter);
- ++counter;
- }
-
- return ipv4;
-}
-
-function serializeIPv4(address) {
- let output = "";
- let n = address;
-
- for (let i = 1; i <= 4; ++i) {
- output = String(n % 256) + output;
- if (i !== 4) {
- output = "." + output;
- }
- n = Math.floor(n / 256);
- }
-
- return output;
-}
-
-function parseIPv6(input) {
- const address = [0, 0, 0, 0, 0, 0, 0, 0];
- let pieceIndex = 0;
- let compress = null;
- let pointer = 0;
-
- input = punycode.ucs2.decode(input);
-
- if (input[pointer] === 58) {
- if (input[pointer + 1] !== 58) {
- return failure;
- }
-
- pointer += 2;
- ++pieceIndex;
- compress = pieceIndex;
- }
-
- while (pointer < input.length) {
- if (pieceIndex === 8) {
- return failure;
- }
-
- if (input[pointer] === 58) {
- if (compress !== null) {
- return failure;
- }
- ++pointer;
- ++pieceIndex;
- compress = pieceIndex;
- continue;
- }
-
- let value = 0;
- let length = 0;
-
- while (length < 4 && isASCIIHex(input[pointer])) {
- value = value * 0x10 + parseInt(at(input, pointer), 16);
- ++pointer;
- ++length;
- }
-
- if (input[pointer] === 46) {
- if (length === 0) {
- return failure;
- }
-
- pointer -= length;
-
- if (pieceIndex > 6) {
- return failure;
- }
-
- let numbersSeen = 0;
-
- while (input[pointer] !== undefined) {
- let ipv4Piece = null;
-
- if (numbersSeen > 0) {
- if (input[pointer] === 46 && numbersSeen < 4) {
- ++pointer;
- } else {
- return failure;
- }
- }
-
- if (!isASCIIDigit(input[pointer])) {
- return failure;
- }
-
- while (isASCIIDigit(input[pointer])) {
- const number = parseInt(at(input, pointer));
- if (ipv4Piece === null) {
- ipv4Piece = number;
- } else if (ipv4Piece === 0) {
- return failure;
- } else {
- ipv4Piece = ipv4Piece * 10 + number;
- }
- if (ipv4Piece > 255) {
- return failure;
- }
- ++pointer;
- }
-
- address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece;
-
- ++numbersSeen;
-
- if (numbersSeen === 2 || numbersSeen === 4) {
- ++pieceIndex;
- }
- }
-
- if (numbersSeen !== 4) {
- return failure;
- }
-
- break;
- } else if (input[pointer] === 58) {
- ++pointer;
- if (input[pointer] === undefined) {
- return failure;
- }
- } else if (input[pointer] !== undefined) {
- return failure;
- }
-
- address[pieceIndex] = value;
- ++pieceIndex;
- }
-
- if (compress !== null) {
- let swaps = pieceIndex - compress;
- pieceIndex = 7;
- while (pieceIndex !== 0 && swaps > 0) {
- const temp = address[compress + swaps - 1];
- address[compress + swaps - 1] = address[pieceIndex];
- address[pieceIndex] = temp;
- --pieceIndex;
- --swaps;
- }
- } else if (compress === null && pieceIndex !== 8) {
- return failure;
- }
-
- return address;
-}
-
-function serializeIPv6(address) {
- let output = "";
- const seqResult = findLongestZeroSequence(address);
- const compress = seqResult.idx;
- let ignore0 = false;
-
- for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) {
- if (ignore0 && address[pieceIndex] === 0) {
- continue;
- } else if (ignore0) {
- ignore0 = false;
- }
-
- if (compress === pieceIndex) {
- const separator = pieceIndex === 0 ? "::" : ":";
- output += separator;
- ignore0 = true;
- continue;
- }
-
- output += address[pieceIndex].toString(16);
-
- if (pieceIndex !== 7) {
- output += ":";
- }
- }
-
- return output;
-}
-
-function parseHost(input, isSpecialArg) {
- if (input[0] === "[") {
- if (input[input.length - 1] !== "]") {
- return failure;
- }
-
- return parseIPv6(input.substring(1, input.length - 1));
- }
-
- if (!isSpecialArg) {
- return parseOpaqueHost(input);
- }
-
- const domain = utf8PercentDecode(input);
- const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false);
- if (asciiDomain === null) {
- return failure;
- }
-
- if (containsForbiddenHostCodePoint(asciiDomain)) {
- return failure;
- }
-
- const ipv4Host = parseIPv4(asciiDomain);
- if (typeof ipv4Host === "number" || ipv4Host === failure) {
- return ipv4Host;
- }
-
- return asciiDomain;
-}
-
-function parseOpaqueHost(input) {
- if (containsForbiddenHostCodePointExcludingPercent(input)) {
- return failure;
- }
-
- let output = "";
- const decoded = punycode.ucs2.decode(input);
- for (let i = 0; i < decoded.length; ++i) {
- output += percentEncodeChar(decoded[i], isC0ControlPercentEncode);
- }
- return output;
-}
-
-function findLongestZeroSequence(arr) {
- let maxIdx = null;
- let maxLen = 1; // only find elements > 1
- let currStart = null;
- let currLen = 0;
-
- for (let i = 0; i < arr.length; ++i) {
- if (arr[i] !== 0) {
- if (currLen > maxLen) {
- maxIdx = currStart;
- maxLen = currLen;
- }
-
- currStart = null;
- currLen = 0;
- } else {
- if (currStart === null) {
- currStart = i;
- }
- ++currLen;
- }
- }
-
- // if trailing zeros
- if (currLen > maxLen) {
- maxIdx = currStart;
- maxLen = currLen;
- }
-
- return {
- idx: maxIdx,
- len: maxLen
- };
-}
-
-function serializeHost(host) {
- if (typeof host === "number") {
- return serializeIPv4(host);
- }
-
- // IPv6 serializer
- if (host instanceof Array) {
- return "[" + serializeIPv6(host) + "]";
- }
-
- return host;
-}
-
-function trimControlChars(url) {
- return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, "");
-}
-
-function trimTabAndNewline(url) {
- return url.replace(/\u0009|\u000A|\u000D/g, "");
-}
-
-function shortenPath(url) {
- const path = url.path;
- if (path.length === 0) {
- return;
- }
- if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) {
- return;
- }
-
- path.pop();
-}
-
-function includesCredentials(url) {
- return url.username !== "" || url.password !== "";
-}
-
-function cannotHaveAUsernamePasswordPort(url) {
- return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file";
-}
-
-function isNormalizedWindowsDriveLetter(string) {
- return /^[A-Za-z]:$/.test(string);
-}
-
-function URLStateMachine(input, base, encodingOverride, url, stateOverride) {
- this.pointer = 0;
- this.input = input;
- this.base = base || null;
- this.encodingOverride = encodingOverride || "utf-8";
- this.stateOverride = stateOverride;
- this.url = url;
- this.failure = false;
- this.parseError = false;
-
- if (!this.url) {
- this.url = {
- scheme: "",
- username: "",
- password: "",
- host: null,
- port: null,
- path: [],
- query: null,
- fragment: null,
-
- cannotBeABaseURL: false
- };
-
- const res = trimControlChars(this.input);
- if (res !== this.input) {
- this.parseError = true;
- }
- this.input = res;
- }
-
- const res = trimTabAndNewline(this.input);
- if (res !== this.input) {
- this.parseError = true;
- }
- this.input = res;
-
- this.state = stateOverride || "scheme start";
-
- this.buffer = "";
- this.atFlag = false;
- this.arrFlag = false;
- this.passwordTokenSeenFlag = false;
-
- this.input = punycode.ucs2.decode(this.input);
-
- for (; this.pointer <= this.input.length; ++this.pointer) {
- const c = this.input[this.pointer];
- const cStr = isNaN(c) ? undefined : String.fromCodePoint(c);
-
- // exec state machine
- const ret = this["parse " + this.state](c, cStr);
- if (!ret) {
- break; // terminate algorithm
- } else if (ret === failure) {
- this.failure = true;
- break;
- }
- }
-}
-
-URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) {
- if (isASCIIAlpha(c)) {
- this.buffer += cStr.toLowerCase();
- this.state = "scheme";
- } else if (!this.stateOverride) {
- this.state = "no scheme";
- --this.pointer;
- } else {
- this.parseError = true;
- return failure;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) {
- if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) {
- this.buffer += cStr.toLowerCase();
- } else if (c === 58) {
- if (this.stateOverride) {
- if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) {
- return false;
- }
-
- if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) {
- return false;
- }
-
- if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") {
- return false;
- }
-
- if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) {
- return false;
- }
- }
- this.url.scheme = this.buffer;
- this.buffer = "";
- if (this.stateOverride) {
- return false;
- }
- if (this.url.scheme === "file") {
- if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) {
- this.parseError = true;
- }
- this.state = "file";
- } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) {
- this.state = "special relative or authority";
- } else if (isSpecial(this.url)) {
- this.state = "special authority slashes";
- } else if (this.input[this.pointer + 1] === 47) {
- this.state = "path or authority";
- ++this.pointer;
- } else {
- this.url.cannotBeABaseURL = true;
- this.url.path.push("");
- this.state = "cannot-be-a-base-URL path";
- }
- } else if (!this.stateOverride) {
- this.buffer = "";
- this.state = "no scheme";
- this.pointer = -1;
- } else {
- this.parseError = true;
- return failure;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) {
- if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) {
- return failure;
- } else if (this.base.cannotBeABaseURL && c === 35) {
- this.url.scheme = this.base.scheme;
- this.url.path = this.base.path.slice();
- this.url.query = this.base.query;
- this.url.fragment = "";
- this.url.cannotBeABaseURL = true;
- this.state = "fragment";
- } else if (this.base.scheme === "file") {
- this.state = "file";
- --this.pointer;
- } else {
- this.state = "relative";
- --this.pointer;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) {
- if (c === 47 && this.input[this.pointer + 1] === 47) {
- this.state = "special authority ignore slashes";
- ++this.pointer;
- } else {
- this.parseError = true;
- this.state = "relative";
- --this.pointer;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) {
- if (c === 47) {
- this.state = "authority";
- } else {
- this.state = "path";
- --this.pointer;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse relative"] = function parseRelative(c) {
- this.url.scheme = this.base.scheme;
- if (isNaN(c)) {
- this.url.username = this.base.username;
- this.url.password = this.base.password;
- this.url.host = this.base.host;
- this.url.port = this.base.port;
- this.url.path = this.base.path.slice();
- this.url.query = this.base.query;
- } else if (c === 47) {
- this.state = "relative slash";
- } else if (c === 63) {
- this.url.username = this.base.username;
- this.url.password = this.base.password;
- this.url.host = this.base.host;
- this.url.port = this.base.port;
- this.url.path = this.base.path.slice();
- this.url.query = "";
- this.state = "query";
- } else if (c === 35) {
- this.url.username = this.base.username;
- this.url.password = this.base.password;
- this.url.host = this.base.host;
- this.url.port = this.base.port;
- this.url.path = this.base.path.slice();
- this.url.query = this.base.query;
- this.url.fragment = "";
- this.state = "fragment";
- } else if (isSpecial(this.url) && c === 92) {
- this.parseError = true;
- this.state = "relative slash";
- } else {
- this.url.username = this.base.username;
- this.url.password = this.base.password;
- this.url.host = this.base.host;
- this.url.port = this.base.port;
- this.url.path = this.base.path.slice(0, this.base.path.length - 1);
-
- this.state = "path";
- --this.pointer;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) {
- if (isSpecial(this.url) && (c === 47 || c === 92)) {
- if (c === 92) {
- this.parseError = true;
- }
- this.state = "special authority ignore slashes";
- } else if (c === 47) {
- this.state = "authority";
- } else {
- this.url.username = this.base.username;
- this.url.password = this.base.password;
- this.url.host = this.base.host;
- this.url.port = this.base.port;
- this.state = "path";
- --this.pointer;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) {
- if (c === 47 && this.input[this.pointer + 1] === 47) {
- this.state = "special authority ignore slashes";
- ++this.pointer;
- } else {
- this.parseError = true;
- this.state = "special authority ignore slashes";
- --this.pointer;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) {
- if (c !== 47 && c !== 92) {
- this.state = "authority";
- --this.pointer;
- } else {
- this.parseError = true;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) {
- if (c === 64) {
- this.parseError = true;
- if (this.atFlag) {
- this.buffer = "%40" + this.buffer;
- }
- this.atFlag = true;
-
- // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars
- const len = countSymbols(this.buffer);
- for (let pointer = 0; pointer < len; ++pointer) {
- const codePoint = this.buffer.codePointAt(pointer);
-
- if (codePoint === 58 && !this.passwordTokenSeenFlag) {
- this.passwordTokenSeenFlag = true;
- continue;
- }
- const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode);
- if (this.passwordTokenSeenFlag) {
- this.url.password += encodedCodePoints;
- } else {
- this.url.username += encodedCodePoints;
- }
- }
- this.buffer = "";
- } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||
- (isSpecial(this.url) && c === 92)) {
- if (this.atFlag && this.buffer === "") {
- this.parseError = true;
- return failure;
- }
- this.pointer -= countSymbols(this.buffer) + 1;
- this.buffer = "";
- this.state = "host";
- } else {
- this.buffer += cStr;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse hostname"] =
-URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) {
- if (this.stateOverride && this.url.scheme === "file") {
- --this.pointer;
- this.state = "file host";
- } else if (c === 58 && !this.arrFlag) {
- if (this.buffer === "") {
- this.parseError = true;
- return failure;
- }
-
- const host = parseHost(this.buffer, isSpecial(this.url));
- if (host === failure) {
- return failure;
- }
-
- this.url.host = host;
- this.buffer = "";
- this.state = "port";
- if (this.stateOverride === "hostname") {
- return false;
- }
- } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||
- (isSpecial(this.url) && c === 92)) {
- --this.pointer;
- if (isSpecial(this.url) && this.buffer === "") {
- this.parseError = true;
- return failure;
- } else if (this.stateOverride && this.buffer === "" &&
- (includesCredentials(this.url) || this.url.port !== null)) {
- this.parseError = true;
- return false;
- }
-
- const host = parseHost(this.buffer, isSpecial(this.url));
- if (host === failure) {
- return failure;
- }
-
- this.url.host = host;
- this.buffer = "";
- this.state = "path start";
- if (this.stateOverride) {
- return false;
- }
- } else {
- if (c === 91) {
- this.arrFlag = true;
- } else if (c === 93) {
- this.arrFlag = false;
- }
- this.buffer += cStr;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) {
- if (isASCIIDigit(c)) {
- this.buffer += cStr;
- } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||
- (isSpecial(this.url) && c === 92) ||
- this.stateOverride) {
- if (this.buffer !== "") {
- const port = parseInt(this.buffer);
- if (port > Math.pow(2, 16) - 1) {
- this.parseError = true;
- return failure;
- }
- this.url.port = port === defaultPort(this.url.scheme) ? null : port;
- this.buffer = "";
- }
- if (this.stateOverride) {
- return false;
- }
- this.state = "path start";
- --this.pointer;
- } else {
- this.parseError = true;
- return failure;
- }
-
- return true;
-};
-
-const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]);
-
-URLStateMachine.prototype["parse file"] = function parseFile(c) {
- this.url.scheme = "file";
-
- if (c === 47 || c === 92) {
- if (c === 92) {
- this.parseError = true;
- }
- this.state = "file slash";
- } else if (this.base !== null && this.base.scheme === "file") {
- if (isNaN(c)) {
- this.url.host = this.base.host;
- this.url.path = this.base.path.slice();
- this.url.query = this.base.query;
- } else if (c === 63) {
- this.url.host = this.base.host;
- this.url.path = this.base.path.slice();
- this.url.query = "";
- this.state = "query";
- } else if (c === 35) {
- this.url.host = this.base.host;
- this.url.path = this.base.path.slice();
- this.url.query = this.base.query;
- this.url.fragment = "";
- this.state = "fragment";
- } else {
- if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points
- !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) ||
- (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points
- !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) {
- this.url.host = this.base.host;
- this.url.path = this.base.path.slice();
- shortenPath(this.url);
- } else {
- this.parseError = true;
- }
-
- this.state = "path";
- --this.pointer;
- }
- } else {
- this.state = "path";
- --this.pointer;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) {
- if (c === 47 || c === 92) {
- if (c === 92) {
- this.parseError = true;
- }
- this.state = "file host";
- } else {
- if (this.base !== null && this.base.scheme === "file") {
- if (isNormalizedWindowsDriveLetterString(this.base.path[0])) {
- this.url.path.push(this.base.path[0]);
- } else {
- this.url.host = this.base.host;
- }
- }
- this.state = "path";
- --this.pointer;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) {
- if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) {
- --this.pointer;
- if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) {
- this.parseError = true;
- this.state = "path";
- } else if (this.buffer === "") {
- this.url.host = "";
- if (this.stateOverride) {
- return false;
- }
- this.state = "path start";
- } else {
- let host = parseHost(this.buffer, isSpecial(this.url));
- if (host === failure) {
- return failure;
- }
- if (host === "localhost") {
- host = "";
- }
- this.url.host = host;
-
- if (this.stateOverride) {
- return false;
- }
-
- this.buffer = "";
- this.state = "path start";
- }
- } else {
- this.buffer += cStr;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse path start"] = function parsePathStart(c) {
- if (isSpecial(this.url)) {
- if (c === 92) {
- this.parseError = true;
- }
- this.state = "path";
-
- if (c !== 47 && c !== 92) {
- --this.pointer;
- }
- } else if (!this.stateOverride && c === 63) {
- this.url.query = "";
- this.state = "query";
- } else if (!this.stateOverride && c === 35) {
- this.url.fragment = "";
- this.state = "fragment";
- } else if (c !== undefined) {
- this.state = "path";
- if (c !== 47) {
- --this.pointer;
- }
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse path"] = function parsePath(c) {
- if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) ||
- (!this.stateOverride && (c === 63 || c === 35))) {
- if (isSpecial(this.url) && c === 92) {
- this.parseError = true;
- }
-
- if (isDoubleDot(this.buffer)) {
- shortenPath(this.url);
- if (c !== 47 && !(isSpecial(this.url) && c === 92)) {
- this.url.path.push("");
- }
- } else if (isSingleDot(this.buffer) && c !== 47 &&
- !(isSpecial(this.url) && c === 92)) {
- this.url.path.push("");
- } else if (!isSingleDot(this.buffer)) {
- if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) {
- if (this.url.host !== "" && this.url.host !== null) {
- this.parseError = true;
- this.url.host = "";
- }
- this.buffer = this.buffer[0] + ":";
- }
- this.url.path.push(this.buffer);
- }
- this.buffer = "";
- if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) {
- while (this.url.path.length > 1 && this.url.path[0] === "") {
- this.parseError = true;
- this.url.path.shift();
- }
- }
- if (c === 63) {
- this.url.query = "";
- this.state = "query";
- }
- if (c === 35) {
- this.url.fragment = "";
- this.state = "fragment";
- }
- } else {
- // TODO: If c is not a URL code point and not "%", parse error.
-
- if (c === 37 &&
- (!isASCIIHex(this.input[this.pointer + 1]) ||
- !isASCIIHex(this.input[this.pointer + 2]))) {
- this.parseError = true;
- }
-
- this.buffer += percentEncodeChar(c, isPathPercentEncode);
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) {
- if (c === 63) {
- this.url.query = "";
- this.state = "query";
- } else if (c === 35) {
- this.url.fragment = "";
- this.state = "fragment";
- } else {
- // TODO: Add: not a URL code point
- if (!isNaN(c) && c !== 37) {
- this.parseError = true;
- }
-
- if (c === 37 &&
- (!isASCIIHex(this.input[this.pointer + 1]) ||
- !isASCIIHex(this.input[this.pointer + 2]))) {
- this.parseError = true;
- }
-
- if (!isNaN(c)) {
- this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode);
- }
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) {
- if (isNaN(c) || (!this.stateOverride && c === 35)) {
- if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") {
- this.encodingOverride = "utf-8";
- }
-
- const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead
- for (let i = 0; i < buffer.length; ++i) {
- if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 ||
- buffer[i] === 0x3C || buffer[i] === 0x3E) {
- this.url.query += percentEncode(buffer[i]);
- } else {
- this.url.query += String.fromCodePoint(buffer[i]);
- }
- }
-
- this.buffer = "";
- if (c === 35) {
- this.url.fragment = "";
- this.state = "fragment";
- }
- } else {
- // TODO: If c is not a URL code point and not "%", parse error.
- if (c === 37 &&
- (!isASCIIHex(this.input[this.pointer + 1]) ||
- !isASCIIHex(this.input[this.pointer + 2]))) {
- this.parseError = true;
- }
-
- this.buffer += cStr;
- }
-
- return true;
-};
-
-URLStateMachine.prototype["parse fragment"] = function parseFragment(c) {
- if (isNaN(c)) { // do nothing
- } else if (c === 0x0) {
- this.parseError = true;
- } else {
- // TODO: If c is not a URL code point and not "%", parse error.
- if (c === 37 &&
- (!isASCIIHex(this.input[this.pointer + 1]) ||
- !isASCIIHex(this.input[this.pointer + 2]))) {
- this.parseError = true;
- }
-
- this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode);
- }
-
- return true;
-};
-
-function serializeURL(url, excludeFragment) {
- let output = url.scheme + ":";
- if (url.host !== null) {
- output += "//";
-
- if (url.username !== "" || url.password !== "") {
- output += url.username;
- if (url.password !== "") {
- output += ":" + url.password;
- }
- output += "@";
- }
-
- output += serializeHost(url.host);
-
- if (url.port !== null) {
- output += ":" + url.port;
- }
- } else if (url.host === null && url.scheme === "file") {
- output += "//";
- }
-
- if (url.cannotBeABaseURL) {
- output += url.path[0];
- } else {
- for (const string of url.path) {
- output += "/" + string;
- }
- }
-
- if (url.query !== null) {
- output += "?" + url.query;
- }
-
- if (!excludeFragment && url.fragment !== null) {
- output += "#" + url.fragment;
- }
-
- return output;
-}
-
-function serializeOrigin(tuple) {
- let result = tuple.scheme + "://";
- result += serializeHost(tuple.host);
-
- if (tuple.port !== null) {
- result += ":" + tuple.port;
- }
-
- return result;
-}
-
-module.exports.serializeURL = serializeURL;
-
-module.exports.serializeURLOrigin = function (url) {
- // https://url.spec.whatwg.org/#concept-url-origin
- switch (url.scheme) {
- case "blob":
- try {
- return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0]));
- } catch (e) {
- // serializing an opaque origin returns "null"
- return "null";
- }
- case "ftp":
- case "gopher":
- case "http":
- case "https":
- case "ws":
- case "wss":
- return serializeOrigin({
- scheme: url.scheme,
- host: url.host,
- port: url.port
- });
- case "file":
- // spec says "exercise to the reader", chrome says "file://"
- return "file://";
- default:
- // serializing an opaque origin returns "null"
- return "null";
- }
-};
-
-module.exports.basicURLParse = function (input, options) {
- if (options === undefined) {
- options = {};
- }
-
- const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride);
- if (usm.failure) {
- return "failure";
- }
-
- return usm.url;
-};
-
-module.exports.setTheUsername = function (url, username) {
- url.username = "";
- const decoded = punycode.ucs2.decode(username);
- for (let i = 0; i < decoded.length; ++i) {
- url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode);
- }
-};
-
-module.exports.setThePassword = function (url, password) {
- url.password = "";
- const decoded = punycode.ucs2.decode(password);
- for (let i = 0; i < decoded.length; ++i) {
- url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode);
- }
-};
-
-module.exports.serializeHost = serializeHost;
-
-module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort;
-
-module.exports.serializeInteger = function (integer) {
- return String(integer);
-};
-
-module.exports.parseURL = function (input, options) {
- if (options === undefined) {
- options = {};
- }
-
- // We don't handle blobs, so this just delegates:
- return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride });
-};
+
+const punycode = __nccwpck_require__(85477);
+const tr46 = __nccwpck_require__(84256);
+
+const specialSchemes = {
+ ftp: 21,
+ file: null,
+ gopher: 70,
+ http: 80,
+ https: 443,
+ ws: 80,
+ wss: 443
+};
+
+const failure = Symbol("failure");
+
+function countSymbols(str) {
+ return punycode.ucs2.decode(str).length;
+}
+
+function at(input, idx) {
+ const c = input[idx];
+ return isNaN(c) ? undefined : String.fromCodePoint(c);
+}
+
+function isASCIIDigit(c) {
+ return c >= 0x30 && c <= 0x39;
+}
+
+function isASCIIAlpha(c) {
+ return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A);
+}
+
+function isASCIIAlphanumeric(c) {
+ return isASCIIAlpha(c) || isASCIIDigit(c);
+}
+
+function isASCIIHex(c) {
+ return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66);
+}
+
+function isSingleDot(buffer) {
+ return buffer === "." || buffer.toLowerCase() === "%2e";
+}
+
+function isDoubleDot(buffer) {
+ buffer = buffer.toLowerCase();
+ return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e";
+}
+
+function isWindowsDriveLetterCodePoints(cp1, cp2) {
+ return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124);
+}
+
+function isWindowsDriveLetterString(string) {
+ return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|");
+}
+
+function isNormalizedWindowsDriveLetterString(string) {
+ return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":";
+}
+
+function containsForbiddenHostCodePoint(string) {
+ return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1;
+}
+
+function containsForbiddenHostCodePointExcludingPercent(string) {
+ return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1;
+}
+
+function isSpecialScheme(scheme) {
+ return specialSchemes[scheme] !== undefined;
+}
+
+function isSpecial(url) {
+ return isSpecialScheme(url.scheme);
+}
+
+function defaultPort(scheme) {
+ return specialSchemes[scheme];
+}
+
+function percentEncode(c) {
+ let hex = c.toString(16).toUpperCase();
+ if (hex.length === 1) {
+ hex = "0" + hex;
+ }
+
+ return "%" + hex;
+}
+
+function utf8PercentEncode(c) {
+ const buf = new Buffer(c);
+
+ let str = "";
+
+ for (let i = 0; i < buf.length; ++i) {
+ str += percentEncode(buf[i]);
+ }
+
+ return str;
+}
+
+function utf8PercentDecode(str) {
+ const input = new Buffer(str);
+ const output = [];
+ for (let i = 0; i < input.length; ++i) {
+ if (input[i] !== 37) {
+ output.push(input[i]);
+ } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) {
+ output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16));
+ i += 2;
+ } else {
+ output.push(input[i]);
+ }
+ }
+ return new Buffer(output).toString();
+}
+
+function isC0ControlPercentEncode(c) {
+ return c <= 0x1F || c > 0x7E;
+}
+
+const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]);
+function isPathPercentEncode(c) {
+ return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c);
+}
+
+const extraUserinfoPercentEncodeSet =
+ new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]);
+function isUserinfoPercentEncode(c) {
+ return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c);
+}
+
+function percentEncodeChar(c, encodeSetPredicate) {
+ const cStr = String.fromCodePoint(c);
+
+ if (encodeSetPredicate(c)) {
+ return utf8PercentEncode(cStr);
+ }
+
+ return cStr;
+}
+
+function parseIPv4Number(input) {
+ let R = 10;
+
+ if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") {
+ input = input.substring(2);
+ R = 16;
+ } else if (input.length >= 2 && input.charAt(0) === "0") {
+ input = input.substring(1);
+ R = 8;
+ }
+
+ if (input === "") {
+ return 0;
+ }
+
+ const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/);
+ if (regex.test(input)) {
+ return failure;
+ }
+
+ return parseInt(input, R);
+}
+
+function parseIPv4(input) {
+ const parts = input.split(".");
+ if (parts[parts.length - 1] === "") {
+ if (parts.length > 1) {
+ parts.pop();
+ }
+ }
+
+ if (parts.length > 4) {
+ return input;
+ }
+
+ const numbers = [];
+ for (const part of parts) {
+ if (part === "") {
+ return input;
+ }
+ const n = parseIPv4Number(part);
+ if (n === failure) {
+ return input;
+ }
+
+ numbers.push(n);
+ }
+
+ for (let i = 0; i < numbers.length - 1; ++i) {
+ if (numbers[i] > 255) {
+ return failure;
+ }
+ }
+ if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) {
+ return failure;
+ }
+
+ let ipv4 = numbers.pop();
+ let counter = 0;
+
+ for (const n of numbers) {
+ ipv4 += n * Math.pow(256, 3 - counter);
+ ++counter;
+ }
+
+ return ipv4;
+}
+
+function serializeIPv4(address) {
+ let output = "";
+ let n = address;
+
+ for (let i = 1; i <= 4; ++i) {
+ output = String(n % 256) + output;
+ if (i !== 4) {
+ output = "." + output;
+ }
+ n = Math.floor(n / 256);
+ }
+
+ return output;
+}
+
+function parseIPv6(input) {
+ const address = [0, 0, 0, 0, 0, 0, 0, 0];
+ let pieceIndex = 0;
+ let compress = null;
+ let pointer = 0;
+
+ input = punycode.ucs2.decode(input);
+
+ if (input[pointer] === 58) {
+ if (input[pointer + 1] !== 58) {
+ return failure;
+ }
+
+ pointer += 2;
+ ++pieceIndex;
+ compress = pieceIndex;
+ }
+
+ while (pointer < input.length) {
+ if (pieceIndex === 8) {
+ return failure;
+ }
+
+ if (input[pointer] === 58) {
+ if (compress !== null) {
+ return failure;
+ }
+ ++pointer;
+ ++pieceIndex;
+ compress = pieceIndex;
+ continue;
+ }
+
+ let value = 0;
+ let length = 0;
+
+ while (length < 4 && isASCIIHex(input[pointer])) {
+ value = value * 0x10 + parseInt(at(input, pointer), 16);
+ ++pointer;
+ ++length;
+ }
+
+ if (input[pointer] === 46) {
+ if (length === 0) {
+ return failure;
+ }
+
+ pointer -= length;
+
+ if (pieceIndex > 6) {
+ return failure;
+ }
+
+ let numbersSeen = 0;
+
+ while (input[pointer] !== undefined) {
+ let ipv4Piece = null;
+
+ if (numbersSeen > 0) {
+ if (input[pointer] === 46 && numbersSeen < 4) {
+ ++pointer;
+ } else {
+ return failure;
+ }
+ }
+
+ if (!isASCIIDigit(input[pointer])) {
+ return failure;
+ }
+
+ while (isASCIIDigit(input[pointer])) {
+ const number = parseInt(at(input, pointer));
+ if (ipv4Piece === null) {
+ ipv4Piece = number;
+ } else if (ipv4Piece === 0) {
+ return failure;
+ } else {
+ ipv4Piece = ipv4Piece * 10 + number;
+ }
+ if (ipv4Piece > 255) {
+ return failure;
+ }
+ ++pointer;
+ }
+
+ address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece;
+
+ ++numbersSeen;
+
+ if (numbersSeen === 2 || numbersSeen === 4) {
+ ++pieceIndex;
+ }
+ }
+
+ if (numbersSeen !== 4) {
+ return failure;
+ }
+
+ break;
+ } else if (input[pointer] === 58) {
+ ++pointer;
+ if (input[pointer] === undefined) {
+ return failure;
+ }
+ } else if (input[pointer] !== undefined) {
+ return failure;
+ }
+
+ address[pieceIndex] = value;
+ ++pieceIndex;
+ }
+
+ if (compress !== null) {
+ let swaps = pieceIndex - compress;
+ pieceIndex = 7;
+ while (pieceIndex !== 0 && swaps > 0) {
+ const temp = address[compress + swaps - 1];
+ address[compress + swaps - 1] = address[pieceIndex];
+ address[pieceIndex] = temp;
+ --pieceIndex;
+ --swaps;
+ }
+ } else if (compress === null && pieceIndex !== 8) {
+ return failure;
+ }
+
+ return address;
+}
+
+function serializeIPv6(address) {
+ let output = "";
+ const seqResult = findLongestZeroSequence(address);
+ const compress = seqResult.idx;
+ let ignore0 = false;
+
+ for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) {
+ if (ignore0 && address[pieceIndex] === 0) {
+ continue;
+ } else if (ignore0) {
+ ignore0 = false;
+ }
+
+ if (compress === pieceIndex) {
+ const separator = pieceIndex === 0 ? "::" : ":";
+ output += separator;
+ ignore0 = true;
+ continue;
+ }
+
+ output += address[pieceIndex].toString(16);
+
+ if (pieceIndex !== 7) {
+ output += ":";
+ }
+ }
+
+ return output;
+}
+
+function parseHost(input, isSpecialArg) {
+ if (input[0] === "[") {
+ if (input[input.length - 1] !== "]") {
+ return failure;
+ }
+
+ return parseIPv6(input.substring(1, input.length - 1));
+ }
+
+ if (!isSpecialArg) {
+ return parseOpaqueHost(input);
+ }
+
+ const domain = utf8PercentDecode(input);
+ const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false);
+ if (asciiDomain === null) {
+ return failure;
+ }
+
+ if (containsForbiddenHostCodePoint(asciiDomain)) {
+ return failure;
+ }
+
+ const ipv4Host = parseIPv4(asciiDomain);
+ if (typeof ipv4Host === "number" || ipv4Host === failure) {
+ return ipv4Host;
+ }
+
+ return asciiDomain;
+}
+
+function parseOpaqueHost(input) {
+ if (containsForbiddenHostCodePointExcludingPercent(input)) {
+ return failure;
+ }
+
+ let output = "";
+ const decoded = punycode.ucs2.decode(input);
+ for (let i = 0; i < decoded.length; ++i) {
+ output += percentEncodeChar(decoded[i], isC0ControlPercentEncode);
+ }
+ return output;
+}
+
+function findLongestZeroSequence(arr) {
+ let maxIdx = null;
+ let maxLen = 1; // only find elements > 1
+ let currStart = null;
+ let currLen = 0;
+
+ for (let i = 0; i < arr.length; ++i) {
+ if (arr[i] !== 0) {
+ if (currLen > maxLen) {
+ maxIdx = currStart;
+ maxLen = currLen;
+ }
+
+ currStart = null;
+ currLen = 0;
+ } else {
+ if (currStart === null) {
+ currStart = i;
+ }
+ ++currLen;
+ }
+ }
+
+ // if trailing zeros
+ if (currLen > maxLen) {
+ maxIdx = currStart;
+ maxLen = currLen;
+ }
+
+ return {
+ idx: maxIdx,
+ len: maxLen
+ };
+}
+
+function serializeHost(host) {
+ if (typeof host === "number") {
+ return serializeIPv4(host);
+ }
+
+ // IPv6 serializer
+ if (host instanceof Array) {
+ return "[" + serializeIPv6(host) + "]";
+ }
+
+ return host;
+}
+
+function trimControlChars(url) {
+ return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, "");
+}
+
+function trimTabAndNewline(url) {
+ return url.replace(/\u0009|\u000A|\u000D/g, "");
+}
+
+function shortenPath(url) {
+ const path = url.path;
+ if (path.length === 0) {
+ return;
+ }
+ if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) {
+ return;
+ }
+
+ path.pop();
+}
+
+function includesCredentials(url) {
+ return url.username !== "" || url.password !== "";
+}
+
+function cannotHaveAUsernamePasswordPort(url) {
+ return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file";
+}
+
+function isNormalizedWindowsDriveLetter(string) {
+ return /^[A-Za-z]:$/.test(string);
+}
+
+function URLStateMachine(input, base, encodingOverride, url, stateOverride) {
+ this.pointer = 0;
+ this.input = input;
+ this.base = base || null;
+ this.encodingOverride = encodingOverride || "utf-8";
+ this.stateOverride = stateOverride;
+ this.url = url;
+ this.failure = false;
+ this.parseError = false;
+
+ if (!this.url) {
+ this.url = {
+ scheme: "",
+ username: "",
+ password: "",
+ host: null,
+ port: null,
+ path: [],
+ query: null,
+ fragment: null,
+
+ cannotBeABaseURL: false
+ };
+
+ const res = trimControlChars(this.input);
+ if (res !== this.input) {
+ this.parseError = true;
+ }
+ this.input = res;
+ }
+
+ const res = trimTabAndNewline(this.input);
+ if (res !== this.input) {
+ this.parseError = true;
+ }
+ this.input = res;
+
+ this.state = stateOverride || "scheme start";
+
+ this.buffer = "";
+ this.atFlag = false;
+ this.arrFlag = false;
+ this.passwordTokenSeenFlag = false;
+
+ this.input = punycode.ucs2.decode(this.input);
+
+ for (; this.pointer <= this.input.length; ++this.pointer) {
+ const c = this.input[this.pointer];
+ const cStr = isNaN(c) ? undefined : String.fromCodePoint(c);
+
+ // exec state machine
+ const ret = this["parse " + this.state](c, cStr);
+ if (!ret) {
+ break; // terminate algorithm
+ } else if (ret === failure) {
+ this.failure = true;
+ break;
+ }
+ }
+}
+
+URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) {
+ if (isASCIIAlpha(c)) {
+ this.buffer += cStr.toLowerCase();
+ this.state = "scheme";
+ } else if (!this.stateOverride) {
+ this.state = "no scheme";
+ --this.pointer;
+ } else {
+ this.parseError = true;
+ return failure;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) {
+ if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) {
+ this.buffer += cStr.toLowerCase();
+ } else if (c === 58) {
+ if (this.stateOverride) {
+ if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) {
+ return false;
+ }
+
+ if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) {
+ return false;
+ }
+
+ if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") {
+ return false;
+ }
+
+ if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) {
+ return false;
+ }
+ }
+ this.url.scheme = this.buffer;
+ this.buffer = "";
+ if (this.stateOverride) {
+ return false;
+ }
+ if (this.url.scheme === "file") {
+ if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) {
+ this.parseError = true;
+ }
+ this.state = "file";
+ } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) {
+ this.state = "special relative or authority";
+ } else if (isSpecial(this.url)) {
+ this.state = "special authority slashes";
+ } else if (this.input[this.pointer + 1] === 47) {
+ this.state = "path or authority";
+ ++this.pointer;
+ } else {
+ this.url.cannotBeABaseURL = true;
+ this.url.path.push("");
+ this.state = "cannot-be-a-base-URL path";
+ }
+ } else if (!this.stateOverride) {
+ this.buffer = "";
+ this.state = "no scheme";
+ this.pointer = -1;
+ } else {
+ this.parseError = true;
+ return failure;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) {
+ if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) {
+ return failure;
+ } else if (this.base.cannotBeABaseURL && c === 35) {
+ this.url.scheme = this.base.scheme;
+ this.url.path = this.base.path.slice();
+ this.url.query = this.base.query;
+ this.url.fragment = "";
+ this.url.cannotBeABaseURL = true;
+ this.state = "fragment";
+ } else if (this.base.scheme === "file") {
+ this.state = "file";
+ --this.pointer;
+ } else {
+ this.state = "relative";
+ --this.pointer;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) {
+ if (c === 47 && this.input[this.pointer + 1] === 47) {
+ this.state = "special authority ignore slashes";
+ ++this.pointer;
+ } else {
+ this.parseError = true;
+ this.state = "relative";
+ --this.pointer;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) {
+ if (c === 47) {
+ this.state = "authority";
+ } else {
+ this.state = "path";
+ --this.pointer;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse relative"] = function parseRelative(c) {
+ this.url.scheme = this.base.scheme;
+ if (isNaN(c)) {
+ this.url.username = this.base.username;
+ this.url.password = this.base.password;
+ this.url.host = this.base.host;
+ this.url.port = this.base.port;
+ this.url.path = this.base.path.slice();
+ this.url.query = this.base.query;
+ } else if (c === 47) {
+ this.state = "relative slash";
+ } else if (c === 63) {
+ this.url.username = this.base.username;
+ this.url.password = this.base.password;
+ this.url.host = this.base.host;
+ this.url.port = this.base.port;
+ this.url.path = this.base.path.slice();
+ this.url.query = "";
+ this.state = "query";
+ } else if (c === 35) {
+ this.url.username = this.base.username;
+ this.url.password = this.base.password;
+ this.url.host = this.base.host;
+ this.url.port = this.base.port;
+ this.url.path = this.base.path.slice();
+ this.url.query = this.base.query;
+ this.url.fragment = "";
+ this.state = "fragment";
+ } else if (isSpecial(this.url) && c === 92) {
+ this.parseError = true;
+ this.state = "relative slash";
+ } else {
+ this.url.username = this.base.username;
+ this.url.password = this.base.password;
+ this.url.host = this.base.host;
+ this.url.port = this.base.port;
+ this.url.path = this.base.path.slice(0, this.base.path.length - 1);
+
+ this.state = "path";
+ --this.pointer;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) {
+ if (isSpecial(this.url) && (c === 47 || c === 92)) {
+ if (c === 92) {
+ this.parseError = true;
+ }
+ this.state = "special authority ignore slashes";
+ } else if (c === 47) {
+ this.state = "authority";
+ } else {
+ this.url.username = this.base.username;
+ this.url.password = this.base.password;
+ this.url.host = this.base.host;
+ this.url.port = this.base.port;
+ this.state = "path";
+ --this.pointer;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) {
+ if (c === 47 && this.input[this.pointer + 1] === 47) {
+ this.state = "special authority ignore slashes";
+ ++this.pointer;
+ } else {
+ this.parseError = true;
+ this.state = "special authority ignore slashes";
+ --this.pointer;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) {
+ if (c !== 47 && c !== 92) {
+ this.state = "authority";
+ --this.pointer;
+ } else {
+ this.parseError = true;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) {
+ if (c === 64) {
+ this.parseError = true;
+ if (this.atFlag) {
+ this.buffer = "%40" + this.buffer;
+ }
+ this.atFlag = true;
+
+ // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars
+ const len = countSymbols(this.buffer);
+ for (let pointer = 0; pointer < len; ++pointer) {
+ const codePoint = this.buffer.codePointAt(pointer);
+
+ if (codePoint === 58 && !this.passwordTokenSeenFlag) {
+ this.passwordTokenSeenFlag = true;
+ continue;
+ }
+ const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode);
+ if (this.passwordTokenSeenFlag) {
+ this.url.password += encodedCodePoints;
+ } else {
+ this.url.username += encodedCodePoints;
+ }
+ }
+ this.buffer = "";
+ } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||
+ (isSpecial(this.url) && c === 92)) {
+ if (this.atFlag && this.buffer === "") {
+ this.parseError = true;
+ return failure;
+ }
+ this.pointer -= countSymbols(this.buffer) + 1;
+ this.buffer = "";
+ this.state = "host";
+ } else {
+ this.buffer += cStr;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse hostname"] =
+URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) {
+ if (this.stateOverride && this.url.scheme === "file") {
+ --this.pointer;
+ this.state = "file host";
+ } else if (c === 58 && !this.arrFlag) {
+ if (this.buffer === "") {
+ this.parseError = true;
+ return failure;
+ }
+
+ const host = parseHost(this.buffer, isSpecial(this.url));
+ if (host === failure) {
+ return failure;
+ }
+
+ this.url.host = host;
+ this.buffer = "";
+ this.state = "port";
+ if (this.stateOverride === "hostname") {
+ return false;
+ }
+ } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||
+ (isSpecial(this.url) && c === 92)) {
+ --this.pointer;
+ if (isSpecial(this.url) && this.buffer === "") {
+ this.parseError = true;
+ return failure;
+ } else if (this.stateOverride && this.buffer === "" &&
+ (includesCredentials(this.url) || this.url.port !== null)) {
+ this.parseError = true;
+ return false;
+ }
+
+ const host = parseHost(this.buffer, isSpecial(this.url));
+ if (host === failure) {
+ return failure;
+ }
+
+ this.url.host = host;
+ this.buffer = "";
+ this.state = "path start";
+ if (this.stateOverride) {
+ return false;
+ }
+ } else {
+ if (c === 91) {
+ this.arrFlag = true;
+ } else if (c === 93) {
+ this.arrFlag = false;
+ }
+ this.buffer += cStr;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) {
+ if (isASCIIDigit(c)) {
+ this.buffer += cStr;
+ } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||
+ (isSpecial(this.url) && c === 92) ||
+ this.stateOverride) {
+ if (this.buffer !== "") {
+ const port = parseInt(this.buffer);
+ if (port > Math.pow(2, 16) - 1) {
+ this.parseError = true;
+ return failure;
+ }
+ this.url.port = port === defaultPort(this.url.scheme) ? null : port;
+ this.buffer = "";
+ }
+ if (this.stateOverride) {
+ return false;
+ }
+ this.state = "path start";
+ --this.pointer;
+ } else {
+ this.parseError = true;
+ return failure;
+ }
+
+ return true;
+};
+
+const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]);
+
+URLStateMachine.prototype["parse file"] = function parseFile(c) {
+ this.url.scheme = "file";
+
+ if (c === 47 || c === 92) {
+ if (c === 92) {
+ this.parseError = true;
+ }
+ this.state = "file slash";
+ } else if (this.base !== null && this.base.scheme === "file") {
+ if (isNaN(c)) {
+ this.url.host = this.base.host;
+ this.url.path = this.base.path.slice();
+ this.url.query = this.base.query;
+ } else if (c === 63) {
+ this.url.host = this.base.host;
+ this.url.path = this.base.path.slice();
+ this.url.query = "";
+ this.state = "query";
+ } else if (c === 35) {
+ this.url.host = this.base.host;
+ this.url.path = this.base.path.slice();
+ this.url.query = this.base.query;
+ this.url.fragment = "";
+ this.state = "fragment";
+ } else {
+ if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points
+ !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) ||
+ (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points
+ !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) {
+ this.url.host = this.base.host;
+ this.url.path = this.base.path.slice();
+ shortenPath(this.url);
+ } else {
+ this.parseError = true;
+ }
+
+ this.state = "path";
+ --this.pointer;
+ }
+ } else {
+ this.state = "path";
+ --this.pointer;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) {
+ if (c === 47 || c === 92) {
+ if (c === 92) {
+ this.parseError = true;
+ }
+ this.state = "file host";
+ } else {
+ if (this.base !== null && this.base.scheme === "file") {
+ if (isNormalizedWindowsDriveLetterString(this.base.path[0])) {
+ this.url.path.push(this.base.path[0]);
+ } else {
+ this.url.host = this.base.host;
+ }
+ }
+ this.state = "path";
+ --this.pointer;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) {
+ if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) {
+ --this.pointer;
+ if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) {
+ this.parseError = true;
+ this.state = "path";
+ } else if (this.buffer === "") {
+ this.url.host = "";
+ if (this.stateOverride) {
+ return false;
+ }
+ this.state = "path start";
+ } else {
+ let host = parseHost(this.buffer, isSpecial(this.url));
+ if (host === failure) {
+ return failure;
+ }
+ if (host === "localhost") {
+ host = "";
+ }
+ this.url.host = host;
+
+ if (this.stateOverride) {
+ return false;
+ }
+
+ this.buffer = "";
+ this.state = "path start";
+ }
+ } else {
+ this.buffer += cStr;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse path start"] = function parsePathStart(c) {
+ if (isSpecial(this.url)) {
+ if (c === 92) {
+ this.parseError = true;
+ }
+ this.state = "path";
+
+ if (c !== 47 && c !== 92) {
+ --this.pointer;
+ }
+ } else if (!this.stateOverride && c === 63) {
+ this.url.query = "";
+ this.state = "query";
+ } else if (!this.stateOverride && c === 35) {
+ this.url.fragment = "";
+ this.state = "fragment";
+ } else if (c !== undefined) {
+ this.state = "path";
+ if (c !== 47) {
+ --this.pointer;
+ }
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse path"] = function parsePath(c) {
+ if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) ||
+ (!this.stateOverride && (c === 63 || c === 35))) {
+ if (isSpecial(this.url) && c === 92) {
+ this.parseError = true;
+ }
+
+ if (isDoubleDot(this.buffer)) {
+ shortenPath(this.url);
+ if (c !== 47 && !(isSpecial(this.url) && c === 92)) {
+ this.url.path.push("");
+ }
+ } else if (isSingleDot(this.buffer) && c !== 47 &&
+ !(isSpecial(this.url) && c === 92)) {
+ this.url.path.push("");
+ } else if (!isSingleDot(this.buffer)) {
+ if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) {
+ if (this.url.host !== "" && this.url.host !== null) {
+ this.parseError = true;
+ this.url.host = "";
+ }
+ this.buffer = this.buffer[0] + ":";
+ }
+ this.url.path.push(this.buffer);
+ }
+ this.buffer = "";
+ if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) {
+ while (this.url.path.length > 1 && this.url.path[0] === "") {
+ this.parseError = true;
+ this.url.path.shift();
+ }
+ }
+ if (c === 63) {
+ this.url.query = "";
+ this.state = "query";
+ }
+ if (c === 35) {
+ this.url.fragment = "";
+ this.state = "fragment";
+ }
+ } else {
+ // TODO: If c is not a URL code point and not "%", parse error.
+
+ if (c === 37 &&
+ (!isASCIIHex(this.input[this.pointer + 1]) ||
+ !isASCIIHex(this.input[this.pointer + 2]))) {
+ this.parseError = true;
+ }
+
+ this.buffer += percentEncodeChar(c, isPathPercentEncode);
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) {
+ if (c === 63) {
+ this.url.query = "";
+ this.state = "query";
+ } else if (c === 35) {
+ this.url.fragment = "";
+ this.state = "fragment";
+ } else {
+ // TODO: Add: not a URL code point
+ if (!isNaN(c) && c !== 37) {
+ this.parseError = true;
+ }
+
+ if (c === 37 &&
+ (!isASCIIHex(this.input[this.pointer + 1]) ||
+ !isASCIIHex(this.input[this.pointer + 2]))) {
+ this.parseError = true;
+ }
+
+ if (!isNaN(c)) {
+ this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode);
+ }
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) {
+ if (isNaN(c) || (!this.stateOverride && c === 35)) {
+ if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") {
+ this.encodingOverride = "utf-8";
+ }
+
+ const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead
+ for (let i = 0; i < buffer.length; ++i) {
+ if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 ||
+ buffer[i] === 0x3C || buffer[i] === 0x3E) {
+ this.url.query += percentEncode(buffer[i]);
+ } else {
+ this.url.query += String.fromCodePoint(buffer[i]);
+ }
+ }
+
+ this.buffer = "";
+ if (c === 35) {
+ this.url.fragment = "";
+ this.state = "fragment";
+ }
+ } else {
+ // TODO: If c is not a URL code point and not "%", parse error.
+ if (c === 37 &&
+ (!isASCIIHex(this.input[this.pointer + 1]) ||
+ !isASCIIHex(this.input[this.pointer + 2]))) {
+ this.parseError = true;
+ }
+
+ this.buffer += cStr;
+ }
+
+ return true;
+};
+
+URLStateMachine.prototype["parse fragment"] = function parseFragment(c) {
+ if (isNaN(c)) { // do nothing
+ } else if (c === 0x0) {
+ this.parseError = true;
+ } else {
+ // TODO: If c is not a URL code point and not "%", parse error.
+ if (c === 37 &&
+ (!isASCIIHex(this.input[this.pointer + 1]) ||
+ !isASCIIHex(this.input[this.pointer + 2]))) {
+ this.parseError = true;
+ }
+
+ this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode);
+ }
+
+ return true;
+};
+
+function serializeURL(url, excludeFragment) {
+ let output = url.scheme + ":";
+ if (url.host !== null) {
+ output += "//";
+
+ if (url.username !== "" || url.password !== "") {
+ output += url.username;
+ if (url.password !== "") {
+ output += ":" + url.password;
+ }
+ output += "@";
+ }
+
+ output += serializeHost(url.host);
+
+ if (url.port !== null) {
+ output += ":" + url.port;
+ }
+ } else if (url.host === null && url.scheme === "file") {
+ output += "//";
+ }
+
+ if (url.cannotBeABaseURL) {
+ output += url.path[0];
+ } else {
+ for (const string of url.path) {
+ output += "/" + string;
+ }
+ }
+
+ if (url.query !== null) {
+ output += "?" + url.query;
+ }
+
+ if (!excludeFragment && url.fragment !== null) {
+ output += "#" + url.fragment;
+ }
+
+ return output;
+}
+
+function serializeOrigin(tuple) {
+ let result = tuple.scheme + "://";
+ result += serializeHost(tuple.host);
+
+ if (tuple.port !== null) {
+ result += ":" + tuple.port;
+ }
+
+ return result;
+}
+
+module.exports.serializeURL = serializeURL;
+
+module.exports.serializeURLOrigin = function (url) {
+ // https://url.spec.whatwg.org/#concept-url-origin
+ switch (url.scheme) {
+ case "blob":
+ try {
+ return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0]));
+ } catch (e) {
+ // serializing an opaque origin returns "null"
+ return "null";
+ }
+ case "ftp":
+ case "gopher":
+ case "http":
+ case "https":
+ case "ws":
+ case "wss":
+ return serializeOrigin({
+ scheme: url.scheme,
+ host: url.host,
+ port: url.port
+ });
+ case "file":
+ // spec says "exercise to the reader", chrome says "file://"
+ return "file://";
+ default:
+ // serializing an opaque origin returns "null"
+ return "null";
+ }
+};
+
+module.exports.basicURLParse = function (input, options) {
+ if (options === undefined) {
+ options = {};
+ }
+
+ const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride);
+ if (usm.failure) {
+ return "failure";
+ }
+
+ return usm.url;
+};
+
+module.exports.setTheUsername = function (url, username) {
+ url.username = "";
+ const decoded = punycode.ucs2.decode(username);
+ for (let i = 0; i < decoded.length; ++i) {
+ url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode);
+ }
+};
+
+module.exports.setThePassword = function (url, password) {
+ url.password = "";
+ const decoded = punycode.ucs2.decode(password);
+ for (let i = 0; i < decoded.length; ++i) {
+ url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode);
+ }
+};
+
+module.exports.serializeHost = serializeHost;
+
+module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort;
+
+module.exports.serializeInteger = function (integer) {
+ return String(integer);
+};
+
+module.exports.parseURL = function (input, options) {
+ if (options === undefined) {
+ options = {};
+ }
+
+ // We don't handle blobs, so this just delegates:
+ return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride });
+};
/***/ }),
@@ -104507,6 +104626,378 @@ function cleanEscapedString(input) {
}
+/***/ }),
+
+/***/ 5975:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+exports.parseISO = parseISO;
+var _index = __nccwpck_require__(64278);
+
+var _index2 = __nccwpck_require__(30926);
+var _index3 = __nccwpck_require__(46439);
+
+/**
+ * The {@link parseISO} function options.
+ */
+
+/**
+ * @name parseISO
+ * @category Common Helpers
+ * @summary Parse ISO string
+ *
+ * @description
+ * Parse the given string in ISO 8601 format and return an instance of Date.
+ *
+ * Function accepts complete ISO 8601 formats as well as partial implementations.
+ * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601
+ *
+ * If the argument isn't a string, the function cannot parse the string or
+ * the values are invalid, it returns Invalid Date.
+ *
+ * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
+ *
+ * @param argument - The value to convert
+ * @param options - An object with options
+ *
+ * @returns The parsed date in the local time zone
+ *
+ * @example
+ * // Convert string '2014-02-11T11:30:30' to date:
+ * const result = parseISO('2014-02-11T11:30:30')
+ * //=> Tue Feb 11 2014 11:30:30
+ *
+ * @example
+ * // Convert string '+02014101' to date,
+ * // if the additional number of digits in the extended year format is 1:
+ * const result = parseISO('+02014101', { additionalDigits: 1 })
+ * //=> Fri Apr 11 2014 00:00:00
+ */
+function parseISO(argument, options) {
+ const invalidDate = () => (0, _index2.constructFrom)(options?.in, NaN);
+
+ const additionalDigits = options?.additionalDigits ?? 2;
+ const dateStrings = splitDateString(argument);
+
+ let date;
+ if (dateStrings.date) {
+ const parseYearResult = parseYear(dateStrings.date, additionalDigits);
+ date = parseDate(parseYearResult.restDateString, parseYearResult.year);
+ }
+
+ if (!date || isNaN(+date)) return invalidDate();
+
+ const timestamp = +date;
+ let time = 0;
+ let offset;
+
+ if (dateStrings.time) {
+ time = parseTime(dateStrings.time);
+ if (isNaN(time)) return invalidDate();
+ }
+
+ if (dateStrings.timezone) {
+ offset = parseTimezone(dateStrings.timezone);
+ if (isNaN(offset)) return invalidDate();
+ } else {
+ const tmpDate = new Date(timestamp + time);
+ const result = (0, _index3.toDate)(0, options?.in);
+ result.setFullYear(
+ tmpDate.getUTCFullYear(),
+ tmpDate.getUTCMonth(),
+ tmpDate.getUTCDate(),
+ );
+ result.setHours(
+ tmpDate.getUTCHours(),
+ tmpDate.getUTCMinutes(),
+ tmpDate.getUTCSeconds(),
+ tmpDate.getUTCMilliseconds(),
+ );
+ return result;
+ }
+
+ return (0, _index3.toDate)(timestamp + time + offset, options?.in);
+}
+
+const patterns = {
+ dateTimeDelimiter: /[T ]/,
+ timeZoneDelimiter: /[Z ]/i,
+ timezone: /([Z+-].*)$/,
+};
+
+const dateRegex =
+ /^-?(?:(\d{3})|(\d{2})(?:-?(\d{2}))?|W(\d{2})(?:-?(\d{1}))?|)$/;
+const timeRegex =
+ /^(\d{2}(?:[.,]\d*)?)(?::?(\d{2}(?:[.,]\d*)?))?(?::?(\d{2}(?:[.,]\d*)?))?$/;
+const timezoneRegex = /^([+-])(\d{2})(?::?(\d{2}))?$/;
+
+function splitDateString(dateString) {
+ const dateStrings = {};
+ const array = dateString.split(patterns.dateTimeDelimiter);
+ let timeString;
+
+ // The regex match should only return at maximum two array elements.
+ // [date], [time], or [date, time].
+ if (array.length > 2) {
+ return dateStrings;
+ }
+
+ if (/:/.test(array[0])) {
+ timeString = array[0];
+ } else {
+ dateStrings.date = array[0];
+ timeString = array[1];
+ if (patterns.timeZoneDelimiter.test(dateStrings.date)) {
+ dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0];
+ timeString = dateString.substr(
+ dateStrings.date.length,
+ dateString.length,
+ );
+ }
+ }
+
+ if (timeString) {
+ const token = patterns.timezone.exec(timeString);
+ if (token) {
+ dateStrings.time = timeString.replace(token[1], "");
+ dateStrings.timezone = token[1];
+ } else {
+ dateStrings.time = timeString;
+ }
+ }
+
+ return dateStrings;
+}
+
+function parseYear(dateString, additionalDigits) {
+ const regex = new RegExp(
+ "^(?:(\\d{4}|[+-]\\d{" +
+ (4 + additionalDigits) +
+ "})|(\\d{2}|[+-]\\d{" +
+ (2 + additionalDigits) +
+ "})$)",
+ );
+
+ const captures = dateString.match(regex);
+ // Invalid ISO-formatted year
+ if (!captures) return { year: NaN, restDateString: "" };
+
+ const year = captures[1] ? parseInt(captures[1]) : null;
+ const century = captures[2] ? parseInt(captures[2]) : null;
+
+ // either year or century is null, not both
+ return {
+ year: century === null ? year : century * 100,
+ restDateString: dateString.slice((captures[1] || captures[2]).length),
+ };
+}
+
+function parseDate(dateString, year) {
+ // Invalid ISO-formatted year
+ if (year === null) return new Date(NaN);
+
+ const captures = dateString.match(dateRegex);
+ // Invalid ISO-formatted string
+ if (!captures) return new Date(NaN);
+
+ const isWeekDate = !!captures[4];
+ const dayOfYear = parseDateUnit(captures[1]);
+ const month = parseDateUnit(captures[2]) - 1;
+ const day = parseDateUnit(captures[3]);
+ const week = parseDateUnit(captures[4]);
+ const dayOfWeek = parseDateUnit(captures[5]) - 1;
+
+ if (isWeekDate) {
+ if (!validateWeekDate(year, week, dayOfWeek)) {
+ return new Date(NaN);
+ }
+ return dayOfISOWeekYear(year, week, dayOfWeek);
+ } else {
+ const date = new Date(0);
+ if (
+ !validateDate(year, month, day) ||
+ !validateDayOfYearDate(year, dayOfYear)
+ ) {
+ return new Date(NaN);
+ }
+ date.setUTCFullYear(year, month, Math.max(dayOfYear, day));
+ return date;
+ }
+}
+
+function parseDateUnit(value) {
+ return value ? parseInt(value) : 1;
+}
+
+function parseTime(timeString) {
+ const captures = timeString.match(timeRegex);
+ if (!captures) return NaN; // Invalid ISO-formatted time
+
+ const hours = parseTimeUnit(captures[1]);
+ const minutes = parseTimeUnit(captures[2]);
+ const seconds = parseTimeUnit(captures[3]);
+
+ if (!validateTime(hours, minutes, seconds)) {
+ return NaN;
+ }
+
+ return (
+ hours * _index.millisecondsInHour +
+ minutes * _index.millisecondsInMinute +
+ seconds * 1000
+ );
+}
+
+function parseTimeUnit(value) {
+ return (value && parseFloat(value.replace(",", "."))) || 0;
+}
+
+function parseTimezone(timezoneString) {
+ if (timezoneString === "Z") return 0;
+
+ const captures = timezoneString.match(timezoneRegex);
+ if (!captures) return 0;
+
+ const sign = captures[1] === "+" ? -1 : 1;
+ const hours = parseInt(captures[2]);
+ const minutes = (captures[3] && parseInt(captures[3])) || 0;
+
+ if (!validateTimezone(hours, minutes)) {
+ return NaN;
+ }
+
+ return (
+ sign *
+ (hours * _index.millisecondsInHour + minutes * _index.millisecondsInMinute)
+ );
+}
+
+function dayOfISOWeekYear(isoWeekYear, week, day) {
+ const date = new Date(0);
+ date.setUTCFullYear(isoWeekYear, 0, 4);
+ const fourthOfJanuaryDay = date.getUTCDay() || 7;
+ const diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay;
+ date.setUTCDate(date.getUTCDate() + diff);
+ return date;
+}
+
+// Validation functions
+
+// February is null to handle the leap year (using ||)
+const daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+function isLeapYearIndex(year) {
+ return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);
+}
+
+function validateDate(year, month, date) {
+ return (
+ month >= 0 &&
+ month <= 11 &&
+ date >= 1 &&
+ date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28))
+ );
+}
+
+function validateDayOfYearDate(year, dayOfYear) {
+ return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365);
+}
+
+function validateWeekDate(_year, week, day) {
+ return week >= 1 && week <= 53 && day >= 0 && day <= 6;
+}
+
+function validateTime(hours, minutes, seconds) {
+ if (hours === 24) {
+ return minutes === 0 && seconds === 0;
+ }
+
+ return (
+ seconds >= 0 &&
+ seconds < 60 &&
+ minutes >= 0 &&
+ minutes < 60 &&
+ hours >= 0 &&
+ hours < 25
+ );
+}
+
+function validateTimezone(_hours, minutes) {
+ return minutes >= 0 && minutes <= 59;
+}
+
+
+/***/ }),
+
+/***/ 25531:
+/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
+
+"use strict";
+
+exports.parseJSON = parseJSON;
+var _index = __nccwpck_require__(46439);
+
+/**
+ * The {@link parseJSON} function options.
+ */
+
+/**
+ * Converts a complete ISO date string in UTC time, the typical format for transmitting
+ * a date in JSON, to a JavaScript `Date` instance.
+ *
+ * This is a minimal implementation for converting dates retrieved from a JSON API to
+ * a `Date` instance which can be used with other functions in the `date-fns` library.
+ * The following formats are supported:
+ *
+ * - `2000-03-15T05:20:10.123Z`: The output of `.toISOString()` and `JSON.stringify(new Date())`
+ * - `2000-03-15T05:20:10Z`: Without milliseconds
+ * - `2000-03-15T05:20:10+00:00`: With a zero offset, the default JSON encoded format in some other languages
+ * - `2000-03-15T05:20:10+05:45`: With a positive or negative offset, the default JSON encoded format in some other languages
+ * - `2000-03-15T05:20:10+0000`: With a zero offset without a colon
+ * - `2000-03-15T05:20:10`: Without a trailing 'Z' symbol
+ * - `2000-03-15T05:20:10.1234567`: Up to 7 digits in milliseconds field. Only first 3 are taken into account since JS does not allow fractional milliseconds
+ * - `2000-03-15 05:20:10`: With a space instead of a 'T' separator for APIs returning a SQL date without reformatting
+ *
+ * For convenience and ease of use these other input types are also supported
+ * via [toDate](https://date-fns.org/docs/toDate):
+ *
+ * - A `Date` instance will be cloned
+ * - A `number` will be treated as a timestamp
+ *
+ * Any other input type or invalid date strings will return an `Invalid Date`.
+ *
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
+ *
+ * @param dateStr - A fully formed ISO8601 date string to convert
+ * @param options - An object with options
+ *
+ * @returns The parsed date in the local time zone
+ */
+function parseJSON(dateStr, options) {
+ const parts = dateStr.match(
+ /(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2})(?:\.(\d{0,7}))?(?:Z|(.)(\d{2}):?(\d{2})?)?/,
+ );
+
+ if (!parts) return (0, _index.toDate)(NaN, options?.in);
+
+ return (0, _index.toDate)(
+ Date.UTC(
+ +parts[1],
+ +parts[2] - 1,
+ +parts[3],
+ +parts[4] - (+parts[9] || 0) * (parts[8] == "-" ? -1 : 1),
+ +parts[5] - (+parts[10] || 0) * (parts[8] == "-" ? -1 : 1),
+ +parts[6],
+ +((parts[7] || "0") + "00").substring(0, 3),
+ ),
+ options?.in,
+ );
+}
+
+
/***/ }),
/***/ 24759:
@@ -107039,378 +107530,6 @@ function isLeapYearIndex(year) {
}
-/***/ }),
-
-/***/ 5975:
-/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
-
-"use strict";
-
-exports.parseISO = parseISO;
-var _index = __nccwpck_require__(64278);
-
-var _index2 = __nccwpck_require__(30926);
-var _index3 = __nccwpck_require__(46439);
-
-/**
- * The {@link parseISO} function options.
- */
-
-/**
- * @name parseISO
- * @category Common Helpers
- * @summary Parse ISO string
- *
- * @description
- * Parse the given string in ISO 8601 format and return an instance of Date.
- *
- * Function accepts complete ISO 8601 formats as well as partial implementations.
- * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601
- *
- * If the argument isn't a string, the function cannot parse the string or
- * the values are invalid, it returns Invalid Date.
- *
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
- *
- * @param argument - The value to convert
- * @param options - An object with options
- *
- * @returns The parsed date in the local time zone
- *
- * @example
- * // Convert string '2014-02-11T11:30:30' to date:
- * const result = parseISO('2014-02-11T11:30:30')
- * //=> Tue Feb 11 2014 11:30:30
- *
- * @example
- * // Convert string '+02014101' to date,
- * // if the additional number of digits in the extended year format is 1:
- * const result = parseISO('+02014101', { additionalDigits: 1 })
- * //=> Fri Apr 11 2014 00:00:00
- */
-function parseISO(argument, options) {
- const invalidDate = () => (0, _index2.constructFrom)(options?.in, NaN);
-
- const additionalDigits = options?.additionalDigits ?? 2;
- const dateStrings = splitDateString(argument);
-
- let date;
- if (dateStrings.date) {
- const parseYearResult = parseYear(dateStrings.date, additionalDigits);
- date = parseDate(parseYearResult.restDateString, parseYearResult.year);
- }
-
- if (!date || isNaN(+date)) return invalidDate();
-
- const timestamp = +date;
- let time = 0;
- let offset;
-
- if (dateStrings.time) {
- time = parseTime(dateStrings.time);
- if (isNaN(time)) return invalidDate();
- }
-
- if (dateStrings.timezone) {
- offset = parseTimezone(dateStrings.timezone);
- if (isNaN(offset)) return invalidDate();
- } else {
- const tmpDate = new Date(timestamp + time);
- const result = (0, _index3.toDate)(0, options?.in);
- result.setFullYear(
- tmpDate.getUTCFullYear(),
- tmpDate.getUTCMonth(),
- tmpDate.getUTCDate(),
- );
- result.setHours(
- tmpDate.getUTCHours(),
- tmpDate.getUTCMinutes(),
- tmpDate.getUTCSeconds(),
- tmpDate.getUTCMilliseconds(),
- );
- return result;
- }
-
- return (0, _index3.toDate)(timestamp + time + offset, options?.in);
-}
-
-const patterns = {
- dateTimeDelimiter: /[T ]/,
- timeZoneDelimiter: /[Z ]/i,
- timezone: /([Z+-].*)$/,
-};
-
-const dateRegex =
- /^-?(?:(\d{3})|(\d{2})(?:-?(\d{2}))?|W(\d{2})(?:-?(\d{1}))?|)$/;
-const timeRegex =
- /^(\d{2}(?:[.,]\d*)?)(?::?(\d{2}(?:[.,]\d*)?))?(?::?(\d{2}(?:[.,]\d*)?))?$/;
-const timezoneRegex = /^([+-])(\d{2})(?::?(\d{2}))?$/;
-
-function splitDateString(dateString) {
- const dateStrings = {};
- const array = dateString.split(patterns.dateTimeDelimiter);
- let timeString;
-
- // The regex match should only return at maximum two array elements.
- // [date], [time], or [date, time].
- if (array.length > 2) {
- return dateStrings;
- }
-
- if (/:/.test(array[0])) {
- timeString = array[0];
- } else {
- dateStrings.date = array[0];
- timeString = array[1];
- if (patterns.timeZoneDelimiter.test(dateStrings.date)) {
- dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0];
- timeString = dateString.substr(
- dateStrings.date.length,
- dateString.length,
- );
- }
- }
-
- if (timeString) {
- const token = patterns.timezone.exec(timeString);
- if (token) {
- dateStrings.time = timeString.replace(token[1], "");
- dateStrings.timezone = token[1];
- } else {
- dateStrings.time = timeString;
- }
- }
-
- return dateStrings;
-}
-
-function parseYear(dateString, additionalDigits) {
- const regex = new RegExp(
- "^(?:(\\d{4}|[+-]\\d{" +
- (4 + additionalDigits) +
- "})|(\\d{2}|[+-]\\d{" +
- (2 + additionalDigits) +
- "})$)",
- );
-
- const captures = dateString.match(regex);
- // Invalid ISO-formatted year
- if (!captures) return { year: NaN, restDateString: "" };
-
- const year = captures[1] ? parseInt(captures[1]) : null;
- const century = captures[2] ? parseInt(captures[2]) : null;
-
- // either year or century is null, not both
- return {
- year: century === null ? year : century * 100,
- restDateString: dateString.slice((captures[1] || captures[2]).length),
- };
-}
-
-function parseDate(dateString, year) {
- // Invalid ISO-formatted year
- if (year === null) return new Date(NaN);
-
- const captures = dateString.match(dateRegex);
- // Invalid ISO-formatted string
- if (!captures) return new Date(NaN);
-
- const isWeekDate = !!captures[4];
- const dayOfYear = parseDateUnit(captures[1]);
- const month = parseDateUnit(captures[2]) - 1;
- const day = parseDateUnit(captures[3]);
- const week = parseDateUnit(captures[4]);
- const dayOfWeek = parseDateUnit(captures[5]) - 1;
-
- if (isWeekDate) {
- if (!validateWeekDate(year, week, dayOfWeek)) {
- return new Date(NaN);
- }
- return dayOfISOWeekYear(year, week, dayOfWeek);
- } else {
- const date = new Date(0);
- if (
- !validateDate(year, month, day) ||
- !validateDayOfYearDate(year, dayOfYear)
- ) {
- return new Date(NaN);
- }
- date.setUTCFullYear(year, month, Math.max(dayOfYear, day));
- return date;
- }
-}
-
-function parseDateUnit(value) {
- return value ? parseInt(value) : 1;
-}
-
-function parseTime(timeString) {
- const captures = timeString.match(timeRegex);
- if (!captures) return NaN; // Invalid ISO-formatted time
-
- const hours = parseTimeUnit(captures[1]);
- const minutes = parseTimeUnit(captures[2]);
- const seconds = parseTimeUnit(captures[3]);
-
- if (!validateTime(hours, minutes, seconds)) {
- return NaN;
- }
-
- return (
- hours * _index.millisecondsInHour +
- minutes * _index.millisecondsInMinute +
- seconds * 1000
- );
-}
-
-function parseTimeUnit(value) {
- return (value && parseFloat(value.replace(",", "."))) || 0;
-}
-
-function parseTimezone(timezoneString) {
- if (timezoneString === "Z") return 0;
-
- const captures = timezoneString.match(timezoneRegex);
- if (!captures) return 0;
-
- const sign = captures[1] === "+" ? -1 : 1;
- const hours = parseInt(captures[2]);
- const minutes = (captures[3] && parseInt(captures[3])) || 0;
-
- if (!validateTimezone(hours, minutes)) {
- return NaN;
- }
-
- return (
- sign *
- (hours * _index.millisecondsInHour + minutes * _index.millisecondsInMinute)
- );
-}
-
-function dayOfISOWeekYear(isoWeekYear, week, day) {
- const date = new Date(0);
- date.setUTCFullYear(isoWeekYear, 0, 4);
- const fourthOfJanuaryDay = date.getUTCDay() || 7;
- const diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay;
- date.setUTCDate(date.getUTCDate() + diff);
- return date;
-}
-
-// Validation functions
-
-// February is null to handle the leap year (using ||)
-const daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
-
-function isLeapYearIndex(year) {
- return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);
-}
-
-function validateDate(year, month, date) {
- return (
- month >= 0 &&
- month <= 11 &&
- date >= 1 &&
- date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28))
- );
-}
-
-function validateDayOfYearDate(year, dayOfYear) {
- return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365);
-}
-
-function validateWeekDate(_year, week, day) {
- return week >= 1 && week <= 53 && day >= 0 && day <= 6;
-}
-
-function validateTime(hours, minutes, seconds) {
- if (hours === 24) {
- return minutes === 0 && seconds === 0;
- }
-
- return (
- seconds >= 0 &&
- seconds < 60 &&
- minutes >= 0 &&
- minutes < 60 &&
- hours >= 0 &&
- hours < 25
- );
-}
-
-function validateTimezone(_hours, minutes) {
- return minutes >= 0 && minutes <= 59;
-}
-
-
-/***/ }),
-
-/***/ 25531:
-/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
-
-"use strict";
-
-exports.parseJSON = parseJSON;
-var _index = __nccwpck_require__(46439);
-
-/**
- * The {@link parseJSON} function options.
- */
-
-/**
- * Converts a complete ISO date string in UTC time, the typical format for transmitting
- * a date in JSON, to a JavaScript `Date` instance.
- *
- * This is a minimal implementation for converting dates retrieved from a JSON API to
- * a `Date` instance which can be used with other functions in the `date-fns` library.
- * The following formats are supported:
- *
- * - `2000-03-15T05:20:10.123Z`: The output of `.toISOString()` and `JSON.stringify(new Date())`
- * - `2000-03-15T05:20:10Z`: Without milliseconds
- * - `2000-03-15T05:20:10+00:00`: With a zero offset, the default JSON encoded format in some other languages
- * - `2000-03-15T05:20:10+05:45`: With a positive or negative offset, the default JSON encoded format in some other languages
- * - `2000-03-15T05:20:10+0000`: With a zero offset without a colon
- * - `2000-03-15T05:20:10`: Without a trailing 'Z' symbol
- * - `2000-03-15T05:20:10.1234567`: Up to 7 digits in milliseconds field. Only first 3 are taken into account since JS does not allow fractional milliseconds
- * - `2000-03-15 05:20:10`: With a space instead of a 'T' separator for APIs returning a SQL date without reformatting
- *
- * For convenience and ease of use these other input types are also supported
- * via [toDate](https://date-fns.org/docs/toDate):
- *
- * - A `Date` instance will be cloned
- * - A `number` will be treated as a timestamp
- *
- * Any other input type or invalid date strings will return an `Invalid Date`.
- *
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
- *
- * @param dateStr - A fully formed ISO8601 date string to convert
- * @param options - An object with options
- *
- * @returns The parsed date in the local time zone
- */
-function parseJSON(dateStr, options) {
- const parts = dateStr.match(
- /(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2})(?:\.(\d{0,7}))?(?:Z|(.)(\d{2}):?(\d{2})?)?/,
- );
-
- if (!parts) return (0, _index.toDate)(NaN, options?.in);
-
- return (0, _index.toDate)(
- Date.UTC(
- +parts[1],
- +parts[2] - 1,
- +parts[3],
- +parts[4] - (+parts[9] || 0) * (parts[8] == "-" ? -1 : 1),
- +parts[5] - (+parts[10] || 0) * (parts[8] == "-" ? -1 : 1),
- +parts[6],
- +((parts[7] || "0") + "00").substring(0, 3),
- ),
- options?.in,
- );
-}
-
-
/***/ }),
/***/ 61930:
diff --git a/src/action/decorate/action.ts b/src/action/decorate/action.ts
index d39be771..8a09f8eb 100644
--- a/src/action/decorate/action.ts
+++ b/src/action/decorate/action.ts
@@ -12,9 +12,9 @@ import { Analysis, AnalysisResult } from '../../helper/interfaces';
export async function decorateAction(analysisResult: AnalysisResult | undefined, analysis: Analysis): Promise {
let summaryBody;
if (analysisResult) {
- summaryBody = createSummaryBody(analysisResult);
+ summaryBody = await createSummaryBody(analysisResult);
} else {
- summaryBody = createErrorSummaryBody(analysis.errorList, analysis.warningList);
+ summaryBody = await createErrorSummaryBody(analysis.errorList, analysis.warningList);
}
if (githubConfig.event.isPullRequest) {
diff --git a/src/action/decorate/markdown.ts b/src/action/decorate/markdown.ts
index ac08af29..68c8a9e8 100644
--- a/src/action/decorate/markdown.ts
+++ b/src/action/decorate/markdown.ts
@@ -30,3 +30,19 @@ export function generateStatusMarkdown(status: Status, hasSuffix = false): strin
export function generateExpandableAreaMarkdown(header: string, body: string): string {
return `${header}
${EOL}${body} ${EOL}${EOL}`;
}
+
+/**
+ * Generates italic text for markdown.
+ * @param text The text to make italic.
+ */
+export function generateItalic(text: string, title?: string): string {
+ return `${text}`;
+}
+
+/**
+ * Generates a hidden comment for markdown.
+ * @param comment The text of the comment.
+ */
+export function generateComment(comment: string): string {
+ return ``;
+}
diff --git a/src/action/decorate/summary.ts b/src/action/decorate/summary.ts
index 1d62f523..b99d69b4 100644
--- a/src/action/decorate/summary.ts
+++ b/src/action/decorate/summary.ts
@@ -3,7 +3,6 @@ import { format } from 'date-fns';
import { range } from 'underscore';
import { summary } from '@actions/core';
import { SummaryTableRow } from '@actions/core/lib/summary';
-
import { ChangedFile } from '../../github/interfaces';
import { Status } from '../../helper/enums';
import { logger } from '../../helper/logger';
@@ -17,15 +16,15 @@ import {
TicsReviewComment,
TicsReviewComments
} from '../../helper/interfaces';
-import { generateExpandableAreaMarkdown, generateStatusMarkdown } from './markdown';
+import { generateComment, generateExpandableAreaMarkdown, generateItalic, generateStatusMarkdown } from './markdown';
import { githubConfig, ticsConfig } from '../../configuration/config';
+import { getCurrentStepPath } from '../../github/runs';
const capitalize = (s: string): string => s && String(s[0]).toUpperCase() + String(s).slice(1);
-export function createSummaryBody(analysisResult: AnalysisResult): string {
+export async function createSummaryBody(analysisResult: AnalysisResult): Promise {
logger.header('Creating summary.');
- summary.addHeading('TICS Quality Gate');
- summary.addHeading(generateStatusMarkdown(getStatus(analysisResult.passed, analysisResult.passedWithWarning), true), 3);
+ setSummaryHeader(getStatus(analysisResult.passed, analysisResult.passedWithWarning));
analysisResult.projectResults.forEach(projectResult => {
if (projectResult.qualityGate) {
@@ -56,6 +55,7 @@ export function createSummaryBody(analysisResult: AnalysisResult): string {
summary.addRaw(createFilesSummary(projectResult.analyzedFiles));
}
});
+ await setSummaryFooter();
logger.info('Created summary.');
@@ -68,11 +68,10 @@ export function createSummaryBody(analysisResult: AnalysisResult): string {
* @param warningList list containing all the warnings found in the TICS run.
* @returns string containing the error summary.
*/
-export function createErrorSummaryBody(errorList: string[], warningList: string[]): string {
+export async function createErrorSummaryBody(errorList: string[], warningList: string[]): Promise {
logger.header('Creating summary.');
- summary.addHeading('TICS Quality Gate');
- summary.addHeading(generateStatusMarkdown(Status.FAILED, true), 3);
+ setSummaryHeader(Status.FAILED);
if (errorList.length > 0) {
summary.addHeading('The following errors have occurred during analysis:', 2);
@@ -90,6 +89,7 @@ export function createErrorSummaryBody(errorList: string[], warningList: string[
summary.addRaw(`:warning: ${warning}${EOL}${EOL}`);
}
}
+ await setSummaryFooter();
logger.info('Created summary.');
return summary.stringify();
@@ -100,18 +100,30 @@ export function createErrorSummaryBody(errorList: string[], warningList: string[
* @param message Message to display in the body of the comment.
* @returns string containing the error summary.
*/
-export function createNothingAnalyzedSummaryBody(message: string): string {
+export async function createNothingAnalyzedSummaryBody(message: string): Promise {
logger.header('Creating summary.');
- summary.addHeading('TICS Quality Gate');
- summary.addHeading(generateStatusMarkdown(Status.PASSED, true), 3);
+ setSummaryHeader(Status.PASSED);
summary.addRaw(message);
+ await setSummaryFooter();
logger.info('Created summary.');
return summary.stringify();
}
+function setSummaryHeader(status: Status) {
+ summary.addHeading('TICS Quality Gate');
+ summary.addHeading(generateStatusMarkdown(status, true), 3);
+}
+
+async function setSummaryFooter() {
+ summary.addEOL();
+ summary.addRaw('');
+ summary.addRaw(generateItalic(await getCurrentStepPath(), 'Workflow / Job / Step'), true);
+ summary.addRaw(generateComment(githubConfig.getCommentIdentifier()));
+}
+
function getConditionHeading(failedOrWarnConditions: Condition[]): string {
const countFailedConditions = failedOrWarnConditions.filter(c => !c.passed).length;
const countWarnConditions = failedOrWarnConditions.filter(c => c.passed && c.passedWithWarning).length;
@@ -378,6 +390,7 @@ function findAnnotationInList(list: ExtendedAnnotation[], annotation: ExtendedAn
* @param unpostableReviewComments Review comments that could not be posted.
* @returns Summary of all the review comments that could not be posted.
*/
+// Exported for testing
export function createUnpostableAnnotationsDetails(unpostableReviewComments: ExtendedAnnotation[]): string {
const label = 'Quality gate failures that cannot be annotated in Files Changed';
let body = '';
diff --git a/src/analysis/client/process-analysis.ts b/src/analysis/client/process-analysis.ts
index 4e858572..ca340a25 100644
--- a/src/analysis/client/process-analysis.ts
+++ b/src/analysis/client/process-analysis.ts
@@ -19,12 +19,12 @@ export async function processIncompleteAnalysis(analysis: Analysis): Promise w.includes('[WARNING 5057]'))) {
- summaryBody = createNothingAnalyzedSummaryBody('No changed files applicable for TICS analysis quality gating.');
+ summaryBody = await createNothingAnalyzedSummaryBody('No changed files applicable for TICS analysis quality gating.');
} else {
failedMessage = 'Explorer URL not returned from TICS analysis.';
- summaryBody = createErrorSummaryBody(analysis.errorList, analysis.warningList);
+ summaryBody = await createErrorSummaryBody(analysis.errorList, analysis.warningList);
}
if (githubConfig.event.isPullRequest) {
diff --git a/src/analysis/qserver.ts b/src/analysis/qserver.ts
index b1818745..c7d5e3f7 100644
--- a/src/analysis/qserver.ts
+++ b/src/analysis/qserver.ts
@@ -28,12 +28,12 @@ export async function qServerAnalysis(): Promise {
if (!verdict.passed) {
verdict.message = 'Failed to complete TICSQServer analysis.';
- const summaryBody = createErrorSummaryBody(analysis.errorList, analysis.warningList);
+ const summaryBody = await createErrorSummaryBody(analysis.errorList, analysis.warningList);
if (githubConfig.event.isPullRequest) {
await postToConversation(false, summaryBody);
}
} else if (analysis.warningList.find(w => w.includes('[WARNING 5057]'))) {
- const summaryBody = createNothingAnalyzedSummaryBody('No changed files applicable for TICS analysis quality gating.');
+ const summaryBody = await createNothingAnalyzedSummaryBody('No changed files applicable for TICS analysis quality gating.');
if (githubConfig.event.isPullRequest) {
await postToConversation(false, summaryBody);
}
diff --git a/src/configuration/github.ts b/src/configuration/github.ts
index 2c39449c..f303e858 100644
--- a/src/configuration/github.ts
+++ b/src/configuration/github.ts
@@ -11,9 +11,14 @@ export class GithubConfig {
readonly event: GithubEvent;
readonly job: string;
readonly action: string;
- readonly id: string;
+ readonly workflow: string;
+ readonly runId: number;
+ readonly runNumber: number;
+ readonly runAttempt: number;
readonly pullRequestNumber: number | undefined;
readonly debugger: boolean;
+ readonly runnerName: string;
+ readonly id: string;
constructor() {
this.apiUrl = context.apiUrl;
@@ -21,8 +26,15 @@ export class GithubConfig {
this.reponame = context.repo.repo;
this.commitSha = context.sha;
this.event = this.getGithubEvent();
- this.job = context.job;
+ this.job = context.job.replace(/[\s|_]+/g, '-');
this.action = context.action.replace('__tiobe_', '');
+ this.workflow = context.workflow.replace(/[\s|_]+/g, '-');
+ this.runId = context.runId;
+ this.runNumber = context.runNumber;
+ this.runAttempt = parseInt(process.env.GITHUB_RUN_ATTEMPT ?? '0', 10);
+ this.pullRequestNumber = this.getPullRequestNumber();
+ this.debugger = isDebug();
+ this.runnerName = process.env.RUNNER_NAME ?? '';
/**
* Construct the id to use for storing tmpdirs. The action name will
@@ -34,10 +46,7 @@ export class GithubConfig {
* include a suffix that consists of the sequence number preceded by an underscore.
* https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables
*/
- const runAttempt = process.env.GITHUB_RUN_ATTEMPT ?? '0';
- this.id = `${context.runId.toString()}_${runAttempt}_${this.job}_${this.action}`;
- this.pullRequestNumber = this.getPullRequestNumber();
- this.debugger = isDebug();
+ this.id = `${this.runId.toString()}_${this.runAttempt.toString()}_${this.job}_${this.action}`;
this.removeWarningListener();
}
@@ -71,6 +80,10 @@ export class GithubConfig {
}
}
+ getCommentIdentifier(): string {
+ return [this.workflow, this.job, this.runNumber, this.runAttempt].join('_');
+ }
+
removeWarningListener(): void {
process.removeAllListeners('warning');
process.on('warning', warning => {
diff --git a/src/github/comments.ts b/src/github/comments.ts
index 41320a27..c05a8c81 100644
--- a/src/github/comments.ts
+++ b/src/github/comments.ts
@@ -59,7 +59,7 @@ export async function postComment(body: string): Promise {
export async function deletePreviousComments(comments: Comment[]): Promise {
logger.header('Deleting comments of previous runs.');
for (const comment of comments) {
- if (commentIncludesTicsTitle(comment.body)) {
+ if (shouldCommentBeDeleted(comment.body)) {
try {
const params = {
owner: githubConfig.owner,
@@ -76,16 +76,55 @@ export async function deletePreviousComments(comments: Comment[]): Promise
logger.info('Deleted review comments of previous runs.');
}
-function commentIncludesTicsTitle(body?: string): boolean {
- const titles = ['TICS Quality Gate
', '## TICS Quality Gate', '## TICS Analysis'];
-
+function shouldCommentBeDeleted(body?: string): boolean {
if (!body) return false;
+ const titles = ['TICS Quality Gate
', '## TICS Quality Gate', '## TICS Analysis'];
+
let includesTitle = false;
- titles.forEach(title => {
- if (body.startsWith(title)) includesTitle = true;
- });
+ for (const title of titles) {
+ if (body.startsWith(title)) {
+ includesTitle = true;
+ }
+ }
+
+ if (includesTitle) {
+ return isWorkflowAndJobInAnotherRun(body);
+ }
+
+ return false;
+}
+
+function isWorkflowAndJobInAnotherRun(body: string): boolean {
+ const regex = //g;
+
+ let identifier = '';
+ // Get the last match of the tag.
+ let match: RegExpExecArray | null = null;
+ while ((match = regex.exec(body))) {
+ if (match[1] !== '') {
+ identifier = match[1];
+ }
+ }
+
+ // If no identifier is found, the comment is
+ // of the old format and should be replaced.
+ if (identifier === '') return true;
+
+ const split = identifier.split('_');
+
+ // If the identifier does not match the correct format, do not replace.
+ if (split.length !== 4) {
+ logger.debug(`Identifier is not of the correct format: ${identifier}`);
+ return false;
+ }
+
+ // If the workflow or job are different, do not replace.
+ if (split[0] !== githubConfig.workflow || split[1] !== githubConfig.job) {
+ return false;
+ }
- return includesTitle;
+ // Only replace if the run number or run attempt are different.
+ return parseInt(split[2], 10) !== githubConfig.runNumber || parseInt(split[3], 10) !== githubConfig.runAttempt;
}
diff --git a/src/github/runs.ts b/src/github/runs.ts
new file mode 100644
index 00000000..619b97b4
--- /dev/null
+++ b/src/github/runs.ts
@@ -0,0 +1,39 @@
+import { logger } from '../helper/logger';
+import { handleOctokitError } from '../helper/response';
+import { githubConfig } from '../configuration/config';
+import { octokit } from './octokit';
+
+/**
+ * Create review on the pull request from the analysis given.
+ * @param body Body containing the summary of the review
+ * @param event Either approve or request changes in the review.
+ */
+export async function getCurrentStepPath(): Promise {
+ const params = {
+ owner: githubConfig.owner,
+ repo: githubConfig.reponame,
+ run_id: githubConfig.runId,
+ attempt_number: githubConfig.runAttempt
+ };
+
+ const stepname = [githubConfig.workflow, githubConfig.job, githubConfig.action];
+ try {
+ logger.debug('Retrieving step name for current step...');
+ const response = await octokit.rest.actions.listJobsForWorkflowRunAttempt(params);
+ logger.debug(JSON.stringify(response.data));
+ const jobs = response.data.jobs.filter(j => j.status === 'in_progress' && j.runner_name === githubConfig.runnerName);
+
+ if (jobs.length === 1) {
+ const job = jobs[0];
+ stepname[1] = job.name;
+ const steps = job.steps?.filter(s => s.status === 'in_progress');
+ if (steps?.length === 1) {
+ stepname[2] = steps[0].name;
+ }
+ }
+ } catch (error: unknown) {
+ const message = handleOctokitError(error);
+ logger.notice(`Retrieving the step name failed: ${message}`);
+ }
+ return stepname.join(' / ');
+}
diff --git a/test/.setup/mock.ts b/test/.setup/mock.ts
index 482ea806..b6e99d0f 100644
--- a/test/.setup/mock.ts
+++ b/test/.setup/mock.ts
@@ -13,6 +13,11 @@ export const githubConfigMock: {
id: string;
pullRequestNumber: number | undefined;
debugger: boolean;
+ workflow: string;
+ runNumber: number;
+ runAttempt: number;
+ runnerName: string;
+ getCommentIdentifier(): string;
} = {
apiUrl: 'github.com/api/v1/',
owner: 'tester',
@@ -23,7 +28,14 @@ export const githubConfigMock: {
action: 'tics-github-action',
id: '123_TICS_1_tics-github-action',
pullRequestNumber: 1,
- debugger: false
+ debugger: false,
+ workflow: 'tics-client',
+ runNumber: 1,
+ runAttempt: 2,
+ runnerName: 'Github Actions 1',
+ getCommentIdentifier(): string {
+ return [this.workflow, this.job, this.runNumber, this.runAttempt].join('_');
+ }
};
export const ticsConfigMock = {
@@ -102,6 +114,9 @@ jest.mock('../../src/github/octokit', () => {
},
repos: {
getCommit: jest.fn()
+ },
+ actions: {
+ listJobsForWorkflowRunAttempt: jest.fn()
}
},
graphql: jest.fn()
@@ -121,6 +136,7 @@ export const contextMock: {
job: string;
runId: number;
runNumber: number;
+ workflow: string;
payload: {
pull_request:
| {
@@ -140,6 +156,7 @@ export const contextMock: {
job: 'TICS',
runId: 123,
runNumber: 1,
+ workflow: 'tics_client',
payload: {
pull_request: {
number: 1
diff --git a/test/integration/configuration.test.ts b/test/integration/configuration.test.ts
index 07b21e51..7a62fc87 100644
--- a/test/integration/configuration.test.ts
+++ b/test/integration/configuration.test.ts
@@ -28,6 +28,8 @@ describe('pullRequestNumber', () => {
eventName: 'pull_request',
runId: 1,
runNumber: 1,
+ job: 'TICS',
+ workflow: 'tics_client',
repo: {
owner: 'owner',
repo: 'repo'
@@ -53,6 +55,8 @@ describe('pullRequestNumber', () => {
eventName: 'pull_request',
runId: 1,
runNumber: 1,
+ job: 'TICS',
+ workflow: 'tics_client',
repo: {
owner: 'owner',
repo: 'repo'
@@ -80,6 +84,8 @@ describe('pullRequestNumber', () => {
eventName: 'pull_request',
runId: 1,
runNumber: 1,
+ job: 'TICS',
+ workflow: 'tics_client',
repo: {
owner: 'owner',
repo: 'repo'
diff --git a/test/integration/httpclient.test.ts b/test/integration/httpclient.test.ts
index f329337a..96d7b733 100644
--- a/test/integration/httpclient.test.ts
+++ b/test/integration/httpclient.test.ts
@@ -10,6 +10,8 @@ process.env['http_proxy'] = proxyUrl;
// set required inputs
process.env.GITHUB_REPOSITORY = 'owner/repo';
process.env.GITHUB_ACTION = '_tics-github-action';
+process.env.GITHUB_JOB = 'tics_client';
+process.env.GITHUB_WORKFLOW = 'tics client';
process.env.INPUT_GITHUBTOKEN = 'token';
process.env.INPUT_MODE = 'client';
process.env.INPUT_PROJECTNAME = 'tics-github-action';
diff --git a/test/integration/octokit.test.ts b/test/integration/octokit.test.ts
index 0f850a67..0b9b8a8f 100644
--- a/test/integration/octokit.test.ts
+++ b/test/integration/octokit.test.ts
@@ -13,6 +13,8 @@ process.env['http_proxy'] = proxyUrl;
process.env.GITHUB_REPOSITORY = 'owner/repo';
process.env.GITHUB_API_URL = 'https://api.github.com';
process.env.GITHUB_ACTION = '_tics-github-action';
+process.env.GITHUB_JOB = 'tics_client';
+process.env.GITHUB_WORKFLOW = 'tics client';
process.env.INPUT_MODE = 'client';
process.env.INPUT_PROJECTNAME = 'tics-github-action';
process.env.INPUT_VIEWERURL = 'http://localhost/tiobeweb/TICS/api/cfg?name=default';
diff --git a/test/unit/action/decorate/action.test.ts b/test/unit/action/decorate/action.test.ts
index e1e5deed..61d8d671 100644
--- a/test/unit/action/decorate/action.test.ts
+++ b/test/unit/action/decorate/action.test.ts
@@ -14,8 +14,8 @@ describe('decorateAction', () => {
let spyPostAnnotations: jest.SpyInstance;
beforeEach(() => {
- spyCreateSummaryBody = jest.spyOn(summary, 'createSummaryBody').mockReturnValue('body');
- spyCreateErrorSummaryBody = jest.spyOn(summary, 'createErrorSummaryBody').mockReturnValue('body');
+ spyCreateSummaryBody = jest.spyOn(summary, 'createSummaryBody').mockResolvedValue('body');
+ spyCreateErrorSummaryBody = jest.spyOn(summary, 'createErrorSummaryBody').mockResolvedValue('body');
spyDecoratePullRequest = jest.spyOn(pullRequest, 'decoratePullRequest').mockImplementation();
spyPostAnnotations = jest.spyOn(annotations, 'postAnnotations').mockImplementation();
});
diff --git a/test/unit/action/decorate/summary.test.ts b/test/unit/action/decorate/summary.test.ts
index b94ebf08..db0ae2f7 100644
--- a/test/unit/action/decorate/summary.test.ts
+++ b/test/unit/action/decorate/summary.test.ts
@@ -26,8 +26,8 @@ describe('createSummaryBody', () => {
ticsConfigMock.displayUrl = 'http://viewer.url/';
});
- test('Should contain blocking after if there are soaked violations', () => {
- const string = createSummaryBody(analysisResultsSoaked);
+ test('Should contain blocking after if there are soaked violations', async () => {
+ const string = await createSummaryBody(analysisResultsSoaked);
expect(string).toContain(':x: Failed
');
expect(string).toContain('1 Condition(s) failed
');
@@ -42,8 +42,8 @@ describe('createSummaryBody', () => {
summary.clear();
});
- test('Should not contain blocking after if there are no soaked violations', () => {
- const string = createSummaryBody(analysisResultsNotSoaked);
+ test('Should not contain blocking after if there are no soaked violations', async () => {
+ const string = await createSummaryBody(analysisResultsNotSoaked);
expect(string).toContain(':x: Failed
');
expect(string).toContain('1 Condition(s) failed
');
@@ -56,8 +56,8 @@ describe('createSummaryBody', () => {
summary.clear();
});
- test('Should contain blocking after if there are partly violations', () => {
- const string = createSummaryBody(analysisResultsPartlySoakedPassed);
+ test('Should contain blocking after if there are partly violations', async () => {
+ const string = await createSummaryBody(analysisResultsPartlySoakedPassed);
expect(string).toContain(':warning: Passed with warnings
');
expect(string).toContain('1 Condition(s) passed with warning
');
@@ -69,8 +69,8 @@ describe('createSummaryBody', () => {
summary.clear();
});
- test('Should contain blocking after for one of the two conditions', () => {
- const string = createSummaryBody(analysisResultsPartlySoakedFailed);
+ test('Should contain blocking after for one of the two conditions', async () => {
+ const string = await createSummaryBody(analysisResultsPartlySoakedFailed);
expect(string).toContain(':x: Failed
');
expect(string).toContain('1 Condition(s) failed, 1 Condition(s) passed with warning
');
@@ -84,8 +84,8 @@ describe('createSummaryBody', () => {
summary.clear();
});
- test('Should pass with no conditions that passed with warnings', () => {
- const string = createSummaryBody(analysisResultsNoSoakedPassed);
+ test('Should pass with no conditions that passed with warnings', async () => {
+ const string = await createSummaryBody(analysisResultsNoSoakedPassed);
expect(string).toContain(':heavy_check_mark: Passed
');
expect(string).toContain('All conditions passed
');
@@ -95,10 +95,10 @@ describe('createSummaryBody', () => {
});
describe('createErrorSummary', () => {
- test('Should return summary of two errors', () => {
+ test('Should return summary of two errors', async () => {
githubConfigMock.debugger = false;
- const body = createErrorSummaryBody(['Error', 'Error'], []);
+ const body = await createErrorSummaryBody(['Error', 'Error'], []);
summary.clear();
expect(body).toContainTimes('The following errors have occurred during analysis:
', 1);
@@ -107,10 +107,10 @@ describe('createErrorSummary', () => {
expect(body).toContainTimes(':warning: Warning', 0);
});
- test('Should return summary of zero warnings on logLevel default', () => {
+ test('Should return summary of zero warnings on logLevel default', async () => {
githubConfigMock.debugger = false;
- const body = createErrorSummaryBody([], ['Warning', 'Warning']);
+ const body = await createErrorSummaryBody([], ['Warning', 'Warning']);
summary.clear();
expect(body).toContainTimes('The following errors have occurred during analysis:
', 0);
@@ -119,35 +119,41 @@ describe('createErrorSummary', () => {
expect(body).toContainTimes(':warning: Warning', 0);
});
- test('Should return summary of two warnings on logLevel debug', () => {
+ test('Should return summary of two warnings on logLevel debug', async () => {
githubConfigMock.debugger = true;
- const body = createErrorSummaryBody([], ['Warning', 'Warning']);
+ const body = await createErrorSummaryBody([], ['Warning', 'Warning']);
summary.clear();
expect(body).toContainTimes('The following errors have occurred during analysis:
', 0);
expect(body).toContainTimes('The following warnings have occurred during analysis:
', 1);
expect(body).toContainTimes(':x: Error', 0);
expect(body).toContainTimes(':warning: Warning', 2);
+ expect(body).toContainTimes('\ntics-client / TICS / tics-github-action', 1);
+ expect(body).toContain('\n');
});
- test('Should return summary of one error and two warnings', () => {
+ test('Should return summary of one error and two warnings', async () => {
githubConfigMock.debugger = true;
- const body = createErrorSummaryBody(['Error'], ['Warning', 'Warning']);
+ const body = await createErrorSummaryBody(['Error'], ['Warning', 'Warning']);
summary.clear();
expect(body).toContainTimes('The following errors have occurred during analysis:
', 1);
expect(body).toContainTimes('The following warnings have occurred during analysis:
', 1);
expect(body).toContainTimes(':x: Error', 1);
expect(body).toContainTimes(':warning: Warning', 2);
+ expect(body).toContainTimes('\ntics-client / TICS / tics-github-action', 1);
+ expect(body).toContainTimes('\n', 1);
});
});
describe('createNothingAnalyzedSummaryBody', () => {
test('Should return summary with the message given', async () => {
- const body = createNothingAnalyzedSummaryBody('message');
- expect(body).toEqual('TICS Quality Gate
\n:heavy_check_mark: Passed
\nmessage');
+ const body = await createNothingAnalyzedSummaryBody('message');
+ expect(body).toEqual(
+ 'TICS Quality Gate
\n:heavy_check_mark: Passed
\nmessage\ntics-client / TICS / tics-github-action\n'
+ );
});
});
diff --git a/test/unit/analysis/qserver.test.ts b/test/unit/analysis/qserver.test.ts
index d33015c6..f011c223 100644
--- a/test/unit/analysis/qserver.test.ts
+++ b/test/unit/analysis/qserver.test.ts
@@ -33,7 +33,7 @@ describe('SetFailed checks (QServer)', () => {
spyGetLastQServerRunDate = jest.spyOn(viewer, 'getLastQServerRunDate');
jest.spyOn(action, 'decorateAction');
- jest.spyOn(summary, 'createNothingAnalyzedSummaryBody').mockReturnValue('body');
+ jest.spyOn(summary, 'createNothingAnalyzedSummaryBody').mockResolvedValue('body');
});
afterEach(() => {
diff --git a/test/unit/configuration/github.test.ts b/test/unit/configuration/github.test.ts
index b95e7895..6d4c7d8a 100644
--- a/test/unit/configuration/github.test.ts
+++ b/test/unit/configuration/github.test.ts
@@ -1,6 +1,7 @@
import * as core from '@actions/core';
import { GithubConfig } from '../../../src/configuration/github';
import { contextMock } from '../../.setup/mock';
+import { GithubEvent } from '../../../src/configuration/github-event';
describe('GitHub Configuration', () => {
let githubConfig: GithubConfig;
@@ -92,4 +93,26 @@ describe('GitHub Configuration', () => {
githubConfig = new GithubConfig();
githubConfig.removeWarningListener();
});
+
+ test('getCommentIdentifier', () => {
+ githubConfig = new GithubConfig();
+ expect(githubConfig.getCommentIdentifier()).toEqual('tics-client_TICS_1_1');
+ });
+
+ test('getGithubEvent', () => {
+ contextMock.eventName = 'undefined';
+ expect(new GithubConfig().event).toEqual(GithubEvent.PUSH);
+ contextMock.eventName = GithubEvent.PUSH.name;
+ expect(new GithubConfig().event).toEqual(GithubEvent.PUSH);
+ contextMock.eventName = GithubEvent.PULL_REQUEST.name;
+ expect(new GithubConfig().event).toEqual(GithubEvent.PULL_REQUEST);
+ contextMock.eventName = GithubEvent.PULL_REQUEST_TARGET.name;
+ expect(new GithubConfig().event).toEqual(GithubEvent.PULL_REQUEST_TARGET);
+ contextMock.eventName = GithubEvent.WORKFLOW_CALL.name;
+ expect(new GithubConfig().event).toEqual(GithubEvent.WORKFLOW_CALL);
+ contextMock.eventName = GithubEvent.WORKFLOW_DISPATCH.name;
+ expect(new GithubConfig().event).toEqual(GithubEvent.WORKFLOW_DISPATCH);
+ contextMock.eventName = GithubEvent.WORKFLOW_RUN.name;
+ expect(new GithubConfig().event).toEqual(GithubEvent.WORKFLOW_RUN);
+ });
});
diff --git a/test/unit/github/comments.test.ts b/test/unit/github/comments.test.ts
index 5c614d67..a0e25378 100644
--- a/test/unit/github/comments.test.ts
+++ b/test/unit/github/comments.test.ts
@@ -130,7 +130,7 @@ describe('deletePreviousComments', () => {
});
test('Should call deleteComment with values', async () => {
- deletePreviousComments([commentWithBody]);
+ await deletePreviousComments([commentWithBody]);
const calledWith = {
owner: githubConfig.owner,
repo: githubConfig.reponame,
@@ -139,11 +139,46 @@ describe('deletePreviousComments', () => {
expect(deleteCommentSpy).toHaveBeenCalledWith(calledWith);
});
- test('Should call deleteComment with values', async () => {
+ test('Should not call deleteComment if body is undefined', async () => {
await deletePreviousComments([commentWithoutBody]);
expect(deleteCommentSpy).toHaveBeenCalledTimes(0);
});
+ test('Should not call deleteComment if body is not TICS', async () => {
+ await deletePreviousComments([commentWithoutTics]);
+ expect(deleteCommentSpy).toHaveBeenCalledTimes(0);
+ });
+
+ test('Should call deleteComment if identifier workflow and job match', async () => {
+ await deletePreviousComments([commentWithIdentifierSameJob]);
+ const calledWith = {
+ owner: githubConfig.owner,
+ repo: githubConfig.reponame,
+ comment_id: 0
+ };
+ expect(deleteCommentSpy).toHaveBeenCalledWith(calledWith);
+ });
+
+ test('Should not call deleteComment if identifier workflow and job match, but they are in the same run', async () => {
+ await deletePreviousComments([commentWithIdentifierSameJobAndRun]);
+ expect(deleteCommentSpy).toHaveBeenCalledTimes(0);
+ });
+
+ test('Should not call deleteComment if identifier workflow and job do not match', async () => {
+ await deletePreviousComments([commentWithIdentifierOtherJob]);
+ expect(deleteCommentSpy).toHaveBeenCalledTimes(0);
+ });
+
+ test('Should not call deleteComment if identifier is of the wrong format', async () => {
+ const debugSpy = jest.spyOn(logger, 'debug');
+
+ await deletePreviousComments([commentWithIdentifierWrongFormat]);
+
+ expect(deleteCommentSpy).toHaveBeenCalledTimes(0);
+ expect(debugSpy).toHaveBeenCalledTimes(1);
+ expect(debugSpy).toHaveBeenCalledWith('Identifier is not of the correct format: tics-client_OTHER_1');
+ });
+
test('Should post a notice when deleteComment throws', async () => {
deleteCommentSpy.mockRejectedValue(Error());
const noticeSpy = jest.spyOn(logger, 'notice');
@@ -167,13 +202,31 @@ const commentWithBody: Comment = {
};
const commentWithoutBody: Comment = {
- url: '',
- html_url: '',
- issue_url: '',
- id: 0,
- node_id: '',
- user: null,
- created_at: '',
- updated_at: '',
+ ...commentWithBody,
body: undefined
};
+
+const commentWithoutTics: Comment = {
+ ...commentWithBody,
+ body: 'Other action content'
+};
+
+const commentWithIdentifierSameJob: Comment = {
+ ...commentWithBody,
+ body: 'TICS Quality Gate
Message Here'
+};
+
+const commentWithIdentifierSameJobAndRun: Comment = {
+ ...commentWithBody,
+ body: 'TICS Quality Gate
Message Here'
+};
+
+const commentWithIdentifierOtherJob: Comment = {
+ ...commentWithBody,
+ body: 'TICS Quality Gate
Message Here'
+};
+
+const commentWithIdentifierWrongFormat: Comment = {
+ ...commentWithBody,
+ body: 'TICS Quality Gate
Message Here'
+};
diff --git a/test/unit/github/runs.test.ts b/test/unit/github/runs.test.ts
new file mode 100644
index 00000000..8bbe7cdc
--- /dev/null
+++ b/test/unit/github/runs.test.ts
@@ -0,0 +1,105 @@
+import { getCurrentStepPath } from '../../../src/github/runs';
+import { octokit } from '../../../src/github/octokit';
+import { githubConfigMock } from '../../.setup/mock';
+
+describe('postReview', () => {
+ let listJobsSpy: jest.SpyInstance;
+
+ beforeEach(() => {
+ listJobsSpy = jest.spyOn(octokit.rest.actions, 'listJobsForWorkflowRunAttempt');
+ });
+
+ test('Should return name when only one step is in progress', async () => {
+ listJobsSpy.mockResolvedValue({
+ data: {
+ jobs: [
+ {
+ name: 'TICS Client',
+ runner_name: 'Github Actions 1',
+ status: 'in_progress',
+ steps: [
+ {
+ name: 'Step 1',
+ status: 'completed'
+ },
+ {
+ name: 'Step 2',
+ status: 'in_progress'
+ }
+ ]
+ },
+ {
+ name: 'TICS Client',
+ runner_name: 'Github Actions 2',
+ status: 'completed',
+ steps: [
+ {
+ name: 'Step 1',
+ status: 'in_progress'
+ },
+ {
+ name: 'Step 2',
+ status: 'in_progress'
+ }
+ ]
+ }
+ ]
+ }
+ });
+
+ const name = await getCurrentStepPath();
+
+ expect(name).toStrictEqual('tics-client / TICS Client / Step 2');
+ });
+
+ test('Should not return name when multiple steps are in progress', async () => {
+ listJobsSpy.mockResolvedValue({
+ data: {
+ jobs: [
+ {
+ name: 'TICS',
+ runner_name: 'Github Actions 1',
+ status: 'in_progress',
+ steps: [
+ {
+ name: 'Step 1',
+ status: 'in_progress'
+ },
+ {
+ name: 'Step 2',
+ status: 'in_progress'
+ }
+ ]
+ },
+ {
+ name: 'TICS',
+ runner_name: 'Github Actions 1',
+ status: 'completed',
+ steps: [
+ {
+ name: 'Step 1',
+ status: 'completed'
+ },
+ {
+ name: 'Step 2',
+ status: 'completed'
+ }
+ ]
+ }
+ ]
+ }
+ });
+
+ const name = await getCurrentStepPath();
+
+ expect(name).toStrictEqual('tics-client / TICS / tics-github-action');
+ });
+
+ test('Should post a notice on createReview', async () => {
+ listJobsSpy.mockRejectedValue(new Error());
+
+ const name = await getCurrentStepPath();
+
+ expect(name).toStrictEqual('tics-client / TICS / tics-github-action');
+ });
+});
diff --git a/test/unit/helper/logger.test.ts b/test/unit/helper/logger.test.ts
index 0b4124ac..e007b077 100644
--- a/test/unit/helper/logger.test.ts
+++ b/test/unit/helper/logger.test.ts
@@ -1,27 +1,46 @@
import * as core from '@actions/core';
import { logger } from '../../../src/helper/logger';
+let infoSpy: jest.SpyInstance;
+let debugSpy: jest.SpyInstance;
+let noticeSpy: jest.SpyInstance;
+let errorSpy: jest.SpyInstance;
+let warningSpy: jest.SpyInstance;
+let setFailedSpy: jest.SpyInstance;
+
+beforeEach(() => {
+ infoSpy = jest.spyOn(core, 'info');
+ debugSpy = jest.spyOn(core, 'debug');
+ noticeSpy = jest.spyOn(core, 'notice');
+ errorSpy = jest.spyOn(core, 'error');
+ warningSpy = jest.spyOn(core, 'warning');
+ setFailedSpy = jest.spyOn(core, 'setFailed');
+});
+
+afterEach(() => {
+ jest.resetAllMocks();
+});
+
describe('info', () => {
test('Should call core.info on info', () => {
- const info = jest.spyOn(core, 'info');
const addNewline = jest.spyOn(logger, 'addNewline');
logger.info('string');
- expect(info).toHaveBeenCalledTimes(1);
- expect(info).toHaveBeenCalledWith('string');
+ expect(infoSpy).toHaveBeenCalledTimes(1);
+ expect(infoSpy).toHaveBeenCalledWith('string');
expect(addNewline).toHaveBeenCalledTimes(0);
expect(logger.called).toEqual('info');
});
test('Should call core.info on header', () => {
- const info = jest.spyOn(core, 'info');
const addNewline = jest.spyOn(logger, 'addNewline');
+ logger.info('error');
logger.header('string');
- expect(info).toHaveBeenCalledTimes(2); // once for header, once for newline
- expect(info).toHaveBeenCalledWith(expect.stringContaining('string'));
+ expect(infoSpy).toHaveBeenCalledTimes(2); // once for header, once for newline
+ expect(infoSpy).toHaveBeenCalledWith(expect.stringContaining('string'));
expect(addNewline).toHaveBeenCalledTimes(1);
expect(addNewline).toHaveBeenCalledWith('header');
expect(logger.called).toEqual('header');
@@ -30,14 +49,13 @@ describe('info', () => {
describe('debug', () => {
test('Should call core.debug on debug', () => {
- const debug = jest.spyOn(core, 'debug');
const addNewline = jest.spyOn(logger, 'addNewline');
logger.setSecretsFilter(['token']);
logger.debug('string token secret');
- expect(debug).toHaveBeenCalledTimes(1);
- expect(debug).toHaveBeenCalledWith('string token ***');
+ expect(debugSpy).toHaveBeenCalledTimes(1);
+ expect(debugSpy).toHaveBeenCalledWith('string token ***');
expect(addNewline).toHaveBeenCalledTimes(0);
expect(logger.called).toEqual('debug');
});
@@ -45,13 +63,12 @@ describe('debug', () => {
describe('notice', () => {
test('Should call core.notice on notice', () => {
- const debug = jest.spyOn(core, 'notice');
const addNewline = jest.spyOn(logger, 'addNewline');
logger.notice('string');
- expect(debug).toHaveBeenCalledTimes(1);
- expect(debug).toHaveBeenCalledWith('string', undefined);
+ expect(noticeSpy).toHaveBeenCalledTimes(1);
+ expect(noticeSpy).toHaveBeenCalledWith('string', undefined);
expect(addNewline).toHaveBeenCalledTimes(0);
expect(logger.called).toEqual('notice');
});
@@ -59,13 +76,12 @@ describe('notice', () => {
describe('warning', () => {
test('Should call core.warning on warning', () => {
- const debug = jest.spyOn(core, 'warning');
const addNewline = jest.spyOn(logger, 'addNewline');
logger.warning('string');
- expect(debug).toHaveBeenCalledTimes(1);
- expect(debug).toHaveBeenCalledWith('\u001b[33mstring', undefined);
+ expect(warningSpy).toHaveBeenCalledTimes(1);
+ expect(warningSpy).toHaveBeenCalledWith('\u001b[33mstring', undefined);
expect(addNewline).toHaveBeenCalledTimes(0);
expect(logger.called).toEqual('warning');
});
@@ -73,13 +89,12 @@ describe('warning', () => {
describe('error', () => {
test('Should call core.error on error', () => {
- const error = jest.spyOn(core, 'error');
const addNewline = jest.spyOn(logger, 'addNewline');
logger.error('error');
- expect(error).toHaveBeenCalledTimes(1);
- expect(error).toHaveBeenCalledWith(expect.stringContaining('error'), undefined);
+ expect(errorSpy).toHaveBeenCalledTimes(1);
+ expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('error'), undefined);
expect(addNewline).toHaveBeenCalledTimes(1);
expect(addNewline).toHaveBeenCalledWith('error');
expect(logger.called).toEqual('error');
@@ -88,15 +103,34 @@ describe('error', () => {
describe('setFailed', () => {
test('Should call core.setFailed on setFailed', () => {
- const setFailed = jest.spyOn(core, 'setFailed');
const addNewline = jest.spyOn(logger, 'addNewline');
logger.setFailed('error');
- expect(setFailed).toHaveBeenCalledTimes(1);
- expect(setFailed).toHaveBeenCalledWith(expect.stringContaining('error'));
+ expect(setFailedSpy).toHaveBeenCalledTimes(1);
+ expect(setFailedSpy).toHaveBeenCalledWith(expect.stringContaining('error'));
expect(addNewline).toHaveBeenCalledTimes(1);
expect(addNewline).toHaveBeenCalledWith('error');
expect(logger.called).toEqual('error');
});
});
+
+describe('maskOutput', () => {
+ test('Should filter out JAVA options', () => {
+ const message = 'Picked up JAVA_OPTIONS testing once';
+
+ logger.info(message);
+ logger.notice(message);
+ logger.debug(message);
+ logger.warning(message);
+ logger.error(message);
+ logger.setFailed(message);
+
+ expect(infoSpy).toHaveBeenCalledTimes(0);
+ expect(noticeSpy).toHaveBeenCalledTimes(0);
+ expect(debugSpy).toHaveBeenCalledTimes(0);
+ expect(warningSpy).toHaveBeenCalledTimes(0);
+ expect(errorSpy).toHaveBeenCalledTimes(0);
+ expect(setFailedSpy).toHaveBeenCalledTimes(0);
+ });
+});