From 5d4d7d515926f3a2728238c632fc5e24795fb2dd Mon Sep 17 00:00:00 2001 From: Sean Grove Date: Fri, 4 Feb 2022 15:21:50 -0800 Subject: [PATCH 1/3] feat: show graph edit link on dev startup, send ops-lib edits to UI, & prettier code output --- src/commands/dev/dev.js | 39 +++++--- src/commands/graph/graph-edit.js | 16 +-- src/lib/one-graph/cli-client.js | 133 ++++++++++++++++++++++--- src/lib/one-graph/cli-netlify-graph.js | 47 ++++++++- 4 files changed, 196 insertions(+), 39 deletions(-) diff --git a/src/commands/dev/dev.js b/src/commands/dev/dev.js index 7beb34bcffb..64957f98d34 100644 --- a/src/commands/dev/dev.js +++ b/src/commands/dev/dev.js @@ -11,8 +11,8 @@ const stripAnsiCc = require('strip-ansi-control-characters') const waitPort = require('wait-port') const { startFunctionsServer } = require('../../lib/functions/server') -const { OneGraphCliClient, startOneGraphCLISession } = require('../../lib/one-graph/cli-client') -const { getNetlifyGraphConfig } = require('../../lib/one-graph/cli-netlify-graph') +const { OneGraphCliClient, loadCLISession, persistNewOperationsDocForSession, startOneGraphCLISession } = require('../../lib/one-graph/cli-client') +const { defaultExampleOperationsDoc, getGraphEditUrlBySiteId, getNetlifyGraphConfig, readGraphQLOperationsSourceFile } = require('../../lib/one-graph/cli-netlify-graph') const { NETLIFYDEV, NETLIFYDEVERR, @@ -110,12 +110,12 @@ const runCommand = (command, env = {}) => { } process.exit(1) }) - ;['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP', 'exit'].forEach((signal) => { - process.on(signal, () => { - commandProcess.kill('SIGTERM', { forceKillAfterTimeout: 500 }) - process.exit() + ;['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP', 'exit'].forEach((signal) => { + process.on(signal, () => { + commandProcess.kill('SIGTERM', { forceKillAfterTimeout: 500 }) + process.exit() + }) }) - }) return commandProcess } @@ -268,11 +268,11 @@ const dev = async (options, command) => { authlifyJWT == null ? {} : { - ONEGRAPH_AUTHLIFY_TOKEN: { - sources: ['general'], - value: authlifyJWT, - }, + ONEGRAPH_AUTHLIFY_TOKEN: { + sources: ['general'], + value: authlifyJWT, }, + }, ), site, }) @@ -349,9 +349,22 @@ const dev = async (options, command) => { await OneGraphCliClient.ensureAppForSite(netlifyToken, site.id) const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options, settings }) - log(`Starting Netlify Graph session, to edit your library run \`netlify graph:edit\` in another tab`) + let graphqlDocument = readGraphQLOperationsSourceFile(netlifyGraphConfig) + + if (!graphqlDocument || graphqlDocument.trim().length === 0) { + graphqlDocument = defaultExampleOperationsDoc + } + + await startOneGraphCLISession({ netlifyGraphConfig, netlifyToken, site, state }) + + // Should be created by startOneGraphCLISession + const oneGraphSessionId = loadCLISession(state) + + await persistNewOperationsDocForSession({ netlifyToken, oneGraphSessionId, operationsDoc: graphqlDocument, siteId: site.id }) + + const graphEditUrl = getGraphEditUrlBySiteId({ siteId: site.id, oneGraphSessionId }) - startOneGraphCLISession({ netlifyGraphConfig, netlifyToken, site, state }) + log(`Starting Netlify Graph session, to edit your library visit ${graphEditUrl} or run \`netlify graph:edit\` in another tab`) } printBanner({ url }) diff --git a/src/commands/graph/graph-edit.js b/src/commands/graph/graph-edit.js index f779eded761..5f3eb9f498b 100644 --- a/src/commands/graph/graph-edit.js +++ b/src/commands/graph/graph-edit.js @@ -3,7 +3,7 @@ const gitRepoInfo = require('git-repo-info') const { OneGraphCliClient, generateSessionName, loadCLISession } = require('../../lib/one-graph/cli-client') const { defaultExampleOperationsDoc, - getGraphEditUrlBySiteName, + getGraphEditUrlBySiteId, getNetlifyGraphConfig, readGraphQLOperationsSourceFile, } = require('../../lib/one-graph/cli-netlify-graph') @@ -19,7 +19,7 @@ const { createCLISession, createPersistedQuery, ensureAppForSite, updateCLISessi * @returns */ const graphEdit = async (options, command) => { - const { api, site, siteInfo, state } = command.netlify + const { site, state } = command.netlify const siteId = site.id if (!site.id) { @@ -60,17 +60,7 @@ const graphEdit = async (options, command) => { await updateCLISessionMetadata(netlifyToken, siteId, oneGraphSessionId, { docId: persistedDoc.id }) - let siteName = siteInfo.name - - if (!siteName) { - const siteData = await api.getSite({ siteId }) - siteName = siteData.name - if (!siteName) { - error(`No site name found for siteId ${siteId}`) - } - } - - const graphEditUrl = getGraphEditUrlBySiteName({ siteName, oneGraphSessionId }) + const graphEditUrl = getGraphEditUrlBySiteId({ siteId, oneGraphSessionId }) await openBrowser({ url: graphEditUrl }) } diff --git a/src/lib/one-graph/cli-client.js b/src/lib/one-graph/cli-client.js index c29ca62f919..a3eb4354cc2 100644 --- a/src/lib/one-graph/cli-client.js +++ b/src/lib/one-graph/cli-client.js @@ -1,13 +1,15 @@ /* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable fp/no-loops */ const os = require('os') +const path = require('path') +const crypto = require('crypto') +const gitRepoInfo = require('git-repo-info') const { GraphQL, InternalConsole, OneGraphClient } = require('netlify-onegraph-internal') const { NetlifyGraph } = require('netlify-onegraph-internal') const { chalk, error, log, warn } = require('../../utils') - -const { createCLISession, createPersistedQuery, ensureAppForSite, updateCLISessionMetadata } = OneGraphClient +const { watchDebounced } = require('../functions/watcher') const { generateFunctionsFile, @@ -19,6 +21,7 @@ const { const { parse } = GraphQL const { defaultExampleOperationsDoc, extractFunctionsFromOperationDoc } = NetlifyGraph +const { createCLISession, createPersistedQuery, ensureAppForSite, updateCLISessionMetadata } = OneGraphClient const internalConsole = { log, @@ -27,6 +30,9 @@ const internalConsole = { debug: console.debug, } +let witnessedIncomingDocumentHashes = [] + +// Keep track of which document hashes we've received from the server so we can ignore events from the filesystem based on them InternalConsole.registerConsole(internalConsole) /** @@ -108,6 +114,26 @@ const monitorCLISessionEvents = (input) => { return close } +/** + * Monitor the operations document for changes + * @param {object} input + * @param {NetlifyGraphConfig} input.netlifyGraphConfig A standalone config object that contains all the information necessary for Netlify Graph to process events + * @param {function} input.onAdd A callback function to handle when the operations document is added + * @param {function} input.onChange A callback function to handle when the operations document is changed + * @param {function} input.onUnlink A callback function to handle when the operations document is unlinked + * @returns {Promise} + */ +const monitorOperationFile = async ({ netlifyGraphConfig, onAdd, onChange, onUnlink }) => { + const filePath = path.resolve(...netlifyGraphConfig.graphQLOperationsSourceFilename) + const newWatcher = await watchDebounced([filePath], { + onAdd, + onChange, + onUnlink + }) + + return newWatcher +} + /** * Fetch the schema for a site, and regenerate all of the downstream files * @param {object} input @@ -146,7 +172,44 @@ const refetchAndGenerateFromOneGraph = async (input) => { } /** - * + * Regenerate the function library based on the current operations document on disk + * @param {object} input + * @param {string} input.schema The GraphQL schema to use when generating code + * @param {NetlifyGraphConfig} input.netlifyGraphConfig A standalone config object that contains all the information necessary for Netlify Graph to process events + * @returns + */ +const regenerateFunctionsFileFromOperationsFile = (input) => { + const { netlifyGraphConfig, schema } = input + + const appOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig) + + const hash = quickHash(appOperationsDoc) + + if (witnessedIncomingDocumentHashes.includes(hash)) { + // We've already seen this document, so don't regenerate + return + } + + const parsedDoc = parse(appOperationsDoc, { + noLocation: true, + }) + const { fragments, functions } = extractFunctionsFromOperationDoc(parsedDoc) + generateFunctionsFile({ netlifyGraphConfig, schema, operationsDoc: appOperationsDoc, functions, fragments }) +} + +/** + * Compute a md5 hash of a string + * @param {string} input String to compute a quick md5 hash for + * @returns hex digest of the input string + */ +const quickHash = (input) => { + const hashSum = crypto.createHash('md5'); + hashSum.update(input); + return hashSum.digest('hex'); +} + +/** + * Fetch a persisted operations doc by its id, write it to the system, and regenerate the library * @param {object} input * @param {string} input.siteId The site id to query against * @param {string} input.netlifyToken The (typically netlify) access token that is used for authentication, if any @@ -155,7 +218,7 @@ const refetchAndGenerateFromOneGraph = async (input) => { * @param {NetlifyGraphConfig} input.netlifyGraphConfig A standalone config object that contains all the information necessary for Netlify Graph to process events * @returns */ -const updateGraphQLOperationsFile = async (input) => { +const updateGraphQLOperationsFileFromPersistedDoc = async (input) => { const { docId, netlifyGraphConfig, netlifyToken, schema, siteId } = input const persistedDoc = await OneGraphClient.fetchPersistedQuery(netlifyToken, siteId, docId) if (!persistedDoc) { @@ -166,12 +229,15 @@ const updateGraphQLOperationsFile = async (input) => { const doc = persistedDoc.query writeGraphQLOperationsSourceFile(netlifyGraphConfig, doc) - const appOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig) - const parsedDoc = parse(appOperationsDoc, { - noLocation: true, - }) - const { fragments, functions } = extractFunctionsFromOperationDoc(parsedDoc) - generateFunctionsFile({ netlifyGraphConfig, schema, operationsDoc: appOperationsDoc, functions, fragments }) + regenerateFunctionsFileFromOperationsFile({ netlifyGraphConfig, schema }) + + const hash = quickHash(doc) + + if (witnessedIncomingDocumentHashes.length > 10) { + witnessedIncomingDocumentHashes.shift() + } + + witnessedIncomingDocumentHashes.push(hash) } const handleCliSessionEvent = async ({ event, netlifyGraphConfig, netlifyToken, schema, siteId }) => { @@ -184,7 +250,7 @@ const handleCliSessionEvent = async ({ event, netlifyGraphConfig, netlifyToken, await generateHandler(netlifyGraphConfig, schema, payload.operationId, payload) break case 'OneGraphNetlifyCliSessionPersistedLibraryUpdatedEvent': - await updateGraphQLOperationsFile({ netlifyToken, docId: payload.docId, netlifyGraphConfig, schema, siteId }) + await updateGraphQLOperationsFileFromPersistedDoc({ netlifyToken, docId: payload.docId, netlifyGraphConfig, schema, siteId }) break default: { warn(`Unrecognized event received, you may need to upgrade your CLI version`, __typename, payload) @@ -193,6 +259,30 @@ const handleCliSessionEvent = async ({ event, netlifyGraphConfig, netlifyToken, } } + +const persistNewOperationsDocForSession = async ({ netlifyToken, oneGraphSessionId, operationsDoc, siteId }) => { + const { branch } = gitRepoInfo() + + const payload = { + appId: siteId, + description: 'Temporary snapshot of local queries', + document: operationsDoc, + tags: ['netlify-cli', `session:${oneGraphSessionId}`, `git-branch:${branch}`, `local-change`], + }; + const persistedDoc = await createPersistedQuery(netlifyToken, payload) + const newMetadata = await { docId: persistedDoc.id } + const result = await OneGraphClient.updateCLISessionMetadata( + netlifyToken, + siteId, + oneGraphSessionId, + newMetadata + ); + + if (result.errors) { + warn("Unable to update session metadata with updated operations doc", result.errors) + } +} + /** * Load the CLI session id from the local state * @param {state} state @@ -201,7 +291,7 @@ const handleCliSessionEvent = async ({ event, netlifyGraphConfig, netlifyToken, const loadCLISession = (state) => state.get('oneGraphSessionId') /** - * Idemponentially save the CLI session id to the local state and start monitoring for CLI events and upstream schema changes + * Idemponentially save the CLI session id to the local state and start monitoring for CLI events, upstream schema changes, and local operation file changes * @param {object} input * @param {string} input.netlifyToken The (typically netlify) access token that is used for authentication, if any * @param {NetlifyGraphConfig} input.netlifyGraphConfig A standalone config object that contains all the information necessary for Netlify Graph to process events @@ -223,6 +313,24 @@ const startOneGraphCLISession = async (input) => { const enabledServices = [] const schema = await OneGraphClient.fetchOneGraphSchema(site.id, enabledServices) + monitorOperationFile( + { + netlifyGraphConfig, + onChange: async (filePath) => { + log('NetlifyGraph operation file changed at', filePath, 'updating function library...') + regenerateFunctionsFileFromOperationsFile({ netlifyGraphConfig, schema }) + const newOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig) + await persistNewOperationsDocForSession({ netlifyToken, oneGraphSessionId, operationsDoc: newOperationsDoc, siteId: site.id }) + }, + onAdd: async (filePath) => { + log('NetlifyGraph operation file created at', filePath, 'creating function library...') + regenerateFunctionsFileFromOperationsFile({ netlifyGraphConfig, schema }) + const newOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig) + await persistNewOperationsDocForSession({ netlifyToken, oneGraphSessionId, operationsDoc: newOperationsDoc, siteId: site.id }) + } + } + ) + monitorCLISessionEvents({ appId: site.id, netlifyToken, @@ -273,6 +381,7 @@ module.exports = { generateSessionName, loadCLISession, monitorCLISessionEvents, + persistNewOperationsDocForSession, refetchAndGenerateFromOneGraph, startOneGraphCLISession, } diff --git a/src/lib/one-graph/cli-netlify-graph.js b/src/lib/one-graph/cli-netlify-graph.js index ae411a90480..f2d23d2ccca 100644 --- a/src/lib/one-graph/cli-netlify-graph.js +++ b/src/lib/one-graph/cli-netlify-graph.js @@ -4,7 +4,7 @@ const process = require('process') const { GraphQL, InternalConsole, NetlifyGraph } = require('netlify-onegraph-internal') -const { detectServerSettings, error, getFunctionsDir, log, warn } = require('../../utils') +const { detectServerSettings, error, execa, getFunctionsDir, log, warn } = require('../../utils') const { printSchema } = GraphQL @@ -241,6 +241,32 @@ const ensureFunctionsPath = (netlifyGraphConfig) => { fs.mkdirSync(fullPath, { recursive: true }) } +let disablePrettierDueToPreviousError = false; + +const runPrettier = async (filePath) => { + if (disablePrettierDueToPreviousError) { + return + } + + const command = `prettier --write ${filePath}` + try { + const commandProcess = execa.command(command, { + preferLocal: true, + // windowsHide needs to be false for child process to terminate properly on Windows + windowsHide: false, + }) + + await commandProcess + } catch (prettierError) { + if (!disablePrettierDueToPreviousError) { + disablePrettierDueToPreviousError = true + warn(prettierError) + warn("Error while running prettier, make sure you have installed it globally with 'npm i -g prettier'") + } + } +} + + /** * Generate a library file with type definitions for a given NetlifyGraphConfig, operationsDoc, and schema, writing them to the filesystem * @param {object} context @@ -267,6 +293,8 @@ const generateFunctionsFile = ({ fragments, functions, netlifyGraphConfig, opera typeDefinitionsSource, 'utf8', ) + runPrettier(path.resolve(...netlifyGraphConfig.netlifyGraphImplementationFilename)) + runPrettier(path.resolve(...netlifyGraphConfig.netlifyGraphTypeDefinitionsFilename)) } /** @@ -384,6 +412,7 @@ const generateHandler = (netlifyGraphConfig, schema, operationId, handlerOptions const absoluteFilename = path.resolve(...filenameArr) fs.writeFileSync(absoluteFilename, content) + runPrettier(absoluteFilename) }) } @@ -405,6 +434,21 @@ const getGraphEditUrlBySiteName = ({ oneGraphSessionId, siteName }) => { return url } +/** + * Get a url to the Netlify Graph UI for the current session by a site's id + * @param {object} options + * @param {string} options.siteId The name of the site as used in the Netlify UI url scheme + * @param {string} options.oneGraphSessionId The oneGraph session id to use when generating the graph-edit link + * @returns {string} The url to the Netlify Graph UI for the current session + */ +const getGraphEditUrlBySiteId = ({ oneGraphSessionId, siteId }) => { + const host = process.env.NETLIFY_APP_HOST || 'app.netlify.com' + // http because app.netlify.com will redirect to https, and localhost will still work for development + const url = `http://${host}/site-redirect/${siteId}/graph/explorer?cliSessionId=${oneGraphSessionId}` + + return url +} + module.exports = { buildSchema, defaultExampleOperationsDoc: NetlifyGraph.defaultExampleOperationsDoc, @@ -413,6 +457,7 @@ module.exports = { generateFunctionsFile, generateHandlerSource: NetlifyGraph.generateHandlerSource, generateHandler, + getGraphEditUrlBySiteId, getGraphEditUrlBySiteName, getNetlifyGraphConfig, parse, From 4570b02a7ec2fb732ba4807f7a1636d6ab1fe3eb Mon Sep 17 00:00:00 2001 From: Sean Grove Date: Fri, 4 Feb 2022 15:23:29 -0800 Subject: [PATCH 2/3] chore: make eslint happy --- src/lib/one-graph/cli-client.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/one-graph/cli-client.js b/src/lib/one-graph/cli-client.js index a3eb4354cc2..bcea3200876 100644 --- a/src/lib/one-graph/cli-client.js +++ b/src/lib/one-graph/cli-client.js @@ -1,8 +1,8 @@ /* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable fp/no-loops */ +const crypto = require('crypto') const os = require('os') const path = require('path') -const crypto = require('crypto') const gitRepoInfo = require('git-repo-info') const { GraphQL, InternalConsole, OneGraphClient } = require('netlify-onegraph-internal') @@ -30,7 +30,7 @@ const internalConsole = { debug: console.debug, } -let witnessedIncomingDocumentHashes = [] +const witnessedIncomingDocumentHashes = [] // Keep track of which document hashes we've received from the server so we can ignore events from the filesystem based on them InternalConsole.registerConsole(internalConsole) @@ -233,7 +233,9 @@ const updateGraphQLOperationsFileFromPersistedDoc = async (input) => { const hash = quickHash(doc) - if (witnessedIncomingDocumentHashes.length > 10) { + const relevantHasLength = 10; + + if (witnessedIncomingDocumentHashes.length > relevantHasLength) { witnessedIncomingDocumentHashes.shift() } From db8e34fc742f6f069da87361ca34903db8f6e26a Mon Sep 17 00:00:00 2001 From: Sean Grove Date: Fri, 4 Feb 2022 15:24:06 -0800 Subject: [PATCH 3/3] chore: fix formatting --- src/commands/dev/dev.js | 43 ++++++++++----- src/lib/one-graph/cli-client.js | 72 ++++++++++++++------------ src/lib/one-graph/cli-netlify-graph.js | 3 +- 3 files changed, 71 insertions(+), 47 deletions(-) diff --git a/src/commands/dev/dev.js b/src/commands/dev/dev.js index 64957f98d34..d13e5d2827f 100644 --- a/src/commands/dev/dev.js +++ b/src/commands/dev/dev.js @@ -11,8 +11,18 @@ const stripAnsiCc = require('strip-ansi-control-characters') const waitPort = require('wait-port') const { startFunctionsServer } = require('../../lib/functions/server') -const { OneGraphCliClient, loadCLISession, persistNewOperationsDocForSession, startOneGraphCLISession } = require('../../lib/one-graph/cli-client') -const { defaultExampleOperationsDoc, getGraphEditUrlBySiteId, getNetlifyGraphConfig, readGraphQLOperationsSourceFile } = require('../../lib/one-graph/cli-netlify-graph') +const { + OneGraphCliClient, + loadCLISession, + persistNewOperationsDocForSession, + startOneGraphCLISession, +} = require('../../lib/one-graph/cli-client') +const { + defaultExampleOperationsDoc, + getGraphEditUrlBySiteId, + getNetlifyGraphConfig, + readGraphQLOperationsSourceFile, +} = require('../../lib/one-graph/cli-netlify-graph') const { NETLIFYDEV, NETLIFYDEVERR, @@ -110,12 +120,12 @@ const runCommand = (command, env = {}) => { } process.exit(1) }) - ;['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP', 'exit'].forEach((signal) => { - process.on(signal, () => { - commandProcess.kill('SIGTERM', { forceKillAfterTimeout: 500 }) - process.exit() - }) + ;['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP', 'exit'].forEach((signal) => { + process.on(signal, () => { + commandProcess.kill('SIGTERM', { forceKillAfterTimeout: 500 }) + process.exit() }) + }) return commandProcess } @@ -268,11 +278,11 @@ const dev = async (options, command) => { authlifyJWT == null ? {} : { - ONEGRAPH_AUTHLIFY_TOKEN: { - sources: ['general'], - value: authlifyJWT, + ONEGRAPH_AUTHLIFY_TOKEN: { + sources: ['general'], + value: authlifyJWT, + }, }, - }, ), site, }) @@ -360,11 +370,18 @@ const dev = async (options, command) => { // Should be created by startOneGraphCLISession const oneGraphSessionId = loadCLISession(state) - await persistNewOperationsDocForSession({ netlifyToken, oneGraphSessionId, operationsDoc: graphqlDocument, siteId: site.id }) + await persistNewOperationsDocForSession({ + netlifyToken, + oneGraphSessionId, + operationsDoc: graphqlDocument, + siteId: site.id, + }) const graphEditUrl = getGraphEditUrlBySiteId({ siteId: site.id, oneGraphSessionId }) - log(`Starting Netlify Graph session, to edit your library visit ${graphEditUrl} or run \`netlify graph:edit\` in another tab`) + log( + `Starting Netlify Graph session, to edit your library visit ${graphEditUrl} or run \`netlify graph:edit\` in another tab`, + ) } printBanner({ url }) diff --git a/src/lib/one-graph/cli-client.js b/src/lib/one-graph/cli-client.js index bcea3200876..feadd72081e 100644 --- a/src/lib/one-graph/cli-client.js +++ b/src/lib/one-graph/cli-client.js @@ -128,7 +128,7 @@ const monitorOperationFile = async ({ netlifyGraphConfig, onAdd, onChange, onUnl const newWatcher = await watchDebounced([filePath], { onAdd, onChange, - onUnlink + onUnlink, }) return newWatcher @@ -203,9 +203,9 @@ const regenerateFunctionsFileFromOperationsFile = (input) => { * @returns hex digest of the input string */ const quickHash = (input) => { - const hashSum = crypto.createHash('md5'); - hashSum.update(input); - return hashSum.digest('hex'); + const hashSum = crypto.createHash('md5') + hashSum.update(input) + return hashSum.digest('hex') } /** @@ -233,7 +233,7 @@ const updateGraphQLOperationsFileFromPersistedDoc = async (input) => { const hash = quickHash(doc) - const relevantHasLength = 10; + const relevantHasLength = 10 if (witnessedIncomingDocumentHashes.length > relevantHasLength) { witnessedIncomingDocumentHashes.shift() @@ -252,7 +252,13 @@ const handleCliSessionEvent = async ({ event, netlifyGraphConfig, netlifyToken, await generateHandler(netlifyGraphConfig, schema, payload.operationId, payload) break case 'OneGraphNetlifyCliSessionPersistedLibraryUpdatedEvent': - await updateGraphQLOperationsFileFromPersistedDoc({ netlifyToken, docId: payload.docId, netlifyGraphConfig, schema, siteId }) + await updateGraphQLOperationsFileFromPersistedDoc({ + netlifyToken, + docId: payload.docId, + netlifyGraphConfig, + schema, + siteId, + }) break default: { warn(`Unrecognized event received, you may need to upgrade your CLI version`, __typename, payload) @@ -261,7 +267,6 @@ const handleCliSessionEvent = async ({ event, netlifyGraphConfig, netlifyToken, } } - const persistNewOperationsDocForSession = async ({ netlifyToken, oneGraphSessionId, operationsDoc, siteId }) => { const { branch } = gitRepoInfo() @@ -270,18 +275,13 @@ const persistNewOperationsDocForSession = async ({ netlifyToken, oneGraphSession description: 'Temporary snapshot of local queries', document: operationsDoc, tags: ['netlify-cli', `session:${oneGraphSessionId}`, `git-branch:${branch}`, `local-change`], - }; + } const persistedDoc = await createPersistedQuery(netlifyToken, payload) const newMetadata = await { docId: persistedDoc.id } - const result = await OneGraphClient.updateCLISessionMetadata( - netlifyToken, - siteId, - oneGraphSessionId, - newMetadata - ); + const result = await OneGraphClient.updateCLISessionMetadata(netlifyToken, siteId, oneGraphSessionId, newMetadata) if (result.errors) { - warn("Unable to update session metadata with updated operations doc", result.errors) + warn('Unable to update session metadata with updated operations doc', result.errors) } } @@ -315,23 +315,31 @@ const startOneGraphCLISession = async (input) => { const enabledServices = [] const schema = await OneGraphClient.fetchOneGraphSchema(site.id, enabledServices) - monitorOperationFile( - { - netlifyGraphConfig, - onChange: async (filePath) => { - log('NetlifyGraph operation file changed at', filePath, 'updating function library...') - regenerateFunctionsFileFromOperationsFile({ netlifyGraphConfig, schema }) - const newOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig) - await persistNewOperationsDocForSession({ netlifyToken, oneGraphSessionId, operationsDoc: newOperationsDoc, siteId: site.id }) - }, - onAdd: async (filePath) => { - log('NetlifyGraph operation file created at', filePath, 'creating function library...') - regenerateFunctionsFileFromOperationsFile({ netlifyGraphConfig, schema }) - const newOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig) - await persistNewOperationsDocForSession({ netlifyToken, oneGraphSessionId, operationsDoc: newOperationsDoc, siteId: site.id }) - } - } - ) + monitorOperationFile({ + netlifyGraphConfig, + onChange: async (filePath) => { + log('NetlifyGraph operation file changed at', filePath, 'updating function library...') + regenerateFunctionsFileFromOperationsFile({ netlifyGraphConfig, schema }) + const newOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig) + await persistNewOperationsDocForSession({ + netlifyToken, + oneGraphSessionId, + operationsDoc: newOperationsDoc, + siteId: site.id, + }) + }, + onAdd: async (filePath) => { + log('NetlifyGraph operation file created at', filePath, 'creating function library...') + regenerateFunctionsFileFromOperationsFile({ netlifyGraphConfig, schema }) + const newOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig) + await persistNewOperationsDocForSession({ + netlifyToken, + oneGraphSessionId, + operationsDoc: newOperationsDoc, + siteId: site.id, + }) + }, + }) monitorCLISessionEvents({ appId: site.id, diff --git a/src/lib/one-graph/cli-netlify-graph.js b/src/lib/one-graph/cli-netlify-graph.js index f2d23d2ccca..960b566c956 100644 --- a/src/lib/one-graph/cli-netlify-graph.js +++ b/src/lib/one-graph/cli-netlify-graph.js @@ -241,7 +241,7 @@ const ensureFunctionsPath = (netlifyGraphConfig) => { fs.mkdirSync(fullPath, { recursive: true }) } -let disablePrettierDueToPreviousError = false; +let disablePrettierDueToPreviousError = false const runPrettier = async (filePath) => { if (disablePrettierDueToPreviousError) { @@ -266,7 +266,6 @@ const runPrettier = async (filePath) => { } } - /** * Generate a library file with type definitions for a given NetlifyGraphConfig, operationsDoc, and schema, writing them to the filesystem * @param {object} context