mirror of
https://github.com/actions/checkout.git
synced 2026-05-06 18:07:35 +02:00
Merge 3ff67abc5a into 900f2210b1
This commit is contained in:
commit
d384b61093
12 changed files with 815 additions and 119 deletions
253
dist/index.js
vendored
253
dist/index.js
vendored
|
|
@ -655,6 +655,7 @@ const io = __importStar(__nccwpck_require__(7436));
|
|||
const path = __importStar(__nccwpck_require__(1017));
|
||||
const regexpHelper = __importStar(__nccwpck_require__(3120));
|
||||
const retryHelper = __importStar(__nccwpck_require__(2155));
|
||||
const child_process_1 = __nccwpck_require__(2081);
|
||||
const git_version_1 = __nccwpck_require__(3142);
|
||||
// Auth header not supported before 2.9
|
||||
// Wire protocol v2 not supported before 2.18
|
||||
|
|
@ -678,6 +679,8 @@ class GitCommandManager {
|
|||
this.doSparseCheckout = false;
|
||||
this.workingDirectory = '';
|
||||
this.gitVersion = new git_version_1.GitVersion();
|
||||
this.timeoutMs = 0;
|
||||
this.networkRetryHelper = new retryHelper.RetryHelper();
|
||||
}
|
||||
branchDelete(remote, branch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
|
|
@ -735,7 +738,7 @@ class GitCommandManager {
|
|||
}
|
||||
};
|
||||
// Suppress the output in order to avoid flooding annotations with innocuous errors.
|
||||
yield this.execGit(args, false, true, listeners);
|
||||
yield this.execGit(args, { silent: true, customListeners: listeners });
|
||||
core.debug(`stderr callback is: ${stderr}`);
|
||||
core.debug(`errline callback is: ${errline}`);
|
||||
core.debug(`stdout callback is: ${stdout}`);
|
||||
|
|
@ -823,7 +826,7 @@ class GitCommandManager {
|
|||
'--name-only',
|
||||
'--get-regexp',
|
||||
pattern
|
||||
], true);
|
||||
], { allowAllExitCodes: true });
|
||||
return output.exitCode === 0;
|
||||
});
|
||||
}
|
||||
|
|
@ -851,15 +854,15 @@ class GitCommandManager {
|
|||
args.push(arg);
|
||||
}
|
||||
const that = this;
|
||||
yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield that.execGit(args);
|
||||
yield this.networkRetryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield that.execGit(args, { timeoutMs: that.timeoutMs });
|
||||
}));
|
||||
});
|
||||
}
|
||||
getDefaultBranch(repositoryUrl) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let output;
|
||||
yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.networkRetryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||
output = yield this.execGit([
|
||||
'ls-remote',
|
||||
'--quiet',
|
||||
|
|
@ -867,7 +870,7 @@ class GitCommandManager {
|
|||
'--symref',
|
||||
repositoryUrl,
|
||||
'HEAD'
|
||||
]);
|
||||
], { timeoutMs: this.timeoutMs });
|
||||
}));
|
||||
if (output) {
|
||||
// Satisfy compiler, will always be set
|
||||
|
|
@ -904,7 +907,7 @@ class GitCommandManager {
|
|||
isDetached() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Note, "branch --show-current" would be simpler but isn't available until Git 2.22
|
||||
const output = yield this.execGit(['rev-parse', '--symbolic-full-name', '--verify', '--quiet', 'HEAD'], true);
|
||||
const output = yield this.execGit(['rev-parse', '--symbolic-full-name', '--verify', '--quiet', 'HEAD'], { allowAllExitCodes: true });
|
||||
return !output.stdout.trim().startsWith('refs/heads/');
|
||||
});
|
||||
}
|
||||
|
|
@ -912,8 +915,8 @@ class GitCommandManager {
|
|||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const args = ['lfs', 'fetch', 'origin', ref];
|
||||
const that = this;
|
||||
yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield that.execGit(args);
|
||||
yield this.networkRetryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield that.execGit(args, { timeoutMs: that.timeoutMs });
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
|
@ -925,8 +928,8 @@ class GitCommandManager {
|
|||
log1(format) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const args = format ? ['log', '-1', format] : ['log', '-1'];
|
||||
const silent = format ? false : true;
|
||||
const output = yield this.execGit(args, false, silent);
|
||||
const silent = !format;
|
||||
const output = yield this.execGit(args, { silent });
|
||||
return output.stdout;
|
||||
});
|
||||
}
|
||||
|
|
@ -956,7 +959,7 @@ class GitCommandManager {
|
|||
shaExists(sha) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const args = ['rev-parse', '--verify', '--quiet', `${sha}^{object}`];
|
||||
const output = yield this.execGit(args, true);
|
||||
const output = yield this.execGit(args, { allowAllExitCodes: true });
|
||||
return output.exitCode === 0;
|
||||
});
|
||||
}
|
||||
|
|
@ -977,7 +980,10 @@ class GitCommandManager {
|
|||
if (recursive) {
|
||||
args.push('--recursive');
|
||||
}
|
||||
yield this.execGit(args);
|
||||
const that = this;
|
||||
yield this.networkRetryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield that.execGit(args, { timeoutMs: that.timeoutMs });
|
||||
}));
|
||||
});
|
||||
}
|
||||
submoduleUpdate(fetchDepth, recursive) {
|
||||
|
|
@ -990,12 +996,15 @@ class GitCommandManager {
|
|||
if (recursive) {
|
||||
args.push('--recursive');
|
||||
}
|
||||
yield this.execGit(args);
|
||||
const that = this;
|
||||
yield this.networkRetryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield that.execGit(args, { timeoutMs: that.timeoutMs });
|
||||
}));
|
||||
});
|
||||
}
|
||||
submoduleStatus() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const output = yield this.execGit(['submodule', 'status'], true);
|
||||
const output = yield this.execGit(['submodule', 'status'], { allowAllExitCodes: true });
|
||||
core.debug(output.stdout);
|
||||
return output.exitCode === 0;
|
||||
});
|
||||
|
|
@ -1008,7 +1017,7 @@ class GitCommandManager {
|
|||
}
|
||||
tryClean() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const output = yield this.execGit(['clean', '-ffdx'], true);
|
||||
const output = yield this.execGit(['clean', '-ffdx'], { allowAllExitCodes: true });
|
||||
return output.exitCode === 0;
|
||||
});
|
||||
}
|
||||
|
|
@ -1019,7 +1028,7 @@ class GitCommandManager {
|
|||
globalConfig ? '--global' : '--local',
|
||||
'--unset-all',
|
||||
configKey
|
||||
], true);
|
||||
], { allowAllExitCodes: true });
|
||||
return output.exitCode === 0;
|
||||
});
|
||||
}
|
||||
|
|
@ -1033,19 +1042,19 @@ class GitCommandManager {
|
|||
args.push(globalConfig ? '--global' : '--local');
|
||||
}
|
||||
args.push('--unset', configKey, configValue);
|
||||
const output = yield this.execGit(args, true);
|
||||
const output = yield this.execGit(args, { allowAllExitCodes: true });
|
||||
return output.exitCode === 0;
|
||||
});
|
||||
}
|
||||
tryDisableAutomaticGarbageCollection() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const output = yield this.execGit(['config', '--local', 'gc.auto', '0'], true);
|
||||
const output = yield this.execGit(['config', '--local', 'gc.auto', '0'], { allowAllExitCodes: true });
|
||||
return output.exitCode === 0;
|
||||
});
|
||||
}
|
||||
tryGetFetchUrl() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const output = yield this.execGit(['config', '--local', '--get', 'remote.origin.url'], true);
|
||||
const output = yield this.execGit(['config', '--local', '--get', 'remote.origin.url'], { allowAllExitCodes: true });
|
||||
if (output.exitCode !== 0) {
|
||||
return '';
|
||||
}
|
||||
|
|
@ -1066,7 +1075,7 @@ class GitCommandManager {
|
|||
args.push(globalConfig ? '--global' : '--local');
|
||||
}
|
||||
args.push('--get-all', configKey);
|
||||
const output = yield this.execGit(args, true);
|
||||
const output = yield this.execGit(args, { allowAllExitCodes: true });
|
||||
if (output.exitCode !== 0) {
|
||||
return [];
|
||||
}
|
||||
|
|
@ -1086,7 +1095,7 @@ class GitCommandManager {
|
|||
args.push(globalConfig ? '--global' : '--local');
|
||||
}
|
||||
args.push('--name-only', '--get-regexp', pattern);
|
||||
const output = yield this.execGit(args, true);
|
||||
const output = yield this.execGit(args, { allowAllExitCodes: true });
|
||||
if (output.exitCode !== 0) {
|
||||
return [];
|
||||
}
|
||||
|
|
@ -1098,7 +1107,7 @@ class GitCommandManager {
|
|||
}
|
||||
tryReset() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const output = yield this.execGit(['reset', '--hard', 'HEAD'], true);
|
||||
const output = yield this.execGit(['reset', '--hard', 'HEAD'], { allowAllExitCodes: true });
|
||||
return output.exitCode === 0;
|
||||
});
|
||||
}
|
||||
|
|
@ -1107,6 +1116,25 @@ class GitCommandManager {
|
|||
return this.gitVersion;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Sets the timeout for network git operations.
|
||||
* @param timeoutSeconds Timeout in seconds. 0 disables the timeout.
|
||||
*/
|
||||
setTimeout(timeoutSeconds) {
|
||||
if (timeoutSeconds < 0) {
|
||||
throw new Error(`Timeout must be non-negative, got ${timeoutSeconds}`);
|
||||
}
|
||||
this.timeoutMs = timeoutSeconds * 1000;
|
||||
}
|
||||
/**
|
||||
* Configures retry behavior for network git operations.
|
||||
* @param maxAttempts Total attempts including the initial one. Must be >= 1.
|
||||
* @param minBackoffSeconds Minimum backoff between retries. Must be <= maxBackoffSeconds.
|
||||
* @param maxBackoffSeconds Maximum backoff between retries.
|
||||
*/
|
||||
setRetryConfig(maxAttempts, minBackoffSeconds, maxBackoffSeconds) {
|
||||
this.networkRetryHelper = new retryHelper.RetryHelper(maxAttempts, minBackoffSeconds, maxBackoffSeconds);
|
||||
}
|
||||
static createCommandManager(workingDirectory, lfs, doSparseCheckout) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const result = new GitCommandManager();
|
||||
|
|
@ -1115,8 +1143,19 @@ class GitCommandManager {
|
|||
});
|
||||
}
|
||||
execGit(args_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (args, allowAllExitCodes = false, silent = false, customListeners = {}) {
|
||||
return __awaiter(this, arguments, void 0, function* (args, options = {}) {
|
||||
const { allowAllExitCodes = false, silent = false, customListeners = {}, timeoutMs = 0 } = options;
|
||||
fshelper.directoryExistsSync(this.workingDirectory, true);
|
||||
// Use child_process.spawn directly when timeout is set,
|
||||
// so we can kill the process on timeout and avoid orphaned git processes.
|
||||
// Note: customListeners are not supported in the timeout path.
|
||||
if (timeoutMs > 0) {
|
||||
if (customListeners &&
|
||||
Object.keys(customListeners).length > 0) {
|
||||
core.debug('customListeners are not supported with timeoutMs and will be ignored');
|
||||
}
|
||||
return yield this.execGitWithTimeout(args, timeoutMs, silent, allowAllExitCodes);
|
||||
}
|
||||
const result = new GitOutput();
|
||||
const env = {};
|
||||
for (const key of Object.keys(process.env)) {
|
||||
|
|
@ -1132,20 +1171,123 @@ class GitCommandManager {
|
|||
};
|
||||
const mergedListeners = Object.assign(Object.assign({}, defaultListener), customListeners);
|
||||
const stdout = [];
|
||||
const options = {
|
||||
const execOptions = {
|
||||
cwd: this.workingDirectory,
|
||||
env,
|
||||
silent,
|
||||
ignoreReturnCode: allowAllExitCodes,
|
||||
listeners: mergedListeners
|
||||
};
|
||||
result.exitCode = yield exec.exec(`"${this.gitPath}"`, args, options);
|
||||
result.exitCode = yield exec.exec(`"${this.gitPath}"`, args, execOptions);
|
||||
result.stdout = stdout.join('');
|
||||
core.debug(result.exitCode.toString());
|
||||
core.debug(result.stdout);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Executes a git command with a timeout. Uses child_process.spawn directly
|
||||
* (instead of @actions/exec) so we can kill the process on timeout and
|
||||
* terminate it cleanly. Does not support customListeners.
|
||||
*/
|
||||
execGitWithTimeout(args, timeoutMs, silent, allowAllExitCodes) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const result = new GitOutput();
|
||||
const env = {};
|
||||
for (const key of Object.keys(process.env)) {
|
||||
env[key] = process.env[key];
|
||||
}
|
||||
for (const key of Object.keys(this.gitEnv)) {
|
||||
env[key] = this.gitEnv[key];
|
||||
}
|
||||
const stdout = [];
|
||||
const stderr = [];
|
||||
return new Promise((resolve, reject) => {
|
||||
var _a;
|
||||
const child = (0, child_process_1.spawn)(this.gitPath, args, {
|
||||
cwd: this.workingDirectory,
|
||||
env,
|
||||
stdio: ['ignore', 'pipe', 'pipe']
|
||||
});
|
||||
(_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
||||
stdout.push(data.toString());
|
||||
});
|
||||
if (child.stderr) {
|
||||
child.stderr.on('data', (data) => {
|
||||
stderr.push(data.toString());
|
||||
if (!silent) {
|
||||
process.stderr.write(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
let settled = false;
|
||||
let timedOut = false;
|
||||
let forceKillTimer;
|
||||
const cleanup = () => {
|
||||
clearTimeout(timer);
|
||||
if (forceKillTimer) {
|
||||
clearTimeout(forceKillTimer);
|
||||
}
|
||||
};
|
||||
const timer = global.setTimeout(() => {
|
||||
timedOut = true;
|
||||
// SIGTERM first, then force SIGKILL after 5 seconds.
|
||||
// On Windows, SIGTERM is equivalent to a forced kill, so
|
||||
// the SIGKILL fallback is effectively a no-op there.
|
||||
child.kill('SIGTERM');
|
||||
forceKillTimer = global.setTimeout(() => {
|
||||
try {
|
||||
child.kill('SIGKILL');
|
||||
}
|
||||
catch (killErr) {
|
||||
core.debug(`Failed to SIGKILL git process: ${killErr}`);
|
||||
}
|
||||
}, 5000);
|
||||
if (forceKillTimer.unref) {
|
||||
forceKillTimer.unref();
|
||||
}
|
||||
}, timeoutMs);
|
||||
if (timer.unref) {
|
||||
timer.unref();
|
||||
}
|
||||
child.on('close', (code) => {
|
||||
if (settled)
|
||||
return;
|
||||
settled = true;
|
||||
cleanup();
|
||||
if (timedOut) {
|
||||
reject(new Error(`Git operation timed out after ${timeoutMs / 1000} seconds: git ${args.slice(0, 5).join(' ')}...`));
|
||||
return;
|
||||
}
|
||||
// null code means killed by signal (e.g. OOM killer, external SIGTERM)
|
||||
if (code === null) {
|
||||
const stderrText = stderr.join('').trim();
|
||||
reject(new Error(`The process 'git' was killed by a signal` +
|
||||
(stderrText ? `\n${stderrText}` : '')));
|
||||
return;
|
||||
}
|
||||
if (code !== 0 && !allowAllExitCodes) {
|
||||
const stderrText = stderr.join('').trim();
|
||||
reject(new Error(`The process 'git' failed with exit code ${code}` +
|
||||
(stderrText ? `\n${stderrText}` : '')));
|
||||
return;
|
||||
}
|
||||
result.exitCode = code;
|
||||
result.stdout = stdout.join('');
|
||||
core.debug(result.exitCode.toString());
|
||||
core.debug(result.stdout);
|
||||
resolve(result);
|
||||
});
|
||||
child.on('error', (err) => {
|
||||
if (settled)
|
||||
return;
|
||||
settled = true;
|
||||
cleanup();
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
initializeCommandManager(workingDirectory, lfs, doSparseCheckout) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
this.workingDirectory = workingDirectory;
|
||||
|
|
@ -1448,6 +1590,10 @@ function getSource(settings) {
|
|||
core.startGroup('Getting Git version info');
|
||||
const git = yield getGitCommandManager(settings);
|
||||
core.endGroup();
|
||||
if (git) {
|
||||
git.setTimeout(settings.timeout);
|
||||
git.setRetryConfig(settings.retryMaxAttempts, settings.retryMinBackoff, settings.retryMaxBackoff);
|
||||
}
|
||||
let authHelper = null;
|
||||
try {
|
||||
if (git) {
|
||||
|
|
@ -2095,6 +2241,41 @@ function getInputs() {
|
|||
// Determine the GitHub URL that the repository is being hosted from
|
||||
result.githubServerUrl = core.getInput('github-server-url');
|
||||
core.debug(`GitHub Host URL = ${result.githubServerUrl}`);
|
||||
// Timeout per network operation attempt
|
||||
const timeoutInput = core.getInput('timeout');
|
||||
result.timeout = Math.floor(Number(timeoutInput !== '' ? timeoutInput : '300'));
|
||||
if (isNaN(result.timeout) || result.timeout < 0) {
|
||||
core.warning(`Invalid value '${timeoutInput}' for 'timeout' input. Using default: 300 seconds.`);
|
||||
result.timeout = 300;
|
||||
}
|
||||
core.debug(`timeout = ${result.timeout}`);
|
||||
// Retry max attempts (total attempts including initial)
|
||||
const retryMaxAttemptsInput = core.getInput('retry-max-attempts');
|
||||
result.retryMaxAttempts = Math.floor(Number(retryMaxAttemptsInput !== '' ? retryMaxAttemptsInput : '3'));
|
||||
if (isNaN(result.retryMaxAttempts) || result.retryMaxAttempts < 1) {
|
||||
core.warning(`Invalid value '${retryMaxAttemptsInput}' for 'retry-max-attempts' input. Using default: 3.`);
|
||||
result.retryMaxAttempts = 3;
|
||||
}
|
||||
core.debug(`retry max attempts = ${result.retryMaxAttempts}`);
|
||||
// Retry backoff range
|
||||
const retryMinBackoffInput = core.getInput('retry-min-backoff');
|
||||
result.retryMinBackoff = Math.floor(Number(retryMinBackoffInput !== '' ? retryMinBackoffInput : '10'));
|
||||
if (isNaN(result.retryMinBackoff) || result.retryMinBackoff < 0) {
|
||||
core.warning(`Invalid value '${retryMinBackoffInput}' for 'retry-min-backoff' input. Using default: 10 seconds.`);
|
||||
result.retryMinBackoff = 10;
|
||||
}
|
||||
core.debug(`retry min backoff = ${result.retryMinBackoff}`);
|
||||
const retryMaxBackoffInput = core.getInput('retry-max-backoff');
|
||||
result.retryMaxBackoff = Math.floor(Number(retryMaxBackoffInput !== '' ? retryMaxBackoffInput : '20'));
|
||||
if (isNaN(result.retryMaxBackoff) || result.retryMaxBackoff < 0) {
|
||||
core.warning(`Invalid value '${retryMaxBackoffInput}' for 'retry-max-backoff' input. Using default: 20 seconds.`);
|
||||
result.retryMaxBackoff = 20;
|
||||
}
|
||||
if (result.retryMaxBackoff < result.retryMinBackoff) {
|
||||
core.warning(`'retry-max-backoff' (${result.retryMaxBackoff}) is less than 'retry-min-backoff' (${result.retryMinBackoff}). Using retry-min-backoff value for both.`);
|
||||
result.retryMaxBackoff = result.retryMinBackoff;
|
||||
}
|
||||
core.debug(`retry max backoff = ${result.retryMaxBackoff}`);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
|
@ -5260,6 +5441,7 @@ class Context {
|
|||
this.action = process.env.GITHUB_ACTION;
|
||||
this.actor = process.env.GITHUB_ACTOR;
|
||||
this.job = process.env.GITHUB_JOB;
|
||||
this.runAttempt = parseInt(process.env.GITHUB_RUN_ATTEMPT, 10);
|
||||
this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10);
|
||||
this.runId = parseInt(process.env.GITHUB_RUN_ID, 10);
|
||||
this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`;
|
||||
|
|
@ -6136,7 +6318,7 @@ class HttpClient {
|
|||
}
|
||||
const usingSsl = parsedUrl.protocol === 'https:';
|
||||
proxyAgent = new undici_1.ProxyAgent(Object.assign({ uri: proxyUrl.href, pipelining: !this._keepAlive ? 0 : 1 }, ((proxyUrl.username || proxyUrl.password) && {
|
||||
token: `${proxyUrl.username}:${proxyUrl.password}`
|
||||
token: `Basic ${Buffer.from(`${proxyUrl.username}:${proxyUrl.password}`).toString('base64')}`
|
||||
})));
|
||||
this._proxyAgentDispatcher = proxyAgent;
|
||||
if (usingSsl && this._ignoreSslError) {
|
||||
|
|
@ -6250,11 +6432,11 @@ function getProxyUrl(reqUrl) {
|
|||
})();
|
||||
if (proxyVar) {
|
||||
try {
|
||||
return new URL(proxyVar);
|
||||
return new DecodedURL(proxyVar);
|
||||
}
|
||||
catch (_a) {
|
||||
if (!proxyVar.startsWith('http://') && !proxyVar.startsWith('https://'))
|
||||
return new URL(`http://${proxyVar}`);
|
||||
return new DecodedURL(`http://${proxyVar}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -6313,6 +6495,19 @@ function isLoopbackAddress(host) {
|
|||
hostLower.startsWith('[::1]') ||
|
||||
hostLower.startsWith('[0:0:0:0:0:0:0:1]'));
|
||||
}
|
||||
class DecodedURL extends URL {
|
||||
constructor(url, base) {
|
||||
super(url, base);
|
||||
this._decodedUsername = decodeURIComponent(super.username);
|
||||
this._decodedPassword = decodeURIComponent(super.password);
|
||||
}
|
||||
get username() {
|
||||
return this._decodedUsername;
|
||||
}
|
||||
get password() {
|
||||
return this._decodedPassword;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=proxy.js.map
|
||||
|
||||
/***/ }),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue