diff --git a/.vscodeignore b/.vscodeignore index 30e3923..4c16d28 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -10,7 +10,9 @@ compile.ts coverage/ jest.config.js -node_modules/ +node_modules/** +!node_modules/@1password/sdk/** +!node_modules/@1password/sdk-core/** package-lock.json src/ !src/op-vscode.code-snippets diff --git a/README.md b/README.md index 788093a..de00184 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,17 @@ # 1Password for VS Code -1Password for VS Code provides you with a set of tools to integrate your development workflow with 1Password, powered by the [1Password CLI](https://developer.1password.com/docs/cli). +1Password for VS Code provides you with a set of tools to integrate your development workflow with 1Password, powered by the [1Password JavaScript SDK](https://github.com/1Password/onepassword-sdk-js). ## Quick start ⚡️ This quick start guide will get you up and running with the extension. -1. **Set up the CLI** - v2.4.0 or greater of the 1Password CLI needs to be [installed on your system](https://developer.1password.com/docs/cli/get-started#install). -2. **Enable biometric unlock** - You must have [biometric unlock](https://developer.1password.com/docs/cli/about-biometric-unlock) enabled. If you don't have a biometric device, you'll still be able to use your device user password. -3. **Install the extension** - From the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=1Password.op-vscode) or [GitHub](https://github.com/1Password/op-vscode/releases) install the latest version of the extension. -4. **Follow the prompts** - You'll be prompted to choose a 1Password account and vault. Follow these prompts to finish setup of the extension. + +1. **Install the desktop app** - Install the [1Password desktop app](https://1password.com/downloads/) and sign in to your account in the app. +2. **Open Developer Settings** - Select your account or collection at the top of the sidebar, then navigate to **Settings > Developer**. +3. **Enable integration** - Under Integrate with the 1Password SDKs, select **Integrate with other apps**. +4. **Install the extension** - From the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=1Password.op-vscode) or [GitHub](https://github.com/1Password/op-vscode/releases) install the latest version of the extension. +5. **Follow the prompts** - You'll be prompted to choose a 1Password account and vault. Follow these prompts to finish setup of the extension. You're all set. Learn more about what the extension is capable of by checking out the [developer portal documentation](https://developer.1password.com/docs/vscode/). diff --git a/compile.ts b/compile.ts index 1fa2a07..8e0c4b9 100644 --- a/compile.ts +++ b/compile.ts @@ -34,7 +34,10 @@ if (existsSync(distPath)) { entryPoints: [`${srcPath}/extension.ts`], bundle: true, platform: "node", - external: ["vscode"], + // The 1Password SDK ships a ~10MB WebAssembly core that it loads from + // disk at runtime (via __dirname), so it can't be bundled. Keep the SDK + // packages external and ship them in node_modules instead. + external: ["vscode", "@1password/sdk", "@1password/sdk-core"], outfile: `${distPath}/extension.js`, minify: isProd, plugins: [createLoggerPlugin("extension")], diff --git a/package.json b/package.json index 0222dbb..e8c5923 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "test": "jest", "typecheck": "tsc --noEmit", "vscode:prepublish": "yarn build", - "watch": "yarn compile --watch" + "watch": "yarn compile --watch", + "package": "vsce package" }, "keywords": [ "1password", @@ -104,6 +105,7 @@ "order": 1, "type": "boolean", "default": true, + "markdownDeprecationMessage": "**Deprecated**: The 1Password SDK does not cache values, so this setting no longer has any effect.", "markdownDescription": "Use CLI cache when performing operations. Learn more about [caching](https://developer.1password.com/docs/cli/reference#cache-item-and-vault-information)." }, "1password.items.passwordRecipe": { @@ -158,7 +160,7 @@ ] }, "dependencies": { - "@1password/op-js": "^0.1.13", + "@1password/sdk": "^0.4.0", "json-to-ast": "^2.1.0", "open": "^8.4.0", "timeago.js": "^4.0.2", @@ -173,6 +175,7 @@ "@types/uuid": "^9.0.1", "@types/vscode": "^1.66.0", "@typescript-eslint/eslint-plugin": "^7.10.0", + "@vscode/vsce": "2.25.0", "cross-env": "^7.0.3", "esbuild": "^0.21.3", "esbuild-register": "^3.5.0", @@ -188,5 +191,8 @@ "typescript": "^5.4.5", "uuid": "^9.0.0", "yaml": "^2.3.1" + }, + "resolutions": { + "cheerio": "^0" } } diff --git a/src/cli.test.ts b/src/cli.test.ts deleted file mode 100644 index 362be8e..0000000 --- a/src/cli.test.ts +++ /dev/null @@ -1,152 +0,0 @@ -import * as opjs from "@1password/op-js"; -import { version } from "../package.json"; -import { window } from "../test/vscode-mock"; -import { CLI, createErrorHandler } from "./cli"; -import { logger } from "./logger"; -import { semverToInt } from "./utils"; - -const cli = new CLI(); -const goodCommand = jest.fn().mockReturnValue("good"); -const error = new Error("bad"); -const badCommand = jest.fn().mockImplementation(() => { - throw error; -}); - -jest.mock("@1password/op-js", () => ({ - // @ts-expect-error ok bud - ...jest.requireActual("@1password/op-js"), - setClientInfo: jest.fn(), - validateCli: jest.fn(), -})); - -describe("createErrorHandler", () => { - const error = new Error("test"); - const handler = createErrorHandler(true); - - beforeEach(() => window.showErrorMessage.mockClear()); - - it("returns a function", () => { - expect(handler).toBeInstanceOf(Function); - }); - - it("handler logs the error", async () => { - const loggerSpy = jest.spyOn(logger, "logError"); - await handler(error); - expect(loggerSpy).toHaveBeenCalledWith(expect.any(String)); - }); - - it("handler displays the error if showError is true", async () => { - await handler(error); - expect(window.showErrorMessage).toHaveBeenCalled(); - }); - - it("handler won't display the error if showError is false", async () => { - await createErrorHandler(false)(error); - expect(window.showErrorMessage).not.toHaveBeenCalled(); - }); -}); - -describe("CLI", () => { - beforeAll(() => { - cli.valid = true; - }); - - describe("constructor", () => { - it("sets op-js user agent info", () => { - new CLI(); - expect(opjs.setClientInfo).toHaveBeenCalledWith({ - build: semverToInt(version), - id: "VSC", - name: "1Password for VS Code", - }); - }); - }); - - describe("execute", () => { - it("guards against execution when cli is invalid", async () => { - cli.valid = false; - await expect(async () => cli.execute(goodCommand)).rejects.toEqual( - new Error("CLI is not valid, please validate it first."), - ); - cli.valid = true; - }); - - it("calls the provided command, returns the command result", async () => { - await expect(cli.execute(goodCommand)).resolves.toEqual("good"); - }); - - it("handles exceptions", async () => { - const loggerSpy = jest.spyOn(logger, "logError"); - await expect(cli.execute(badCommand)).resolves.toBeUndefined(); - expect(loggerSpy).toHaveBeenCalledWith(expect.any(String)); - }); - }); - - describe("isInvalid", () => { - const validateSpy = jest.spyOn(cli, "validate"); - - beforeEach(() => validateSpy.mockClear()); - - it("returns false if valid is true, does not check again", async () => { - const result = await cli.isInvalid(); - expect(validateSpy).not.toHaveBeenCalled(); - expect(result).toBe(false); - }); - - it("checks validity if valid is false", async () => { - cli.valid = false; - await cli.isInvalid(); - expect(validateSpy).toHaveBeenCalled(); - cli.valid = true; - }); - }); - - describe("validate", () => { - it("sets valid to true when cli is valid", async () => { - await cli.validate(); - expect(opjs.validateCli).toHaveBeenCalled(); - expect(cli.valid).toBe(true); - }); - - it("sets valid to false and warns when cli could not be located", async () => { - const error = new opjs.ValidationError("not-found"); - jest.spyOn(opjs, "validateCli").mockImplementation(() => { - throw error; - }); - await cli.validate(); - expect(cli.valid).toBe(false); - }); - - it("sets valid to false and warns when cli is incorrect version", async () => { - const error = new opjs.ValidationError("version"); - jest.spyOn(opjs, "validateCli").mockImplementation(() => { - throw error; - }); - await cli.validate(); - expect(cli.valid).toBe(false); - }); - - it("re-throws a caught error that is not a ValidationError", async () => { - const error = new Error("foo"); - jest.spyOn(opjs, "validateCli").mockImplementation(() => { - throw error; - }); - await expect(async () => await cli.validate()).rejects.toThrow( - error.message, - ); - expect(cli.valid).toBe(false); - }); - - it("re-throws a caught ValidationError with an unknown type", async () => { - // @ts-expect-error testing invalid type - const error = new opjs.ValidationError("foo"); - jest.spyOn(opjs, "validateCli").mockImplementation(() => { - throw error; - }); - await expect(async () => await cli.validate()).rejects.toThrow( - error.message, - ); - expect(cli.valid).toBe(false); - }); - }); -}); diff --git a/src/cli.ts b/src/cli.ts deleted file mode 100644 index 78fae09..0000000 --- a/src/cli.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { setClientInfo, validateCli, ValidationError } from "@1password/op-js"; -import { default as open } from "open"; -import { window } from "vscode"; -import { version } from "../package.json"; -import { URLS } from "./constants"; -import { logger } from "./logger"; -import { endWithPunctuation, semverToInt } from "./utils"; - -export const createErrorHandler = - (showError: boolean) => async (error: Error) => { - const errorPrefix = "Error executing CLI command"; - - let errorMessage = errorPrefix; - if (error.message) { - errorMessage += `: ${endWithPunctuation(error.message)}`; - } - - // TODO: update to log error code when JS wrapper starts providing it - logger.logError(errorPrefix); - - if (!showError) { - return; - } - - await window.showErrorMessage(errorMessage); - }; - -export class CLI { - public valid = false; - - public constructor() { - setClientInfo({ - name: "1Password for VS Code", - id: "VSC", - build: semverToInt(version), - }); - } - - public async execute( - command: () => TReturn, - showError = true, - ): Promise { - if (!this.valid) { - throw new Error("CLI is not valid, please validate it first."); - } - - let output: TReturn; - try { - output = command(); - } catch (error) { - await createErrorHandler(showError)(error); - return; - } - - return output; - } - - public async isInvalid(): Promise { - if (!this.valid) { - await this.validate(); - } - - return !this.valid; - } - - public async validate(): Promise { - this.valid = true; - - try { - await validateCli(); - } catch (error: any) { - this.valid = false; - - if (!(error instanceof ValidationError)) { - throw error; - } - - switch (error.type) { - case "not-found": - const openInstallDocs = "Open installation documentation"; - - if ( - (await window.showErrorMessage( - "CLI is not installed. Please install it to use 1Password for VS Code.", - openInstallDocs, - )) === openInstallDocs - ) { - await open(URLS.CLI_INSTALL_DOCS); - } - - break; - case "version": - const openUpgradeDocs = "Open upgrade documentation"; - - if ( - (await window.showErrorMessage( - `${error.message}. Please upgrade to the latest version to use 1Password for VS Code.`, - openUpgradeDocs, - )) === openUpgradeDocs - ) { - await open(URLS.CLI_UPGRADE_DOCS); - } - - break; - default: - throw error; - } - } - } -} diff --git a/src/client.test.ts b/src/client.test.ts new file mode 100644 index 0000000..44bba17 --- /dev/null +++ b/src/client.test.ts @@ -0,0 +1,111 @@ +import { window } from "../test/vscode-mock"; +import { OnePassword } from "./client"; + +const createClientMock = jest.fn, [unknown]>(); +jest.mock("@1password/sdk", () => ({ + createClient: async (config: unknown) => await createClientMock(config), + DesktopAuth: class DesktopAuth { + public constructor(public accountName: string) {} + }, +})); + +const openMock = jest.fn(); +jest.mock("open", () => ({ + // eslint-disable-next-line @typescript-eslint/naming-convention + __esModule: true, + default: (...args: unknown[]) => openMock(...args), +})); + +const account = "my.1password.com"; +const nativeLibError = new Error("Native library is not available."); + +describe("OnePassword", () => { + let op: OnePassword; + + beforeEach(() => { + jest.clearAllMocks(); + op = new OnePassword(); + }); + + describe("getClient", () => { + it("returns undefined and does not authenticate when no account is set", async () => { + expect(await op.getClient()).toBeUndefined(); + expect(createClientMock).not.toHaveBeenCalled(); + }); + + it("returns the created client", async () => { + const client = { secrets: {} }; + createClientMock.mockResolvedValue(client); + op.setAccount(account); + expect(await op.getClient()).toBe(client); + }); + + it("caches the client across calls", async () => { + createClientMock.mockResolvedValue({ secrets: {} }); + op.setAccount(account); + await op.getClient(); + await op.getClient(); + expect(createClientMock).toHaveBeenCalledTimes(1); + }); + + it("shows an actionable notification when the desktop app integration is unavailable", async () => { + createClientMock.mockRejectedValue(nativeLibError); + op.setAccount(account); + const result = await op.getClient(); + expect(result).toBeUndefined(); + expect(window.showErrorMessage).toHaveBeenCalledWith( + expect.stringContaining( + "Couldn't connect to the 1Password desktop app", + ), + "Learn more", + ); + }); + + it("opens the docs when the user chooses Learn more", async () => { + createClientMock.mockRejectedValue(nativeLibError); + window.showErrorMessage.mockResolvedValueOnce("Learn more"); + op.setAccount(account); + await op.getClient(); + expect(openMock).toHaveBeenCalled(); + }); + + it("only notifies once on quiet paths until the account changes", async () => { + createClientMock.mockRejectedValue(nativeLibError); + op.setAccount(account); + await op.getClient(false); + await op.getClient(false); + expect(window.showErrorMessage).toHaveBeenCalledTimes(1); + }); + }); + + describe("execute", () => { + it("returns undefined and does not run the command without a client", async () => { + const command = jest.fn(async () => { + await Promise.resolve(); + }); + expect(await op.execute(command)).toBeUndefined(); + expect(command).not.toHaveBeenCalled(); + }); + + it("runs the command with the client and returns its result", async () => { + createClientMock.mockResolvedValue({ secrets: {} }); + op.setAccount(account); + const result = await op.execute(async () => { + await Promise.resolve(); + return "value"; + }); + expect(result).toBe("value"); + }); + + it("handles errors thrown by the command", async () => { + createClientMock.mockResolvedValue({ secrets: {} }); + op.setAccount(account); + const result = await op.execute(async () => { + await Promise.resolve(); + throw new Error("boom"); + }); + expect(result).toBeUndefined(); + expect(window.showErrorMessage).toHaveBeenCalled(); + }); + }); +}); diff --git a/src/client.ts b/src/client.ts new file mode 100644 index 0000000..e998658 --- /dev/null +++ b/src/client.ts @@ -0,0 +1,171 @@ +import { Client, createClient, DesktopAuth, Item } from "@1password/sdk"; +import { default as open } from "open"; +import { window } from "vscode"; +import { version } from "../package.json"; +import { URLS } from "./constants"; +import { logger } from "./logger"; +import { endWithPunctuation } from "./utils"; + +export const INTEGRATION_NAME = "1Password for VS Code"; + +export const createErrorHandler = + (showError: boolean) => async (error: Error) => { + const errorPrefix = "Error performing 1Password operation"; + + let errorMessage = errorPrefix; + if (error.message) { + errorMessage += `: ${endWithPunctuation(error.message)}`; + } + + logger.logError(errorMessage); + + if (!showError) { + return; + } + + await window.showErrorMessage(errorMessage); + }; + +// Wraps the 1Password JavaScript SDK. Authentication is performed against the +// 1Password desktop app (with biometric unlock) using the account the user +// configured during setup. A client is created lazily and reused until the +// configured account changes. +export class OnePassword { + private client?: Client; + private accountName?: string; + // The desktop app integration error is a one-time setup problem, so we + // surface it even on otherwise-quiet paths but only notify once until the + // account changes or a client connects. + private appIntegrationErrorNotified = false; + + public get authenticated(): boolean { + return Boolean(this.client); + } + + // Set the account the SDK client should authenticate against. Changing the + // account discards any existing client so the next operation re-authenticates. + public setAccount(accountName?: string): void { + if (this.accountName !== accountName) { + this.accountName = accountName; + this.client = undefined; + this.appIntegrationErrorNotified = false; + } + } + + public async getClient(showError = true): Promise { + if (this.client) { + return this.client; + } + + if (!this.accountName) { + return undefined; + } + + try { + this.client = await createClient({ + auth: new DesktopAuth(this.accountName), + integrationName: INTEGRATION_NAME, + integrationVersion: version, + }); + this.appIntegrationErrorNotified = false; + } catch (error) { + await this.handleError(error as Error, showError); + this.client = undefined; + } + + return this.client; + } + + // The SDK throws "Native library is not available." when it can't talk to + // the 1Password desktop app — almost always because the app isn't running, + // is locked, or doesn't have app integration enabled. Surface that with a + // clear, actionable notification instead of the raw SDK message. + private isAppIntegrationError(error: Error): boolean { + const message = error?.message ?? ""; + return ( + message.includes("Native library is not available") || + message.includes("1Password desktop application") + ); + } + + private async handleError(error: Error, showError: boolean): Promise { + if (!this.isAppIntegrationError(error)) { + await createErrorHandler(showError)(error); + return; + } + + const message = + "Couldn't connect to the 1Password desktop app. Make sure it's installed and unlocked, then turn on \"Integrate with other apps\" under Settings → Developer in the 1Password app."; + logger.logError(message); + + if (!showError && this.appIntegrationErrorNotified) { + return; + } + + this.appIntegrationErrorNotified = true; + + const learnMore = "Learn more"; + const response = await window.showErrorMessage(message, learnMore); + if (response === learnMore) { + await open(URLS.DESKTOP_APP_DOCS); + } + } + + public async isInvalid(): Promise { + return !(await this.getClient()); + } + + public async execute( + command: (client: Client) => Promise, + showError = true, + ): Promise { + const client = await this.getClient(showError); + if (!client) { + return undefined; + } + + try { + return await command(client); + } catch (error) { + await this.handleError(error as Error, showError); + return undefined; + } + } + + // Resolve a full item from vault and item references, where either may be a + // title or an ID. The SDK's `items.get` requires concrete IDs, so when a + // reference isn't a valid ID we fall back to listing the vault to find a match. + public async resolveItem( + vaultRef: string, + itemRef: string, + showError = true, + ): Promise { + return this.execute(async (client) => { + const vaultId = await this.resolveVaultId(client, vaultRef); + + try { + return await client.items.get(vaultId, itemRef); + } catch { + const items = await client.items.list(vaultId); + const match = items.find( + (i) => i.id === itemRef || i.title === itemRef, + ); + + if (!match) { + throw new Error("Could not find vault item."); + } + + return client.items.get(vaultId, match.id); + } + }, showError); + } + + private async resolveVaultId( + client: Client, + vaultRef: string, + ): Promise { + const vaults = await client.vaults.list({ decryptDetails: true }); + const match = vaults.find((v) => v.id === vaultRef || v.title === vaultRef); + return match ? match.id : vaultRef; + } +} diff --git a/src/constants.ts b/src/constants.ts index d5a8773..340482c 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -25,14 +25,14 @@ export const INTERNAL_COMMANDS = { export const STATE = { ACCOUNT_UUID: "accountUuid", - ACCOUNT_URL: "accountUrl", VAULT_ID: "vaultId", DISABLE_CONFIG_REMINDER: "disableConfigReminder", }; export const URLS = { - CLI_INSTALL_DOCS: "https://developer.1password.com/docs/cli/get-started", - CLI_UPGRADE_DOCS: "https://developer.1password.com/docs/cli/upgrade", + DESKTOP_APP_DOCS: + "https://developer.1password.com/docs/sdks/setup-authentication/#desktop-app-integration", + SDK_DOCS: "https://developer.1password.com/docs/sdks", }; export const REGEXP = { @@ -41,22 +41,21 @@ export const REGEXP = { CAPITALIZED_WORDS: /(api|aws|id|uuid|url)/gi, }; -// Used for testing -export const SENSITIVE_FIELD_TYPES = [ - "CONCEALED", - "SSHKEY", - "CREDIT_CARD_NUMBER", -] as const; - -export const NONSENSITIVE_FIELD_TYPES = [ - "ADDRESS", - "CREDIT_CARD_TYPE", - "DATE", - "EMAIL", - "GENDER", - "MENU", - "MONTH_YEAR", - "PHONE", - "STRING", - "URL", -] as const; +// These map to the 1Password SDK's `ItemFieldType` enum values. +export const SENSITIVE_FIELD_TYPES: readonly string[] = [ + "Concealed", + "SshKey", + "CreditCardNumber", +]; + +export const NONSENSITIVE_FIELD_TYPES: readonly string[] = [ + "Address", + "CreditCardType", + "Date", + "Email", + "Menu", + "MonthYear", + "Phone", + "Text", + "Url", +]; diff --git a/src/core.ts b/src/core.ts index 2356021..79750ac 100644 --- a/src/core.ts +++ b/src/core.ts @@ -1,7 +1,6 @@ -import { vault } from "@1password/op-js"; import type { ExtensionContext } from "vscode"; import { commands, window } from "vscode"; -import { CLI } from "./cli"; +import { OnePassword } from "./client"; import { COMMANDS, INTERNAL_COMMANDS } from "./constants"; import { Editor } from "./editor"; import { Injection } from "./injection"; @@ -11,7 +10,7 @@ import { Setup } from "./setup"; import { createOpenOPHandler, OpvsUriHandler } from "./url-utils"; export class Core { - public cli: CLI; + public op: OnePassword; private setup: Setup; public items: Items; @@ -28,7 +27,7 @@ export class Core { ), ); - this.cli = new CLI(); + this.op = new OnePassword(); this.setup = new Setup(this); this.items = new Items(this); @@ -39,20 +38,12 @@ export class Core { } private async authenticate(): Promise { - if (await this.cli.isInvalid()) { - return; - } - - // Hack to get CLI to prompt for biometrics - await this.cli.execute(() => vault.list(), false); - } - - public get accountUuid(): string { - return this.setup.accountUuid; + // Creating the SDK client prompts the desktop app for biometric unlock. + await this.op.getClient(); } - public get accountUrl(): string { - return this.setup.accountUrl; + public get accountId(): string { + return this.setup.accountId; } public get vaultId(): string { diff --git a/src/editor.ts b/src/editor.ts index 25dcee1..2950c5e 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -1,4 +1,3 @@ -import os from "os"; import { Disposable, languages } from "vscode"; import { config } from "./configuration"; import type { Core } from "./core"; @@ -16,8 +15,6 @@ export class Editor { } private configure(): void { - const isWindows = os.platform() === "win32"; - for (const subscription of this.subscriptions) { subscription.dispose(); } @@ -35,16 +32,13 @@ export class Editor { provideDocumentLinks, }, ), - // Windows doesn't persist auth between commands, so authenticating - // first has no effect, preventing hover previews from working - !isWindows && - languages.registerHoverProvider( - { scheme: "file" }, - { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - provideHover: provideHover.bind(this.core), - }, - ), + languages.registerHoverProvider( + { scheme: "file" }, + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + provideHover: provideHover.bind(this.core), + }, + ), ]; this.core.context.subscriptions.push(...this.subscriptions); diff --git a/src/injection.ts b/src/injection.ts index 708dd29..3dd262c 100644 --- a/src/injection.ts +++ b/src/injection.ts @@ -1,4 +1,3 @@ -import { inject } from "@1password/op-js"; import type { TextDocument, Uri } from "vscode"; import { commands, ProgressLocation, window, workspace } from "vscode"; import { COMMANDS, EXTENSION_ID, REGEXP } from "./constants"; @@ -75,10 +74,33 @@ export class Injection { private async injectSecrets(currentDocument: TextDocument) { const input = currentDocument.getText(); - const result = await this.core.cli.execute(() => - inject.data(input), + + // The SDK has no bulk text injection, so we find every secret reference + // in the document, resolve them in one batch, and substitute the values + // back into the text. + const matcher = new RegExp(REGEXP.SECRET_REFERENCE.source, "gm"); + const references = [...new Set(input.match(matcher) ?? [])]; + + if (references.length === 0) { + return; + } + + const resolved = await this.core.op.execute(async (client) => + client.secrets.resolveAll(references), ); + if (!resolved) { + return; + } + + let result = input; + for (const reference of references) { + const response = resolved.individualResponses[reference]; + if (response?.content) { + result = result.split(reference).join(response.content.secret); + } + } + const injectedDocument = await workspace.openTextDocument({ language: currentDocument.languageId, content: result, diff --git a/src/items.test.ts b/src/items.test.ts index 3f8242c..bfe3c9c 100644 --- a/src/items.test.ts +++ b/src/items.test.ts @@ -1,3 +1,4 @@ +import { type ItemFieldType, Secrets } from "@1password/sdk"; import { createItem, createItemField } from "../test/factories"; import { generateUUID } from "../test/utils"; import { commands, configGet, env, window } from "../test/vscode-mock"; @@ -8,14 +9,32 @@ import { } from "./constants"; import { generatePasswordArg, Items } from "./items"; +jest.mock("@1password/sdk", () => ({ + ItemCategory: { Login: "Login" }, + ItemFieldType: { + Concealed: "Concealed", + Text: "Text", + Url: "Url", + Email: "Email", + Address: "Address", + Date: "Date", + MonthYear: "MonthYear", + Phone: "Phone", + }, + Secrets: { + generatePassword: jest.fn(() => ({ password: "generated-password" })), + }, +})); + describe("Items", () => { let items: Items; const core = { context: { subscriptions: [], }, - cli: { + op: { isInvalid: jest.fn().mockResolvedValue(false), + resolveItem: jest.fn(), execute: jest.fn(), }, vaultId: generateUUID(), @@ -23,10 +42,14 @@ describe("Items", () => { beforeEach(() => { items = new Items(core as any); + (Secrets.generatePassword as jest.Mock).mockReturnValue({ + password: "generated-password", + }); }); afterEach(() => { jest.resetAllMocks(); + core.op.isInvalid.mockResolvedValue(false); }); describe("constructor", () => { @@ -50,12 +73,6 @@ describe("Items", () => { describe("getItem", () => { const title = "My Item"; - it.skip("requires a vault to be chosen", async () => { - // items.core.vaultId = null; - await items.getItem(); - expect(window.showErrorMessage).toHaveBeenCalled(); - }); - it("asks for the vault item", async () => { await items.getItem(); expect(window.showInputBox).toHaveBeenCalledWith({ @@ -67,18 +84,18 @@ describe("Items", () => { it("aborts if no vault item value supplied", async () => { window.showInputBox.mockReturnValue(null); await items.getItem(); - expect(core.cli.execute).not.toHaveBeenCalled(); + expect(core.op.resolveItem).not.toHaveBeenCalled(); }); - it("uses the cli to get the vault item", async () => { + it("uses the SDK to get the vault item", async () => { window.showInputBox.mockReturnValue(title); await items.getItem(); - expect(core.cli.execute).toHaveBeenCalled(); + expect(core.op.resolveItem).toHaveBeenCalled(); }); it("aborts if the vault item is not found", async () => { window.showInputBox.mockReturnValue("My Item"); - core.cli.execute.mockReturnValue(null); + core.op.resolveItem.mockReturnValue(null); await items.getItem(); expect(window.showQuickPick).not.toHaveBeenCalled(); }); @@ -89,7 +106,7 @@ describe("Items", () => { fields: [createItemField({ value: undefined })], }); window.showInputBox.mockReturnValue(title); - core.cli.execute.mockReturnValue(item); + core.op.resolveItem.mockReturnValue(item); await items.getItem(); expect(window.showWarningMessage).toHaveBeenCalledWith( expect.stringContaining("no fields with values"), @@ -99,10 +116,10 @@ describe("Items", () => { it("asks for the field to use", async () => { const item = createItem({ title }); window.showInputBox.mockReturnValue(title); - core.cli.execute.mockReturnValue(item); + core.op.resolveItem.mockReturnValue(item); await items.getItem(); expect(window.showQuickPick).toHaveBeenCalledWith( - item.fields.map((field) => field.label), + item.fields.map((field) => field.title), { ignoreFocusOut: true, title: "Choose which field to use", @@ -113,7 +130,7 @@ describe("Items", () => { it("aborts if no field is chosen", async () => { const item = createItem({ title }); window.showInputBox.mockReturnValue(title); - core.cli.execute.mockReturnValue(item); + core.op.resolveItem.mockReturnValue(item); window.showQuickPick.mockReturnValue(null); await items.getItem(); }); @@ -123,8 +140,8 @@ describe("Items", () => { const item = createItem({ title }); window.showInputBox.mockReturnValue(title); window.activeTextEditor.selections = []; - core.cli.execute.mockReturnValue(item); - window.showQuickPick.mockReturnValue(item.fields[0].label); + core.op.resolveItem.mockReturnValue(item); + window.showQuickPick.mockReturnValue(item.fields[0].title); await items.getItem(); expect(env.clipboard.writeText).toHaveBeenCalledWith( item.fields[0].value, @@ -138,8 +155,8 @@ describe("Items", () => { it("replaces the selection with the retrieved item value", async () => { const item = createItem({ title }); window.showInputBox.mockReturnValue(title); - core.cli.execute.mockReturnValue(item); - window.showQuickPick.mockReturnValue(item.fields[0].label); + core.op.resolveItem.mockReturnValue(item); + window.showQuickPick.mockReturnValue(item.fields[0].title); await items.getItem(); expect(window.activeTextEditor.edit).toHaveBeenCalled(); }); @@ -150,22 +167,22 @@ describe("Items", () => { const itemTitle = "API Keys"; const fieldLabel = "bearer token"; - it("aborts if the cli is not valid", async () => { - core.cli.isInvalid.mockReturnValue(true); + it("aborts if the client is not valid", async () => { + core.op.isInvalid.mockResolvedValue(true); await items.getReferenceMetadata(vaultName, itemTitle, fieldLabel); - expect(core.cli.execute).not.toHaveBeenCalled(); + expect(core.op.resolveItem).not.toHaveBeenCalled(); }); - it("uses the cli to get the vault item, throws if no vault item found", async () => { + it("uses the SDK to get the vault item, throws if no vault item found", async () => { await expect( items.getReferenceMetadata(vaultName, itemTitle, fieldLabel), ).rejects.toEqual(new Error("Could not find vault item.")); - expect(core.cli.execute).toHaveBeenCalled(); + expect(core.op.resolveItem).toHaveBeenCalled(); }); it("throws if unable to find the specified field in a vault item", async () => { const item = createItem(); - core.cli.execute.mockReturnValue(item); + core.op.resolveItem.mockReturnValue(item); await expect( items.getReferenceMetadata(vaultName, itemTitle, fieldLabel), ).rejects.toEqual(new Error("Could not find vault item field.")); @@ -174,9 +191,9 @@ describe("Items", () => { it("returns the item formatted as item and field metadata", async () => { const item = createItem({ title: itemTitle, - fields: [createItemField({ label: fieldLabel })], + fields: [createItemField({ title: fieldLabel })], }); - core.cli.execute.mockReturnValue(item); + core.op.resolveItem.mockReturnValue(item); await expect( items.getReferenceMetadata(vaultName, itemTitle, fieldLabel), ).resolves.toEqual({ @@ -187,9 +204,9 @@ describe("Items", () => { }, item: { category: expect.any(String) as string, - createdAt: expect.any(String) as string, + createdAt: expect.any(Date) as Date, title: itemTitle, - updatedAt: expect.any(String) as string, + updatedAt: expect.any(Date) as Date, }, }); }); @@ -197,14 +214,13 @@ describe("Items", () => { it("does not omit field value if field is a non-sensitive type", async () => { for (const type of NONSENSITIVE_FIELD_TYPES) { const field = createItemField({ - label: fieldLabel, - // @ts-expect-error TODO: op-js needs to update these types - type, + title: fieldLabel, + fieldType: type as unknown as ItemFieldType, }); const item = createItem({ fields: [field], }); - core.cli.execute.mockReturnValue(item); + core.op.resolveItem.mockReturnValue(item); const result = await items.getReferenceMetadata( vaultName, itemTitle, @@ -217,10 +233,14 @@ describe("Items", () => { it("omits field value if field is a sensitive type", async () => { for (const type of SENSITIVE_FIELD_TYPES) { const item = createItem({ - // @ts-expect-error TODO: op-js needs to update these types - fields: [createItemField({ label: fieldLabel, type })], + fields: [ + createItemField({ + title: fieldLabel, + fieldType: type as unknown as ItemFieldType, + }), + ], }); - core.cli.execute.mockReturnValue(item); + core.op.resolveItem.mockReturnValue(item); const result = await items.getReferenceMetadata( vaultName, itemTitle, @@ -244,31 +264,32 @@ describe("Items", () => { expect(window.showInputBox).toHaveBeenCalledWith({ ignoreFocusOut: true, title: "What do you want to call this item?", + value: undefined, }); }); it("aborts if no item name supplied", async () => { window.showInputBox.mockReturnValue(null); await items.saveItem(generatePasswordArg); - expect(core.cli.execute).not.toHaveBeenCalled(); + expect(core.op.execute).not.toHaveBeenCalled(); }); - it("uses the cli with the `generate-password` flag set when generating a password", async () => { + it("generates a password and creates an item when generating a password", async () => { const recipe = "letters,digits,symbols,32"; window.showInputBox.mockReturnValue(title); configGet.mockReturnValue(recipe); await items.saveItem(generatePasswordArg); - expect(core.cli.execute).toHaveBeenCalled(); + expect(core.op.execute).toHaveBeenCalled(); }); - it("uses the cli with field assignments when saving an item from individual inputs", async () => { + it("creates an item with field assignments when saving from individual inputs", async () => { const input = { - itemValue: "foo", + fieldValue: "foo", location: "example location", }; window.showInputBox.mockReturnValue(title); await items.saveItem([input] as any); - expect(core.cli.execute).toHaveBeenCalled(); + expect(core.op.execute).toHaveBeenCalled(); }); }); }); diff --git a/src/items.ts b/src/items.ts index cb97368..ba10ae8 100644 --- a/src/items.ts +++ b/src/items.ts @@ -1,11 +1,10 @@ -import type { - Field, - FieldAssignment, - FieldPurpose, +import { Item, - OutputCategory, -} from "@1password/op-js"; -import { item } from "@1password/op-js"; + ItemCategory, + ItemField, + ItemFieldType, + Secrets, +} from "@1password/sdk"; import type { Range, Selection } from "vscode"; import { commands, env, window } from "vscode"; import { config, ConfigKey } from "./configuration"; @@ -13,16 +12,27 @@ import { COMMANDS, NONSENSITIVE_FIELD_TYPES } from "./constants"; import type { Core } from "./core"; import { FIELD_TYPE_PATTERNS } from "./secret-detection/patterns"; import { Suggestion } from "./secret-detection/suggestion"; -import { formatField, formatTitle, maskString } from "./utils"; +import { + buildSecretReference, + formatField, + formatTitle, + maskString, + parsePasswordRecipe, + toItemFieldType, +} from "./utils"; export interface ReferenceMetaData { item: { title: string; - category: OutputCategory; - createdAt: string; - updatedAt: string; + category: ItemCategory; + createdAt: Date; + updatedAt: Date; + }; + field: { + label: string; + type: ItemFieldType; + value?: string; }; - field: Pick; } export interface SaveItemInput { @@ -51,8 +61,8 @@ export class Items { ); } - public async getItem(): Promise { - if (await this.core.cli.isInvalid()) { + public async getItem(): Promise { + if (await this.core.op.isInvalid()) { return; } @@ -73,12 +83,9 @@ export class Items { return; } - const vaultItem = await this.core.cli.execute( - () => - item.get(itemValue, { - vault: this.core.vaultId, - cache: config.get(ConfigKey.ItemsCacheValues), - }) as Item, + const vaultItem = await this.core.op.resolveItem( + this.core.vaultId, + itemValue, ); if (!vaultItem) { @@ -94,7 +101,7 @@ export class Items { } const fieldValue = await window.showQuickPick( - fieldsWithValues.map((field) => field.label), + fieldsWithValues.map((field) => field.title), { title: "Choose which field to use", ignoreFocusOut: true, @@ -105,8 +112,13 @@ export class Items { return; } - const field = vaultItem.fields.find((f) => f.label === fieldValue); - return this.getItemCallback(field); + const field = vaultItem.fields.find((f) => f.title === fieldValue); + const reference = buildSecretReference( + vaultItem.vaultId, + vaultItem.id, + field.id, + ); + return this.getItemCallback(field, reference); } public async getReferenceMetadata( @@ -114,25 +126,18 @@ export class Items { itemId: string, fieldIdOrLabel: string, ): Promise { - if (await this.core.cli.isInvalid()) { + if (await this.core.op.isInvalid()) { return; } - const vaultItem = await this.core.cli.execute( - () => - item.get(itemId, { - vault: vaultId, - cache: config.get(ConfigKey.ItemsCacheValues), - }) as Item, - false, - ); + const vaultItem = await this.core.op.resolveItem(vaultId, itemId, false); if (!vaultItem) { throw new Error("Could not find vault item."); } const field = vaultItem.fields.find( - (f) => f.id === fieldIdOrLabel || f.label === fieldIdOrLabel, + (f) => f.id === fieldIdOrLabel || f.title === fieldIdOrLabel, ); if (!field) { @@ -143,14 +148,13 @@ export class Items { item: { title: vaultItem.title, category: vaultItem.category, - createdAt: vaultItem.created_at, - updatedAt: vaultItem.updated_at, + createdAt: vaultItem.createdAt, + updatedAt: vaultItem.updatedAt, }, field: { - label: field.label, - type: field.type, - // @ts-expect-error TODO: op-js needs to update these types - value: NONSENSITIVE_FIELD_TYPES.includes(field.type) + label: field.title, + type: field.fieldType, + value: NONSENSITIVE_FIELD_TYPES.includes(field.fieldType) ? field.value : undefined, }, @@ -160,7 +164,7 @@ export class Items { public async saveItem( input?: SaveItemInput[] | typeof generatePasswordArg, ): Promise { - if (await this.core.cli.isInvalid()) { + if (await this.core.op.isInvalid()) { return; } @@ -185,9 +189,22 @@ export class Items { return; } - let fields: FieldAssignment[] = []; + let fields: ItemField[] = []; + + if (generatePassword) { + const { password } = Secrets.generatePassword( + parsePasswordRecipe(config.get(ConfigKey.ItemsPasswordRecipe)), + ); - if (!generatePassword) { + fields = [ + { + id: "", + title: "password", + fieldType: ItemFieldType.Concealed, + value: password, + }, + ]; + } else { fields = await this.createFieldAssignments(input); if (fields.length === 0) { @@ -195,14 +212,12 @@ export class Items { } } - let vaultItem = await this.core.cli.execute(() => - item.create(fields, { + const vaultItem = await this.core.op.execute(async (client) => + client.items.create({ + vaultId: this.core.vaultId, title: itemTitle, - category: "Login", - vault: this.core.vaultId, - generatePassword: generatePassword - ? config.get(ConfigKey.ItemsPasswordRecipe) - : false, + category: ItemCategory.Login, + fields, }), ); @@ -211,14 +226,6 @@ export class Items { return; } - vaultItem = await this.core.cli.execute( - () => item.get(vaultItem.id) as Item, - ); - - if (!vaultItem) { - return; - } - await this.insertSavedItem(input, vaultItem); await window.showInformationMessage( @@ -226,7 +233,10 @@ export class Items { ); } - private async getItemCallback(field: Field): Promise { + private async getItemCallback( + field: ItemField, + reference: string, + ): Promise { const editor = window.activeTextEditor; const selections = editor?.selections; if (!editor || selections.length === 0) { @@ -247,7 +257,7 @@ export class Items { for (const selection of selections) { editBuilder.replace( selection, - useReference ? field.reference : field.value, + useReference ? reference : field.value, ); } }); @@ -271,13 +281,11 @@ export class Items { })); } - // eslint-disable-next-line sonarjs/cognitive-complexity private async createFieldAssignments( input: SaveItemInput[], - ): Promise { - const fields: FieldAssignment[] = []; + ): Promise { + const fields: ItemField[] = []; const isOnlyOne = input.length === 1; - let passwordPurposeAssigned = false; for (const set of input) { const { fieldValue } = set; @@ -293,8 +301,7 @@ export class Items { } const suggestedLabel = suggestion?.field || "value"; - const fieldType = suggestion?.type || "concealed"; - let purpose: FieldPurpose | undefined; + const fieldType = toItemFieldType(suggestion?.type); const fieldLabel = await window.showInputBox({ title: isOnlyOne @@ -310,16 +317,12 @@ export class Items { continue; } - if (!passwordPurposeAssigned) { - switch (fieldLabel) { - case "password": - purpose = "PASSWORD"; - passwordPurposeAssigned = true; - break; - } - } - - fields.push([fieldLabel, fieldType, fieldValue, purpose]); + fields.push({ + id: "", + title: fieldLabel, + fieldType, + value: fieldValue, + }); } return fields; @@ -342,12 +345,17 @@ export class Items { const selections = editor?.selections; if (selections.length === 1) { const field = vaultItem.fields.find( - (field) => field.label === "password", + (field) => field.title === "password", + ); + const reference = buildSecretReference( + vaultItem.vaultId, + vaultItem.id, + field.id, ); await editor.edit((editBuilder) => editBuilder.insert( selections[0].active, - useReference ? field.reference : field.value, + useReference ? reference : field.value, ), ); } @@ -363,8 +371,13 @@ export class Items { const field = vaultItem.fields.find( (field) => field.value === fieldValue, ); + const reference = buildSecretReference( + vaultItem.vaultId, + vaultItem.id, + field.id, + ); await editor.edit((editBuilder) => - editBuilder.replace(location, field.reference), + editBuilder.replace(location, reference), ); } } diff --git a/src/language-providers/hover.test.ts b/src/language-providers/hover.test.ts index 9f6c522..2580865 100644 --- a/src/language-providers/hover.test.ts +++ b/src/language-providers/hover.test.ts @@ -1,11 +1,17 @@ +import { ItemCategory, ItemFieldType } from "@1password/sdk"; import { format as formatTime } from "timeago.js"; import { Hover } from "vscode"; import * as vscode from "../../test/vscode-mock"; -import { Core } from "../core"; +import type { Core } from "../core"; import { ReferenceMetaData } from "../items"; import { formatTitle } from "../utils"; import { provideHover } from "./hover"; +jest.mock("@1password/sdk", () => ({ + ItemCategory: { Login: "Login" }, + ItemFieldType: { Text: "Text", Concealed: "Concealed" }, +})); + const appendMarkdownSpy = jest.fn<{ value: string }, string[]>(); const hoverSpy = jest.spyOn(vscode, "Hover"); const markdownStringSpy = jest @@ -15,8 +21,8 @@ const markdownStringSpy = jest })); const reference = "op://vault/item/field"; const core = { - cli: { - execute: jest.fn(), + op: { + getClient: jest.fn(), }, items: { getReferenceMetadata: jest.fn(), @@ -25,13 +31,13 @@ const core = { const mockMetaData: ReferenceMetaData = { item: { title: "Item Test", - category: "LOGIN", - createdAt: "2017-10-15T23:26:32Z", - updatedAt: "2019-06-20T22:09:59Z", + category: ItemCategory.Login, + createdAt: new Date("2017-10-15T23:26:32Z"), + updatedAt: new Date("2019-06-20T22:09:59Z"), }, field: { label: "Field Test", - type: "STRING", + type: ItemFieldType.Text, value: "Value Test", }, }; @@ -63,7 +69,7 @@ describe("provideHover", () => { }); it("provides a 'please authenticate' hover if the user is not authenticated", async () => { - core.cli.execute.mockResolvedValueOnce(null); + core.op.getClient.mockResolvedValueOnce(null); const result = await createHover(reference); expect(result).toBeDefined(); @@ -76,7 +82,7 @@ describe("provideHover", () => { it("provides an error hover if one occured in getReferenceMetadata while retrieving reference metadata", async () => { const errorMessage = "you've done it again!"; - core.cli.execute.mockResolvedValueOnce({}); + core.op.getClient.mockResolvedValueOnce({}); core.items.getReferenceMetadata.mockRejectedValueOnce( new Error(errorMessage), ); @@ -89,7 +95,7 @@ describe("provideHover", () => { }); it("provides a hover with the reference metadata", async () => { - core.cli.execute.mockResolvedValueOnce({}); + core.op.getClient.mockResolvedValueOnce({}); core.items.getReferenceMetadata.mockResolvedValueOnce(mockMetaData); const result = await createHover(reference); diff --git a/src/language-providers/hover.ts b/src/language-providers/hover.ts index 53b46eb..572cfe0 100644 --- a/src/language-providers/hover.ts +++ b/src/language-providers/hover.ts @@ -1,4 +1,3 @@ -import { ListAccount, whoami } from "@1password/op-js"; import { format as formatTime } from "timeago.js"; import type { TextDocument } from "vscode"; import { Hover, MarkdownString, Position, Range } from "vscode"; @@ -45,11 +44,9 @@ export async function provideHover( new Position(position.line, index + value.length - 1), ); - const authenticated = await this.cli.execute(() => - whoami(), - ); + const client = await this.op.getClient(false); - if (!authenticated) { + if (!client) { const markdownUnauthed = new MarkdownString(); markdownUnauthed.isTrusted = true; markdownUnauthed.appendMarkdown( @@ -58,11 +55,6 @@ export async function provideHover( return new Hover(markdownUnauthed, range); } - // HACK / FIXME: In Windows the CLI cannot perform succesive commands too quickly, - // so we need to give it a second after the whoami call before looking up item details. - // This is an issue in the CLI, not the extension. - await new Promise((resolve) => setTimeout(resolve, 1000)); - let metaData: ReferenceMetaData; try { metaData = await this.items.getReferenceMetadata(vault, item, field); @@ -90,7 +82,6 @@ export async function provideHover( markdownField.supportThemeIcons = true; markdownField.appendMarkdown( `$(output-view-icon) Field: **${metaData.field.label}**\n\n${ - // @ts-expect-error TODO: op-js needs to update these types NONSENSITIVE_FIELD_TYPES.includes(metaData.field.type) ? `\`\`\`\n${metaData.field.value}\n\`\`\`` : "_Value hidden_" diff --git a/src/secret-detection/parsers/index.ts b/src/secret-detection/parsers/index.ts index 1d1c596..a8eeb2b 100644 --- a/src/secret-detection/parsers/index.ts +++ b/src/secret-detection/parsers/index.ts @@ -1,8 +1,12 @@ -import { FieldAssignmentType } from "@1password/op-js"; import { Range, TextDocument } from "vscode"; import { combineRegexp } from "../../utils"; import { getPatternSuggestion, VALUE_PATTERNS } from "../patterns"; -import { BRANDS, SECRET_KEY_HINT, Suggestion } from "../suggestion"; +import { + BRANDS, + FieldAssignmentType, + SECRET_KEY_HINT, + Suggestion, +} from "../suggestion"; export interface ParserMatch { range: Range; diff --git a/src/secret-detection/suggestion.ts b/src/secret-detection/suggestion.ts index f4f83c7..b6e40ea 100644 --- a/src/secret-detection/suggestion.ts +++ b/src/secret-detection/suggestion.ts @@ -1,4 +1,6 @@ -import { FieldAssignmentType } from "@1password/op-js"; +// The subset of field types secret detection can suggest when creating an +// item. These are mapped to the SDK's `ItemFieldType` at item-creation time. +export type FieldAssignmentType = "concealed" | "text" | "email" | "url"; export interface Suggestion { item?: string; diff --git a/src/setup.ts b/src/setup.ts index 5a6a9c2..078f18d 100644 --- a/src/setup.ts +++ b/src/setup.ts @@ -1,17 +1,9 @@ -import { - AbbreviatedVault, - account, - ListAccount, - setGlobalFlags, - vault, -} from "@1password/op-js"; import { commands, window } from "vscode"; import { COMMANDS, DEBUG, STATE } from "./constants"; import type { Core } from "./core"; export class Setup { - public accountUuid?: string; - public accountUrl?: string; + public accountId?: string; public vaultId?: string; public constructor(private core: Core) { @@ -27,22 +19,15 @@ export class Setup { ); } - private setAccountIdFlag() { - setGlobalFlags({ - account: this.accountUuid, - }); - } - // eslint-disable-next-line sonarjs/cognitive-complexity public async configure(): Promise { - if (await this.core.cli.isInvalid()) { - return; - } - - this.accountUuid = await this.core.context.secrets.get(STATE.ACCOUNT_UUID); - this.accountUrl = await this.core.context.secrets.get(STATE.ACCOUNT_URL); + this.accountId = await this.core.context.secrets.get(STATE.ACCOUNT_UUID); this.vaultId = await this.core.context.secrets.get(STATE.VAULT_ID); + // Make the stored account available to the SDK client so it can + // authenticate against the 1Password desktop app. + this.core.op.setAccount(this.accountId); + let promptForVault = true; const dontRemindMe = "Don't remind me"; @@ -57,7 +42,7 @@ export class Setup { "true", ); - if ((!this.accountUuid || !this.accountUrl) && !reminderDisabled) { + if (!this.accountId && !reminderDisabled) { const chooseAccount = "Choose account"; const response = await window.showInformationMessage( @@ -69,11 +54,9 @@ export class Setup { await this.chooseAccount(); promptForVault = false; } - } else { - this.setAccountIdFlag(); } - if (!this.accountUuid || !this.accountUrl) { + if (!this.accountId) { if (!reminderDisabled) { const response = await window.showWarningMessage( 'You must choose an account to perform 1Password operations in VS Code. When you want to choose an account run the "1Password: Choose account" command.', @@ -120,96 +103,50 @@ export class Setup { } public async chooseAccount(): Promise { - if (await this.core.cli.isInvalid()) { - return; - } - - const accountsList = await this.core.cli.execute(() => - account.list(), - ); - - if (accountsList.length === 0) { - const open1Password = "Open 1Password"; - - const response = await window.showInformationMessage( - "You don't have any 1Password accounts. Please create one to perform operations in VS Code.", - open1Password, - ); - - if (response === open1Password) { - await commands.executeCommand(COMMANDS.OPEN_1PASSWORD); - } + // The SDK can't enumerate accounts, so the user supplies the account + // name (as shown in the 1Password desktop app), its sign-in address, or + // its UUID. This value is used to authenticate via the desktop app. + const account = await window.showInputBox({ + title: "Enter your 1Password account", + prompt: + "Use your account name as shown in the 1Password desktop app, its sign-in address (e.g. my.1password.com), or its UUID.", + placeHolder: "my.1password.com", + ignoreFocusOut: true, + }); + if (!account) { return; } - const response = await window.showQuickPick( - accountsList - .map((account) => ({ - label: account.email, - description: account.url, - })) - .sort((a, b) => { - if (a.label < b.label) { - return -1; - } - if (a.label > b.label) { - return 1; - } - return 0; - }), - { - title: "Choose an account", - ignoreFocusOut: true, - }, - ); + const isChanged = this.accountId !== account; + this.accountId = account; + await this.core.context.secrets.store(STATE.ACCOUNT_UUID, account); + this.core.op.setAccount(account); - if (response) { - const account = accountsList.find( - (account) => - account.email === response.label && - account.url === response.description, - ); - - const isChanged = this.accountUuid !== account.account_uuid; - this.accountUuid = account.user_uuid; - this.accountUrl = account.url; - await this.core.context.secrets.store( - STATE.ACCOUNT_UUID, - account.account_uuid, - ); - await this.core.context.secrets.store(STATE.ACCOUNT_URL, account.url); - this.setAccountIdFlag(); - - if (isChanged) { - await this.chooseVault(); - } + if (isChanged) { + await this.chooseVault(); } } public async chooseVault(): Promise { - if (await this.core.cli.isInvalid()) { - return; - } - - if (!this.accountUuid || !this.accountUrl) { + if (!this.accountId) { await window.showErrorMessage( 'You must choose a 1Password account before choosing a vault. To choose an account run the "1Password: Choose account" command.', ); + return; } - const vaultsList = await this.core.cli.execute(() => - vault.list(), + const vaultsList = await this.core.op.execute(async (client) => + client.vaults.list({ decryptDetails: true }), ); - // You cannot have 0 vaults, but if you don't authorize the - // vault lookup this value will be undefined. + // If the desktop app authorization was declined this value is undefined. if (!vaultsList) { return; } const response = await window.showQuickPick( - vaultsList.map((vault) => vault.name).sort(), + vaultsList.map((vault) => vault.title).sort(), { title: "Choose an account vault", ignoreFocusOut: true, @@ -217,7 +154,7 @@ export class Setup { ); if (response) { - const vault = vaultsList.find((vault) => vault.name === response); + const vault = vaultsList.find((vault) => vault.title === response); this.vaultId = vault.id; await this.core.context.secrets.store(STATE.VAULT_ID, vault.id); diff --git a/src/url-utils.ts b/src/url-utils.ts index ce9e7c6..7933ded 100644 --- a/src/url-utils.ts +++ b/src/url-utils.ts @@ -1,4 +1,3 @@ -import { Item, item } from "@1password/op-js"; import { default as open } from "open"; import { commands, env, Uri, UriHandler } from "vscode"; import { COMMANDS, QUALIFIED_EXTENSION_ID } from "./constants"; @@ -35,12 +34,14 @@ export const createOpenOPHandler = itemValue: string; }; - const vaultItem = await core.cli.execute( - () => item.get(itemValue, { vault: vaultValue }) as Item, - ); + const vaultItem = await core.op.resolveItem(vaultValue, itemValue); - url.searchParams.append("a", core.accountUuid); - url.searchParams.append("v", vaultItem.vault.id); + if (!vaultItem) { + return; + } + + url.searchParams.append("a", core.accountId); + url.searchParams.append("v", vaultItem.vaultId); url.searchParams.append("i", vaultItem.id); break; } diff --git a/src/utils.ts b/src/utils.ts index f6eed83..ef11fcc 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,6 @@ +import { ItemFieldType, PasswordRecipe } from "@1password/sdk"; import { REGEXP } from "./constants"; +import type { FieldAssignmentType } from "./secret-detection/suggestion"; export const semverToInt = (input: string) => input @@ -6,6 +8,55 @@ export const semverToInt = (input: string) => .map((n) => n.padStart(2, "0")) .join(""); +// Build a secret reference (op://vault/item/field) from IDs. The SDK resolves +// references that use either names or IDs, and IDs are unambiguous. +export const buildSecretReference = ( + vaultId: string, + itemId: string, + fieldId: string, +): string => `op://${vaultId}/${itemId}/${fieldId}`; + +// Map the extension's internal field assignment types (used by secret +// detection) to the SDK's `ItemFieldType` enum used when creating items. +export const toItemFieldType = ( + type: FieldAssignmentType = "concealed", +): ItemFieldType => { + switch (type) { + case "text": + return ItemFieldType.Text; + case "email": + return ItemFieldType.Email; + case "url": + return ItemFieldType.Url; + case "concealed": + default: + return ItemFieldType.Concealed; + } +}; + +// Parse a CLI-style password recipe string (e.g. "letters,digits,symbols,32") +// into the SDK's `PasswordRecipe` object. +export const parsePasswordRecipe = (recipe: string): PasswordRecipe => { + const parts = (recipe || "") + .split(",") + .map((part) => part.trim().toLowerCase()) + .filter(Boolean); + + const length = + parts + .map((part) => Number.parseInt(part, 10)) + .find((n) => !Number.isNaN(n)) ?? 32; + + return { + type: "Random", + parameters: { + includeDigits: parts.includes("digits"), + includeSymbols: parts.includes("symbols"), + length, + }, + }; +}; + export const titleCase = (value: string): string => value.replace( /\w\S*/g, diff --git a/test/factories.ts b/test/factories.ts index 40a6921..e260a57 100644 --- a/test/factories.ts +++ b/test/factories.ts @@ -1,5 +1,4 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -import { Field, File, Item } from "@1password/op-js"; +import { Item, ItemCategory, ItemField, ItemFieldType } from "@1password/sdk"; import { generateUUID, randomNumber, sample } from "./utils"; export const createItem = (overrides: Partial = {}): Item => { @@ -8,58 +7,38 @@ export const createItem = (overrides: Partial = {}): Item => { return { id: uuid, title: `Vault Item ${id}`, - vault: { - id: `vault-123`, - name: "My Vault", - }, - category: "LOGIN", - last_edited_by: "user-123", - created_at: new Date().toString(), - updated_at: new Date().toString(), + category: ItemCategory.Login, + vaultId: "vault-123", fields: [createItemField()], - version: 1, sections: [], + notes: "", + tags: [], + websites: [], + version: 1, + files: [], + createdAt: new Date(), + updatedAt: new Date(), ...overrides, }; }; -export const createItemField = (overrides: Partial = {}): Field => { - const type = sample([ - "STRING", - "URL", - "ADDRESS", - "DATE", - "MONTH_YEAR", - "EMAIL", - "PHONE", +export const createItemField = ( + overrides: Partial = {}, +): ItemField => { + const fieldType = sample([ + ItemFieldType.Text, + ItemFieldType.Url, + ItemFieldType.Address, + ItemFieldType.Date, + ItemFieldType.MonthYear, + ItemFieldType.Email, + ItemFieldType.Phone, ]); return { id: generateUUID(), - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - type: type as any, - label: `${type} field ${randomNumber()}`, + title: `${fieldType} field ${randomNumber()}`, + fieldType, value: "Some Value", ...overrides, }; }; - -export const createItemFile = (overrides: Partial = {}): File => ({ - id: generateUUID(), - name: `File ${randomNumber()}`, - size: 260, - content_path: "/path/to/file.txt", - section: { - id: `section-123`, - }, - ...overrides, -}); - -export const createItemUrlField = ( - primary = true, -): { - primary: boolean; - href: string; -} => ({ - primary, - href: `https://1password.com/${generateUUID()}`, -}); diff --git a/yarn.lock b/yarn.lock index aab1ebb..fb0c6a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19,19 +19,23 @@ eslint-plugin-react-hooks "^4.6.0" eslint-plugin-sonarjs "^0.21.0" -"@1password/op-js@^0.1.13": - version "0.1.13" - resolved "https://registry.yarnpkg.com/@1password/op-js/-/op-js-0.1.13.tgz#7eb7fed700a4e7b7d4efb727397fc2fd53ba52dd" - integrity sha512-ZZBLxVqywFdvIbLv2xWw2N1ImSi183rRKf90vV19KRMReNyLwuD0dv6IrKrIdrJU33IuV3Gz85Z4K2a1PJTBDg== - dependencies: - lookpath "^1.2.2" - semver "^7.6.2" - "@1password/prettier-config@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@1password/prettier-config/-/prettier-config-1.1.3.tgz#5f958928d48b8ad4f57e175112c66c8f8e1808ba" integrity sha512-yue6IdD/pPiv1CPKTvjK952+9fhR6er0zhcXhEFuvJqw4zqH9AxWSwIRd4obMV/XWX1ZR/qimHgQbzgq+Z8gJg== +"@1password/sdk-core@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@1password/sdk-core/-/sdk-core-0.4.0.tgz#46479577f42f09d595e388d705c14e307161949e" + integrity sha512-vjeI1o4wiONY+t1naA4dtUp6HktdLH1D2S+tN1Lh4l41S9XIUHxrljov9B5u6G+VHr7f2MUoxmzXA9zT3aokQQ== + +"@1password/sdk@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@1password/sdk/-/sdk-0.4.0.tgz#2edf39e055734e595fe3941fb519ebc1a4cb7ff9" + integrity sha512-RIypujc9R/UeUaobjyClTYokqRFpcaIkHq+EO/X9XoHId98Vg+SbjwGV+yygRC4MyHwYNo1KP1iEbZcqJ4ZTdw== + dependencies: + "@1password/sdk-core" "0.4.0" + "@ampproject/remapping@^2.1.0": version "2.1.2" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" @@ -1186,6 +1190,36 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== +"@vscode/vsce@2.25.0": + version "2.25.0" + resolved "https://registry.yarnpkg.com/@vscode/vsce/-/vsce-2.25.0.tgz#93421c1cfdf0c73ecf273698951ca0dc09bf6f37" + integrity sha512-VXMCGUaP6wKBadA7vFQdsksxkBAMoh4ecZgXBwauZMASAgnwYesHyLnqIyWYeRwjy2uEpitHvz/1w5ENnR30pg== + dependencies: + azure-devops-node-api "^12.5.0" + chalk "^2.4.2" + cheerio "^1.0.0-rc.9" + cockatiel "^3.1.2" + commander "^6.2.1" + form-data "^4.0.0" + glob "^7.0.6" + hosted-git-info "^4.0.2" + jsonc-parser "^3.2.0" + leven "^3.1.0" + markdown-it "^12.3.2" + mime "^1.3.4" + minimatch "^3.0.3" + parse-semver "^1.1.1" + read "^1.0.7" + semver "^7.5.2" + tmp "^0.2.1" + typed-rest-client "^1.8.4" + url-join "^4.0.1" + xml2js "^0.5.0" + yauzl "^2.3.1" + yazl "^2.2.2" + optionalDependencies: + keytar "^7.7.0" + abab@^2.0.3, abab@^2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" @@ -1466,6 +1500,14 @@ axobject-query@^3.2.1: dependencies: dequal "^2.0.3" +azure-devops-node-api@^12.5.0: + version "12.5.0" + resolved "https://registry.yarnpkg.com/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz#38b9efd7c5ac74354fe4e8dbe42697db0b8e85a5" + integrity sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og== + dependencies: + tunnel "0.0.6" + typed-rest-client "^1.8.4" + babel-jest@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" @@ -1532,6 +1574,25 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1591,16 +1652,37 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + builtin-modules@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -1620,6 +1702,14 @@ call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: get-intrinsic "^1.2.4" set-function-length "^1.2.1" +call-bound@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1667,6 +1757,33 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== +cheerio@^0, cheerio@^1.0.0-rc.9: + version "0.22.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" + integrity sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA== + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash.assignin "^4.0.9" + lodash.bind "^4.1.4" + lodash.defaults "^4.0.1" + lodash.filter "^4.4.0" + lodash.flatten "^4.2.0" + lodash.foreach "^4.3.0" + lodash.map "^4.4.0" + lodash.merge "^4.4.0" + lodash.pick "^4.2.1" + lodash.reduce "^4.4.0" + lodash.reject "^4.4.0" + lodash.some "^4.4.0" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + ci-info@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" @@ -1706,6 +1823,11 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= +cockatiel@^3.1.2: + version "3.2.1" + resolved "https://registry.yarnpkg.com/cockatiel/-/cockatiel-3.2.1.tgz#575f937bc4040a20ae27352a6d07c9c5a741981f" + integrity sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q== + code-error-fragment@0.0.230: version "0.0.230" resolved "https://registry.yarnpkg.com/code-error-fragment/-/code-error-fragment-0.0.230.tgz#d736d75c832445342eca1d1fedbf17d9618b14d7" @@ -1757,6 +1879,11 @@ commander@12.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + comment-parser@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.4.1.tgz#bdafead37961ac079be11eb7ec65c4d021eaf9cc" @@ -1790,6 +1917,21 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA== + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + cssom@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" @@ -1874,11 +2016,23 @@ decimal.js@^10.2.1: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -1930,6 +2084,11 @@ dequal@^2.0.3: resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== +detect-libc@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" + integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -1961,6 +2120,32 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + domexception@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" @@ -1968,6 +2153,38 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw== + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -1998,6 +2215,28 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.5" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" + integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== + dependencies: + once "^1.4.0" + +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -2090,6 +2329,11 @@ es-define-property@^1.0.0: dependencies: get-intrinsic "^1.2.4" +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + es-errors@^1.1.0, es-errors@^1.2.1, es-errors@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" @@ -2122,6 +2366,13 @@ es-object-atoms@^1.0.0: dependencies: es-errors "^1.3.0" +es-object-atoms@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz#a2d0b373205724dfa525d23b0c3e1b1ca582c99b" + integrity sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw== + dependencies: + es-errors "^1.3.0" + es-set-tostringtag@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" @@ -2131,6 +2382,16 @@ es-set-tostringtag@^2.0.3: has-tostringtag "^1.0.2" hasown "^2.0.1" +es-set-tostringtag@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" + integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== + dependencies: + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + has-tostringtag "^1.0.2" + hasown "^2.0.2" + es-shim-unscopables@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" @@ -2487,6 +2748,11 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expect@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" @@ -2537,6 +2803,13 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -2619,6 +2892,22 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.5" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.5.tgz#b49e48858045ff4cbf6b03e1805cebcad3679053" + integrity sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + es-set-tostringtag "^2.1.0" + hasown "^2.0.2" + mime-types "^2.1.12" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -2689,11 +2978,35 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" +get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -2721,6 +3034,11 @@ get-symbol-description@^1.0.2: es-errors "^1.3.0" get-intrinsic "^1.2.4" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -2746,6 +3064,18 @@ glob@^10.2.2: minipass "^7.0.4" path-scurry "^1.11.0" +glob@^7.0.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" @@ -2797,6 +3127,11 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + graceful-fs@^4.1.2, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" @@ -2851,6 +3186,11 @@ has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + has-tostringtag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" @@ -2879,6 +3219,13 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: dependencies: function-bind "^1.1.2" +hosted-git-info@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== + dependencies: + lru-cache "^6.0.0" + hosted-git-info@^6.0.0: version "6.1.1" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.1.tgz#629442c7889a69c05de604d52996b74fe6f26d58" @@ -2898,6 +3245,18 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== +htmlparser2@^3.9.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -2937,6 +3296,11 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" @@ -2976,11 +3340,16 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" @@ -3861,6 +4230,11 @@ json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== +jsonc-parser@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz#f2a524b4f7fd11e3d791e559977ad60b98b798b4" + integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ== + "jsx-ast-utils@^2.4.1 || ^3.0.0": version "3.2.2" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.2.tgz#6ab1e52c71dfc0c0707008a91729a9491fe9f76c" @@ -3879,6 +4253,14 @@ jsx-ast-utils@^3.3.5: object.assign "^4.1.4" object.values "^1.1.6" +keytar@^7.7.0: + version "7.9.0" + resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.9.0.tgz#4c6225708f51b50cbf77c5aae81721964c2918cb" + integrity sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ== + dependencies: + node-addon-api "^4.3.0" + prebuild-install "^7.0.1" + keyv@^4.5.3: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -3951,6 +4333,13 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +linkify-it@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" + integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== + dependencies: + uc.micro "^1.0.1" + lint-staged@^15.2.4: version "15.2.4" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.2.4.tgz#b8376b459a308d40e5dfdae302f333fa4c4bf126" @@ -3993,17 +4382,52 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash.assignin@^4.0.9: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + integrity sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg== + +lodash.bind@^4.1.4: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" + integrity sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA== + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= +lodash.defaults@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== + +lodash.filter@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" + integrity sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ== + +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g== + +lodash.foreach@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + integrity sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ== + +lodash.map@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" + integrity sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q== + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.merge@^4.6.2: +lodash.merge@^4.4.0, lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== @@ -4013,6 +4437,26 @@ lodash.mergewith@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== +lodash.pick@^4.2.1: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== + +lodash.reduce@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" + integrity sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw== + +lodash.reject@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" + integrity sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ== + +lodash.some@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + integrity sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ== + lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -4029,11 +4473,6 @@ log-update@^6.0.0: strip-ansi "^7.1.0" wrap-ansi "^9.0.0" -lookpath@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/lookpath/-/lookpath-1.2.2.tgz#bddcd1440b6643e07495138376d43aed38bcd454" - integrity sha512-k2Gmn8iV6qdME3ztZC2spubmQISimFOPLuQKiPaLcVdRz0IpdxrNClVepMlyTJlhodm/zG/VfbkWERm3kUIh+Q== - loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -4077,6 +4516,27 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" +markdown-it@^12.3.2: + version "12.3.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" + integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== + dependencies: + argparse "^2.0.1" + entities "~2.1.0" + linkify-it "^3.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -4115,6 +4575,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +mime@^1.3.4: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -4125,6 +4590,11 @@ mimic-fn@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimatch@9.0.3: version "9.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" @@ -4132,6 +4602,13 @@ minimatch@9.0.3: dependencies: brace-expansion "^2.0.1" +minimatch@^3.0.3, minimatch@^3.1.1: + version "3.1.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e" + integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w== + dependencies: + brace-expansion "^1.1.7" + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -4151,11 +4628,21 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +minimist@^1.2.3: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4: version "7.1.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.1.tgz#f7f85aff59aa22f110b20e27692465cf3bf89481" integrity sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA== +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -4176,11 +4663,33 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +mute-stream@~0.0.4: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +napi-build-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e" + integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +node-abi@^3.3.0: + version "3.92.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.92.0.tgz#18e2214677499b8dda81ffcd095afc763d5a9802" + integrity sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ== + dependencies: + semver "^7.3.5" + +node-addon-api@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" + integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4232,6 +4741,13 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" +nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" @@ -4252,6 +4768,11 @@ object-inspect@^1.13.1: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== +object-inspect@^1.13.3, object-inspect@^1.13.4: + version "1.13.4" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== + object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -4314,7 +4835,7 @@ object.values@^1.1.5, object.values@^1.1.6, object.values@^1.1.7: define-properties "^1.2.1" es-object-atoms "^1.0.0" -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -4418,6 +4939,13 @@ parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-semver@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/parse-semver/-/parse-semver-1.1.1.tgz#9a4afd6df063dc4826f93fba4a99cf223f666cb8" + integrity sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ== + dependencies: + semver "^5.1.0" + parse5@6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" @@ -4461,6 +4989,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -4498,6 +5031,24 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== +prebuild-install@^7.0.1: + version "7.1.3" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.3.tgz#d630abad2b147443f20a212917beae68b8092eec" + integrity sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^2.0.0" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -4549,6 +5100,14 @@ psl@^1.1.33: resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== +pump@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.4.tgz#1f313430527fa8b905622ebd22fe1444e757ab3c" + integrity sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -4559,6 +5118,13 @@ punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +qs@^6.9.1: + version "6.15.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.2.tgz#fd55426d710403ddccc45e0f9eab16db7727ece9" + integrity sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw== + dependencies: + side-channel "^1.1.0" + querystringify@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" @@ -4569,6 +5135,16 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-is@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -4602,6 +5178,22 @@ read-package-json@^6.0.0: normalize-package-data "^5.0.0" npm-normalize-package-bin "^3.0.0" +read@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ== + dependencies: + mute-stream "~0.0.4" + +readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + reflect.getprototypeof@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz#3ab04c32a8390b770712b7a8633972702d278859" @@ -4731,6 +5323,11 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" +safe-buffer@^5.0.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -4750,6 +5347,11 @@ safe-regex-test@^1.0.3: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sax@>=0.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.6.0.tgz#da59637629307b97e7c4cb28e080a7bc38560d5b" + integrity sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA== + saxes@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" @@ -4764,12 +5366,22 @@ saxes@^5.0.1: dependencies: lru-cache "^6.0.0" +semver@^5.1.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2: +semver@^7.5.2: + version "7.8.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.1.tgz#bf4970b5e70fda0686363cc18bfe8805d5ed957e" + integrity sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg== + +semver@^7.5.3, semver@^7.5.4, semver@^7.6.0: version "7.6.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== @@ -4808,6 +5420,35 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +side-channel-list@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.1.tgz#c2e0b5a14a540aebee3bbc6c3f8666cc9b509127" + integrity sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.4" + +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -4827,6 +5468,17 @@ side-channel@^1.0.6: get-intrinsic "^1.2.4" object-inspect "^1.13.1" +side-channel@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" + signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -4837,6 +5489,20 @@ signal-exit@^4.0.1, signal-exit@^4.1.0: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -4973,7 +5639,16 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5062,7 +5737,21 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -5108,6 +5797,11 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -5147,6 +5841,27 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +tar-fs@^2.0.0: + version "2.1.4" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.4.tgz#800824dbf4ef06ded9afea4acafe71c67c76b930" + integrity sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -5179,6 +5894,11 @@ timeago.js@^4.0.2: resolved "https://registry.yarnpkg.com/timeago.js/-/timeago.js-4.0.2.tgz#724e8c8833e3490676c7bb0a75f5daf20e558028" integrity sha512-a7wPxPdVlQL7lqvitHGGRsofhdwtkoSXPGATFuSOA2i1ZNQEPLrGnj68vOp2sOJTCFAQVXPeNMX/GctBaO9L2w== +tmp@^0.2.1: + version "0.2.7" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.7.tgz#26f4db11d1601ce8012dcb8a798ece1c06a99059" + integrity sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -5264,6 +5984,18 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tunnel@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" + integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -5337,6 +6069,15 @@ typed-array-length@^1.0.6: is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" +typed-rest-client@^1.8.4: + version "1.8.11" + resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-1.8.11.tgz#6906f02e3c91e8d851579f255abf0fd60800a04d" + integrity sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA== + dependencies: + qs "^6.9.1" + tunnel "0.0.6" + underscore "^1.12.1" + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -5349,6 +6090,11 @@ typescript@^5.4.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" @@ -5369,6 +6115,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +underscore@^1.12.1: + version "1.13.8" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.8.tgz#a93a21186c049dbf0e847496dba72b7bd8c1e92b" + integrity sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ== + undici-types@~5.25.1: version "5.25.3" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" @@ -5386,6 +6137,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +url-join@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" + integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== + url-parse@^1.5.3: version "1.5.10" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" @@ -5394,6 +6150,11 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + uuid@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" @@ -5535,7 +6296,16 @@ word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -5587,6 +6357,19 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xml2js@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.5.0.tgz#d9440631fbb2ed800203fad106f2724f62c493b7" + integrity sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" @@ -5640,6 +6423,21 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yauzl@^2.3.1: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yazl@^2.2.2: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" + integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== + dependencies: + buffer-crc32 "~0.2.3" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"