From 86d25b74531104a448086bbb46181d63dbecb5e1 Mon Sep 17 00:00:00 2001 From: gagik Date: Thu, 21 Nov 2024 14:02:51 +0100 Subject: [PATCH 01/14] WIP --- .vscode/settings.json | 1 - .../activeConnectionCodeLensProvider.ts | 4 +- src/editors/editorsController.ts | 5 +++ .../queryWithCopilotCodeLensProvider.ts | 39 +++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 src/editors/queryWithCopilotCodeLensProvider.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 732bb7406..32baf6163 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,5 @@ // Place your settings in this file to overwrite default and user settings. { - "editor.formatOnSave": false, "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, diff --git a/src/editors/activeConnectionCodeLensProvider.ts b/src/editors/activeConnectionCodeLensProvider.ts index 046b335eb..fee92432e 100644 --- a/src/editors/activeConnectionCodeLensProvider.ts +++ b/src/editors/activeConnectionCodeLensProvider.ts @@ -24,7 +24,7 @@ export default class ActiveConnectionCodeLensProvider this._onDidChangeCodeLenses.fire(); }); - this._activeConnectionChangedHandler = () => { + this._activeConnectionChangedHandler = (): void => { this._onDidChangeCodeLenses.fire(); }; this._connectionController.addEventListener( @@ -65,7 +65,7 @@ export default class ActiveConnectionCodeLensProvider return [codeLens]; } - deactivate() { + deactivate(): void { this._connectionController.removeEventListener( DataServiceEventTypes.ACTIVE_CONNECTION_CHANGED, this._activeConnectionChangedHandler diff --git a/src/editors/editorsController.ts b/src/editors/editorsController.ts index 51c111f82..0e3ede7e4 100644 --- a/src/editors/editorsController.ts +++ b/src/editors/editorsController.ts @@ -32,6 +32,7 @@ import type PlaygroundResultProvider from './playgroundResultProvider'; import { PLAYGROUND_RESULT_SCHEME } from './playgroundResultProvider'; import { StatusView } from '../views'; import type TelemetryService from '../telemetry/telemetryService'; +import type { QueryWithCopilotCodeLensProvider } from './queryWithCopilotCodeLensProvider'; const log = createLogger('editors controller'); @@ -102,6 +103,7 @@ export default class EditorsController { _exportToLanguageCodeLensProvider: ExportToLanguageCodeLensProvider; _editDocumentCodeLensProvider: EditDocumentCodeLensProvider; _collectionDocumentsCodeLensProvider: CollectionDocumentsCodeLensProvider; + _queryWithCopilotCodeLensProvider: QueryWithCopilotCodeLensProvider; constructor({ context, @@ -115,6 +117,7 @@ export default class EditorsController { playgroundSelectedCodeActionProvider, playgroundDiagnosticsCodeActionProvider, editDocumentCodeLensProvider, + queryWithCopilotCodeLensProvider, }: { context: vscode.ExtensionContext; connectionController: ConnectionController; @@ -127,6 +130,7 @@ export default class EditorsController { playgroundSelectedCodeActionProvider: PlaygroundSelectedCodeActionProvider; playgroundDiagnosticsCodeActionProvider: PlaygroundDiagnosticsCodeActionProvider; editDocumentCodeLensProvider: EditDocumentCodeLensProvider; + queryWithCopilotCodeLensProvider: QueryWithCopilotCodeLensProvider; }) { this._connectionController = connectionController; this._playgroundController = playgroundController; @@ -160,6 +164,7 @@ export default class EditorsController { playgroundSelectedCodeActionProvider; this._playgroundDiagnosticsCodeActionProvider = playgroundDiagnosticsCodeActionProvider; + this._queryWithCopilotCodeLensProvider = queryWithCopilotCodeLensProvider; vscode.workspace.onDidCloseTextDocument((e) => { const uriParams = new URLSearchParams(e.uri.query); diff --git a/src/editors/queryWithCopilotCodeLensProvider.ts b/src/editors/queryWithCopilotCodeLensProvider.ts new file mode 100644 index 000000000..29afd3369 --- /dev/null +++ b/src/editors/queryWithCopilotCodeLensProvider.ts @@ -0,0 +1,39 @@ +import * as vscode from 'vscode'; +import EXTENSION_COMMANDS from '../commands'; + +const COPILOT_CHAT_EXTENSION_ID = 'GitHub.copilot-chat'; + +export class QueryWithCopilotCodeLensProvider + implements vscode.CodeLensProvider +{ + constructor() {} + + readonly onDidChangeCodeLenses: vscode.Event = + vscode.extensions.onDidChange; + + provideCodeLenses(): vscode.CodeLens[] { + // We can only detect whether a user has the Copilot extension active + // but not whether it has an active subscription. + const hasCopilotInstalled = + vscode.extensions.getExtension(COPILOT_CHAT_EXTENSION_ID)?.isActive === + true; + + if (!hasCopilotInstalled) { + return []; + } + + return [ + new vscode.CodeLens(new vscode.Range(0, 0, 0, 0), { + title: '✨ Generate query with MongoDB Copilot', + command: EXTENSION_COMMANDS.SEND_PARTICIPANT_MESSAGE, + arguments: [ + { + message: '/query ', + isNewChat: true, + isPartialQuery: true, + }, + ], + }), + ]; + } +} From 6feac32331b212d0055992d43c536656641a9deb Mon Sep 17 00:00:00 2001 From: gagik Date: Fri, 22 Nov 2024 14:43:03 +0100 Subject: [PATCH 02/14] add query codelens and shorten wording --- src/commands/index.ts | 2 + .../activeConnectionCodeLensProvider.ts | 6 +- src/editors/editorsController.ts | 4 + .../queryWithCopilotCodeLensProvider.ts | 26 ++-- src/mdbExtensionController.ts | 25 ++++ src/participant/participant.ts | 65 +++++++-- src/participant/participantTypes.ts | 12 ++ .../activeConnectionCodeLensProvider.test.ts | 10 +- .../queryWithCopilotCodeLensProvider.test.ts | 133 ++++++++++++++++++ 9 files changed, 252 insertions(+), 31 deletions(-) create mode 100644 src/participant/participantTypes.ts create mode 100644 src/test/suite/editors/queryWithCopilotCodeLensProvider.test.ts diff --git a/src/commands/index.ts b/src/commands/index.ts index 209990b10..21096c2e5 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -79,6 +79,8 @@ enum EXTENSION_COMMANDS { // Chat participant. OPEN_PARTICIPANT_CODE_IN_PLAYGROUND = 'mdb.openParticipantCodeInPlayground', + SEND_MESSAGE_TO_PARTICIPANT = 'mdb.sendMessageToParticipant', + SEND_MESSAGE_TO_PARTICIPANT_FROM_INPUT = 'mdb.sendMessageToParticipantFromInput', RUN_PARTICIPANT_CODE = 'mdb.runParticipantCode', CONNECT_WITH_PARTICIPANT = 'mdb.connectWithParticipant', SELECT_DATABASE_WITH_PARTICIPANT = 'mdb.selectDatabaseWithParticipant', diff --git a/src/editors/activeConnectionCodeLensProvider.ts b/src/editors/activeConnectionCodeLensProvider.ts index fee92432e..c4c4cc7c9 100644 --- a/src/editors/activeConnectionCodeLensProvider.ts +++ b/src/editors/activeConnectionCodeLensProvider.ts @@ -50,10 +50,10 @@ export default class ActiveConnectionCodeLensProvider ? getDBFromConnectionString(connectionString) : null; message = defaultDB - ? `Currently connected to ${this._connectionController.getActiveConnectionName()} with default database ${defaultDB}. Click here to change connection.` - : `Currently connected to ${this._connectionController.getActiveConnectionName()}. Click here to change connection.`; + ? `Connected to ${this._connectionController.getActiveConnectionName()} with default database ${defaultDB}` + : `Connected to ${this._connectionController.getActiveConnectionName()}`; } else { - message = 'Disconnected. Click here to connect.'; + message = 'Connect'; } codeLens.command = { diff --git a/src/editors/editorsController.ts b/src/editors/editorsController.ts index 0e3ede7e4..eee7366e2 100644 --- a/src/editors/editorsController.ts +++ b/src/editors/editorsController.ts @@ -418,6 +418,10 @@ export default class EditorsController { ) ); this._context.subscriptions.push( + vscode.languages.registerCodeLensProvider( + { language: 'javascript' }, + this._queryWithCopilotCodeLensProvider + ), vscode.languages.registerCodeLensProvider( { language: 'javascript' }, this._activeConnectionCodeLensProvider diff --git a/src/editors/queryWithCopilotCodeLensProvider.ts b/src/editors/queryWithCopilotCodeLensProvider.ts index 29afd3369..72caec139 100644 --- a/src/editors/queryWithCopilotCodeLensProvider.ts +++ b/src/editors/queryWithCopilotCodeLensProvider.ts @@ -1,5 +1,7 @@ import * as vscode from 'vscode'; import EXTENSION_COMMANDS from '../commands'; +import type { SendMessageToParticipantFromInputOptions } from '../participant/participantTypes'; +import { isPlayground } from '../utils/playground'; const COPILOT_CHAT_EXTENSION_ID = 'GitHub.copilot-chat'; @@ -11,7 +13,11 @@ export class QueryWithCopilotCodeLensProvider readonly onDidChangeCodeLenses: vscode.Event = vscode.extensions.onDidChange; - provideCodeLenses(): vscode.CodeLens[] { + provideCodeLenses(document: vscode.TextDocument): vscode.CodeLens[] { + if (!isPlayground(document.uri)) { + return []; + } + // We can only detect whether a user has the Copilot extension active // but not whether it has an active subscription. const hasCopilotInstalled = @@ -22,17 +28,19 @@ export class QueryWithCopilotCodeLensProvider return []; } + const options: SendMessageToParticipantFromInputOptions = { + prompt: 'Describe the query you would like to generate.', + placeHolder: + 'e.g. Find the document in sample_mflix.users with the name of Kayden Washington', + messagePrefix: '/query', + isNewChat: true, + }; + return [ new vscode.CodeLens(new vscode.Range(0, 0, 0, 0), { title: '✨ Generate query with MongoDB Copilot', - command: EXTENSION_COMMANDS.SEND_PARTICIPANT_MESSAGE, - arguments: [ - { - message: '/query ', - isNewChat: true, - isPartialQuery: true, - }, - ], + command: EXTENSION_COMMANDS.SEND_MESSAGE_TO_PARTICIPANT_FROM_INPUT, + arguments: [options], }), ]; } diff --git a/src/mdbExtensionController.ts b/src/mdbExtensionController.ts index 0f8e6bdf6..b6f24d21d 100644 --- a/src/mdbExtensionController.ts +++ b/src/mdbExtensionController.ts @@ -48,6 +48,11 @@ import type { } from './participant/participant'; import ParticipantController from './participant/participant'; import type { OpenSchemaCommandArgs } from './participant/prompts/schema'; +import { QueryWithCopilotCodeLensProvider } from './editors/queryWithCopilotCodeLensProvider'; +import type { + SendMessageToParticipantOptions, + SendMessageToParticipantFromInputOptions, +} from './participant/participantTypes'; // This class is the top-level controller for our extension. // Commands which the extensions handles are defined in the function `activate`. @@ -68,6 +73,7 @@ export default class MDBExtensionController implements vscode.Disposable { _languageServerController: LanguageServerController; _webviewController: WebviewController; _playgroundResultViewProvider: PlaygroundResultProvider; + _queryWithCopilotCodeLensProvider: QueryWithCopilotCodeLensProvider; _activeConnectionCodeLensProvider: ActiveConnectionCodeLensProvider; _editDocumentCodeLensProvider: EditDocumentCodeLensProvider; _exportToLanguageCodeLensProvider: ExportToLanguageCodeLensProvider; @@ -106,6 +112,8 @@ export default class MDBExtensionController implements vscode.Disposable { this._connectionController, this._editDocumentCodeLensProvider ); + this._queryWithCopilotCodeLensProvider = + new QueryWithCopilotCodeLensProvider(); this._activeConnectionCodeLensProvider = new ActiveConnectionCodeLensProvider(this._connectionController); this._exportToLanguageCodeLensProvider = @@ -143,6 +151,7 @@ export default class MDBExtensionController implements vscode.Disposable { playgroundDiagnosticsCodeActionProvider: this._playgroundDiagnosticsCodeActionProvider, editDocumentCodeLensProvider: this._editDocumentCodeLensProvider, + queryWithCopilotCodeLensProvider: this._queryWithCopilotCodeLensProvider, }); this._webviewController = new WebviewController({ connectionController: this._connectionController, @@ -306,6 +315,22 @@ export default class MDBExtensionController implements vscode.Disposable { }); } ); + this.registerParticipantCommand( + EXTENSION_COMMANDS.SEND_MESSAGE_TO_PARTICIPANT, + async (options: SendMessageToParticipantOptions) => { + await this._participantController.sendMessageToParticipant(options); + return true; + } + ); + this.registerParticipantCommand( + EXTENSION_COMMANDS.SEND_MESSAGE_TO_PARTICIPANT_FROM_INPUT, + async (options: SendMessageToParticipantFromInputOptions) => { + await this._participantController.sendMessageToParticipantFromInput( + options + ); + return true; + } + ); this.registerParticipantCommand( EXTENSION_COMMANDS.RUN_PARTICIPANT_CODE, ({ runnableContent }: RunParticipantCodeCommandArgs) => { diff --git a/src/participant/participant.ts b/src/participant/participant.ts index c8ee509c3..a0463490d 100644 --- a/src/participant/participant.ts +++ b/src/participant/participant.ts @@ -46,6 +46,10 @@ import type { PromptIntent } from './prompts/intent'; import type { DataService } from 'mongodb-data-service'; import { ParticipantErrorTypes } from './participantErrorTypes'; import { PromptHistory } from './prompts/promptHistory'; +import type { + SendMessageToParticipantOptions, + SendMessageToParticipantFromInputOptions, +} from './participantTypes'; const log = createLogger('participant'); @@ -121,9 +125,46 @@ export default class ParticipantController { * in the chat. To work around this, we can write a message as the user, which will * trigger the chat handler and give us access to the model. */ - writeChatMessageAsUser(message: string): Thenable { + async sendMessageToParticipant( + options: SendMessageToParticipantOptions + ): Promise { + const { message, isNewChat = false, isPartialQuery = false } = options; + + if (isNewChat) { + await vscode.commands.executeCommand('workbench.action.chat.newChat'); + await vscode.commands.executeCommand( + 'workbench.action.chat.clearHistory' + ); + } + return vscode.commands.executeCommand('workbench.action.chat.open', { query: `@MongoDB ${message}`, + isPartialQuery, + }); + } + + async sendMessageToParticipantFromInput( + options: SendMessageToParticipantFromInputOptions + ): Promise { + const { + messagePrefix = '', + isNewChat = false, + isPartialQuery = false, + ...inputBoxOptions + } = options; + + const message = await vscode.window.showInputBox({ + ...inputBoxOptions, + }); + + if (message === undefined || message.trim() === '') { + return Promise.resolve(); + } + + return this.sendMessageToParticipant({ + message: `${messagePrefix ? `${messagePrefix} ` : ''}${message}`, + isNewChat, + isPartialQuery, }); } @@ -444,9 +485,9 @@ export default class ParticipantController { const connectionName = this._connectionController.getActiveConnectionName(); - return this.writeChatMessageAsUser( - `${command ? `${command} ` : ''}${connectionName}` - ) as Promise; + return this.sendMessageToParticipant({ + message: `${command ? `${command} ` : ''}${connectionName}`, + }) as Promise; } getConnectionsTree(command: ParticipantCommand): vscode.MarkdownString[] { @@ -485,7 +526,7 @@ export default class ParticipantController { const dataService = this._connectionController.getActiveDataService(); if (!dataService) { // Run a blank command to get the user to connect first. - void this.writeChatMessageAsUser(command); + void this.sendMessageToParticipant({ message: command }); return []; } @@ -533,9 +574,9 @@ export default class ParticipantController { databaseName: databaseName, }); - return this.writeChatMessageAsUser( - `${command} ${databaseName}` - ) as Promise; + return this.sendMessageToParticipant({ + message: `${command} ${databaseName}`, + }) as Promise; } async getCollectionQuickPicks({ @@ -548,7 +589,7 @@ export default class ParticipantController { const dataService = this._connectionController.getActiveDataService(); if (!dataService) { // Run a blank command to get the user to connect first. - void this.writeChatMessageAsUser(command); + void this.sendMessageToParticipant({ message: command }); return []; } @@ -609,9 +650,9 @@ export default class ParticipantController { databaseName: databaseName, collectionName: collectionName, }); - return this.writeChatMessageAsUser( - `${command} ${collectionName}` - ) as Promise; + return this.sendMessageToParticipant({ + message: `${command} ${collectionName}`, + }) as Promise; } renderDatabasesTree({ diff --git a/src/participant/participantTypes.ts b/src/participant/participantTypes.ts new file mode 100644 index 000000000..d28b5f1b3 --- /dev/null +++ b/src/participant/participantTypes.ts @@ -0,0 +1,12 @@ +import type * as vscode from 'vscode'; + +export type SendMessageToParticipantOptions = { + message: string; + isNewChat?: boolean; + isPartialQuery?: boolean; +}; + +export type SendMessageToParticipantFromInputOptions = { + messagePrefix?: string; +} & Omit & + vscode.InputBoxOptions; diff --git a/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts b/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts index 0af23e134..4e2de73b2 100644 --- a/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts +++ b/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts @@ -61,9 +61,7 @@ suite('Active Connection CodeLens Provider Test Suite', () => { expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); - expect(codeLens[0].command?.title).to.be.equal( - 'Disconnected. Click here to connect.' - ); + expect(codeLens[0].command?.title).to.be.equal('Connect'); expect(codeLens[0].range.start.line).to.be.equal(0); expect(codeLens[0].range.end.line).to.be.equal(0); }); @@ -111,9 +109,7 @@ suite('Active Connection CodeLens Provider Test Suite', () => { expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); - expect(codeLens[0].command?.title).to.be.equal( - 'Currently connected to fakeName. Click here to change connection.' - ); + expect(codeLens[0].command?.title).to.be.equal('Connected to fakeName'); expect(codeLens[0].range.start.line).to.be.equal(0); expect(codeLens[0].range.end.line).to.be.equal(0); expect(codeLens[0].command?.command).to.be.equal( @@ -133,7 +129,7 @@ suite('Active Connection CodeLens Provider Test Suite', () => { expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); expect(codeLens[0].command?.title).to.be.equal( - 'Currently connected to fakeName with default database fakeDBName. Click here to change connection.' + 'Connected to fakeName with default database fakeDBName' ); expect(codeLens[0].range.start.line).to.be.equal(0); expect(codeLens[0].range.end.line).to.be.equal(0); diff --git a/src/test/suite/editors/queryWithCopilotCodeLensProvider.test.ts b/src/test/suite/editors/queryWithCopilotCodeLensProvider.test.ts new file mode 100644 index 000000000..4435dd685 --- /dev/null +++ b/src/test/suite/editors/queryWithCopilotCodeLensProvider.test.ts @@ -0,0 +1,133 @@ +import * as vscode from 'vscode'; +import { beforeEach, afterEach } from 'mocha'; +import { expect } from 'chai'; +import sinon from 'sinon'; +import path from 'path'; +import { QueryWithCopilotCodeLensProvider } from '../../../editors/queryWithCopilotCodeLensProvider'; +import EXTENSION_COMMANDS from '../../../commands'; + +suite('Query with Copilot CodeLens Provider Test Suite', () => { + let testCodeLensProvider: QueryWithCopilotCodeLensProvider; + const sandbox = sinon.createSandbox(); + + const mockExtensionChangeEmitter: vscode.EventEmitter = + new vscode.EventEmitter(); + + beforeEach(() => { + sandbox.replaceGetter( + vscode.extensions, + 'onDidChange', + () => mockExtensionChangeEmitter.event + ); + + testCodeLensProvider = new QueryWithCopilotCodeLensProvider(); + }); + + afterEach(() => { + sandbox.restore(); + }); + + suite('the MongoDB playground in JS', () => { + const mockFileName = path.join('nonexistent', 'playground-test.mongodb.js'); + const mockDocumentUri = vscode.Uri.from({ + path: mockFileName, + scheme: 'untitled', + }); + const mockTextDoc: vscode.TextDocument = { + uri: mockDocumentUri, + } as Pick as vscode.TextDocument; + + suite('does not have the copilot extension', () => { + beforeEach(() => { + sandbox.stub(vscode.extensions, 'getExtension').returns(undefined); + }); + + test('should not show the codelens', () => { + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); + + expect(codeLens).to.be.an('array'); + expect(codeLens.length).to.be.equal(0); + }); + }); + + suite('has the extension but it is not active', () => { + test('should not show the codelens', () => { + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); + + expect(codeLens).to.be.an('array'); + expect(codeLens.length).to.be.equal(0); + }); + }); + + suite('has the copilot extension active', () => { + beforeEach(() => { + sandbox.stub(vscode.extensions, 'getExtension').returns({ + isActive: true, + } as vscode.Extension); + }); + + test('should show the codelens', () => { + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); + + expect(codeLens).to.be.an('array'); + expect(codeLens.length).to.be.equal(1); + expect(codeLens[0].command?.title).to.be.equal( + '✨ Generate query with MongoDB Copilot' + ); + expect(codeLens[0].range.start.line).to.be.equal(0); + expect(codeLens[0].range.end.line).to.be.equal(0); + expect(codeLens[0].command?.command).to.be.equal( + EXTENSION_COMMANDS.SEND_MESSAGE_TO_PARTICIPANT_FROM_INPUT + ); + }); + }); + + suite('on extensions list changes', function () { + test('calls onDidChangeCodeLenses', function () { + const extensionListChanged = sinon.stub(); + testCodeLensProvider.onDidChangeCodeLenses(extensionListChanged); + + mockExtensionChangeEmitter.fire(); + + expect(extensionListChanged).calledOnce; + }); + }); + }); + + suite('the regular JS file', () => { + const mockFileName = path.join('nonexistent', 'playground-test.js'); + const mockDocumentUri = vscode.Uri.from({ + path: mockFileName, + scheme: 'untitled', + }); + const mockTextDoc: vscode.TextDocument = { + uri: mockDocumentUri, + } as Pick as vscode.TextDocument; + + suite('does not have the copilot extension', () => { + beforeEach(() => { + sandbox.stub(vscode.extensions, 'getExtension').returns(undefined); + }); + + test('should not show the codelens', () => { + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); + + expect(codeLens).to.be.an('array'); + expect(codeLens.length).to.be.equal(0); + }); + }); + + suite('has the copilot extension active', () => { + beforeEach(() => { + sandbox.stub(vscode.extensions, 'getExtension').returns(undefined); + }); + + test('should not show the codelens', () => { + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); + + expect(codeLens).to.be.an('array'); + expect(codeLens.length).to.be.equal(0); + }); + }); + }); +}); From 474beb3d2110766fb7ec2da64e224e0905c3c0e2 Mon Sep 17 00:00:00 2001 From: gagik Date: Fri, 22 Nov 2024 14:46:23 +0100 Subject: [PATCH 03/14] revert vscode change --- .vscode/settings.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 32baf6163..732bb7406 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ // Place your settings in this file to overwrite default and user settings. { + "editor.formatOnSave": false, "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, From e915b3fcd8c8d218b9e74b90e68d7480892a2106 Mon Sep 17 00:00:00 2001 From: gagik Date: Fri, 22 Nov 2024 14:47:27 +0100 Subject: [PATCH 04/14] wording change --- src/editors/queryWithCopilotCodeLensProvider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/editors/queryWithCopilotCodeLensProvider.ts b/src/editors/queryWithCopilotCodeLensProvider.ts index 72caec139..e5a47dae0 100644 --- a/src/editors/queryWithCopilotCodeLensProvider.ts +++ b/src/editors/queryWithCopilotCodeLensProvider.ts @@ -20,11 +20,11 @@ export class QueryWithCopilotCodeLensProvider // We can only detect whether a user has the Copilot extension active // but not whether it has an active subscription. - const hasCopilotInstalled = + const hasCopilotChatActive = vscode.extensions.getExtension(COPILOT_CHAT_EXTENSION_ID)?.isActive === true; - if (!hasCopilotInstalled) { + if (!hasCopilotChatActive) { return []; } From e17008f0acd41285c82898350f9e85bd7c6f41ac Mon Sep 17 00:00:00 2001 From: gagik Date: Mon, 25 Nov 2024 11:29:32 +0100 Subject: [PATCH 05/14] Add icons to connect to MongoDB --- fonts/mongodb-icons.woff | Bin 0 -> 1204 bytes package-lock.json | 754 ++++++++++++++++++ package.json | 20 +- scripts/generate-icon-font.ts | 63 ++ .../activeConnectionCodeLensProvider.ts | 6 +- 5 files changed, 839 insertions(+), 4 deletions(-) create mode 100644 fonts/mongodb-icons.woff create mode 100644 scripts/generate-icon-font.ts diff --git a/fonts/mongodb-icons.woff b/fonts/mongodb-icons.woff new file mode 100644 index 0000000000000000000000000000000000000000..fdac68fa6458958744bae19eefbbb54f286493c7 GIT binary patch literal 1204 zcmXT-cXMN4WB>w|EezZsn*9re4`QPN_ux<`1_nkBplAvZuTo4^GxZPFHv)>~0Qsgs zoZy-4;FFx2SO64T0_1OEU|_QOrn;FwJ*P4a$c_Mt`GVA4R4xk3NKFKq!?Xg(R|R6T zcqLob44@!T>;jN42E-~1oD6~)xg`}qu@^wT01z8609}xipA1s>11cuP$j0y?H?aa} zFEhw}@<6P>D9Ip`mzbLh6w?5@#|Eh0KlSGdrC;MXD{mXqLY(WzeW^yUtheVWN0J>KH`o@HOUzRdWt<_5;1 zLQ%m(lN(+tnyc8S&;N5`#n+jW=XkiD?QNSjud(pdv&h}6Z>yTCd=GZqzUJ{Hwl^Z` z%M(`5QBq}}d%9%DkD|l*U;BEJyk}=@R{daZwe06RZSOTjWsAzLsPFyP^mR+&noZX> za#mLdJxhs)e z@xS}#S#ge^6^#jt4Bl8Y2EKZG@%3dd-o&KUKcj_D=U5cz-u`_$@KAA^_RMV@Q?p)w zW_)49vI`sr;P_#9#AMp`{No?9c*z}-5fU31#Wq;5GYfYxGqkQ@c0i~DhO>i`q+|di zKLg_g25FFck`ox1#5B~HfGMGZffK?vWMlT>U=Ufs_#GDii2?};X$*{N3eT9F*xLRl z*fBG3Co`G>_18`~>vzaO#BIORL64&|GI|P4^X|-;GJmcPr&Gj+#Dn{$WHxRwK3k%Y z__p{5i%t8!HvfnBPFDyscb-!zKWF>-Ze|ce_>YG6!=EmceBGdBvG`s4Y8Ue}b|0CG zc^RFaS?PT^bLW6?+zjTJ#S6r3{?9pM8#hyX#}Vn`sek6(RIf{4_fTy9nbJECyLUFu zyq?1M;l)wmwL!Kox(nBYT26hb)_rE8bynJ?DcWmY)N?kMSE)=jnK+f(@P22}?6S4K zE=eVNZBdakQ=>%O)~DtiUb@wF{Z+3U?HkV-Hnur=l{VP19P5~?Y1pc=-?5G3+59{A z&5f%LUf5Z**P*?x`nSse*>ZtVJ3Be1on!SqvvF}$lJ`%&$nKV3Ek;t77cZQZyCj+G zyR4u*+sN>zfVX+*f_AaDPgLZ0t$%+1V^C%gFzilP1Ji;4!^OEju19#BdpJ|2MI^Iq z_Jq&cHzF+09uQXlUnwJN%d9MH%&jdwFSajbmF3l>s$=Q8?foLPy)6q=10.0.0" + } + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -6649,6 +6675,13 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "dev": true, + "license": "MIT" + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -6939,6 +6972,13 @@ "node": ">=8" } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -7650,6 +7690,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-callsite/node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/callsite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", @@ -7679,6 +7755,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys/node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001669", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", @@ -8436,6 +8550,13 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, + "node_modules/cubic2quad": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cubic2quad/-/cubic2quad-1.2.1.tgz", + "integrity": "sha512-wT5Y7mO8abrV16gnssKdmIhIbA9wSkeMzhh27jAguKrV82i24wER0vL5TGhUJ9dbJNDcigoRZ0IAHFEEEI4THQ==", + "dev": true, + "license": "MIT" + }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", @@ -8492,6 +8613,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", @@ -11510,6 +11668,13 @@ "node": ">=6.9.0" } }, + "node_modules/geometry-interfaces": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/geometry-interfaces/-/geometry-interfaces-1.1.4.tgz", + "integrity": "sha512-qD6OdkT6NcES9l4Xx3auTpwraQruU7dARbQPVO71MKvkGYw5/z/oIiGymuFXrRaEQa5Y67EIojUpaLeGEa5hGA==", + "dev": true, + "license": "MIT" + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -11938,6 +12103,16 @@ "lodash": "^4.17.21" } }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -12403,6 +12578,16 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -12813,6 +12998,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -12968,6 +13163,16 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -13887,6 +14092,19 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -13999,6 +14217,72 @@ "node": ">= 0.10.0" } }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -14026,6 +14310,13 @@ "node": ">= 0.6" } }, + "node_modules/microbuffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/microbuffer/-/microbuffer-1.0.0.tgz", + "integrity": "sha512-O/SUXauVN4x6RaEJFqSPcXNtLFL+QzJHKZlyDVYFwcDDRVca3Fa/37QXXC+4zAGGa4YhHrHxKXuuHvLDIQECtA==", + "dev": true, + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -14103,6 +14394,16 @@ "node": ">=4" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -14135,6 +14436,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -14945,6 +15271,16 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "node_modules/neatequal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/neatequal/-/neatequal-1.0.0.tgz", + "integrity": "sha512-sVt5awO4a4w24QmAthdrCPiVRW3naB8FGLdyadin01BH+6BzNPEBwGrpwCczQvPlULS6uXTItTe1PJ5P0kYm7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "varstream": "^0.3.2" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -15438,6 +15774,42 @@ "node": "*" } }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -16875,6 +17247,60 @@ "node": ">=4" } }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/read-pkg/node_modules/path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -16931,6 +17357,20 @@ "node": ">= 10.13.0" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/redux": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", @@ -18368,6 +18808,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -18429,6 +18882,108 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg-pathdata": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", + "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/svg2ttf": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-6.0.3.tgz", + "integrity": "sha512-CgqMyZrbOPpc+WqH7aga4JWkDPso23EgypLsbQ6gN3uoPWwwiLjXvzgrwGADBExvCRJrWFzAeK1bSoSpE7ixSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.7.2", + "argparse": "^2.0.1", + "cubic2quad": "^1.2.1", + "lodash": "^4.17.10", + "microbuffer": "^1.0.0", + "svgpath": "^2.1.5" + }, + "bin": { + "svg2ttf": "svg2ttf.js" + } + }, + "node_modules/svg2ttf/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/svgicons2svgfont": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-10.0.6.tgz", + "integrity": "sha512-fUgQEVg3XwTbOHvlXahHGqCet5Wvfo1bV4DCvbSRvjsOCPCRunYbG4dUJCPegps37BMph3eOrfoobhH5AWuC6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^7.2.0", + "geometry-interfaces": "^1.1.4", + "glob": "^7.1.6", + "neatequal": "^1.0.0", + "readable-stream": "^3.4.0", + "sax": "^1.2.4", + "svg-pathdata": "^6.0.0" + }, + "bin": { + "svgicons2svgfont": "bin/svgicons2svgfont.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/svgicons2svgfont/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/svgicons2svgfont/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/svgicons2svgfont/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/svgpath": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.6.0.tgz", + "integrity": "sha512-OIWR6bKzXvdXYyO4DK/UWa1VA1JeKq8E+0ug2DG98Y/vOmMpfZNj+TIG988HjfYSqtcy/hFOtZq/n/j5GSESNg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/fontello/svg2ttf?sponsor=1" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -18952,6 +19507,16 @@ "node": ">=18" } }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/triple-beam": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", @@ -19082,6 +19647,35 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/ttf2eot": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-2.0.0.tgz", + "integrity": "sha512-U56aG2Ylw7psLOmakjemAzmpqVgeadwENg9oaDjaZG5NYX4WB6+7h74bNPcc+0BXsoU5A/XWiHabDXyzFOmsxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.6", + "microbuffer": "^1.0.0" + }, + "bin": { + "ttf2eot": "ttf2eot.js" + } + }, + "node_modules/ttf2woff": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-2.0.2.tgz", + "integrity": "sha512-X68badwBjAy/+itU49scLjXUL094up+rHuYk+YAOTTBYSUMOmLZ7VyhZJuqQESj1gnyLAC2/5V8Euv+mExmyPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.6", + "microbuffer": "^1.0.0", + "pako": "^1.0.0" + }, + "bin": { + "ttf2woff": "ttf2woff.js" + } + }, "node_modules/tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -19475,6 +20069,22 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/varstream": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/varstream/-/varstream-0.3.2.tgz", + "integrity": "sha512-OpR3Usr9dGZZbDttlTxdviGdxiURI0prX68+DuaN/JfIDbK9ZOmREKM6PgmelsejMnhgjXmEEEgf+E4NbsSqMg==", + "dev": true, + "dependencies": { + "readable-stream": "^1.0.33" + }, + "bin": { + "json2varstream": "cli/json2varstream.js", + "varstream2json": "cli/varstream2json.js" + }, + "engines": { + "node": ">=0.10.*" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -19590,6 +20200,27 @@ "node": ">=10.13.0" } }, + "node_modules/wawoff2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wawoff2/-/wawoff2-2.0.1.tgz", + "integrity": "sha512-r0CEmvpH63r4T15ebFqeOjGqU4+EgTx4I510NtK35EMciSdcTxCw3Byy3JnBonz7iyIFZ0AbVo0bbFpEVuhCYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "woff2_compress.js": "bin/woff2_compress.js", + "woff2_decompress.js": "bin/woff2_decompress.js" + } + }, + "node_modules/wawoff2/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -19607,6 +20238,129 @@ "node": ">= 8" } }, + "node_modules/webfont": { + "version": "11.2.26", + "resolved": "https://registry.npmjs.org/webfont/-/webfont-11.2.26.tgz", + "integrity": "sha512-ms9abzcJGMBj5yVTpNfAcyQB0SNzmi10aBlKLC7kAt1TQ5eZqieRhvhxN1BrXaizWV0nksp6vLqBfaJmBWmF7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^5.2.0", + "deepmerge": "^4.2.2", + "globby": "^11.0.0", + "meow": "^9.0.0", + "nunjucks": "^3.2.3", + "p-limit": "^3.1.0", + "parse-json": "^5.2.0", + "resolve-from": "^5.0.0", + "svg2ttf": "^6.0.2", + "svgicons2svgfont": "^10.0.3", + "ttf2eot": "^2.0.0", + "ttf2woff": "^2.0.2", + "wawoff2": "^2.0.0", + "xml2js": "^0.4.23" + }, + "bin": { + "webfont": "dist/cli.js" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/webfont/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webfont/node_modules/cosmiconfig/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webfont/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webfont/node_modules/import-fresh/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/webfont/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webfont/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/webfont/node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/package.json b/package.json index aa670b06c..e677313e1 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "release-draft": "node ./scripts/release-draft.js", "reformat": "prettier --write .", "snyk-test": "node scripts/snyk-test.js", + "generate-icon-font": "ts-node ./scripts/generate-icon-font.ts", "generate-vulnerability-report": "mongodb-sbom-tools generate-vulnerability-report --snyk-reports=.sbom/snyk-test-result.json --dependencies=.sbom/dependencies.json --fail-on=high", "create-vulnerability-tickets": "mongodb-sbom-tools generate-vulnerability-report --snyk-reports=.sbom/snyk-test-result.json --dependencies=.sbom/dependencies.json --create-jira-issues", "prepare": "husky", @@ -1154,6 +1155,22 @@ "description": "Specify a shell command that is run to start the browser for authenticating with the OIDC identity provider for the server connection. Leave this empty for default browser." } } + }, + "icons": { + "connection-active": { + "description": "MongoDB Icon", + "default": { + "fontPath": "./fonts/mongodb-icons.woff", + "fontCharacter": "\\ea01" + } + }, + "connection-inactive": { + "description": "MongoDB Icon", + "default": { + "fontPath": "./fonts/mongodb-icons.woff", + "fontCharacter": "\\ea02" + } + } } }, "dependencies": { @@ -1198,7 +1215,6 @@ "@mongodb-js/oidc-mock-provider": "^0.10.1", "@mongodb-js/oidc-plugin": "^0.4.0", "@mongodb-js/prettier-config-devtools": "^1.0.1", - "mongodb-rag-core": "^0.4.1", "@mongodb-js/sbom-tools": "^0.7.2", "@mongodb-js/signing-utils": "^0.3.6", "@mongosh/service-provider-core": "^2.3.3", @@ -1241,6 +1257,7 @@ "mocha-junit-reporter": "^2.2.1", "mocha-multi": "^1.1.7", "mongodb-client-encryption": "^6.1.0", + "mongodb-rag-core": "^0.4.1", "mongodb-runner": "^5.7.0", "node-fetch": "^2.7.0", "node-loader": "^0.6.0", @@ -1260,6 +1277,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.2", "typescript": "^4.9.5", + "webfont": "^11.2.26", "webpack": "^5.95.0", "webpack-bundle-analyzer": "^4.10.2", "webpack-cli": "^5.1.4", diff --git a/scripts/generate-icon-font.ts b/scripts/generate-icon-font.ts new file mode 100644 index 000000000..9f9ce3d8f --- /dev/null +++ b/scripts/generate-icon-font.ts @@ -0,0 +1,63 @@ +import webfont from 'webfont'; +import fs from 'fs/promises'; +import { GlyphData } from 'webfont/dist/src/types'; + +/** Icons to include in the generated icon font */ +const INCLUDED_ICONS = ['connection-active', 'connection-inactive']; + +/** + * Generates an icon font from the included icons and outputs package.json + * configuration field for those icons as specified in + * https://code.visualstudio.com/api/references/icons-in-labels + */ +async function main(): Promise { + const font = await webfont({ + files: INCLUDED_ICONS.map((icon) => `./images/light/${icon}.svg`), + fontName: 'MongoDB Icons', + formats: ['woff'], + normalize: true, + centerHorizontally: true, + }); + + if (!font.woff) { + throw new Error('Error occurred generating template'); + } + + await fs.writeFile('./fonts/mongodb-icons.woff', font.woff); + + const iconsConfig = {}; + font.glyphsData?.forEach((glyph) => { + if (!glyph.metadata?.name) { + throw new Error('There is a glyph without a name'); + } + iconsConfig[glyph.metadata.name] = { + description: 'MongoDB Icon', + default: { + fontPath: './fonts/mongodb-icons.woff', + fontCharacter: getUnicodeHex(glyph), + }, + }; + }); + + // Prints out the VSCode configuration package.json + console.info( + JSON.stringify( + { + icons: iconsConfig, + }, + undefined, + 2 + ) + ); +} + +function getUnicodeHex(glyph: GlyphData): string { + if (glyph.metadata?.unicode == undefined) { + throw new Error('No unicode defined'); + } + const hex = glyph.metadata?.unicode[0].codePointAt(0)!.toString(16); + + return `\\${hex}`; +} + +main(); diff --git a/src/editors/activeConnectionCodeLensProvider.ts b/src/editors/activeConnectionCodeLensProvider.ts index c4c4cc7c9..efd240c2c 100644 --- a/src/editors/activeConnectionCodeLensProvider.ts +++ b/src/editors/activeConnectionCodeLensProvider.ts @@ -50,10 +50,10 @@ export default class ActiveConnectionCodeLensProvider ? getDBFromConnectionString(connectionString) : null; message = defaultDB - ? `Connected to ${this._connectionController.getActiveConnectionName()} with default database ${defaultDB}` - : `Connected to ${this._connectionController.getActiveConnectionName()}`; + ? `$(connection-active)Connected to ${this._connectionController.getActiveConnectionName()} with default database ${defaultDB}` + : `$(connection-active)Connected to ${this._connectionController.getActiveConnectionName()}`; } else { - message = 'Connect'; + message = '$(connection-inactive)Connect'; } codeLens.command = { From 27f0aad56abe9eda9367363303b09ee0e8631cd9 Mon Sep 17 00:00:00 2001 From: gagik Date: Mon, 25 Nov 2024 11:37:48 +0100 Subject: [PATCH 06/14] Fix tests --- .../editors/activeConnectionCodeLensProvider.test.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts b/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts index 4e2de73b2..b74bb83e7 100644 --- a/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts +++ b/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts @@ -61,7 +61,9 @@ suite('Active Connection CodeLens Provider Test Suite', () => { expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); - expect(codeLens[0].command?.title).to.be.equal('Connect'); + expect(codeLens[0].command?.title).to.be.equal( + '$(connection-inactive)Connect' + ); expect(codeLens[0].range.start.line).to.be.equal(0); expect(codeLens[0].range.end.line).to.be.equal(0); }); @@ -109,7 +111,9 @@ suite('Active Connection CodeLens Provider Test Suite', () => { expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); - expect(codeLens[0].command?.title).to.be.equal('Connected to fakeName'); + expect(codeLens[0].command?.title).to.be.equal( + '$(connection-active)Connected to fakeName' + ); expect(codeLens[0].range.start.line).to.be.equal(0); expect(codeLens[0].range.end.line).to.be.equal(0); expect(codeLens[0].command?.command).to.be.equal( @@ -129,7 +133,7 @@ suite('Active Connection CodeLens Provider Test Suite', () => { expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); expect(codeLens[0].command?.title).to.be.equal( - 'Connected to fakeName with default database fakeDBName' + '$(connection-active)Connected to fakeName with default database fakeDBName' ); expect(codeLens[0].range.start.line).to.be.equal(0); expect(codeLens[0].range.end.line).to.be.equal(0); From bce4de9bf3d872d5c2e11f97cef310af39957e25 Mon Sep 17 00:00:00 2001 From: gagik Date: Mon, 25 Nov 2024 14:29:13 +0100 Subject: [PATCH 07/14] check for copilot extension, not chat --- src/editors/queryWithCopilotCodeLensProvider.ts | 6 ++---- src/participant/constants.ts | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/editors/queryWithCopilotCodeLensProvider.ts b/src/editors/queryWithCopilotCodeLensProvider.ts index e5a47dae0..c7093db03 100644 --- a/src/editors/queryWithCopilotCodeLensProvider.ts +++ b/src/editors/queryWithCopilotCodeLensProvider.ts @@ -2,8 +2,7 @@ import * as vscode from 'vscode'; import EXTENSION_COMMANDS from '../commands'; import type { SendMessageToParticipantFromInputOptions } from '../participant/participantTypes'; import { isPlayground } from '../utils/playground'; - -const COPILOT_CHAT_EXTENSION_ID = 'GitHub.copilot-chat'; +import { COPILOT_EXTENSION_ID } from '../participant/constants'; export class QueryWithCopilotCodeLensProvider implements vscode.CodeLensProvider @@ -21,8 +20,7 @@ export class QueryWithCopilotCodeLensProvider // We can only detect whether a user has the Copilot extension active // but not whether it has an active subscription. const hasCopilotChatActive = - vscode.extensions.getExtension(COPILOT_CHAT_EXTENSION_ID)?.isActive === - true; + vscode.extensions.getExtension(COPILOT_EXTENSION_ID)?.isActive === true; if (!hasCopilotChatActive) { return []; diff --git a/src/participant/constants.ts b/src/participant/constants.ts index 90fd81490..1aeec079e 100644 --- a/src/participant/constants.ts +++ b/src/participant/constants.ts @@ -3,6 +3,7 @@ import { ChatMetadataStore } from './chatMetadata'; export const CHAT_PARTICIPANT_ID = 'mongodb.participant'; export const CHAT_PARTICIPANT_MODEL = 'gpt-4o'; +export const COPILOT_EXTENSION_ID = 'GitHub.copilot'; export type ParticipantResponseType = | 'query' From 99128f5a4cf96992522471070430a97a86461fbf Mon Sep 17 00:00:00 2001 From: gagik Date: Tue, 26 Nov 2024 13:41:49 +0100 Subject: [PATCH 08/14] Add namespacing --- fonts/mongodb-icons.woff | Bin 1204 -> 1244 bytes package.json | 4 ++-- scripts/generate-icon-font.ts | 2 +- .../activeConnectionCodeLensProvider.ts | 6 +++--- .../activeConnectionCodeLensProvider.test.ts | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/fonts/mongodb-icons.woff b/fonts/mongodb-icons.woff index fdac68fa6458958744bae19eefbbb54f286493c7..c12f6799b9969a9997c3059adb93b3cd4cb1513a 100644 GIT binary patch delta 529 zcmdnOd52S^+~3WOfsp|SSne=zgJ=$oi6Z9p)<9N*=Ol;xj8M1}2+t zs+;-Kb1Kt->=>X}2@p@Y?sdR5BQ-GvD0TtJR|jIVcwJkC44@!T><5r90mLc{N(}ND zxg`}049o&RJ_s8CMHzDPlY#1(6`*2LjMI!5i*geyfEF_w00rfNSb;Yz#nF~zV1vWSASaXIa!qH(? zHrHXswjbd>JWdXJ%FPB5GXz~H8ZaEHVdm~nf(?3sgH%?1K27v@GLb!_Wez$;g! zbtReCB=*mL`PauJXWYFk>~%UeEiy%Tyx7!eNw@3eWY~R;xa}&9_*K_b*GU>apV#y!I+DRNr6?2jk zQW6pv9vzw8XGCt86AM;)=oIj8M1}2+t zs+;-Kb1Kt->11cuP$Y#XwAvduCXfZQTnn50j6&NKMWbzVoQ-NX{ zKnK|XHTb7KpSz|YzqkbG`jm-($_!KH95`_5z<~oSEj$IY1e<0`M9h@j(9~dZU8Ief z=i~Yr5)lWO1SSc(PBdUxe}Kh|fnoA;#_jd0-GN*U20YG_w?zmZT>nV$&s~Y+ivQg= z&x&*WtY}PFWbnqKG4R#fi?1(x@g^p%{uwQNI>(|w_xA78frpCQv}bPPn40zaGvf;* zmR&%HR?JCGNJ&Uwc*JDd_Wa`?vv|oJk`WRc7{xYNurmvHFf+8SVRk^MOGxxfa8Qzz z3}EDEV4T1p4KaX$NlZhH3FyrV22PNH3`~Y>%sw0pA}bibLoIlaD3Fkl#=xki@Qlfc Ut?hq;9Ww)WGNajMf976B0GnTnIRF3v diff --git a/package.json b/package.json index e677313e1..86a2ce518 100644 --- a/package.json +++ b/package.json @@ -1157,14 +1157,14 @@ } }, "icons": { - "connection-active": { + "mdb-connection-active": { "description": "MongoDB Icon", "default": { "fontPath": "./fonts/mongodb-icons.woff", "fontCharacter": "\\ea01" } }, - "connection-inactive": { + "mdb-connection-inactive": { "description": "MongoDB Icon", "default": { "fontPath": "./fonts/mongodb-icons.woff", diff --git a/scripts/generate-icon-font.ts b/scripts/generate-icon-font.ts index 9f9ce3d8f..da65d96b2 100644 --- a/scripts/generate-icon-font.ts +++ b/scripts/generate-icon-font.ts @@ -30,7 +30,7 @@ async function main(): Promise { if (!glyph.metadata?.name) { throw new Error('There is a glyph without a name'); } - iconsConfig[glyph.metadata.name] = { + iconsConfig[`mdb-${glyph.metadata.name}`] = { description: 'MongoDB Icon', default: { fontPath: './fonts/mongodb-icons.woff', diff --git a/src/editors/activeConnectionCodeLensProvider.ts b/src/editors/activeConnectionCodeLensProvider.ts index efd240c2c..cb34e90fd 100644 --- a/src/editors/activeConnectionCodeLensProvider.ts +++ b/src/editors/activeConnectionCodeLensProvider.ts @@ -50,10 +50,10 @@ export default class ActiveConnectionCodeLensProvider ? getDBFromConnectionString(connectionString) : null; message = defaultDB - ? `$(connection-active)Connected to ${this._connectionController.getActiveConnectionName()} with default database ${defaultDB}` - : `$(connection-active)Connected to ${this._connectionController.getActiveConnectionName()}`; + ? `$(mdb-connection-active)Connected to ${this._connectionController.getActiveConnectionName()} with default database ${defaultDB}` + : `$(mdb-connection-active)Connected to ${this._connectionController.getActiveConnectionName()}`; } else { - message = '$(connection-inactive)Connect'; + message = '$(mdb-connection-inactive)Connect'; } codeLens.command = { diff --git a/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts b/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts index b74bb83e7..05a65ca53 100644 --- a/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts +++ b/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts @@ -62,7 +62,7 @@ suite('Active Connection CodeLens Provider Test Suite', () => { expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); expect(codeLens[0].command?.title).to.be.equal( - '$(connection-inactive)Connect' + '$(mdb-connection-inactive)Connect' ); expect(codeLens[0].range.start.line).to.be.equal(0); expect(codeLens[0].range.end.line).to.be.equal(0); @@ -112,7 +112,7 @@ suite('Active Connection CodeLens Provider Test Suite', () => { expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); expect(codeLens[0].command?.title).to.be.equal( - '$(connection-active)Connected to fakeName' + '$(mdb-connection-active)Connected to fakeName' ); expect(codeLens[0].range.start.line).to.be.equal(0); expect(codeLens[0].range.end.line).to.be.equal(0); @@ -133,7 +133,7 @@ suite('Active Connection CodeLens Provider Test Suite', () => { expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); expect(codeLens[0].command?.title).to.be.equal( - '$(connection-active)Connected to fakeName with default database fakeDBName' + '$(mdb-connection-active)Connected to fakeName with default database fakeDBName' ); expect(codeLens[0].range.start.line).to.be.equal(0); expect(codeLens[0].range.end.line).to.be.equal(0); From b7f961898bddfc5e4c4076d1bdfe7b22c4f3db44 Mon Sep 17 00:00:00 2001 From: gagik Date: Wed, 27 Nov 2024 09:47:10 +0100 Subject: [PATCH 09/14] add codelens telemetry --- src/editors/queryWithCopilotCodeLensProvider.ts | 1 + src/participant/participant.ts | 5 +++++ src/participant/participantTypes.ts | 1 + src/telemetry/telemetryService.ts | 12 ++++++++++++ 4 files changed, 19 insertions(+) diff --git a/src/editors/queryWithCopilotCodeLensProvider.ts b/src/editors/queryWithCopilotCodeLensProvider.ts index c7093db03..2df01871d 100644 --- a/src/editors/queryWithCopilotCodeLensProvider.ts +++ b/src/editors/queryWithCopilotCodeLensProvider.ts @@ -32,6 +32,7 @@ export class QueryWithCopilotCodeLensProvider 'e.g. Find the document in sample_mflix.users with the name of Kayden Washington', messagePrefix: '/query', isNewChat: true, + source: 'query with copilot codelens', }; return [ diff --git a/src/participant/participant.ts b/src/participant/participant.ts index b59139c95..f39cec2bc 100644 --- a/src/participant/participant.ts +++ b/src/participant/participant.ts @@ -159,9 +159,14 @@ export default class ParticipantController { messagePrefix = '', isNewChat = false, isPartialQuery = false, + source, ...inputBoxOptions } = options; + this._telemetryService.trackCopilotParticipantSubmittedFromInputBox({ + source, + }); + const message = await vscode.window.showInputBox({ ...inputBoxOptions, }); diff --git a/src/participant/participantTypes.ts b/src/participant/participantTypes.ts index d28b5f1b3..dbf6787c8 100644 --- a/src/participant/participantTypes.ts +++ b/src/participant/participantTypes.ts @@ -8,5 +8,6 @@ export type SendMessageToParticipantOptions = { export type SendMessageToParticipantFromInputOptions = { messagePrefix?: string; + source?: 'query with copilot codelens'; } & Omit & vscode.InputBoxOptions; diff --git a/src/telemetry/telemetryService.ts b/src/telemetry/telemetryService.ts index 1d4238e66..1b1e92869 100644 --- a/src/telemetry/telemetryService.ts +++ b/src/telemetry/telemetryService.ts @@ -130,6 +130,10 @@ export type CopilotIntroductionProperties = { is_copilot_active: boolean; }; +export type ParticipantOpenedFromInputBoxProperties = { + source?: 'query with copilot codelens'; +}; + export function chatResultFeedbackKindToTelemetryValue( kind: vscode.ChatResultFeedbackKind ): TelemetryFeedbackKind { @@ -161,6 +165,7 @@ type TelemetryEventProperties = | ParticipantFeedbackProperties | ParticipantResponseFailedProperties | ParticipantPromptProperties + | ParticipantOpenedFromInputBoxProperties | ParticipantResponseProperties | CopilotIntroductionProperties; @@ -186,6 +191,7 @@ export enum TelemetryEventTypes { PARTICIPANT_RESPONSE_FAILED = 'Participant Response Failed', PARTICIPANT_PROMPT_SUBMITTED = 'Participant Prompt Submitted', PARTICIPANT_RESPONSE_GENERATED = 'Participant Response Generated', + PARTICIPANT_SUBMITTED_FROM_INPUT_BOX = 'Participant Submitted From Input Box', COPILOT_INTRODUCTION_CLICKED = 'Copilot Introduction Clicked', COPILOT_INTRODUCTION_DISMISSED = 'Copilot Introduction Dismissed', } @@ -440,6 +446,12 @@ export default class TelemetryService { this.track(TelemetryEventTypes.PARTICIPANT_FEEDBACK, props); } + trackCopilotParticipantSubmittedFromInputBox( + props: ParticipantOpenedFromInputBoxProperties + ): void { + this.track(TelemetryEventTypes.PARTICIPANT_SUBMITTED_FROM_INPUT_BOX, props); + } + trackCopilotParticipantError(err: any, command: string): void { let errorCode: string | undefined; let errorName: ParticipantErrorTypes; From a9c2836f3be67be2cababf768d8fd72611f02fb1 Mon Sep 17 00:00:00 2001 From: Gagik Amaryan Date: Wed, 27 Nov 2024 16:31:58 +0100 Subject: [PATCH 10/14] Update src/editors/queryWithCopilotCodeLensProvider.ts Co-authored-by: Alena Khineika --- src/editors/queryWithCopilotCodeLensProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/editors/queryWithCopilotCodeLensProvider.ts b/src/editors/queryWithCopilotCodeLensProvider.ts index 2df01871d..5e68f830c 100644 --- a/src/editors/queryWithCopilotCodeLensProvider.ts +++ b/src/editors/queryWithCopilotCodeLensProvider.ts @@ -27,7 +27,7 @@ export class QueryWithCopilotCodeLensProvider } const options: SendMessageToParticipantFromInputOptions = { - prompt: 'Describe the query you would like to generate.', + prompt: 'Describe the query you would like to generate', placeHolder: 'e.g. Find the document in sample_mflix.users with the name of Kayden Washington', messagePrefix: '/query', From b0ca54309ed5eac593d87f37671acf6068ea8423 Mon Sep 17 00:00:00 2001 From: gagik Date: Thu, 28 Nov 2024 13:14:16 +0100 Subject: [PATCH 11/14] use DocumentSource --- src/participant/participantTypes.ts | 3 ++- src/telemetry/telemetryService.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/participant/participantTypes.ts b/src/participant/participantTypes.ts index dbf6787c8..3d271b2a1 100644 --- a/src/participant/participantTypes.ts +++ b/src/participant/participantTypes.ts @@ -1,4 +1,5 @@ import type * as vscode from 'vscode'; +import type { DocumentSource } from '../documentSource'; export type SendMessageToParticipantOptions = { message: string; @@ -8,6 +9,6 @@ export type SendMessageToParticipantOptions = { export type SendMessageToParticipantFromInputOptions = { messagePrefix?: string; - source?: 'query with copilot codelens'; + source?: DocumentSource; } & Omit & vscode.InputBoxOptions; diff --git a/src/telemetry/telemetryService.ts b/src/telemetry/telemetryService.ts index 1b1e92869..d78c1f0d1 100644 --- a/src/telemetry/telemetryService.ts +++ b/src/telemetry/telemetryService.ts @@ -131,7 +131,7 @@ export type CopilotIntroductionProperties = { }; export type ParticipantOpenedFromInputBoxProperties = { - source?: 'query with copilot codelens'; + source?: DocumentSource; }; export function chatResultFeedbackKindToTelemetryValue( From c87078682c6ef67cf93b063aede4179097e93bb5 Mon Sep 17 00:00:00 2001 From: gagik Date: Thu, 28 Nov 2024 13:17:38 +0100 Subject: [PATCH 12/14] use document source --- src/documentSource.ts | 1 + src/editors/queryWithCopilotCodeLensProvider.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/documentSource.ts b/src/documentSource.ts index 171e3e48b..4c110ca04 100644 --- a/src/documentSource.ts +++ b/src/documentSource.ts @@ -2,4 +2,5 @@ export enum DocumentSource { DOCUMENT_SOURCE_TREEVIEW = 'treeview', DOCUMENT_SOURCE_PLAYGROUND = 'playground', DOCUMENT_SOURCE_COLLECTIONVIEW = 'collectionview', + DOCUMENT_SOURCE_QUERY_WITH_COPILOT_CODELENS = 'query with copilot codelens', } diff --git a/src/editors/queryWithCopilotCodeLensProvider.ts b/src/editors/queryWithCopilotCodeLensProvider.ts index 5e68f830c..23b3958a4 100644 --- a/src/editors/queryWithCopilotCodeLensProvider.ts +++ b/src/editors/queryWithCopilotCodeLensProvider.ts @@ -3,6 +3,7 @@ import EXTENSION_COMMANDS from '../commands'; import type { SendMessageToParticipantFromInputOptions } from '../participant/participantTypes'; import { isPlayground } from '../utils/playground'; import { COPILOT_EXTENSION_ID } from '../participant/constants'; +import { DocumentSource } from '../documentSource'; export class QueryWithCopilotCodeLensProvider implements vscode.CodeLensProvider @@ -32,7 +33,7 @@ export class QueryWithCopilotCodeLensProvider 'e.g. Find the document in sample_mflix.users with the name of Kayden Washington', messagePrefix: '/query', isNewChat: true, - source: 'query with copilot codelens', + source: DocumentSource.DOCUMENT_SOURCE_QUERY_WITH_COPILOT_CODELENS, }; return [ From 145af8d0dace7802f08cc19c67f09cb31757e087 Mon Sep 17 00:00:00 2001 From: gagik Date: Thu, 28 Nov 2024 13:23:30 +0100 Subject: [PATCH 13/14] use sendMessage in extensionController --- src/mdbExtensionController.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/mdbExtensionController.ts b/src/mdbExtensionController.ts index 6890be53c..ee3b9a2b7 100644 --- a/src/mdbExtensionController.ts +++ b/src/mdbExtensionController.ts @@ -975,12 +975,9 @@ export default class MDBExtensionController implements vscode.Disposable { const copilot = vscode.extensions.getExtension('github.copilot-chat'); if (result?.title === action) { - await vscode.commands.executeCommand('workbench.action.chat.newChat'); - await vscode.commands.executeCommand( - 'workbench.action.chat.clearHistory' - ); - await vscode.commands.executeCommand('workbench.action.chat.open', { - query: '@MongoDB ', + await this._participantController.sendMessageToParticipant({ + message: '', + isNewChat: true, isPartialQuery: true, }); this._telemetryService.trackCopilotIntroductionClicked({ From 692dc1cc6eb1e30551a5ef00bd452f363a34a8f7 Mon Sep 17 00:00:00 2001 From: gagik Date: Thu, 28 Nov 2024 13:24:28 +0100 Subject: [PATCH 14/14] change srv text --- src/connectionController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/connectionController.ts b/src/connectionController.ts index 301db9e97..4bffaa094 100644 --- a/src/connectionController.ts +++ b/src/connectionController.ts @@ -201,7 +201,7 @@ export default class ConnectionController { ignoreFocusOut: true, placeHolder: 'e.g. mongodb+srv://username:password@cluster0.mongodb.net/admin', - prompt: 'Enter your connection string (SRV or standard)', + prompt: 'Enter your SRV or standard connection string', validateInput: (uri: string) => { if ( !uri.startsWith('mongodb://') &&