@sap/cli-core 2023.24.0 → 2024.1.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/CHANGELOG.md CHANGED
@@ -5,6 +5,59 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 2024.1.0
9
+
10
+ ### Fixed
11
+
12
+ - The `--browser` option introduced with version `2023.25.0` did not apply the default correctly in case the option `--browser` was not explicitly specified.
13
+
14
+ ## 2023.25.0
15
+
16
+ ### Added
17
+
18
+ - A check for the correct node version environment when using the CLI. In case the node version does not satisfy the minimum node version required by the CLI to function correctly, a warning is printed to the console.
19
+
20
+ - When printing the help information for the `login` command, the list of options now includes the login-specific options such as `--authorization-url` and `--token-url`. Previously the help showed the following options:
21
+
22
+ ```bash
23
+ <CLI> login --help
24
+ Usage: <CLI> login [options]
25
+ log in to your account using interactive OAuth authentication
26
+ Options:
27
+ -H, --host <host> specifies the url where the tenant is hosted (optional)
28
+ -h, --help display help for command
29
+ ```
30
+
31
+ With this version, the help looks like this:
32
+
33
+ ```bash
34
+ <CLI> login --help
35
+ Usage: <CLI> login [options]
36
+ log in to your account using interactive OAuth authentication
37
+ Options:
38
+ -H, --host <host> specifies the url where the tenant is hosted (optional)
39
+ -A, --authorization-url <url> authorization url for interactive oauth session authentication (optional)
40
+ -t, --token-url <url> token url for interactive oauth session authentication (optional)
41
+ -c, --client-id <id> client id for interactive oauth session authentication (optional)
42
+ -C, --client-secret <secret> client secret for interactive oauth session authentication (optional)
43
+ -a, --access-token <token> access token for interactive oauth session authentication (optional)
44
+ -b, --code <code> code for oauth token retrieval (optional)
45
+ -r, --refresh-token <token> refresh token for interactive oauth session authentication (optional)
46
+ -s, --secrets-file <file> path to secrets file (optional)
47
+ -h, --help display help for command
48
+ Only command-specific options are listed here. To learn more about available generic options, visit https://tinyurl.com/yck8vv4w
49
+ ```
50
+
51
+ - Added the option `--browser <browser>` to the login command. Users can now choose explicitly which browser to open when logging in to a tenant. By default the system's default browser is used.
52
+
53
+ ### Fixed
54
+
55
+ - The HTTPS proxy support introduced with `2023.24.0` did not respect the underlying `axios` module configuration need to disable the native proxy handling by passing `proxy: false` to the request configuration.
56
+
57
+ ### Changed
58
+
59
+ - Previously, when running the `logout` command but no secrets existed anymore, the command would fail with exit code 1 and an error message. Now, when running the `logout` command but there are no secrets to logout from, the command fails silently.
60
+
8
61
  ## 2023.24.0
9
62
 
10
63
  ### Fixed
@@ -8,8 +8,8 @@ const utils_1 = require("../utils");
8
8
  const setAuthorization_1 = require("./setAuthorization");
9
9
  const constants_1 = require("../../../../../constants");
10
10
  const options_1 = require("../../../../../utils/options");
11
- const utils_2 = require("../../../../../utils/utils");
12
11
  const SecretsStorageSingleton_1 = require("../../../../../cache/secrets/SecretsStorageSingleton");
12
+ const openUtils_1 = require("../../../../../utils/openUtils");
13
13
  const getLogger = () => (0, logger_1.get)("commands.handler.authentication.oauth.tokenProvider.utils.refreshToken");
