From 2086dcf0a9ace4073a2dc99c89800293d6745b0a Mon Sep 17 00:00:00 2001 From: Harold Shen Date: Wed, 30 Oct 2024 16:01:08 -0400 Subject: [PATCH 1/6] Use config to determine path for generated operations --- .../src/data-connect/ad-hoc-mutations.ts | 49 ++++++++--- .../src/data-connect/code-lens-provider.ts | 10 +-- .../src/test/integration/fishfood/graphql.ts | 85 +++++++++++++++++++ 3 files changed, 125 insertions(+), 19 deletions(-) diff --git a/firebase-vscode/src/data-connect/ad-hoc-mutations.ts b/firebase-vscode/src/data-connect/ad-hoc-mutations.ts index e20fe750d11..c0a304b398c 100644 --- a/firebase-vscode/src/data-connect/ad-hoc-mutations.ts +++ b/firebase-vscode/src/data-connect/ad-hoc-mutations.ts @@ -16,6 +16,8 @@ import { import { checkIfFileExists, upsertFile } from "./file-utils"; import { DataConnectService } from "./service"; import { DATA_CONNECT_EVENT_NAME } from "../analytics"; +import { dataConnectConfigs } from "./config"; +import { firstWhereDefined } from "../utils/signal"; export function registerAdHoc( dataConnectService: DataConnectService, @@ -47,6 +49,7 @@ export function registerAdHoc( async function schemaReadData( document: DocumentNode, ast: ObjectTypeDefinitionNode, + documentPath: string, ) { // TODO(rrousselGit) - this is a temporary solution due to the lack of a "schema". // As such, we hardcoded the list of allowed primitives. @@ -62,8 +65,12 @@ export function registerAdHoc( "Any", ]); - const basePath = vscode.workspace.rootPath + "/dataconnect/"; - const filePath = vscode.Uri.file(`${basePath}${ast.name.value}_read.gql`); + const configs = await firstWhereDefined(dataConnectConfigs); + const dataconnectConfig = + configs.tryReadValue?.findEnclosingServiceForPath(documentPath); + + const basePath = dataconnectConfig?.path; + const filePath = vscode.Uri.file(`${basePath}/${ast.name.value}_read.gql`); // Recursively build a query for the object type. // Returns undefined if the query is empty. @@ -136,12 +143,20 @@ query { * File will be created (unsaved) in operations/ folder, with an auto-generated named based on the schema type * Mutation will be generated with all * */ - async function schemaAddData(ast: ObjectTypeDefinitionNode) { + async function schemaAddData( + ast: ObjectTypeDefinitionNode, + documentPath: string, + ) { // generate content for the file const preamble = "# This is a file for you to write an un-named mutation. \n# Only one un-named mutation is allowed per file."; - const introspect = (await dataConnectService.introspect())?.data; - const schema = buildClientSchema(introspect!); + + const introspect = await dataConnectService.introspect(); + if (!introspect.data) { + vscode.window.showErrorMessage("Failed to generate mutation. Please check your compilation errors."); + return; + } + const schema = buildClientSchema(introspect.data); const dataType = schema.getType(`${ast.name.value}_Data`); if (!isInputObjectType(dataType)) return; @@ -152,8 +167,15 @@ query { ), ); const content = [preamble, adhocMutation].join("\n"); - const basePath = vscode.workspace.rootPath + "/dataconnect/"; - const filePath = vscode.Uri.file(`${basePath}${ast.name.value}_insert.gql`); + + // get root where dataconnect.yaml lives + const configs = await firstWhereDefined(dataConnectConfigs); + const dataconnectConfig = + configs.tryReadValue?.findEnclosingServiceForPath(documentPath); + const basePath = dataconnectConfig?.path; + console.log("HAROLD: ", basePath) + + const filePath = vscode.Uri.file(`${basePath}/${ast.name.value}_insert.gql`); const doesFileExist = await checkIfFileExists(filePath); if (!doesFileExist) { @@ -202,7 +224,10 @@ query { selections: [ { kind: Kind.FIELD, - name: { kind: Kind.NAME, value: `${singularName.charAt(0).toLowerCase()}${singularName.slice(1)}_insert` }, + name: { + kind: Kind.NAME, + value: `${singularName.charAt(0).toLowerCase()}${singularName.slice(1)}_insert`, + }, arguments: [ { kind: Kind.ARGUMENT, @@ -251,16 +276,16 @@ query { return Disposable.from( vscode.commands.registerCommand( "firebase.dataConnect.schemaAddData", - (ast) => { + (ast, uri) => { telemetryLogger.logUsage(DATA_CONNECT_EVENT_NAME.ADD_DATA); - schemaAddData(ast); + schemaAddData(ast, uri); }, ), vscode.commands.registerCommand( "firebase.dataConnect.schemaReadData", - (document, ast) => { + (document, ast, uri) => { telemetryLogger.logUsage(DATA_CONNECT_EVENT_NAME.READ_DATA); - schemaReadData(document, ast); + schemaReadData(document, ast, uri); }, ), ); diff --git a/firebase-vscode/src/data-connect/code-lens-provider.ts b/firebase-vscode/src/data-connect/code-lens-provider.ts index 331cab7affc..51679fd0d43 100644 --- a/firebase-vscode/src/data-connect/code-lens-provider.ts +++ b/firebase-vscode/src/data-connect/code-lens-provider.ts @@ -150,18 +150,14 @@ export class SchemaCodeLensProvider extends ComputedCodeLensProvider { if (x.kind === Kind.OBJECT_TYPE_DEFINITION && x.loc) { const line = x.loc.startToken.line - 1; const range = new vscode.Range(line, 0, line, 0); - const position = new vscode.Position(line, 0); - const schemaLocation = { - documentPath: document.fileName, - position: position, - }; + const documentPath = document.fileName; codeLenses.push( new vscode.CodeLens(range, { title: `$(database) Add data`, command: "firebase.dataConnect.schemaAddData", tooltip: "Generate a mutation to add data of this type", - arguments: [x, schemaLocation], + arguments: [x, documentPath], }), ); @@ -170,7 +166,7 @@ export class SchemaCodeLensProvider extends ComputedCodeLensProvider { title: `$(database) Read data`, command: "firebase.dataConnect.schemaReadData", tooltip: "Generate a query to read data of this type", - arguments: [documentNode, x], + arguments: [documentNode, x, documentPath], }), ); } diff --git a/firebase-vscode/src/test/integration/fishfood/graphql.ts b/firebase-vscode/src/test/integration/fishfood/graphql.ts index d04fd3feeda..df117b6e853 100644 --- a/firebase-vscode/src/test/integration/fishfood/graphql.ts +++ b/firebase-vscode/src/test/integration/fishfood/graphql.ts @@ -154,6 +154,91 @@ firebaseSuite("GraphQL", async function () { }, ); + + firebaseTest( + "Add Data should generate file in correct folder", + async function () { + const workbench = await browser.getWorkbench(); + + const sidebar = new FirebaseSidebar(workbench); + await sidebar.openExtensionSidebar(); + + const schemaFilePath = path.join( + __dirname, + "..", + "..", + "test_projects", + "fishfood", + "dataconnect", + "schema", + "schema.gql", + ); + + // Open the schema file + const editorView = new EditorView(workbench); + await editorView.openFile(schemaFilePath); + + // Verify that inline Add Data button is displayed + const addDataButton = await editorView.addDataButton; + await addDataButton.waitForDisplayed(); + + // Click the Add Data button + await addDataButton.click(); + + // Wait a bit for the mutation to be generated + await browser.pause(1500); + + // Verify the generated mutation file path + const activeEditor = await editorView.getActiveEditor(); + const filePath = activeEditor?.document.fileName; + console.log(filePath); + expect(filePath).toBe("../../test_projects/fishfood/Post_insert.gql"); + + await editorView.closeCurrentEditor(); + }, + ); + + firebaseTest( + "Read Data should generate file in correct folder", + async function () { + const workbench = await browser.getWorkbench(); + + const sidebar = new FirebaseSidebar(workbench); + await sidebar.openExtensionSidebar(); + + const schemaFilePath = path.join( + __dirname, + "..", + "..", + "test_projects", + "fishfood", + "dataconnect", + "schema", + "schema.gql", + ); + + // Open the schema file + const editorView = new EditorView(workbench); + await editorView.openFile(schemaFilePath); + + // Verify that inline Read Data button is displayed + const readDataButton = await editorView.readDataButton; + await readDataButton.waitForDisplayed(); + + // Click the Read Data button + await readDataButton.click(); + + // Wait a bit for the query to be generated + await browser.pause(1500); + + // Verify the generated query file path + const activeEditor = await editorView.getActiveEditor(); + const filePath = activeEditor?.document.fileName; + expect(filePath).toBe("../../test_projects/fishfood/Post_read.gql"); + await editorView.closeCurrentEditor(); + }, + ); + firebaseTest( "GraphQL schema file should allow reading new data", async function () { From d05753158e0d5ca1448e5ab5e2004f090fa77d1e Mon Sep 17 00:00:00 2001 From: Harold Shen Date: Wed, 30 Oct 2024 16:05:41 -0400 Subject: [PATCH 2/6] remove console log --- firebase-vscode/src/data-connect/ad-hoc-mutations.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/firebase-vscode/src/data-connect/ad-hoc-mutations.ts b/firebase-vscode/src/data-connect/ad-hoc-mutations.ts index c0a304b398c..3fe6511465f 100644 --- a/firebase-vscode/src/data-connect/ad-hoc-mutations.ts +++ b/firebase-vscode/src/data-connect/ad-hoc-mutations.ts @@ -173,7 +173,6 @@ query { const dataconnectConfig = configs.tryReadValue?.findEnclosingServiceForPath(documentPath); const basePath = dataconnectConfig?.path; - console.log("HAROLD: ", basePath) const filePath = vscode.Uri.file(`${basePath}/${ast.name.value}_insert.gql`); const doesFileExist = await checkIfFileExists(filePath); From f2e75b00b03e80130422af22e8c21e2b05115a2c Mon Sep 17 00:00:00 2001 From: Harold Shen Date: Wed, 30 Oct 2024 16:09:10 -0400 Subject: [PATCH 3/6] changelog --- firebase-vscode/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/firebase-vscode/CHANGELOG.md b/firebase-vscode/CHANGELOG.md index 57f36902d1e..c1d3cfceb8f 100644 --- a/firebase-vscode/CHANGELOG.md +++ b/firebase-vscode/CHANGELOG.md @@ -1,6 +1,7 @@ ## NEXT - [Added] Persist FIREBASE_BINARY env variable to settings. +- [Fixed] Fixed an issue where Add data and Read data would generate operations in the wrong folder ## 0.10.5 From 2a3d9b23ac19cd33b754c828a9a127db218bb9d7 Mon Sep 17 00:00:00 2001 From: Harold Shen Date: Wed, 30 Oct 2024 16:27:42 -0400 Subject: [PATCH 4/6] update test --- .../src/test/integration/fishfood/graphql.ts | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/firebase-vscode/src/test/integration/fishfood/graphql.ts b/firebase-vscode/src/test/integration/fishfood/graphql.ts index df117b6e853..f81ec9a4918 100644 --- a/firebase-vscode/src/test/integration/fishfood/graphql.ts +++ b/firebase-vscode/src/test/integration/fishfood/graphql.ts @@ -154,6 +154,53 @@ firebaseSuite("GraphQL", async function () { }, ); + firebaseTest( + "GraphQL schema file should allow reading new data", + async function () { + const workbench = await browser.getWorkbench(); + + const sidebar = new FirebaseSidebar(workbench); + await sidebar.openExtensionSidebar(); + + const schemaFilePath = path.join( + __dirname, + "..", + "..", + "test_projects", + "fishfood", + "dataconnect", + "schema", + "schema.gql", + ); + + // Open the schema file + const editorView = new EditorView(workbench); + await editorView.openFile(schemaFilePath); + + // Verify that inline Read Data button is displayed + const readDataButton = await editorView.readDataButton; + await readDataButton.waitForDisplayed(); + + // Click the Read Data button + await readDataButton.click(); + + // Wait a bit for the query to be generated + await browser.pause(1000); + + // Verify the generated query + const activeEditor = await editorView.getActiveEditor(); + const editorTitle = activeEditor?.document.fileName.split("/").pop(); + const editorContent = await editorView.activeEditorContent(); + + expect(editorContent).toHaveText(`query { + posts{ + id + content + } +}`); + expect(editorTitle).toBe("Post_read.gql"); + }, + ); firebaseTest( "Add Data should generate file in correct folder", @@ -191,56 +238,16 @@ firebaseSuite("GraphQL", async function () { // Verify the generated mutation file path const activeEditor = await editorView.getActiveEditor(); const filePath = activeEditor?.document.fileName; - console.log(filePath); - expect(filePath).toBe("../../test_projects/fishfood/Post_insert.gql"); + expect(filePath).toContain( + "test_projects/fishfood/dataconnect/Post_insert.gql", + ); await editorView.closeCurrentEditor(); }, ); - firebaseTest( - "Read Data should generate file in correct folder", - async function () { - const workbench = await browser.getWorkbench(); - - const sidebar = new FirebaseSidebar(workbench); - await sidebar.openExtensionSidebar(); - - const schemaFilePath = path.join( - __dirname, - "..", - "..", - "test_projects", - "fishfood", - "dataconnect", - "schema", - "schema.gql", - ); - - // Open the schema file - const editorView = new EditorView(workbench); - await editorView.openFile(schemaFilePath); - - // Verify that inline Read Data button is displayed - const readDataButton = await editorView.readDataButton; - await readDataButton.waitForDisplayed(); - - // Click the Read Data button - await readDataButton.click(); - - // Wait a bit for the query to be generated - await browser.pause(1500); - - // Verify the generated query file path - const activeEditor = await editorView.getActiveEditor(); - const filePath = activeEditor?.document.fileName; - expect(filePath).toBe("../../test_projects/fishfood/Post_read.gql"); - await editorView.closeCurrentEditor(); - }, - ); - firebaseTest( - "GraphQL schema file should allow reading new data", + "Read Data should generate file in correct folder", async function () { const workbench = await browser.getWorkbench(); @@ -270,20 +277,13 @@ firebaseSuite("GraphQL", async function () { await readDataButton.click(); // Wait a bit for the query to be generated - await browser.pause(1000); + await browser.pause(1500); - // Verify the generated query + // Verify the generated query file path const activeEditor = await editorView.getActiveEditor(); - const editorTitle = activeEditor?.document.fileName.split("/").pop(); - const editorContent = await editorView.activeEditorContent(); - - expect(editorContent).toHaveText(`query { - posts{ - id - content - } -}`); - expect(editorTitle).toBe("Post_read.gql"); + const filePath = activeEditor?.document.fileName; + expect(filePath).toBe("test_projects/fishfood/dataconnect/Post_read.gql"); + await editorView.closeCurrentEditor(); }, ); }); From bc7032eb6ad2749b51f1695cea45505c64250bc7 Mon Sep 17 00:00:00 2001 From: Harold Shen Date: Thu, 31 Oct 2024 14:07:19 -0400 Subject: [PATCH 5/6] update other test --- firebase-vscode/src/test/integration/fishfood/graphql.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase-vscode/src/test/integration/fishfood/graphql.ts b/firebase-vscode/src/test/integration/fishfood/graphql.ts index f81ec9a4918..1097736e233 100644 --- a/firebase-vscode/src/test/integration/fishfood/graphql.ts +++ b/firebase-vscode/src/test/integration/fishfood/graphql.ts @@ -282,7 +282,7 @@ firebaseSuite("GraphQL", async function () { // Verify the generated query file path const activeEditor = await editorView.getActiveEditor(); const filePath = activeEditor?.document.fileName; - expect(filePath).toBe("test_projects/fishfood/dataconnect/Post_read.gql"); + expect(filePath).toContain("test_projects/fishfood/dataconnect/Post_read.gql"); await editorView.closeCurrentEditor(); }, ); From 67dd1f7789fff518d5e3762fd7d8c2a8c06933cc Mon Sep 17 00:00:00 2001 From: Harold Shen Date: Thu, 7 Nov 2024 13:51:21 -0500 Subject: [PATCH 6/6] changelog format --- firebase-vscode/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/firebase-vscode/CHANGELOG.md b/firebase-vscode/CHANGELOG.md index fad0d07a0aa..d3419b9d5b0 100644 --- a/firebase-vscode/CHANGELOG.md +++ b/firebase-vscode/CHANGELOG.md @@ -1,4 +1,5 @@ ## NEXT + - [Fixed] Fixed an issue where Add data and Read data would generate operations in the wrong folder ## 0.10.6