@pilatos/bitbucket-cli 1.10.1 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1262 -42
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -26,6 +26,7 @@ var __export = (target, all) => {
|
|
|
26
26
|
set: (newValue) => all[name] = () => newValue
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
29
30
|
var __require = import.meta.require;
|
|
30
31
|
|
|
31
32
|
// node_modules/commander/lib/error.js
|
|
@@ -13522,6 +13523,660 @@ var require_follow_redirects = __commonJS((exports, module) => {
|
|
|
13522
13523
|
module.exports.wrap = wrap;
|
|
13523
13524
|
});
|
|
13524
13525
|
|
|
13526
|
+
// node_modules/is-docker/index.js
|
|
13527
|
+
import fs from "fs";
|
|
13528
|
+
function hasDockerEnv() {
|
|
13529
|
+
try {
|
|
13530
|
+
fs.statSync("/.dockerenv");
|
|
13531
|
+
return true;
|
|
13532
|
+
} catch {
|
|
13533
|
+
return false;
|
|
13534
|
+
}
|
|
13535
|
+
}
|
|
13536
|
+
function hasDockerCGroup() {
|
|
13537
|
+
try {
|
|
13538
|
+
return fs.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
13539
|
+
} catch {
|
|
13540
|
+
return false;
|
|
13541
|
+
}
|
|
13542
|
+
}
|
|
13543
|
+
function isDocker() {
|
|
13544
|
+
if (isDockerCached === undefined) {
|
|
13545
|
+
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
13546
|
+
}
|
|
13547
|
+
return isDockerCached;
|
|
13548
|
+
}
|
|
13549
|
+
var isDockerCached;
|
|
13550
|
+
var init_is_docker = () => {};
|
|
13551
|
+
|
|
13552
|
+
// node_modules/is-inside-container/index.js
|
|
13553
|
+
import fs2 from "fs";
|
|
13554
|
+
function isInsideContainer() {
|
|
13555
|
+
if (cachedResult === undefined) {
|
|
13556
|
+
cachedResult = hasContainerEnv() || isDocker();
|
|
13557
|
+
}
|
|
13558
|
+
return cachedResult;
|
|
13559
|
+
}
|
|
13560
|
+
var cachedResult, hasContainerEnv = () => {
|
|
13561
|
+
try {
|
|
13562
|
+
fs2.statSync("/run/.containerenv");
|
|
13563
|
+
return true;
|
|
13564
|
+
} catch {
|
|
13565
|
+
return false;
|
|
13566
|
+
}
|
|
13567
|
+
};
|
|
13568
|
+
var init_is_inside_container = __esm(() => {
|
|
13569
|
+
init_is_docker();
|
|
13570
|
+
});
|
|
13571
|
+
|
|
13572
|
+
// node_modules/is-wsl/index.js
|
|
13573
|
+
import process3 from "process";
|
|
13574
|
+
import os2 from "os";
|
|
13575
|
+
import fs3 from "fs";
|
|
13576
|
+
var isWsl = () => {
|
|
13577
|
+
if (process3.platform !== "linux") {
|
|
13578
|
+
return false;
|
|
13579
|
+
}
|
|
13580
|
+
if (os2.release().toLowerCase().includes("microsoft")) {
|
|
13581
|
+
if (isInsideContainer()) {
|
|
13582
|
+
return false;
|
|
13583
|
+
}
|
|
13584
|
+
return true;
|
|
13585
|
+
}
|
|
13586
|
+
try {
|
|
13587
|
+
if (fs3.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
|
|
13588
|
+
return !isInsideContainer();
|
|
13589
|
+
}
|
|
13590
|
+
} catch {}
|
|
13591
|
+
if (fs3.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs3.existsSync("/run/WSL")) {
|
|
13592
|
+
return !isInsideContainer();
|
|
13593
|
+
}
|
|
13594
|
+
return false;
|
|
13595
|
+
}, is_wsl_default;
|
|
13596
|
+
var init_is_wsl = __esm(() => {
|
|
13597
|
+
init_is_inside_container();
|
|
13598
|
+
is_wsl_default = process3.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
13599
|
+
});
|
|
13600
|
+
|
|
13601
|
+
// node_modules/powershell-utils/index.js
|
|
13602
|
+
import process4 from "process";
|
|
13603
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
13604
|
+
import { promisify } from "util";
|
|
13605
|
+
import childProcess from "child_process";
|
|
13606
|
+
var execFile, powerShellPath = () => `${process4.env.SYSTEMROOT || process4.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`, executePowerShell = async (command, options = {}) => {
|
|
13607
|
+
const {
|
|
13608
|
+
powerShellPath: psPath,
|
|
13609
|
+
...execFileOptions
|
|
13610
|
+
} = options;
|
|
13611
|
+
const encodedCommand = executePowerShell.encodeCommand(command);
|
|
13612
|
+
return execFile(psPath ?? powerShellPath(), [
|
|
13613
|
+
...executePowerShell.argumentsPrefix,
|
|
13614
|
+
encodedCommand
|
|
13615
|
+
], {
|
|
13616
|
+
encoding: "utf8",
|
|
13617
|
+
...execFileOptions
|
|
13618
|
+
});
|
|
13619
|
+
};
|
|
13620
|
+
var init_powershell_utils = __esm(() => {
|
|
13621
|
+
execFile = promisify(childProcess.execFile);
|
|
13622
|
+
executePowerShell.argumentsPrefix = [
|
|
13623
|
+
"-NoProfile",
|
|
13624
|
+
"-NonInteractive",
|
|
13625
|
+
"-ExecutionPolicy",
|
|
13626
|
+
"Bypass",
|
|
13627
|
+
"-EncodedCommand"
|
|
13628
|
+
];
|
|
13629
|
+
executePowerShell.encodeCommand = (command) => Buffer2.from(command, "utf16le").toString("base64");
|
|
13630
|
+
executePowerShell.escapeArgument = (value) => `'${String(value).replaceAll("'", "''")}'`;
|
|
13631
|
+
});
|
|
13632
|
+
|
|
13633
|
+
// node_modules/wsl-utils/utilities.js
|
|
13634
|
+
function parseMountPointFromConfig(content) {
|
|
13635
|
+
for (const line of content.split(`
|
|
13636
|
+
`)) {
|
|
13637
|
+
if (/^\s*#/.test(line)) {
|
|
13638
|
+
continue;
|
|
13639
|
+
}
|
|
13640
|
+
const match = /^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(line);
|
|
13641
|
+
if (!match) {
|
|
13642
|
+
continue;
|
|
13643
|
+
}
|
|
13644
|
+
return match.groups.mountPoint.trim().replaceAll(/^["']|["']$/g, "");
|
|
13645
|
+
}
|
|
13646
|
+
}
|
|
13647
|
+
|
|
13648
|
+
// node_modules/wsl-utils/index.js
|
|
13649
|
+
import { promisify as promisify2 } from "util";
|
|
13650
|
+
import childProcess2 from "child_process";
|
|
13651
|
+
import fs4, { constants as fsConstants } from "fs/promises";
|
|
13652
|
+
var execFile2, wslDrivesMountPoint, powerShellPathFromWsl = async () => {
|
|
13653
|
+
const mountPoint = await wslDrivesMountPoint();
|
|
13654
|
+
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
13655
|
+
}, powerShellPath2, canAccessPowerShellPromise, canAccessPowerShell = async () => {
|
|
13656
|
+
canAccessPowerShellPromise ??= (async () => {
|
|
13657
|
+
try {
|
|
13658
|
+
const psPath = await powerShellPath2();
|
|
13659
|
+
await fs4.access(psPath, fsConstants.X_OK);
|
|
13660
|
+
return true;
|
|
13661
|
+
} catch {
|
|
13662
|
+
return false;
|
|
13663
|
+
}
|
|
13664
|
+
})();
|
|
13665
|
+
return canAccessPowerShellPromise;
|
|
13666
|
+
}, wslDefaultBrowser = async () => {
|
|
13667
|
+
const psPath = await powerShellPath2();
|
|
13668
|
+
const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
13669
|
+
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
13670
|
+
return stdout.trim();
|
|
13671
|
+
}, convertWslPathToWindows = async (path) => {
|
|
13672
|
+
if (/^[a-z]+:\/\//i.test(path)) {
|
|
13673
|
+
return path;
|
|
13674
|
+
}
|
|
13675
|
+
try {
|
|
13676
|
+
const { stdout } = await execFile2("wslpath", ["-aw", path], { encoding: "utf8" });
|
|
13677
|
+
return stdout.trim();
|
|
13678
|
+
} catch {
|
|
13679
|
+
return path;
|
|
13680
|
+
}
|
|
13681
|
+
};
|
|
13682
|
+
var init_wsl_utils = __esm(() => {
|
|
13683
|
+
init_is_wsl();
|
|
13684
|
+
init_powershell_utils();
|
|
13685
|
+
init_is_wsl();
|
|
13686
|
+
execFile2 = promisify2(childProcess2.execFile);
|
|
13687
|
+
wslDrivesMountPoint = (() => {
|
|
13688
|
+
const defaultMountPoint = "/mnt/";
|
|
13689
|
+
let mountPoint;
|
|
13690
|
+
return async function() {
|
|
13691
|
+
if (mountPoint) {
|
|
13692
|
+
return mountPoint;
|
|
13693
|
+
}
|
|
13694
|
+
const configFilePath = "/etc/wsl.conf";
|
|
13695
|
+
let isConfigFileExists = false;
|
|
13696
|
+
try {
|
|
13697
|
+
await fs4.access(configFilePath, fsConstants.F_OK);
|
|
13698
|
+
isConfigFileExists = true;
|
|
13699
|
+
} catch {}
|
|
13700
|
+
if (!isConfigFileExists) {
|
|
13701
|
+
return defaultMountPoint;
|
|
13702
|
+
}
|
|
13703
|
+
const configContent = await fs4.readFile(configFilePath, { encoding: "utf8" });
|
|
13704
|
+
const parsedMountPoint = parseMountPointFromConfig(configContent);
|
|
13705
|
+
if (parsedMountPoint === undefined) {
|
|
13706
|
+
return defaultMountPoint;
|
|
13707
|
+
}
|
|
13708
|
+
mountPoint = parsedMountPoint;
|
|
13709
|
+
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
13710
|
+
return mountPoint;
|
|
13711
|
+
};
|
|
13712
|
+
})();
|
|
13713
|
+
powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
|
|
13714
|
+
});
|
|
13715
|
+
|
|
13716
|
+
// node_modules/define-lazy-prop/index.js
|
|
13717
|
+
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
13718
|
+
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
|
|
13719
|
+
Object.defineProperty(object, propertyName, {
|
|
13720
|
+
configurable: true,
|
|
13721
|
+
enumerable: true,
|
|
13722
|
+
get() {
|
|
13723
|
+
const result = valueGetter();
|
|
13724
|
+
define(result);
|
|
13725
|
+
return result;
|
|
13726
|
+
},
|
|
13727
|
+
set(value) {
|
|
13728
|
+
define(value);
|
|
13729
|
+
}
|
|
13730
|
+
});
|
|
13731
|
+
return object;
|
|
13732
|
+
}
|
|
13733
|
+
|
|
13734
|
+
// node_modules/default-browser-id/index.js
|
|
13735
|
+
import { promisify as promisify3 } from "util";
|
|
13736
|
+
import process5 from "process";
|
|
13737
|
+
import { execFile as execFile3 } from "child_process";
|
|
13738
|
+
async function defaultBrowserId() {
|
|
13739
|
+
if (process5.platform !== "darwin") {
|
|
13740
|
+
throw new Error("macOS only");
|
|
13741
|
+
}
|
|
13742
|
+
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
13743
|
+
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
13744
|
+
const browserId = match?.groups.id ?? "com.apple.Safari";
|
|
13745
|
+
if (browserId === "com.apple.safari") {
|
|
13746
|
+
return "com.apple.Safari";
|
|
13747
|
+
}
|
|
13748
|
+
return browserId;
|
|
13749
|
+
}
|
|
13750
|
+
var execFileAsync;
|
|
13751
|
+
var init_default_browser_id = __esm(() => {
|
|
13752
|
+
execFileAsync = promisify3(execFile3);
|
|
13753
|
+
});
|
|
13754
|
+
|
|
13755
|
+
// node_modules/run-applescript/index.js
|
|
13756
|
+
import process6 from "process";
|
|
13757
|
+
import { promisify as promisify4 } from "util";
|
|
13758
|
+
import { execFile as execFile4, execFileSync } from "child_process";
|
|
13759
|
+
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
13760
|
+
if (process6.platform !== "darwin") {
|
|
13761
|
+
throw new Error("macOS only");
|
|
13762
|
+
}
|
|
13763
|
+
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
13764
|
+
const execOptions = {};
|
|
13765
|
+
if (signal) {
|
|
13766
|
+
execOptions.signal = signal;
|
|
13767
|
+
}
|
|
13768
|
+
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
|
|
13769
|
+
return stdout.trim();
|
|
13770
|
+
}
|
|
13771
|
+
var execFileAsync2;
|
|
13772
|
+
var init_run_applescript = __esm(() => {
|
|
13773
|
+
execFileAsync2 = promisify4(execFile4);
|
|
13774
|
+
});
|
|
13775
|
+
|
|
13776
|
+
// node_modules/bundle-name/index.js
|
|
13777
|
+
async function bundleName(bundleId) {
|
|
13778
|
+
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
13779
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
13780
|
+
}
|
|
13781
|
+
var init_bundle_name = __esm(() => {
|
|
13782
|
+
init_run_applescript();
|
|
13783
|
+
});
|
|
13784
|
+
|
|
13785
|
+
// node_modules/default-browser/windows.js
|
|
13786
|
+
import { promisify as promisify5 } from "util";
|
|
13787
|
+
import { execFile as execFile5 } from "child_process";
|
|
13788
|
+
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
13789
|
+
const { stdout } = await _execFileAsync("reg", [
|
|
13790
|
+
"QUERY",
|
|
13791
|
+
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
13792
|
+
"/v",
|
|
13793
|
+
"ProgId"
|
|
13794
|
+
]);
|
|
13795
|
+
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
13796
|
+
if (!match) {
|
|
13797
|
+
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
13798
|
+
}
|
|
13799
|
+
const { id } = match.groups;
|
|
13800
|
+
const dotIndex = id.lastIndexOf(".");
|
|
13801
|
+
const hyphenIndex = id.lastIndexOf("-");
|
|
13802
|
+
const baseIdByDot = dotIndex === -1 ? undefined : id.slice(0, dotIndex);
|
|
13803
|
+
const baseIdByHyphen = hyphenIndex === -1 ? undefined : id.slice(0, hyphenIndex);
|
|
13804
|
+
return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
|
|
13805
|
+
}
|
|
13806
|
+
var execFileAsync3, windowsBrowserProgIds, _windowsBrowserProgIdMap, UnknownBrowserError;
|
|
13807
|
+
var init_windows = __esm(() => {
|
|
13808
|
+
execFileAsync3 = promisify5(execFile5);
|
|
13809
|
+
windowsBrowserProgIds = {
|
|
13810
|
+
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
13811
|
+
MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
|
|
13812
|
+
MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
|
|
13813
|
+
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
13814
|
+
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
13815
|
+
ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
|
|
13816
|
+
ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
|
|
13817
|
+
ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
|
|
13818
|
+
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
13819
|
+
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
13820
|
+
BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
|
|
13821
|
+
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
|
|
13822
|
+
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
13823
|
+
OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
|
|
13824
|
+
VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
|
|
13825
|
+
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
|
|
13826
|
+
};
|
|
13827
|
+
_windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
|
|
13828
|
+
UnknownBrowserError = class UnknownBrowserError extends Error {
|
|
13829
|
+
};
|
|
13830
|
+
});
|
|
13831
|
+
|
|
13832
|
+
// node_modules/default-browser/index.js
|
|
13833
|
+
import { promisify as promisify6 } from "util";
|
|
13834
|
+
import process7 from "process";
|
|
13835
|
+
import { execFile as execFile6 } from "child_process";
|
|
13836
|
+
async function defaultBrowser2() {
|
|
13837
|
+
if (process7.platform === "darwin") {
|
|
13838
|
+
const id = await defaultBrowserId();
|
|
13839
|
+
const name = await bundleName(id);
|
|
13840
|
+
return { name, id };
|
|
13841
|
+
}
|
|
13842
|
+
if (process7.platform === "linux") {
|
|
13843
|
+
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
13844
|
+
const id = stdout.trim();
|
|
13845
|
+
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
13846
|
+
return { name, id };
|
|
13847
|
+
}
|
|
13848
|
+
if (process7.platform === "win32") {
|
|
13849
|
+
return defaultBrowser();
|
|
13850
|
+
}
|
|
13851
|
+
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
13852
|
+
}
|
|
13853
|
+
var execFileAsync4, titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
13854
|
+
var init_default_browser = __esm(() => {
|
|
13855
|
+
init_default_browser_id();
|
|
13856
|
+
init_bundle_name();
|
|
13857
|
+
init_windows();
|
|
13858
|
+
init_windows();
|
|
13859
|
+
execFileAsync4 = promisify6(execFile6);
|
|
13860
|
+
});
|
|
13861
|
+
|
|
13862
|
+
// node_modules/is-in-ssh/index.js
|
|
13863
|
+
import process8 from "process";
|
|
13864
|
+
var isInSsh, is_in_ssh_default;
|
|
13865
|
+
var init_is_in_ssh = __esm(() => {
|
|
13866
|
+
isInSsh = Boolean(process8.env.SSH_CONNECTION || process8.env.SSH_CLIENT || process8.env.SSH_TTY);
|
|
13867
|
+
is_in_ssh_default = isInSsh;
|
|
13868
|
+
});
|
|
13869
|
+
|
|
13870
|
+
// node_modules/open/index.js
|
|
13871
|
+
var exports_open = {};
|
|
13872
|
+
__export(exports_open, {
|
|
13873
|
+
openApp: () => openApp,
|
|
13874
|
+
default: () => open_default,
|
|
13875
|
+
apps: () => apps
|
|
13876
|
+
});
|
|
13877
|
+
import process9 from "process";
|
|
13878
|
+
import path from "path";
|
|
13879
|
+
import { fileURLToPath } from "url";
|
|
13880
|
+
import childProcess3 from "child_process";
|
|
13881
|
+
import fs5, { constants as fsConstants2 } from "fs/promises";
|
|
13882
|
+
function detectArchBinary(binary) {
|
|
13883
|
+
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
13884
|
+
return binary;
|
|
13885
|
+
}
|
|
13886
|
+
const { [arch]: archBinary } = binary;
|
|
13887
|
+
if (!archBinary) {
|
|
13888
|
+
throw new Error(`${arch} is not supported`);
|
|
13889
|
+
}
|
|
13890
|
+
return archBinary;
|
|
13891
|
+
}
|
|
13892
|
+
function detectPlatformBinary({ [platform]: platformBinary }, { wsl } = {}) {
|
|
13893
|
+
if (wsl && is_wsl_default) {
|
|
13894
|
+
return detectArchBinary(wsl);
|
|
13895
|
+
}
|
|
13896
|
+
if (!platformBinary) {
|
|
13897
|
+
throw new Error(`${platform} is not supported`);
|
|
13898
|
+
}
|
|
13899
|
+
return detectArchBinary(platformBinary);
|
|
13900
|
+
}
|
|
13901
|
+
var fallbackAttemptSymbol, __dirname2, localXdgOpenPath, platform, arch, tryEachApp = async (apps, opener) => {
|
|
13902
|
+
if (apps.length === 0) {
|
|
13903
|
+
return;
|
|
13904
|
+
}
|
|
13905
|
+
const errors = [];
|
|
13906
|
+
for (const app of apps) {
|
|
13907
|
+
try {
|
|
13908
|
+
return await opener(app);
|
|
13909
|
+
} catch (error) {
|
|
13910
|
+
errors.push(error);
|
|
13911
|
+
}
|
|
13912
|
+
}
|
|
13913
|
+
throw new AggregateError(errors, "Failed to open in all supported apps");
|
|
13914
|
+
}, baseOpen = async (options) => {
|
|
13915
|
+
options = {
|
|
13916
|
+
wait: false,
|
|
13917
|
+
background: false,
|
|
13918
|
+
newInstance: false,
|
|
13919
|
+
allowNonzeroExitCode: false,
|
|
13920
|
+
...options
|
|
13921
|
+
};
|
|
13922
|
+
const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
|
|
13923
|
+
delete options[fallbackAttemptSymbol];
|
|
13924
|
+
if (Array.isArray(options.app)) {
|
|
13925
|
+
return tryEachApp(options.app, (singleApp) => baseOpen({
|
|
13926
|
+
...options,
|
|
13927
|
+
app: singleApp,
|
|
13928
|
+
[fallbackAttemptSymbol]: true
|
|
13929
|
+
}));
|
|
13930
|
+
}
|
|
13931
|
+
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
13932
|
+
appArguments = [...appArguments];
|
|
13933
|
+
if (Array.isArray(app)) {
|
|
13934
|
+
return tryEachApp(app, (appName) => baseOpen({
|
|
13935
|
+
...options,
|
|
13936
|
+
app: {
|
|
13937
|
+
name: appName,
|
|
13938
|
+
arguments: appArguments
|
|
13939
|
+
},
|
|
13940
|
+
[fallbackAttemptSymbol]: true
|
|
13941
|
+
}));
|
|
13942
|
+
}
|
|
13943
|
+
if (app === "browser" || app === "browserPrivate") {
|
|
13944
|
+
const ids = {
|
|
13945
|
+
"com.google.chrome": "chrome",
|
|
13946
|
+
"google-chrome.desktop": "chrome",
|
|
13947
|
+
"com.brave.browser": "brave",
|
|
13948
|
+
"org.mozilla.firefox": "firefox",
|
|
13949
|
+
"firefox.desktop": "firefox",
|
|
13950
|
+
"com.microsoft.msedge": "edge",
|
|
13951
|
+
"com.microsoft.edge": "edge",
|
|
13952
|
+
"com.microsoft.edgemac": "edge",
|
|
13953
|
+
"microsoft-edge.desktop": "edge",
|
|
13954
|
+
"com.apple.safari": "safari"
|
|
13955
|
+
};
|
|
13956
|
+
const flags = {
|
|
13957
|
+
chrome: "--incognito",
|
|
13958
|
+
brave: "--incognito",
|
|
13959
|
+
firefox: "--private-window",
|
|
13960
|
+
edge: "--inPrivate"
|
|
13961
|
+
};
|
|
13962
|
+
let browser;
|
|
13963
|
+
if (is_wsl_default) {
|
|
13964
|
+
const progId = await wslDefaultBrowser();
|
|
13965
|
+
const browserInfo = _windowsBrowserProgIdMap.get(progId);
|
|
13966
|
+
browser = browserInfo ?? {};
|
|
13967
|
+
} else {
|
|
13968
|
+
browser = await defaultBrowser2();
|
|
13969
|
+
}
|
|
13970
|
+
if (browser.id in ids) {
|
|
13971
|
+
const browserName = ids[browser.id.toLowerCase()];
|
|
13972
|
+
if (app === "browserPrivate") {
|
|
13973
|
+
if (browserName === "safari") {
|
|
13974
|
+
throw new Error("Safari doesn't support opening in private mode via command line");
|
|
13975
|
+
}
|
|
13976
|
+
appArguments.push(flags[browserName]);
|
|
13977
|
+
}
|
|
13978
|
+
return baseOpen({
|
|
13979
|
+
...options,
|
|
13980
|
+
app: {
|
|
13981
|
+
name: apps[browserName],
|
|
13982
|
+
arguments: appArguments
|
|
13983
|
+
}
|
|
13984
|
+
});
|
|
13985
|
+
}
|
|
13986
|
+
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
13987
|
+
}
|
|
13988
|
+
let command;
|
|
13989
|
+
const cliArguments = [];
|
|
13990
|
+
const childProcessOptions = {};
|
|
13991
|
+
let shouldUseWindowsInWsl = false;
|
|
13992
|
+
if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
|
|
13993
|
+
shouldUseWindowsInWsl = await canAccessPowerShell();
|
|
13994
|
+
}
|
|
13995
|
+
if (platform === "darwin") {
|
|
13996
|
+
command = "open";
|
|
13997
|
+
if (options.wait) {
|
|
13998
|
+
cliArguments.push("--wait-apps");
|
|
13999
|
+
}
|
|
14000
|
+
if (options.background) {
|
|
14001
|
+
cliArguments.push("--background");
|
|
14002
|
+
}
|
|
14003
|
+
if (options.newInstance) {
|
|
14004
|
+
cliArguments.push("--new");
|
|
14005
|
+
}
|
|
14006
|
+
if (app) {
|
|
14007
|
+
cliArguments.push("-a", app);
|
|
14008
|
+
}
|
|
14009
|
+
} else if (platform === "win32" || shouldUseWindowsInWsl) {
|
|
14010
|
+
command = await powerShellPath2();
|
|
14011
|
+
cliArguments.push(...executePowerShell.argumentsPrefix);
|
|
14012
|
+
if (!is_wsl_default) {
|
|
14013
|
+
childProcessOptions.windowsVerbatimArguments = true;
|
|
14014
|
+
}
|
|
14015
|
+
if (is_wsl_default && options.target) {
|
|
14016
|
+
options.target = await convertWslPathToWindows(options.target);
|
|
14017
|
+
}
|
|
14018
|
+
const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
|
|
14019
|
+
if (options.wait) {
|
|
14020
|
+
encodedArguments.push("-Wait");
|
|
14021
|
+
}
|
|
14022
|
+
if (app) {
|
|
14023
|
+
encodedArguments.push(executePowerShell.escapeArgument(app));
|
|
14024
|
+
if (options.target) {
|
|
14025
|
+
appArguments.push(options.target);
|
|
14026
|
+
}
|
|
14027
|
+
} else if (options.target) {
|
|
14028
|
+
encodedArguments.push(executePowerShell.escapeArgument(options.target));
|
|
14029
|
+
}
|
|
14030
|
+
if (appArguments.length > 0) {
|
|
14031
|
+
appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
|
|
14032
|
+
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
14033
|
+
}
|
|
14034
|
+
options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
|
|
14035
|
+
if (!options.wait) {
|
|
14036
|
+
childProcessOptions.stdio = "ignore";
|
|
14037
|
+
}
|
|
14038
|
+
} else {
|
|
14039
|
+
if (app) {
|
|
14040
|
+
command = app;
|
|
14041
|
+
} else {
|
|
14042
|
+
const isBundled = !__dirname2 || __dirname2 === "/";
|
|
14043
|
+
let exeLocalXdgOpen = false;
|
|
14044
|
+
try {
|
|
14045
|
+
await fs5.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
14046
|
+
exeLocalXdgOpen = true;
|
|
14047
|
+
} catch {}
|
|
14048
|
+
const useSystemXdgOpen = process9.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
14049
|
+
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
14050
|
+
}
|
|
14051
|
+
if (appArguments.length > 0) {
|
|
14052
|
+
cliArguments.push(...appArguments);
|
|
14053
|
+
}
|
|
14054
|
+
if (!options.wait) {
|
|
14055
|
+
childProcessOptions.stdio = "ignore";
|
|
14056
|
+
childProcessOptions.detached = true;
|
|
14057
|
+
}
|
|
14058
|
+
}
|
|
14059
|
+
if (platform === "darwin" && appArguments.length > 0) {
|
|
14060
|
+
cliArguments.push("--args", ...appArguments);
|
|
14061
|
+
}
|
|
14062
|
+
if (options.target) {
|
|
14063
|
+
cliArguments.push(options.target);
|
|
14064
|
+
}
|
|
14065
|
+
const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
|
|
14066
|
+
if (options.wait) {
|
|
14067
|
+
return new Promise((resolve, reject) => {
|
|
14068
|
+
subprocess.once("error", reject);
|
|
14069
|
+
subprocess.once("close", (exitCode) => {
|
|
14070
|
+
if (!options.allowNonzeroExitCode && exitCode !== 0) {
|
|
14071
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
14072
|
+
return;
|
|
14073
|
+
}
|
|
14074
|
+
resolve(subprocess);
|
|
14075
|
+
});
|
|
14076
|
+
});
|
|
14077
|
+
}
|
|
14078
|
+
if (isFallbackAttempt) {
|
|
14079
|
+
return new Promise((resolve, reject) => {
|
|
14080
|
+
subprocess.once("error", reject);
|
|
14081
|
+
subprocess.once("spawn", () => {
|
|
14082
|
+
subprocess.once("close", (exitCode) => {
|
|
14083
|
+
subprocess.off("error", reject);
|
|
14084
|
+
if (exitCode !== 0) {
|
|
14085
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
14086
|
+
return;
|
|
14087
|
+
}
|
|
14088
|
+
subprocess.unref();
|
|
14089
|
+
resolve(subprocess);
|
|
14090
|
+
});
|
|
14091
|
+
});
|
|
14092
|
+
});
|
|
14093
|
+
}
|
|
14094
|
+
subprocess.unref();
|
|
14095
|
+
return new Promise((resolve, reject) => {
|
|
14096
|
+
subprocess.once("error", reject);
|
|
14097
|
+
subprocess.once("spawn", () => {
|
|
14098
|
+
subprocess.off("error", reject);
|
|
14099
|
+
resolve(subprocess);
|
|
14100
|
+
});
|
|
14101
|
+
});
|
|
14102
|
+
}, open = (target, options) => {
|
|
14103
|
+
if (typeof target !== "string") {
|
|
14104
|
+
throw new TypeError("Expected a `target`");
|
|
14105
|
+
}
|
|
14106
|
+
return baseOpen({
|
|
14107
|
+
...options,
|
|
14108
|
+
target
|
|
14109
|
+
});
|
|
14110
|
+
}, openApp = (name, options) => {
|
|
14111
|
+
if (typeof name !== "string" && !Array.isArray(name)) {
|
|
14112
|
+
throw new TypeError("Expected a valid `name`");
|
|
14113
|
+
}
|
|
14114
|
+
const { arguments: appArguments = [] } = options ?? {};
|
|
14115
|
+
if (appArguments !== undefined && appArguments !== null && !Array.isArray(appArguments)) {
|
|
14116
|
+
throw new TypeError("Expected `appArguments` as Array type");
|
|
14117
|
+
}
|
|
14118
|
+
return baseOpen({
|
|
14119
|
+
...options,
|
|
14120
|
+
app: {
|
|
14121
|
+
name,
|
|
14122
|
+
arguments: appArguments
|
|
14123
|
+
}
|
|
14124
|
+
});
|
|
14125
|
+
}, apps, open_default;
|
|
14126
|
+
var init_open = __esm(() => {
|
|
14127
|
+
init_wsl_utils();
|
|
14128
|
+
init_powershell_utils();
|
|
14129
|
+
init_default_browser();
|
|
14130
|
+
init_is_inside_container();
|
|
14131
|
+
init_is_in_ssh();
|
|
14132
|
+
fallbackAttemptSymbol = Symbol("fallbackAttempt");
|
|
14133
|
+
__dirname2 = import.meta.url ? path.dirname(fileURLToPath(import.meta.url)) : "";
|
|
14134
|
+
localXdgOpenPath = path.join(__dirname2, "xdg-open");
|
|
14135
|
+
({ platform, arch } = process9);
|
|
14136
|
+
apps = {
|
|
14137
|
+
browser: "browser",
|
|
14138
|
+
browserPrivate: "browserPrivate"
|
|
14139
|
+
};
|
|
14140
|
+
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
14141
|
+
darwin: "google chrome",
|
|
14142
|
+
win32: "chrome",
|
|
14143
|
+
linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
|
|
14144
|
+
}, {
|
|
14145
|
+
wsl: {
|
|
14146
|
+
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
14147
|
+
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
14148
|
+
}
|
|
14149
|
+
}));
|
|
14150
|
+
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
14151
|
+
darwin: "brave browser",
|
|
14152
|
+
win32: "brave",
|
|
14153
|
+
linux: ["brave-browser", "brave"]
|
|
14154
|
+
}, {
|
|
14155
|
+
wsl: {
|
|
14156
|
+
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
14157
|
+
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
14158
|
+
}
|
|
14159
|
+
}));
|
|
14160
|
+
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
14161
|
+
darwin: "firefox",
|
|
14162
|
+
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
14163
|
+
linux: "firefox"
|
|
14164
|
+
}, {
|
|
14165
|
+
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
14166
|
+
}));
|
|
14167
|
+
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
14168
|
+
darwin: "microsoft edge",
|
|
14169
|
+
win32: "msedge",
|
|
14170
|
+
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
14171
|
+
}, {
|
|
14172
|
+
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
14173
|
+
}));
|
|
14174
|
+
defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
14175
|
+
darwin: "Safari"
|
|
14176
|
+
}));
|
|
14177
|
+
open_default = open;
|
|
14178
|
+
});
|
|
14179
|
+
|
|
13525
14180
|
// node_modules/commander/esm.mjs
|
|
13526
14181
|
var import__ = __toESM(require_commander(), 1);
|
|
13527
14182
|
var {
|
|
@@ -13606,6 +14261,7 @@ var ServiceTokens = {
|
|
|
13606
14261
|
ContextService: "ContextService",
|
|
13607
14262
|
OutputService: "OutputService",
|
|
13608
14263
|
HttpClient: "HttpClient",
|
|
14264
|
+
OAuthService: "OAuthService",
|
|
13609
14265
|
VersionService: "VersionService",
|
|
13610
14266
|
PullrequestsApi: "PullrequestsApi",
|
|
13611
14267
|
RepositoriesApi: "RepositoriesApi",
|
|
@@ -13801,6 +14457,7 @@ class ConfigService {
|
|
|
13801
14457
|
const config = await this.getConfig();
|
|
13802
14458
|
await this.setConfig({
|
|
13803
14459
|
...config,
|
|
14460
|
+
authMethod: "basic",
|
|
13804
14461
|
username: credentials.username,
|
|
13805
14462
|
apiToken: credentials.apiToken
|
|
13806
14463
|
});
|
|
@@ -13828,6 +14485,56 @@ class ConfigService {
|
|
|
13828
14485
|
getConfigPath() {
|
|
13829
14486
|
return this.configFile;
|
|
13830
14487
|
}
|
|
14488
|
+
async getAuthMethod() {
|
|
14489
|
+
const config = await this.getConfig();
|
|
14490
|
+
return config.authMethod ?? "basic";
|
|
14491
|
+
}
|
|
14492
|
+
async getOAuthCredentials() {
|
|
14493
|
+
const config = await this.getConfig();
|
|
14494
|
+
const { oauthAccessToken, oauthRefreshToken, oauthExpiresAt } = config;
|
|
14495
|
+
if (!oauthAccessToken || !oauthRefreshToken || !oauthExpiresAt) {
|
|
14496
|
+
throw new BBError({
|
|
14497
|
+
code: 1001 /* AUTH_REQUIRED */,
|
|
14498
|
+
message: "OAuth authentication required. Run 'bb auth login' to authenticate."
|
|
14499
|
+
});
|
|
14500
|
+
}
|
|
14501
|
+
return {
|
|
14502
|
+
accessToken: oauthAccessToken,
|
|
14503
|
+
refreshToken: oauthRefreshToken,
|
|
14504
|
+
expiresAt: oauthExpiresAt
|
|
14505
|
+
};
|
|
14506
|
+
}
|
|
14507
|
+
async setOAuthCredentials(credentials) {
|
|
14508
|
+
const config = await this.getConfig();
|
|
14509
|
+
const { username: _u, apiToken: _t, ...rest } = config;
|
|
14510
|
+
await this.setConfig({
|
|
14511
|
+
...rest,
|
|
14512
|
+
authMethod: "oauth",
|
|
14513
|
+
oauthAccessToken: credentials.accessToken,
|
|
14514
|
+
oauthRefreshToken: credentials.refreshToken,
|
|
14515
|
+
oauthExpiresAt: credentials.expiresAt
|
|
14516
|
+
});
|
|
14517
|
+
}
|
|
14518
|
+
async clearOAuthCredentials() {
|
|
14519
|
+
const config = await this.getConfig();
|
|
14520
|
+
const {
|
|
14521
|
+
authMethod: _am,
|
|
14522
|
+
oauthAccessToken: _at,
|
|
14523
|
+
oauthRefreshToken: _rt,
|
|
14524
|
+
oauthExpiresAt: _ea,
|
|
14525
|
+
oauthClientId: _ci,
|
|
14526
|
+
oauthClientSecret: _cs,
|
|
14527
|
+
...rest
|
|
14528
|
+
} = config;
|
|
14529
|
+
await this.setConfig(rest);
|
|
14530
|
+
}
|
|
14531
|
+
async isOAuthTokenExpired() {
|
|
14532
|
+
const config = await this.getConfig();
|
|
14533
|
+
if (!config.oauthExpiresAt) {
|
|
14534
|
+
return true;
|
|
14535
|
+
}
|
|
14536
|
+
return Date.now() >= (config.oauthExpiresAt - 60) * 1000;
|
|
14537
|
+
}
|
|
13831
14538
|
clearCache() {
|
|
13832
14539
|
this.configCache = null;
|
|
13833
14540
|
}
|
|
@@ -18205,7 +18912,7 @@ function getRetryDelay(error, attempt) {
|
|
|
18205
18912
|
function sleep(ms) {
|
|
18206
18913
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
18207
18914
|
}
|
|
18208
|
-
function createApiClient(configService) {
|
|
18915
|
+
function createApiClient(configService, oauthService) {
|
|
18209
18916
|
const instance = axios_default.create({
|
|
18210
18917
|
baseURL: BASE_URL,
|
|
18211
18918
|
headers: {
|
|
@@ -18217,9 +18924,15 @@ function createApiClient(configService) {
|
|
|
18217
18924
|
if (process.env.DEBUG === "true") {
|
|
18218
18925
|
console.debug(`[HTTP] ${config.method?.toUpperCase()} ${config.url}`);
|
|
18219
18926
|
}
|
|
18220
|
-
const
|
|
18221
|
-
|
|
18222
|
-
|
|
18927
|
+
const authMethod = await configService.getAuthMethod();
|
|
18928
|
+
if (authMethod === "oauth" && oauthService) {
|
|
18929
|
+
const accessToken = await oauthService.getValidAccessToken();
|
|
18930
|
+
config.headers.Authorization = `Bearer ${accessToken}`;
|
|
18931
|
+
} else {
|
|
18932
|
+
const credentials = await configService.getCredentials();
|
|
18933
|
+
const authString = Buffer.from(`${credentials.username}:${credentials.apiToken}`).toString("base64");
|
|
18934
|
+
config.headers.Authorization = `Basic ${authString}`;
|
|
18935
|
+
}
|
|
18223
18936
|
return config;
|
|
18224
18937
|
}, (error) => Promise.reject(error));
|
|
18225
18938
|
instance.interceptors.response.use((response) => {
|
|
@@ -18235,6 +18948,25 @@ function createApiClient(configService) {
|
|
|
18235
18948
|
console.debug(`[HTTP] Error Response Body:`, JSON.stringify(error.response.data, null, 2));
|
|
18236
18949
|
}
|
|
18237
18950
|
}
|
|
18951
|
+
if (error.response?.status === 401 && oauthService) {
|
|
18952
|
+
const config = error.config;
|
|
18953
|
+
if (config && !config.__tokenRefreshed) {
|
|
18954
|
+
const authMethod = await configService.getAuthMethod();
|
|
18955
|
+
if (authMethod === "oauth") {
|
|
18956
|
+
try {
|
|
18957
|
+
config.__tokenRefreshed = true;
|
|
18958
|
+
const newToken = await oauthService.refreshAccessToken();
|
|
18959
|
+
config.headers.Authorization = `Bearer ${newToken}`;
|
|
18960
|
+
return instance(config);
|
|
18961
|
+
} catch {
|
|
18962
|
+
throw new BBError({
|
|
18963
|
+
code: 1003 /* AUTH_EXPIRED */,
|
|
18964
|
+
message: `OAuth token expired. Run 'bb auth login' to re-authenticate.`
|
|
18965
|
+
});
|
|
18966
|
+
}
|
|
18967
|
+
}
|
|
18968
|
+
}
|
|
18969
|
+
}
|
|
18238
18970
|
if (error.response && RETRYABLE_STATUS_CODES.has(error.response.status)) {
|
|
18239
18971
|
const config = error.config;
|
|
18240
18972
|
if (config) {
|
|
@@ -18285,6 +19017,405 @@ function extractErrorMessage(data) {
|
|
|
18285
19017
|
}
|
|
18286
19018
|
return;
|
|
18287
19019
|
}
|
|
19020
|
+
// src/services/oauth.service.ts
|
|
19021
|
+
import { createServer } from "http";
|
|
19022
|
+
import { randomBytes } from "crypto";
|
|
19023
|
+
var BITBUCKET_AUTHORIZE_URL = "https://bitbucket.org/site/oauth2/authorize";
|
|
19024
|
+
var BITBUCKET_TOKEN_URL = "https://bitbucket.org/site/oauth2/access_token";
|
|
19025
|
+
var CALLBACK_PORT = 19872;
|
|
19026
|
+
var CALLBACK_PATH = "/callback";
|
|
19027
|
+
var CALLBACK_URL = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
|
|
19028
|
+
var AUTH_TIMEOUT_MS = 5 * 60 * 1000;
|
|
19029
|
+
var DEFAULT_CLIENT_ID = "ErUBvNmdYtfVHgW6J4";
|
|
19030
|
+
var DEFAULT_CLIENT_SECRET = "QnrWypuKXv7YvU7WJwQRza2n2QfHCEw5";
|
|
19031
|
+
var OAUTH_SCOPES = [
|
|
19032
|
+
"account",
|
|
19033
|
+
"repository",
|
|
19034
|
+
"repository:admin",
|
|
19035
|
+
"pullrequest",
|
|
19036
|
+
"pullrequest:write"
|
|
19037
|
+
].join(" ");
|
|
19038
|
+
function generateState() {
|
|
19039
|
+
return randomBytes(16).toString("hex");
|
|
19040
|
+
}
|
|
19041
|
+
|
|
19042
|
+
class OAuthService {
|
|
19043
|
+
configService;
|
|
19044
|
+
constructor(configService) {
|
|
19045
|
+
this.configService = configService;
|
|
19046
|
+
}
|
|
19047
|
+
async authorize(clientId, clientSecret) {
|
|
19048
|
+
const resolvedClientId = clientId ?? await this.getClientId();
|
|
19049
|
+
const state = generateState();
|
|
19050
|
+
const authUrl = this.buildAuthUrl(resolvedClientId, state);
|
|
19051
|
+
const { code } = await this.waitForCallback(authUrl, state);
|
|
19052
|
+
const tokenResponse = await this.exchangeCode(code, resolvedClientId, clientSecret);
|
|
19053
|
+
const expiresAt = Math.floor(Date.now() / 1000) + tokenResponse.expires_in;
|
|
19054
|
+
await this.configService.setOAuthCredentials({
|
|
19055
|
+
accessToken: tokenResponse.access_token,
|
|
19056
|
+
refreshToken: tokenResponse.refresh_token,
|
|
19057
|
+
expiresAt
|
|
19058
|
+
});
|
|
19059
|
+
if (clientId) {
|
|
19060
|
+
await this.configService.setValue("oauthClientId", clientId);
|
|
19061
|
+
}
|
|
19062
|
+
if (clientSecret) {
|
|
19063
|
+
await this.configService.setValue("oauthClientSecret", clientSecret);
|
|
19064
|
+
}
|
|
19065
|
+
const userInfo = await this.fetchUserInfo(tokenResponse.access_token);
|
|
19066
|
+
return userInfo;
|
|
19067
|
+
}
|
|
19068
|
+
async refreshAccessToken() {
|
|
19069
|
+
const credentials = await this.configService.getOAuthCredentials();
|
|
19070
|
+
const clientId = await this.getClientId();
|
|
19071
|
+
const clientSecret = await this.getClientSecret();
|
|
19072
|
+
const params = new URLSearchParams({
|
|
19073
|
+
grant_type: "refresh_token",
|
|
19074
|
+
refresh_token: credentials.refreshToken
|
|
19075
|
+
});
|
|
19076
|
+
const response = await fetch(BITBUCKET_TOKEN_URL, {
|
|
19077
|
+
method: "POST",
|
|
19078
|
+
headers: {
|
|
19079
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
19080
|
+
Authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString("base64")}`
|
|
19081
|
+
},
|
|
19082
|
+
body: params.toString()
|
|
19083
|
+
});
|
|
19084
|
+
if (!response.ok) {
|
|
19085
|
+
const errorBody = await response.text();
|
|
19086
|
+
throw new BBError({
|
|
19087
|
+
code: 1003 /* AUTH_EXPIRED */,
|
|
19088
|
+
message: `Failed to refresh OAuth token. Run 'bb auth login' to re-authenticate.`,
|
|
19089
|
+
context: { status: response.status, body: errorBody }
|
|
19090
|
+
});
|
|
19091
|
+
}
|
|
19092
|
+
const tokenResponse = await response.json();
|
|
19093
|
+
const expiresAt = Math.floor(Date.now() / 1000) + tokenResponse.expires_in;
|
|
19094
|
+
await this.configService.setOAuthCredentials({
|
|
19095
|
+
accessToken: tokenResponse.access_token,
|
|
19096
|
+
refreshToken: tokenResponse.refresh_token,
|
|
19097
|
+
expiresAt
|
|
19098
|
+
});
|
|
19099
|
+
return tokenResponse.access_token;
|
|
19100
|
+
}
|
|
19101
|
+
async revokeToken() {
|
|
19102
|
+
try {
|
|
19103
|
+
const credentials = await this.configService.getOAuthCredentials();
|
|
19104
|
+
const clientId = await this.getClientId();
|
|
19105
|
+
const clientSecret = await this.getClientSecret();
|
|
19106
|
+
const params = new URLSearchParams({
|
|
19107
|
+
token: credentials.accessToken
|
|
19108
|
+
});
|
|
19109
|
+
await fetch("https://bitbucket.org/site/oauth2/revoke", {
|
|
19110
|
+
method: "POST",
|
|
19111
|
+
headers: {
|
|
19112
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
19113
|
+
Authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString("base64")}`
|
|
19114
|
+
},
|
|
19115
|
+
body: params.toString()
|
|
19116
|
+
});
|
|
19117
|
+
} catch {}
|
|
19118
|
+
}
|
|
19119
|
+
async getValidAccessToken() {
|
|
19120
|
+
const isExpired = await this.configService.isOAuthTokenExpired();
|
|
19121
|
+
if (isExpired) {
|
|
19122
|
+
return this.refreshAccessToken();
|
|
19123
|
+
}
|
|
19124
|
+
const credentials = await this.configService.getOAuthCredentials();
|
|
19125
|
+
return credentials.accessToken;
|
|
19126
|
+
}
|
|
19127
|
+
async getClientId() {
|
|
19128
|
+
const customClientId = await this.configService.getValue("oauthClientId");
|
|
19129
|
+
return customClientId ?? DEFAULT_CLIENT_ID;
|
|
19130
|
+
}
|
|
19131
|
+
async getClientSecret() {
|
|
19132
|
+
const customSecret = await this.configService.getValue("oauthClientSecret");
|
|
19133
|
+
return customSecret ?? DEFAULT_CLIENT_SECRET;
|
|
19134
|
+
}
|
|
19135
|
+
buildAuthUrl(clientId, state) {
|
|
19136
|
+
const params = new URLSearchParams({
|
|
19137
|
+
client_id: clientId,
|
|
19138
|
+
response_type: "code",
|
|
19139
|
+
redirect_uri: CALLBACK_URL,
|
|
19140
|
+
scope: OAUTH_SCOPES,
|
|
19141
|
+
state
|
|
19142
|
+
});
|
|
19143
|
+
return `${BITBUCKET_AUTHORIZE_URL}?${params.toString()}`;
|
|
19144
|
+
}
|
|
19145
|
+
async waitForCallback(authUrl, expectedState) {
|
|
19146
|
+
return new Promise((resolve, reject) => {
|
|
19147
|
+
let server;
|
|
19148
|
+
let timeout;
|
|
19149
|
+
const cleanup = () => {
|
|
19150
|
+
clearTimeout(timeout);
|
|
19151
|
+
server?.close();
|
|
19152
|
+
};
|
|
19153
|
+
timeout = setTimeout(() => {
|
|
19154
|
+
cleanup();
|
|
19155
|
+
reject(new BBError({
|
|
19156
|
+
code: 1002 /* AUTH_INVALID */,
|
|
19157
|
+
message: "Authorization timed out. Please try again."
|
|
19158
|
+
}));
|
|
19159
|
+
}, AUTH_TIMEOUT_MS);
|
|
19160
|
+
server = createServer((req, res) => {
|
|
19161
|
+
const url2 = new URL(req.url ?? "/", `http://localhost:${CALLBACK_PORT}`);
|
|
19162
|
+
if (url2.pathname !== CALLBACK_PATH) {
|
|
19163
|
+
res.writeHead(404);
|
|
19164
|
+
res.end("Not found");
|
|
19165
|
+
return;
|
|
19166
|
+
}
|
|
19167
|
+
const code = url2.searchParams.get("code");
|
|
19168
|
+
const state = url2.searchParams.get("state");
|
|
19169
|
+
const error = url2.searchParams.get("error");
|
|
19170
|
+
const errorDescription = url2.searchParams.get("error_description");
|
|
19171
|
+
if (error) {
|
|
19172
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
19173
|
+
res.end(this.buildErrorPage(errorDescription ?? error));
|
|
19174
|
+
cleanup();
|
|
19175
|
+
reject(new BBError({
|
|
19176
|
+
code: 1002 /* AUTH_INVALID */,
|
|
19177
|
+
message: `Authorization was denied: ${errorDescription ?? error}. Run "bb auth login --app-password" to use an API token instead.`
|
|
19178
|
+
}));
|
|
19179
|
+
return;
|
|
19180
|
+
}
|
|
19181
|
+
if (!code || state !== expectedState) {
|
|
19182
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
19183
|
+
res.end(this.buildErrorPage("Invalid callback parameters"));
|
|
19184
|
+
cleanup();
|
|
19185
|
+
reject(new BBError({
|
|
19186
|
+
code: 1002 /* AUTH_INVALID */,
|
|
19187
|
+
message: "Invalid authorization callback. Please try again."
|
|
19188
|
+
}));
|
|
19189
|
+
return;
|
|
19190
|
+
}
|
|
19191
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
19192
|
+
res.end(this.buildSuccessPage());
|
|
19193
|
+
cleanup();
|
|
19194
|
+
resolve({ code });
|
|
19195
|
+
});
|
|
19196
|
+
server.on("error", (err) => {
|
|
19197
|
+
cleanup();
|
|
19198
|
+
if (err.code === "EADDRINUSE") {
|
|
19199
|
+
reject(new BBError({
|
|
19200
|
+
code: 1002 /* AUTH_INVALID */,
|
|
19201
|
+
message: `Port ${CALLBACK_PORT} is already in use. Close the application using it and try again.`
|
|
19202
|
+
}));
|
|
19203
|
+
} else {
|
|
19204
|
+
reject(new BBError({
|
|
19205
|
+
code: 7001 /* NETWORK_ERROR */,
|
|
19206
|
+
message: `Failed to start callback server: ${err.message}`,
|
|
19207
|
+
cause: err
|
|
19208
|
+
}));
|
|
19209
|
+
}
|
|
19210
|
+
});
|
|
19211
|
+
server.listen(CALLBACK_PORT, async () => {
|
|
19212
|
+
try {
|
|
19213
|
+
const open2 = (await Promise.resolve().then(() => (init_open(), exports_open))).default;
|
|
19214
|
+
await open2(authUrl);
|
|
19215
|
+
} catch {}
|
|
19216
|
+
console.error(`If the browser doesn't open, visit:
|
|
19217
|
+
${authUrl}
|
|
19218
|
+
`);
|
|
19219
|
+
});
|
|
19220
|
+
});
|
|
19221
|
+
}
|
|
19222
|
+
async exchangeCode(code, clientId, clientSecretOverride) {
|
|
19223
|
+
const clientSecret = clientSecretOverride ?? await this.getClientSecret();
|
|
19224
|
+
const params = new URLSearchParams({
|
|
19225
|
+
grant_type: "authorization_code",
|
|
19226
|
+
code,
|
|
19227
|
+
redirect_uri: CALLBACK_URL
|
|
19228
|
+
});
|
|
19229
|
+
const response = await fetch(BITBUCKET_TOKEN_URL, {
|
|
19230
|
+
method: "POST",
|
|
19231
|
+
headers: {
|
|
19232
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
19233
|
+
Authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString("base64")}`
|
|
19234
|
+
},
|
|
19235
|
+
body: params.toString()
|
|
19236
|
+
});
|
|
19237
|
+
if (!response.ok) {
|
|
19238
|
+
const errorBody = await response.text();
|
|
19239
|
+
throw new BBError({
|
|
19240
|
+
code: 1002 /* AUTH_INVALID */,
|
|
19241
|
+
message: `Failed to exchange authorization code. Please try again.`,
|
|
19242
|
+
context: { status: response.status, body: errorBody }
|
|
19243
|
+
});
|
|
19244
|
+
}
|
|
19245
|
+
return await response.json();
|
|
19246
|
+
}
|
|
19247
|
+
async fetchUserInfo(accessToken) {
|
|
19248
|
+
const response = await fetch("https://api.bitbucket.org/2.0/user", {
|
|
19249
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
19250
|
+
});
|
|
19251
|
+
if (!response.ok) {
|
|
19252
|
+
throw new BBError({
|
|
19253
|
+
code: 1002 /* AUTH_INVALID */,
|
|
19254
|
+
message: "Failed to verify OAuth credentials."
|
|
19255
|
+
});
|
|
19256
|
+
}
|
|
19257
|
+
const user = await response.json();
|
|
19258
|
+
return {
|
|
19259
|
+
username: user.username,
|
|
19260
|
+
displayName: user.display_name,
|
|
19261
|
+
accountId: user.account_id
|
|
19262
|
+
};
|
|
19263
|
+
}
|
|
19264
|
+
buildPageShell(content) {
|
|
19265
|
+
return `<!DOCTYPE html>
|
|
19266
|
+
<html lang="en"><head>
|
|
19267
|
+
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
19268
|
+
<title>Bitbucket CLI</title>
|
|
19269
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
19270
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
19271
|
+
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
19272
|
+
<style>
|
|
19273
|
+
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
|
19274
|
+
:root{
|
|
19275
|
+
--bg:#181c24;
|
|
19276
|
+
--surface:#1e2330;
|
|
19277
|
+
--border:hsl(216,24%,27%);
|
|
19278
|
+
--text:#e0e4ec;
|
|
19279
|
+
--text-dim:#8892a4;
|
|
19280
|
+
--accent:hsl(216,100%,50%);
|
|
19281
|
+
--accent-glow:hsla(216,100%,52%,0.2);
|
|
19282
|
+
--accent-soft:hsla(216,100%,52%,0.09);
|
|
19283
|
+
--font:'Space Grotesk',sans-serif;
|
|
19284
|
+
--mono:'IBM Plex Mono',monospace;
|
|
19285
|
+
}
|
|
19286
|
+
body{
|
|
19287
|
+
font-family:var(--font);
|
|
19288
|
+
background:var(--bg);
|
|
19289
|
+
color:var(--text);
|
|
19290
|
+
min-height:100vh;
|
|
19291
|
+
display:flex;
|
|
19292
|
+
align-items:center;
|
|
19293
|
+
justify-content:center;
|
|
19294
|
+
background-image:
|
|
19295
|
+
radial-gradient(ellipse 80% 60% at 50% 0%,var(--accent-glow),transparent),
|
|
19296
|
+
radial-gradient(circle at 100% 100%,var(--accent-soft),transparent 50%);
|
|
19297
|
+
}
|
|
19298
|
+
.scene{
|
|
19299
|
+
display:flex;
|
|
19300
|
+
flex-direction:column;
|
|
19301
|
+
align-items:center;
|
|
19302
|
+
gap:2rem;
|
|
19303
|
+
animation:enter 600ms cubic-bezier(.16,1,.3,1) both;
|
|
19304
|
+
}
|
|
19305
|
+
@keyframes enter{
|
|
19306
|
+
from{opacity:0;transform:translateY(16px) scale(.97)}
|
|
19307
|
+
to{opacity:1;transform:translateY(0) scale(1)}
|
|
19308
|
+
}
|
|
19309
|
+
.logo{
|
|
19310
|
+
width:56px;height:56px;
|
|
19311
|
+
background:var(--accent);
|
|
19312
|
+
border-radius:14px;
|
|
19313
|
+
display:flex;align-items:center;justify-content:center;
|
|
19314
|
+
font-family:var(--mono);font-weight:700;font-size:24px;
|
|
19315
|
+
color:#fff;
|
|
19316
|
+
box-shadow:0 0 0 1px hsla(216,100%,70%,0.15),0 8px 32px hsla(216,100%,40%,0.25);
|
|
19317
|
+
animation:logo-in 700ms cubic-bezier(.16,1,.3,1) both;
|
|
19318
|
+
animation-delay:100ms;
|
|
19319
|
+
}
|
|
19320
|
+
@keyframes logo-in{
|
|
19321
|
+
from{opacity:0;transform:scale(.6) rotate(-8deg)}
|
|
19322
|
+
to{opacity:1;transform:scale(1) rotate(0)}
|
|
19323
|
+
}
|
|
19324
|
+
.card{
|
|
19325
|
+
background:var(--surface);
|
|
19326
|
+
border:1px solid var(--border);
|
|
19327
|
+
border-radius:16px;
|
|
19328
|
+
padding:2.5rem 3rem;
|
|
19329
|
+
text-align:center;
|
|
19330
|
+
max-width:420px;
|
|
19331
|
+
width:100%;
|
|
19332
|
+
box-shadow:0 1px 2px rgba(0,0,0,0.2),0 16px 48px rgba(0,0,0,0.15);
|
|
19333
|
+
animation:card-in 600ms cubic-bezier(.16,1,.3,1) both;
|
|
19334
|
+
animation-delay:200ms;
|
|
19335
|
+
}
|
|
19336
|
+
@keyframes card-in{
|
|
19337
|
+
from{opacity:0;transform:translateY(12px)}
|
|
19338
|
+
to{opacity:1;transform:translateY(0)}
|
|
19339
|
+
}
|
|
19340
|
+
.icon-ring{
|
|
19341
|
+
width:52px;height:52px;
|
|
19342
|
+
border-radius:50%;
|
|
19343
|
+
display:flex;align-items:center;justify-content:center;
|
|
19344
|
+
margin:0 auto 1.25rem;
|
|
19345
|
+
animation:ring-pop 500ms cubic-bezier(.16,1,.3,1) both;
|
|
19346
|
+
animation-delay:450ms;
|
|
19347
|
+
}
|
|
19348
|
+
@keyframes ring-pop{
|
|
19349
|
+
from{opacity:0;transform:scale(.5)}
|
|
19350
|
+
to{opacity:1;transform:scale(1)}
|
|
19351
|
+
}
|
|
19352
|
+
.icon-ring svg{width:28px;height:28px}
|
|
19353
|
+
.icon-ring.success{background:hsla(152,68%,46%,0.12);color:hsl(152,68%,46%)}
|
|
19354
|
+
.icon-ring.error{background:hsla(0,72%,56%,0.12);color:hsl(0,72%,56%)}
|
|
19355
|
+
h1{
|
|
19356
|
+
font-size:1.35rem;font-weight:700;
|
|
19357
|
+
letter-spacing:-0.02em;
|
|
19358
|
+
margin-bottom:0.5rem;
|
|
19359
|
+
animation:text-in 500ms ease both;animation-delay:500ms;
|
|
19360
|
+
}
|
|
19361
|
+
.subtitle{
|
|
19362
|
+
font-size:0.9rem;color:var(--text-dim);
|
|
19363
|
+
line-height:1.5;
|
|
19364
|
+
animation:text-in 500ms ease both;animation-delay:580ms;
|
|
19365
|
+
}
|
|
19366
|
+
@keyframes text-in{
|
|
19367
|
+
from{opacity:0;transform:translateY(6px)}
|
|
19368
|
+
to{opacity:1;transform:translateY(0)}
|
|
19369
|
+
}
|
|
19370
|
+
.hint{
|
|
19371
|
+
font-family:var(--mono);font-size:0.72rem;
|
|
19372
|
+
color:var(--text-dim);letter-spacing:0.02em;
|
|
19373
|
+
opacity:0;animation:text-in 500ms ease forwards;animation-delay:700ms;
|
|
19374
|
+
}
|
|
19375
|
+
.hint a{
|
|
19376
|
+
color:var(--accent);text-decoration:none;
|
|
19377
|
+
text-underline-offset:0.2em;
|
|
19378
|
+
}
|
|
19379
|
+
.hint a:hover{text-decoration:underline}
|
|
19380
|
+
.hint kbd{
|
|
19381
|
+
background:var(--surface);border:1px solid var(--border);
|
|
19382
|
+
border-radius:4px;padding:0.15em 0.45em;
|
|
19383
|
+
font-family:var(--mono);font-size:0.72rem;
|
|
19384
|
+
}
|
|
19385
|
+
</style>
|
|
19386
|
+
</head><body>
|
|
19387
|
+
<div class="scene">
|
|
19388
|
+
<div class="logo">bb</div>
|
|
19389
|
+
<div class="card">${content}</div>
|
|
19390
|
+
</div>
|
|
19391
|
+
</body></html>`;
|
|
19392
|
+
}
|
|
19393
|
+
buildSuccessPage() {
|
|
19394
|
+
return this.buildPageShell(`
|
|
19395
|
+
<div class="icon-ring success">
|
|
19396
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
19397
|
+
<polyline points="20 6 9 17 4 12"/>
|
|
19398
|
+
</svg>
|
|
19399
|
+
</div>
|
|
19400
|
+
<h1>Authenticated</h1>
|
|
19401
|
+
<p class="subtitle">You're all set. Close this tab and return to your terminal.</p>
|
|
19402
|
+
<p class="hint"><a href="https://bitbucket-cli.paulvanderlei.com" target="_blank" rel="noopener">View documentation</a></p>
|
|
19403
|
+
`);
|
|
19404
|
+
}
|
|
19405
|
+
buildErrorPage(message) {
|
|
19406
|
+
const escaped = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
19407
|
+
return this.buildPageShell(`
|
|
19408
|
+
<div class="icon-ring error">
|
|
19409
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
19410
|
+
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
|
|
19411
|
+
</svg>
|
|
19412
|
+
</div>
|
|
19413
|
+
<h1>Authentication Failed</h1>
|
|
19414
|
+
<p class="subtitle">${escaped}</p>
|
|
19415
|
+
<p class="hint"><a href="https://bitbucket-cli.paulvanderlei.com/help/troubleshooting/" target="_blank" rel="noopener">Troubleshooting guide</a></p>
|
|
19416
|
+
`);
|
|
19417
|
+
}
|
|
19418
|
+
}
|
|
18288
19419
|
// src/services/reviewer.service.ts
|
|
18289
19420
|
function extractReviewerUuids(reviewers) {
|
|
18290
19421
|
if (!reviewers) {
|
|
@@ -20035,12 +21166,12 @@ var RepositoriesApiAxiosParamCreator = function(configuration) {
|
|
|
20035
21166
|
options: localVarRequestOptions
|
|
20036
21167
|
};
|
|
20037
21168
|
},
|
|
20038
|
-
repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet: async (commit,
|
|
21169
|
+
repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet: async (commit, path2, repoSlug, workspace, renames, q, sort, options = {}) => {
|
|
20039
21170
|
assertParamExists("repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet", "commit", commit);
|
|
20040
|
-
assertParamExists("repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet", "path",
|
|
21171
|
+
assertParamExists("repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet", "path", path2);
|
|
20041
21172
|
assertParamExists("repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet", "repoSlug", repoSlug);
|
|
20042
21173
|
assertParamExists("repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet", "workspace", workspace);
|
|
20043
|
-
const localVarPath = `/repositories/{workspace}/{repo_slug}/filehistory/{commit}/{path}`.replace(`{${"commit"}}`, encodeURIComponent(String(commit))).replace(`{${"path"}}`, encodeURIComponent(String(
|
|
21174
|
+
const localVarPath = `/repositories/{workspace}/{repo_slug}/filehistory/{commit}/{path}`.replace(`{${"commit"}}`, encodeURIComponent(String(commit))).replace(`{${"path"}}`, encodeURIComponent(String(path2))).replace(`{${"repo_slug"}}`, encodeURIComponent(String(repoSlug))).replace(`{${"workspace"}}`, encodeURIComponent(String(workspace)));
|
|
20044
21175
|
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
|
20045
21176
|
let baseOptions;
|
|
20046
21177
|
if (configuration) {
|
|
@@ -20580,12 +21711,12 @@ var RepositoriesApiAxiosParamCreator = function(configuration) {
|
|
|
20580
21711
|
options: localVarRequestOptions
|
|
20581
21712
|
};
|
|
20582
21713
|
},
|
|
20583
|
-
repositoriesWorkspaceRepoSlugSrcCommitPathGet: async (commit,
|
|
21714
|
+
repositoriesWorkspaceRepoSlugSrcCommitPathGet: async (commit, path2, repoSlug, workspace, format, q, sort, maxDepth, options = {}) => {
|
|
20584
21715
|
assertParamExists("repositoriesWorkspaceRepoSlugSrcCommitPathGet", "commit", commit);
|
|
20585
|
-
assertParamExists("repositoriesWorkspaceRepoSlugSrcCommitPathGet", "path",
|
|
21716
|
+
assertParamExists("repositoriesWorkspaceRepoSlugSrcCommitPathGet", "path", path2);
|
|
20586
21717
|
assertParamExists("repositoriesWorkspaceRepoSlugSrcCommitPathGet", "repoSlug", repoSlug);
|
|
20587
21718
|
assertParamExists("repositoriesWorkspaceRepoSlugSrcCommitPathGet", "workspace", workspace);
|
|
20588
|
-
const localVarPath = `/repositories/{workspace}/{repo_slug}/src/{commit}/{path}`.replace(`{${"commit"}}`, encodeURIComponent(String(commit))).replace(`{${"path"}}`, encodeURIComponent(String(
|
|
21719
|
+
const localVarPath = `/repositories/{workspace}/{repo_slug}/src/{commit}/{path}`.replace(`{${"commit"}}`, encodeURIComponent(String(commit))).replace(`{${"path"}}`, encodeURIComponent(String(path2))).replace(`{${"repo_slug"}}`, encodeURIComponent(String(repoSlug))).replace(`{${"workspace"}}`, encodeURIComponent(String(workspace)));
|
|
20589
21720
|
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
|
20590
21721
|
let baseOptions;
|
|
20591
21722
|
if (configuration) {
|
|
@@ -20759,8 +21890,8 @@ var RepositoriesApiFp = function(configuration) {
|
|
|
20759
21890
|
const localVarOperationServerBasePath = operationServerMap["RepositoriesApi.repositoriesWorkspaceRepoSlugDelete"]?.[localVarOperationServerIndex]?.url;
|
|
20760
21891
|
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
20761
21892
|
},
|
|
20762
|
-
async repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet(commit,
|
|
20763
|
-
const localVarAxiosArgs = await localVarAxiosParamCreator.repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet(commit,
|
|
21893
|
+
async repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet(commit, path2, repoSlug, workspace, renames, q, sort, options) {
|
|
21894
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet(commit, path2, repoSlug, workspace, renames, q, sort, options);
|
|
20764
21895
|
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
|
20765
21896
|
const localVarOperationServerBasePath = operationServerMap["RepositoriesApi.repositoriesWorkspaceRepoSlugFilehistoryCommitPathGet"]?.[localVarOperationServerIndex]?.url;
|
|
20766
21897
|
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
@@ -20885,8 +22016,8 @@ var RepositoriesApiFp = function(configuration) {
|
|
|
20885
22016
|
const localVarOperationServerBasePath = operationServerMap["RepositoriesApi.repositoriesWorkspaceRepoSlugPut"]?.[localVarOperationServerIndex]?.url;
|
|
20886
22017
|
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
20887
22018
|
},
|
|
20888
|
-
async repositoriesWorkspaceRepoSlugSrcCommitPathGet(commit,
|
|
20889
|
-
const localVarAxiosArgs = await localVarAxiosParamCreator.repositoriesWorkspaceRepoSlugSrcCommitPathGet(commit,
|
|
22019
|
+
async repositoriesWorkspaceRepoSlugSrcCommitPathGet(commit, path2, repoSlug, workspace, format, q, sort, maxDepth, options) {
|
|
22020
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.repositoriesWorkspaceRepoSlugSrcCommitPathGet(commit, path2, repoSlug, workspace, format, q, sort, maxDepth, options);
|
|
20890
22021
|
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
|
20891
22022
|
const localVarOperationServerBasePath = operationServerMap["RepositoriesApi.repositoriesWorkspaceRepoSlugSrcCommitPathGet"]?.[localVarOperationServerIndex]?.url;
|
|
20892
22023
|
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
@@ -21223,14 +22354,45 @@ class BaseCommand {
|
|
|
21223
22354
|
class LoginCommand extends BaseCommand {
|
|
21224
22355
|
configService;
|
|
21225
22356
|
usersApi;
|
|
22357
|
+
oauthService;
|
|
21226
22358
|
name = "login";
|
|
21227
|
-
description = "Authenticate with Bitbucket
|
|
21228
|
-
constructor(configService, usersApi, output) {
|
|
22359
|
+
description = "Authenticate with Bitbucket";
|
|
22360
|
+
constructor(configService, usersApi, oauthService, output) {
|
|
21229
22361
|
super(output);
|
|
21230
22362
|
this.configService = configService;
|
|
21231
22363
|
this.usersApi = usersApi;
|
|
22364
|
+
this.oauthService = oauthService;
|
|
21232
22365
|
}
|
|
21233
22366
|
async execute(options, context) {
|
|
22367
|
+
const useAppPassword = options.appPassword || options.username !== undefined || options.password !== undefined || process.env.BB_API_TOKEN !== undefined;
|
|
22368
|
+
if (useAppPassword) {
|
|
22369
|
+
return this.loginWithApiToken(options, context);
|
|
22370
|
+
}
|
|
22371
|
+
return this.loginWithOAuth(options, context);
|
|
22372
|
+
}
|
|
22373
|
+
async loginWithOAuth(options, context) {
|
|
22374
|
+
this.output.info("Opening browser to authenticate with Bitbucket...");
|
|
22375
|
+
try {
|
|
22376
|
+
const userInfo = await this.oauthService.authorize(options.clientId, options.clientSecret);
|
|
22377
|
+
if (context.globalOptions.json) {
|
|
22378
|
+
this.output.json({
|
|
22379
|
+
authenticated: true,
|
|
22380
|
+
method: "oauth",
|
|
22381
|
+
user: {
|
|
22382
|
+
username: userInfo.username,
|
|
22383
|
+
displayName: userInfo.displayName,
|
|
22384
|
+
accountId: userInfo.accountId
|
|
22385
|
+
}
|
|
22386
|
+
});
|
|
22387
|
+
return;
|
|
22388
|
+
}
|
|
22389
|
+
this.output.success(`Logged in as ${userInfo.displayName} (${userInfo.username})`);
|
|
22390
|
+
} catch (error) {
|
|
22391
|
+
await this.configService.clearOAuthCredentials();
|
|
22392
|
+
throw error;
|
|
22393
|
+
}
|
|
22394
|
+
}
|
|
22395
|
+
async loginWithApiToken(options, context) {
|
|
21234
22396
|
const username = options.username || process.env.BB_USERNAME;
|
|
21235
22397
|
const apiToken = options.password || process.env.BB_API_TOKEN;
|
|
21236
22398
|
if (!username) {
|
|
@@ -21245,6 +22407,7 @@ class LoginCommand extends BaseCommand {
|
|
|
21245
22407
|
message: "API token is required. Use --password option or set BB_API_TOKEN environment variable."
|
|
21246
22408
|
});
|
|
21247
22409
|
}
|
|
22410
|
+
await this.configService.clearOAuthCredentials();
|
|
21248
22411
|
await this.configService.setCredentials({ username, apiToken });
|
|
21249
22412
|
try {
|
|
21250
22413
|
const response = await this.usersApi.userGet();
|
|
@@ -21252,6 +22415,7 @@ class LoginCommand extends BaseCommand {
|
|
|
21252
22415
|
if (context.globalOptions.json) {
|
|
21253
22416
|
this.output.json({
|
|
21254
22417
|
authenticated: true,
|
|
22418
|
+
method: "api_token",
|
|
21255
22419
|
user: {
|
|
21256
22420
|
username: user.username,
|
|
21257
22421
|
displayName: user.display_name,
|
|
@@ -21274,14 +22438,22 @@ class LoginCommand extends BaseCommand {
|
|
|
21274
22438
|
// src/commands/auth/logout.command.ts
|
|
21275
22439
|
class LogoutCommand extends BaseCommand {
|
|
21276
22440
|
configService;
|
|
22441
|
+
oauthService;
|
|
21277
22442
|
name = "logout";
|
|
21278
22443
|
description = "Log out of Bitbucket";
|
|
21279
|
-
constructor(configService, output) {
|
|
22444
|
+
constructor(configService, oauthService, output) {
|
|
21280
22445
|
super(output);
|
|
21281
22446
|
this.configService = configService;
|
|
22447
|
+
this.oauthService = oauthService;
|
|
21282
22448
|
}
|
|
21283
22449
|
async execute(_options, context) {
|
|
21284
|
-
await this.configService.
|
|
22450
|
+
const authMethod = await this.configService.getAuthMethod();
|
|
22451
|
+
if (authMethod === "oauth") {
|
|
22452
|
+
await this.oauthService.revokeToken();
|
|
22453
|
+
await this.configService.clearOAuthCredentials();
|
|
22454
|
+
} else {
|
|
22455
|
+
await this.configService.clearCredentials();
|
|
22456
|
+
}
|
|
21285
22457
|
if (context.globalOptions.json) {
|
|
21286
22458
|
this.output.json({ authenticated: false, success: true });
|
|
21287
22459
|
return;
|
|
@@ -21303,7 +22475,10 @@ class StatusCommand extends BaseCommand {
|
|
|
21303
22475
|
}
|
|
21304
22476
|
async execute(_options, context) {
|
|
21305
22477
|
const config = await this.configService.getConfig();
|
|
21306
|
-
|
|
22478
|
+
const authMethod = await this.configService.getAuthMethod();
|
|
22479
|
+
const hasBasicAuth = config.username && config.apiToken;
|
|
22480
|
+
const hasOAuth = config.oauthAccessToken && config.oauthRefreshToken;
|
|
22481
|
+
if (!hasBasicAuth && !hasOAuth) {
|
|
21307
22482
|
if (context.globalOptions.json) {
|
|
21308
22483
|
this.output.json({ authenticated: false });
|
|
21309
22484
|
return;
|
|
@@ -21316,21 +22491,41 @@ class StatusCommand extends BaseCommand {
|
|
|
21316
22491
|
const response = await this.usersApi.userGet();
|
|
21317
22492
|
const user = response.data;
|
|
21318
22493
|
if (context.globalOptions.json) {
|
|
21319
|
-
|
|
22494
|
+
const jsonOutput = {
|
|
21320
22495
|
authenticated: true,
|
|
22496
|
+
method: authMethod,
|
|
21321
22497
|
user: {
|
|
21322
22498
|
username: user.username,
|
|
21323
22499
|
displayName: user.display_name,
|
|
21324
22500
|
accountId: user.account_id
|
|
21325
22501
|
},
|
|
21326
22502
|
defaultWorkspace: config.defaultWorkspace
|
|
21327
|
-
}
|
|
22503
|
+
};
|
|
22504
|
+
if (authMethod === "oauth" && config.oauthExpiresAt) {
|
|
22505
|
+
jsonOutput.tokenExpiresAt = config.oauthExpiresAt;
|
|
22506
|
+
}
|
|
22507
|
+
this.output.json(jsonOutput);
|
|
21328
22508
|
return;
|
|
21329
22509
|
}
|
|
21330
22510
|
this.output.success("Logged in to Bitbucket");
|
|
22511
|
+
this.output.text(` Authentication: ${this.output.highlight(authMethod === "oauth" ? "OAuth" : "API Token")}`);
|
|
21331
22512
|
this.output.text(` Username: ${this.output.highlight(user.username ?? "")}`);
|
|
21332
22513
|
this.output.text(` Display name: ${user.display_name}`);
|
|
21333
22514
|
this.output.text(` Account ID: ${user.account_id}`);
|
|
22515
|
+
if (authMethod === "oauth" && config.oauthExpiresAt) {
|
|
22516
|
+
const expiresIn = config.oauthExpiresAt - Math.floor(Date.now() / 1000);
|
|
22517
|
+
if (expiresIn > 0) {
|
|
22518
|
+
const hours = Math.floor(expiresIn / 3600);
|
|
22519
|
+
const minutes = Math.floor(expiresIn % 3600 / 60);
|
|
22520
|
+
const parts = [];
|
|
22521
|
+
if (hours > 0)
|
|
22522
|
+
parts.push(`${hours}h`);
|
|
22523
|
+
parts.push(`${minutes}m`);
|
|
22524
|
+
this.output.text(` Token expires: in ${parts.join(" ")}`);
|
|
22525
|
+
} else {
|
|
22526
|
+
this.output.text(` Token expires: ${this.output.yellow("expired (will refresh automatically)")}`);
|
|
22527
|
+
}
|
|
22528
|
+
}
|
|
21334
22529
|
if (config.defaultWorkspace) {
|
|
21335
22530
|
this.output.text(` Default workspace: ${this.output.highlight(config.defaultWorkspace)}`);
|
|
21336
22531
|
}
|
|
@@ -21347,13 +22542,25 @@ class StatusCommand extends BaseCommand {
|
|
|
21347
22542
|
// src/commands/auth/token.command.ts
|
|
21348
22543
|
class TokenCommand extends BaseCommand {
|
|
21349
22544
|
configService;
|
|
22545
|
+
oauthService;
|
|
21350
22546
|
name = "token";
|
|
21351
22547
|
description = "Print the current access token";
|
|
21352
|
-
constructor(configService, output) {
|
|
22548
|
+
constructor(configService, oauthService, output) {
|
|
21353
22549
|
super(output);
|
|
21354
22550
|
this.configService = configService;
|
|
22551
|
+
this.oauthService = oauthService;
|
|
21355
22552
|
}
|
|
21356
22553
|
async execute(_options, context) {
|
|
22554
|
+
const authMethod = await this.configService.getAuthMethod();
|
|
22555
|
+
if (authMethod === "oauth") {
|
|
22556
|
+
const accessToken = await this.oauthService.getValidAccessToken();
|
|
22557
|
+
if (context.globalOptions.json) {
|
|
22558
|
+
this.output.json({ token: accessToken, type: "bearer" });
|
|
22559
|
+
return;
|
|
22560
|
+
}
|
|
22561
|
+
this.output.text(accessToken);
|
|
22562
|
+
return;
|
|
22563
|
+
}
|
|
21357
22564
|
const credentials = await this.configService.getCredentials();
|
|
21358
22565
|
if (!credentials.username || !credentials.apiToken) {
|
|
21359
22566
|
throw new BBError({
|
|
@@ -21363,7 +22570,7 @@ class TokenCommand extends BaseCommand {
|
|
|
21363
22570
|
}
|
|
21364
22571
|
const token = Buffer.from(`${credentials.username}:${credentials.apiToken}`).toString("base64");
|
|
21365
22572
|
if (context.globalOptions.json) {
|
|
21366
|
-
this.output.json({ token });
|
|
22573
|
+
this.output.json({ token, type: "basic" });
|
|
21367
22574
|
return;
|
|
21368
22575
|
}
|
|
21369
22576
|
this.output.text(token);
|
|
@@ -21488,8 +22695,8 @@ function getCommitFilePath(file) {
|
|
|
21488
22695
|
if (!isRecord(file)) {
|
|
21489
22696
|
return;
|
|
21490
22697
|
}
|
|
21491
|
-
const
|
|
21492
|
-
return typeof
|
|
22698
|
+
const path2 = file.path;
|
|
22699
|
+
return typeof path2 === "string" && path2.length > 0 ? path2 : undefined;
|
|
21493
22700
|
}
|
|
21494
22701
|
function parseDiffstatFile(value) {
|
|
21495
22702
|
if (!isRecord(value)) {
|
|
@@ -22270,7 +23477,7 @@ class ViewPRCommand extends BaseCommand {
|
|
|
22270
23477
|
}
|
|
22271
23478
|
|
|
22272
23479
|
// src/commands/pr/edit.command.ts
|
|
22273
|
-
import * as
|
|
23480
|
+
import * as fs6 from "fs";
|
|
22274
23481
|
class EditPRCommand extends BaseCommand {
|
|
22275
23482
|
pullrequestsApi;
|
|
22276
23483
|
contextService;
|
|
@@ -22324,7 +23531,7 @@ class EditPRCommand extends BaseCommand {
|
|
|
22324
23531
|
let body = options.body;
|
|
22325
23532
|
if (options.bodyFile) {
|
|
22326
23533
|
try {
|
|
22327
|
-
body =
|
|
23534
|
+
body = fs6.readFileSync(options.bodyFile, "utf-8");
|
|
22328
23535
|
} catch (err) {
|
|
22329
23536
|
throw new BBError({
|
|
22330
23537
|
code: 9999 /* UNKNOWN */,
|
|
@@ -22596,8 +23803,8 @@ class CheckoutPRCommand extends BaseCommand {
|
|
|
22596
23803
|
|
|
22597
23804
|
// src/commands/pr/diff.command.ts
|
|
22598
23805
|
import { exec } from "child_process";
|
|
22599
|
-
import { promisify } from "util";
|
|
22600
|
-
var execAsync =
|
|
23806
|
+
import { promisify as promisify7 } from "util";
|
|
23807
|
+
var execAsync = promisify7(exec);
|
|
22601
23808
|
|
|
22602
23809
|
class DiffPRCommand extends BaseCommand {
|
|
22603
23810
|
pullrequestsApi;
|
|
@@ -22709,11 +23916,11 @@ class DiffPRCommand extends BaseCommand {
|
|
|
22709
23916
|
}
|
|
22710
23917
|
async openInBrowser(url2) {
|
|
22711
23918
|
this.output.info(`Opening ${url2} in your browser...`);
|
|
22712
|
-
const
|
|
23919
|
+
const platform2 = process.platform;
|
|
22713
23920
|
let command;
|
|
22714
|
-
if (
|
|
23921
|
+
if (platform2 === "darwin") {
|
|
22715
23922
|
command = `open "${url2}"`;
|
|
22716
|
-
} else if (
|
|
23923
|
+
} else if (platform2 === "win32") {
|
|
22717
23924
|
command = `start "" "${url2}"`;
|
|
22718
23925
|
} else {
|
|
22719
23926
|
command = `xdg-open "${url2}"`;
|
|
@@ -23676,24 +24883,32 @@ function bootstrap(options = {}) {
|
|
|
23676
24883
|
container.register(ServiceTokens.ConfigService, () => new ConfigService);
|
|
23677
24884
|
container.register(ServiceTokens.GitService, () => new GitService);
|
|
23678
24885
|
container.register(ServiceTokens.OutputService, () => new OutputService({ noColor: options.noColor }));
|
|
24886
|
+
container.register(ServiceTokens.OAuthService, () => {
|
|
24887
|
+
const configService = container.resolve(ServiceTokens.ConfigService);
|
|
24888
|
+
return new OAuthService(configService);
|
|
24889
|
+
});
|
|
23679
24890
|
container.register(ServiceTokens.PullrequestsApi, () => {
|
|
23680
24891
|
const configService = container.resolve(ServiceTokens.ConfigService);
|
|
23681
|
-
const
|
|
24892
|
+
const oauthService = container.resolve(ServiceTokens.OAuthService);
|
|
24893
|
+
const axiosInstance = createApiClient(configService, oauthService);
|
|
23682
24894
|
return new PullrequestsApi(undefined, undefined, axiosInstance);
|
|
23683
24895
|
});
|
|
23684
24896
|
container.register(ServiceTokens.RepositoriesApi, () => {
|
|
23685
24897
|
const configService = container.resolve(ServiceTokens.ConfigService);
|
|
23686
|
-
const
|
|
24898
|
+
const oauthService = container.resolve(ServiceTokens.OAuthService);
|
|
24899
|
+
const axiosInstance = createApiClient(configService, oauthService);
|
|
23687
24900
|
return new RepositoriesApi(undefined, undefined, axiosInstance);
|
|
23688
24901
|
});
|
|
23689
24902
|
container.register(ServiceTokens.UsersApi, () => {
|
|
23690
24903
|
const configService = container.resolve(ServiceTokens.ConfigService);
|
|
23691
|
-
const
|
|
24904
|
+
const oauthService = container.resolve(ServiceTokens.OAuthService);
|
|
24905
|
+
const axiosInstance = createApiClient(configService, oauthService);
|
|
23692
24906
|
return new UsersApi(undefined, undefined, axiosInstance);
|
|
23693
24907
|
});
|
|
23694
24908
|
container.register(ServiceTokens.CommitStatusesApi, () => {
|
|
23695
24909
|
const configService = container.resolve(ServiceTokens.ConfigService);
|
|
23696
|
-
const
|
|
24910
|
+
const oauthService = container.resolve(ServiceTokens.OAuthService);
|
|
24911
|
+
const axiosInstance = createApiClient(configService, oauthService);
|
|
23697
24912
|
return new CommitStatusesApi(undefined, undefined, axiosInstance);
|
|
23698
24913
|
});
|
|
23699
24914
|
container.register(ServiceTokens.ContextService, () => {
|
|
@@ -23704,13 +24919,15 @@ function bootstrap(options = {}) {
|
|
|
23704
24919
|
container.register(ServiceTokens.LoginCommand, () => {
|
|
23705
24920
|
const configService = container.resolve(ServiceTokens.ConfigService);
|
|
23706
24921
|
const usersApi = container.resolve(ServiceTokens.UsersApi);
|
|
24922
|
+
const oauthService = container.resolve(ServiceTokens.OAuthService);
|
|
23707
24923
|
const output = container.resolve(ServiceTokens.OutputService);
|
|
23708
|
-
return new LoginCommand(configService, usersApi, output);
|
|
24924
|
+
return new LoginCommand(configService, usersApi, oauthService, output);
|
|
23709
24925
|
});
|
|
23710
24926
|
container.register(ServiceTokens.LogoutCommand, () => {
|
|
23711
24927
|
const configService = container.resolve(ServiceTokens.ConfigService);
|
|
24928
|
+
const oauthService = container.resolve(ServiceTokens.OAuthService);
|
|
23712
24929
|
const output = container.resolve(ServiceTokens.OutputService);
|
|
23713
|
-
return new LogoutCommand(configService, output);
|
|
24930
|
+
return new LogoutCommand(configService, oauthService, output);
|
|
23714
24931
|
});
|
|
23715
24932
|
container.register(ServiceTokens.StatusCommand, () => {
|
|
23716
24933
|
const configService = container.resolve(ServiceTokens.ConfigService);
|
|
@@ -23720,8 +24937,9 @@ function bootstrap(options = {}) {
|
|
|
23720
24937
|
});
|
|
23721
24938
|
container.register(ServiceTokens.TokenCommand, () => {
|
|
23722
24939
|
const configService = container.resolve(ServiceTokens.ConfigService);
|
|
24940
|
+
const oauthService = container.resolve(ServiceTokens.OAuthService);
|
|
23723
24941
|
const output = container.resolve(ServiceTokens.OutputService);
|
|
23724
|
-
return new TokenCommand(configService, output);
|
|
24942
|
+
return new TokenCommand(configService, oauthService, output);
|
|
23725
24943
|
});
|
|
23726
24944
|
container.register(ServiceTokens.CloneCommand, () => {
|
|
23727
24945
|
const gitService = container.resolve(ServiceTokens.GitService);
|
|
@@ -24064,14 +25282,16 @@ cli.name("bb").description("A command-line interface for Bitbucket Cloud").versi
|
|
|
24064
25282
|
} catch {}
|
|
24065
25283
|
});
|
|
24066
25284
|
var authCmd = new Command("auth").description("Authenticate with Bitbucket");
|
|
24067
|
-
authCmd.command("login").description("Authenticate with Bitbucket
|
|
25285
|
+
authCmd.command("login").description("Authenticate with Bitbucket (OAuth or API token)").option("-u, --username <username>", "Bitbucket username (implies API token auth)").option("-p, --password <password>", "Bitbucket API token (implies API token auth)").option("--app-password", "Use API token authentication instead of OAuth").option("--client-id <clientId>", "Custom OAuth consumer client ID").option("--client-secret <clientSecret>", "Custom OAuth consumer client secret").addHelpText("after", buildHelpText({
|
|
24068
25286
|
examples: [
|
|
24069
|
-
"bb auth login
|
|
25287
|
+
"bb auth login",
|
|
25288
|
+
"bb auth login --app-password -u myuser -p mytoken",
|
|
25289
|
+
"bb auth login --client-id <id>",
|
|
24070
25290
|
"BB_USERNAME=myuser BB_API_TOKEN=mytoken bb auth login"
|
|
24071
25291
|
],
|
|
24072
25292
|
envVars: {
|
|
24073
25293
|
BB_USERNAME: "Used when --username is not provided",
|
|
24074
|
-
BB_API_TOKEN: "Used when --password is not provided"
|
|
25294
|
+
BB_API_TOKEN: "Used when --password is not provided (implies API token auth)"
|
|
24075
25295
|
}
|
|
24076
25296
|
})).action(async (options) => {
|
|
24077
25297
|
await runCommand(ServiceTokens.LoginCommand, options, cli);
|