14
14
  const refreshToken = async (forceRefresh = false) => {
15
15
  const { info: logInfo, debug } = getLogger();
@@ -90,7 +90,7 @@ const getCode = async (authorizeUrl, clientId) => {
90
90
  debug("failed to retrieve code from options", err);
91
91
  return (await Promise.all([
92
92
  (0, exports.retrieveCode)(),
93
- (0, utils_2.openUrlInBrowser)(authorizeUrl, {
93
+ (0, openUtils_1.openUrlInBrowser)(authorizeUrl, {
94
94
  response_type: "code",
95
95
  client_id: clientId,
96
96
  }),
@@ -8,6 +8,8 @@ const init_command_1 = require("./config.command/cache.command/init.command");
8
8
  const utils_1 = require("../cache/secrets/utils");
9
9
  const utils_2 = require("../logger/utils");
10
10
  const utils_3 = require("../utils/utils");
11
+ const utils_4 = require("./utils");
12
+ const openUtils_1 = require("../utils/openUtils");
11
13
  const getLogger = () => (0, logger_1.get)("commands.login");
12
14
  const verifyHost = async () => async () => {
13
15
  const logger = getLogger();
@@ -41,6 +43,19 @@ const loginCommand = {
41
43
  { ...constants_1.OPTION_HOST, hidden: false, required: true },
42
44
  constants_1.OPTION_VERBOSE,
43
45
  constants_1.OPTION_OPTIONS_FILE,
46
+ { ...constants_1.OPTION_AUTHORIZATION_URL, hidden: false },
47
+ { ...constants_1.OPTION_TOKEN_URL, hidden: false },
48
+ { ...constants_1.OPTION_CLIENT_ID, hidden: false },
49
+ { ...constants_1.OPTION_CLIENT_SECRET, hidden: false },
50
+ { ...constants_1.OPTION_ACCESS_TOKEN, hidden: false },
51
+ { ...constants_1.OPTION_CODE, hidden: false },
52
+ { ...constants_1.OPTION_REFRESH_TOKEN, hidden: false },
53
+ { ...constants_1.OPTION_SECRETS_FILE, hidden: false },
54
+ {
55
+ ...constants_1.OPTION_BROWSER,
56
+ choices: utils_4.getBrowserChoices,
57
+ default: openUtils_1.getDefaultBrowser,
58
+ },
44
59
  ]), (0, handler_1.createMandatoryOptionsHandler)(), verifyHost, (0, handler_1.createOauthHandler)(), initializeCache),
45
60
  };
46
61
  exports.default = loginCommand;
@@ -16,7 +16,6 @@ const handler = async () => async () => {
16
16
  const logger = (0, logger_1.get)("commands.logout");
17
17
  logger.error("failed to delete secrets file from cache", err);
18
18
  (0, utils_1.logVerbose)(logger, err.message);
19
- throw new Error("failed to delete secrets file from cache");
20
19
  }
21
20
  };
22
21
  const logoutCommand = {
@@ -1,2 +1,3 @@
1
1
  import { ChoicesFunction } from "../types";
2
2
  export declare const getChoices: ChoicesFunction;
3
+ export declare const getBrowserChoices: ChoicesFunction;
package/commands/utils.js CHANGED
@@ -1,8 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getChoices = void 0;
3
+ exports.getBrowserChoices = exports.getChoices = void 0;
4
+ const open_1 = require("open");
4
5
  const SecretsStorageSingleton_1 = require("../cache/secrets/SecretsStorageSingleton");
5
6
  const getChoices = async () => {
6
7
  return SecretsStorageSingleton_1.SecretsStorageSingleton.SINGLETON.getAllSecrets().map((secret) => secret.id.toString(10));
7
8
  };
8
9
  exports.getChoices = getChoices;
10
+ const getBrowserChoices = async () => {
11
+ return Object.keys(open_1.apps);
12
+ };
13
+ exports.getBrowserChoices = getBrowserChoices;
package/constants.d.ts CHANGED
@@ -44,3 +44,4 @@ export declare const CONFIG_PASSCODE_FUNCTION = "passcodeFunction";
44
44
  export declare const OPTION_OPTIONS_FILE: Option;
45
45
  export declare const OPTION_FILE_PATH: Option;
46
46
  export declare const OPTION_INPUT: Option;
47
+ export declare const OPTION_BROWSER: Option;
package/constants.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.OPTION_INPUT = exports.OPTION_FILE_PATH = exports.OPTION_OPTIONS_FILE = exports.CONFIG_PASSCODE_FUNCTION = exports.OPTION_PASSCODE = exports.OPTION_CODE = exports.OPTION_SECRETS_FILE = exports.OPTION_EXPIRES_IN = exports.OPTION_REFRESH_TOKEN = exports.OPTION_ACCESS_TOKEN = exports.OPTION_TOKEN_URL = exports.OPTION_AUTHORIZATION_URL = exports.OPTION_CLIENT_SECRET = exports.OPTION_CLIENT_ID = exports.OPTION_FORCE = exports.OPTION_VERBOSE = exports.OPTION_NO_PRETTY = exports.OPTION_OUTPUT = exports.OPTION_LOGIN_ID = exports.OPTION_HOST = exports.OPTION_HELP = exports.OPTION_VERSION = exports.CACHE_SECRETS_FILE = exports.PATH_TO_ERROR_HTML = exports.PATH_TO_SUCCESS_HTML = exports.X_OUTPUT_FILE_NAME = exports.X_CSRF_TOKEN = exports.DISCOVERY_METADATA_PATH = exports.SEGMENTS_TO_REMOVE_FOR_PASSCODE_AUTH = exports.CLI_GENERIC_OPTIONS_HELP = exports.CLI_SUPPORTED_AUTHENTICATION_METHODS = exports.CLI_DEPRECATION_MESSAGE = exports.CLI_DEPRECATED = exports.CLI_VERSION = exports.CLI_SAP_HELP = exports.CLI_DISCOVERY_PATH = exports.CLI_DESCRIPTION = exports.CLI_PACKAGE_NAME = exports.CLI_NAME = exports.AuthenticationMethod = exports.DISCOVERY_DOCUMENT_PREFIX = exports.VERSION = void 0;
6
+ exports.OPTION_BROWSER = exports.OPTION_INPUT = exports.OPTION_FILE_PATH = exports.OPTION_OPTIONS_FILE = exports.CONFIG_PASSCODE_FUNCTION = exports.OPTION_PASSCODE = exports.OPTION_CODE = exports.OPTION_SECRETS_FILE = exports.OPTION_EXPIRES_IN = exports.OPTION_REFRESH_TOKEN = exports.OPTION_ACCESS_TOKEN = exports.OPTION_TOKEN_URL = exports.OPTION_AUTHORIZATION_URL = exports.OPTION_CLIENT_SECRET = exports.OPTION_CLIENT_ID = exports.OPTION_FORCE = exports.OPTION_VERBOSE = exports.OPTION_NO_PRETTY = exports.OPTION_OUTPUT = exports.OPTION_LOGIN_ID = exports.OPTION_HOST = exports.OPTION_HELP = exports.OPTION_VERSION = exports.CACHE_SECRETS_FILE = exports.PATH_TO_ERROR_HTML = exports.PATH_TO_SUCCESS_HTML = exports.X_OUTPUT_FILE_NAME = exports.X_CSRF_TOKEN = exports.DISCOVERY_METADATA_PATH = exports.SEGMENTS_TO_REMOVE_FOR_PASSCODE_AUTH = exports.CLI_GENERIC_OPTIONS_HELP = exports.CLI_SUPPORTED_AUTHENTICATION_METHODS = exports.CLI_DEPRECATION_MESSAGE = exports.CLI_DEPRECATED = exports.CLI_VERSION = exports.CLI_SAP_HELP = exports.CLI_DISCOVERY_PATH = exports.CLI_DESCRIPTION = exports.CLI_PACKAGE_NAME = exports.CLI_NAME = exports.AuthenticationMethod = exports.DISCOVERY_DOCUMENT_PREFIX = exports.VERSION = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const utils_1 = require("./utils/utils");
9
9
  exports.VERSION = (0, utils_1.getVersion)();
@@ -203,3 +203,12 @@ exports.OPTION_INPUT = {
203
203
  type: "text",
204
204
  },
205
205
  };
206
+ exports.OPTION_BROWSER = {
207
+ longName: "browser",
208
+ description: "specifies the browser to open",
209
+ args: [{ name: "browser" }],
210
+ prompts: {
211
+ message: "Select your browser:",
212
+ type: "select",
213
+ },
214
+ };
package/dwc/run.js CHANGED
@@ -31,6 +31,7 @@ const run = async () => {
31
31
  output(message);
32
32
  }
33
33
  await SecretsStorageSingleton_1.SecretsStorageSingleton.SINGLETON.synchronizeSecretsToStorage();
34
+ (0, utils_1.verifyNodeVersion)();
34
35
  if (exitCode > 0) {
35
36
  process.exit(exitCode);
36
37
  }
package/dwc/utils.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  import { Option } from "../types";
3
3
  export declare const addCommandsFromFolder: (pathToFolder: string, program: Command) => Promise<void>;
4
+ export declare function verifyNodeVersion(): void;
4
5
  export declare const checkVersion: () => Promise<void>;
5
6
  export declare const compareEtags: () => Promise<void>;
6
7
  export declare const getOptionValueFromArgv: ({ longName }: Option) => string;
package/dwc/utils.js CHANGED
@@ -3,9 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getOptionValueFromArgv = exports.compareEtags = exports.checkVersion = exports.addCommandsFromFolder = void 0;
6
+ exports.getOptionValueFromArgv = exports.compareEtags = exports.checkVersion = exports.verifyNodeVersion = exports.addCommandsFromFolder = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const compare_versions_1 = require("compare-versions");
9
10
  const logger_1 = require("../logger");
10
11
  const discovery_1 = require("../discovery");
11
12
  const commands_1 = require("../utils/commands");
@@ -38,6 +39,16 @@ const addCommandsFromFolder = async (pathToFolder, program) => {
38
39
  }
39
40
  };
40
41
  exports.addCommandsFromFolder = addCommandsFromFolder;
42
+ function verifyNodeVersion() {
43
+ const { output } = getLogger();
44
+ const { node } = (0, utils_1.getEngines)();
45
+ const version = process.version.replace("v", "").trim();
46
+ if (!(0, compare_versions_1.satisfies)(version, node)) {
47
+ output(`WARNING: the current node version ${version} does not satisfy the required node version ${node}.` +
48
+ ` The CLI might not behave as expected. Please make sure to install a matching node version.`);
49
+ }
50
+ }
51
+ exports.verifyNodeVersion = verifyNodeVersion;
41
52
  const checkVersion = async () => {
42
53
  const { output, error } = getLogger();
43
54
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cli-core",
3
- "version": "2023.24.0",
3
+ "version": "2024.1.0",
4
4
  "description": "Command-Line Interface (CLI) Core Module",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "SAP SE",
@@ -18,8 +18,9 @@
18
18
  ],
19
19
  "dependencies": {
20
20
  "ajv": "8.12.0",
21
- "axios": "1.5.1",
21
+ "axios": "1.6.1",
22
22
  "commander": "11.1.0",
23
+ "compare-versions": "6.1.0",
23
24
  "config": "3.3.9",
24
25
  "dotenv": "16.3.1",
25
26
  "fs-extra": "11.1.1",
package/types.d.ts CHANGED
@@ -129,6 +129,9 @@ export type PackageJson = {
129
129
  bin?: {
130
130
  [key: string]: string;
131
131
  };
132
+ engines: {
133
+ node: string;
134
+ };
132
135
  };
133
136
  export type DiscoveryMetadata = {
134
137
  tenant: string;
@@ -137,12 +140,13 @@ export type DiscoveryMetadata = {
137
140
  export type KeyValuePair = {
138
141
  [key: string]: any;
139
142
  };
143
+ export type DefaultFunction = () => Promise<string>;
140
144
  export type ChoicesFunction = () => Promise<Array<string>>;
141
145
  export type Choices = Array<string>;
142
146
  export type Option = {
143
147
  longName: string;
144
148
  description: string;
145
- default?: string;
149
+ default?: string | DefaultFunction;
146
150
  required?: boolean;
147
151
  choices?: Choices | ChoicesFunction;
148
152
  args?: Array<{
package/utils/commands.js CHANGED
@@ -81,8 +81,11 @@ const buildOption = async ({ longName, description, choices, required, default:
81
81
  : "";
82
82
  const option = new commander_1.Option(`-${shortFlag}, --${longName}${argStr}`, newDescr)
83
83
  .makeOptionMandatory(mandatory)
84
- .default(defaultValue)
85
84
  .hideHelp(!!hidden);
85
+ if (defaultValue) {
86
+ const defaultStr = typeof defaultValue === "function" ? await defaultValue() : defaultValue;
87
+ option.default(defaultStr);
88
+ }
86
89
  let choicesArr = [];
87
90
  if (choices) {
88
91
  choicesArr = typeof choices === "function" ? await choices() : choices;
@@ -50,6 +50,7 @@ const fetch = async (config) => {
50
50
  }
51
51
  const res = await (0, axios_1.default)({
52
52
  httpsAgent,
53
+ proxy: false,
53
54
  ...config,
54
55
  ...exports.DEFAULTS,
55
56
  headers: {
@@ -0,0 +1,10 @@
1
+ import { AppName } from "open";
2
+ export type Browser = {
3
+ name: AppName;
4
+ app: string;
5
+ };
6
+ export declare function getSupportedBrowsers(): Array<Browser>;
7
+ export declare function getDefaultBrowser(): Promise<string>;
8
+ export declare const openUrlInBrowser: (url: string, queryParameters?: {
9
+ [key: string]: string;
10
+ }) => Promise<void>;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.openUrlInBrowser = exports.getDefaultBrowser = exports.getSupportedBrowsers = void 0;
27
+ const open_1 = __importStar(require("open"));
28
+ const constants_1 = require("../constants");
29
+ const options_1 = require("./options");
30
+ const logger_1 = require("../logger");
31
+ const getLogger = () => (0, logger_1.get)("utils.open");
32
+ function getSupportedBrowsers() {
33
+ return Object.entries(open_1.apps).map(([key, value]) => ({
34
+ name: key,
35
+ app: value,
36
+ }));
37
+ }
38
+ exports.getSupportedBrowsers = getSupportedBrowsers;
39
+ async function getDefaultBrowser() {
40
+ return getSupportedBrowsers()[0].name;
41
+ }
42
+ exports.getDefaultBrowser = getDefaultBrowser;
43
+ async function getBrowser() {
44
+ const browser = (0, options_1.getOptionValueFromConfig)(constants_1.OPTION_BROWSER, await getDefaultBrowser());
45
+ return open_1.apps[browser];
46
+ }
47
+ const openUrlInBrowser = async (url, queryParameters = {}) => {
48
+ const browser = await getBrowser();
49
+ const u = new URL(url);
50
+ for (const [key, value] of Object.entries(queryParameters)) {
51
+ u.searchParams.append(key, value);
52
+ }
53
+ const urlString = u.toString();
54
+ const { debug } = getLogger();
55
+ debug(`open browser ${browser} at ${urlString}`);
56
+ await (0, open_1.default)(urlString, { app: { name: browser } });
57
+ };
58
+ exports.openUrlInBrowser = openUrlInBrowser;
package/utils/utils.d.ts CHANGED
@@ -10,6 +10,7 @@ export declare const getVersion: (cwd?: string) => string;
10
10
  export declare const getName: (cwd?: string) => string;
11
11
  export declare const getPackageName: (cwd?: string) => string;
12
12
  export declare const getDescription: (cwd?: string) => string;
13
+ export declare const getEngines: (cwd?: string) => PackageJson["engines"];
13
14
  export declare const getBin: (cwd?: string) => string;
14
15
  export declare const removeScopeFromPackageName: (packageName: string) => string;
15
16
  export declare const parseTenant: (tenant: string) => string;
@@ -24,6 +25,3 @@ export declare const getInfoFromTenant: (tenant: string, verbose: boolean, print
24
25
  export declare function removeQueryParametersFromUrl(sUrl: string): string;
25
26
  export declare const sha256: (string: string) => string;
26
27
  export declare const toConstantCase: (string: string) => string;
27
- export declare const openUrlInBrowser: (url: string, queryParameters?: {
28
- [key: string]: string;
29
- }) => Promise<void>;
package/utils/utils.js CHANGED
@@ -26,11 +26,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.openUrlInBrowser = exports.toConstantCase = exports.sha256 = exports.removeQueryParametersFromUrl = exports.getInfoFromTenant = exports.parseTenant = exports.removeScopeFromPackageName = exports.getBin = exports.getDescription = exports.getPackageName = exports.getName = exports.getVersion = exports.readPackageJson = exports.requireFile = exports.parseVersion = exports.buildOptionName = void 0;
29
+ exports.toConstantCase = exports.sha256 = exports.removeQueryParametersFromUrl = exports.getInfoFromTenant = exports.parseTenant = exports.removeScopeFromPackageName = exports.getBin = exports.getEngines = exports.getDescription = exports.getPackageName = exports.getName = exports.getVersion = exports.readPackageJson = exports.requireFile = exports.parseVersion = exports.buildOptionName = void 0;
30
30
  const crypto = __importStar(require("crypto"));
31
31
  const path_1 = __importDefault(require("path"));
32
32
  const lodash_1 = require("lodash");
33
- const open_1 = __importDefault(require("open"));
34
33
  const logger_1 = require("../logger");
35
34
  const commands_1 = require("./commands");
36
35
  let pgk;
@@ -92,6 +91,10 @@ const getDescription = (cwd = "") => {
92
91
  return (0, exports.readPackageJson)(cwd, true).description;
93
92
  };
94
93
  exports.getDescription = getDescription;
94
+ const getEngines = (cwd = "") => {
95
+ return (0, exports.readPackageJson)(cwd, true).engines;
96
+ };
97
+ exports.getEngines = getEngines;
95
98
  const getBin = (cwd = "") => {
96
99
  const keys = Object.keys((0, exports.readPackageJson)(cwd, true).bin || {});
97
100
  if (keys.length === 0) {
@@ -165,14 +168,3 @@ crypto.createHash("sha256").update(string).digest("base64");
165
168
  exports.sha256 = sha256;
166
169
  const toConstantCase = (string) => (0, lodash_1.upperCase)(string).replace(/ /g, "_");
167
170
  exports.toConstantCase = toConstantCase;
168
- const openUrlInBrowser = async (url, queryParameters = {}) => {
169
- const u = new URL(url);
170
- for (const [key, value] of Object.entries(queryParameters)) {
171
- u.searchParams.append(key, value);
172
- }
173
- const urlString = u.toString();
174
- const { debug } = getLogger();
175
- debug(`open browser at ${urlString}`);
176
- await (0, open_1.default)(urlString);
177
- };
178
- exports.openUrlInBrowser = openUrlInBrowser;