Skip to content

Commit

Permalink
feat: Allow user to configure an editor to open file for Graph (#4699)
Browse files Browse the repository at this point in the history
* feat: allow user to configure an editor to open file

* chore: update contributors field

* chore: update dep

* chore: fix formatting, because of course we check for that on push

* chore: update snapshots with new codegen

* chore: update dep

* fix: handle pr feedback

Co-authored-by: sgrove <sgrove@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 15, 2022
1 parent 76f209f commit 8f64f93
Show file tree
Hide file tree
Showing 8 changed files with 19,406 additions and 15,684 deletions.
28 changes: 7 additions & 21 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@
"git-clone": "^0.2.0",
"git-repo-info": "^2.1.0",
"gitconfiglocal": "^2.1.0",
"graphql": "^16.1.0",
"hasbin": "^1.2.3",
"hasha": "^5.2.2",
"http-proxy": "^1.18.0",
Expand All @@ -285,7 +284,7 @@
"multiparty": "^4.2.1",
"netlify": "^11.0.1",
"netlify-headers-parser": "^6.0.2",
"netlify-onegraph-internal": "0.0.50",
"netlify-onegraph-internal": "0.3.1",
"netlify-redirect-parser": "^13.0.5",
"netlify-redirector": "^0.2.1",
"node-fetch": "^2.6.0",
Expand Down
10 changes: 9 additions & 1 deletion src/commands/graph/graph-pull.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,15 @@ const graphPull = async (options, command) => {
if (next.events) {
const ackIds = []
for (const event of next.events) {
await handleCliSessionEvent({ netlifyToken, event, netlifyGraphConfig, schema, siteId: site.id })
await handleCliSessionEvent({
netlifyToken,
event,
netlifyGraphConfig,
schema,
sessionId: oneGraphSessionId,
siteId: site.id,
siteRoot: site.root,
})
ackIds.push(event.id)
}

Expand Down
120 changes: 102 additions & 18 deletions src/lib/one-graph/cli-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ const { GraphQL, InternalConsole, OneGraphClient } = require('netlify-onegraph-i
const { NetlifyGraph } = require('netlify-onegraph-internal')

// eslint-disable-next-line no-unused-vars
const { StateConfig, USER_AGENT, chalk, error, log, warn, watchDebounced } = require('../../utils')
const { StateConfig, USER_AGENT, chalk, error, execa, log, warn, watchDebounced } = require('../../utils')

const {
generateFunctionsFile,
generateHandlerByOperationId,
loadNetlifyGraphConfig,
normalizeOperationsDoc,
readGraphQLOperationsSourceFile,
writeGraphQLOperationsSourceFile,
Expand All @@ -24,8 +25,8 @@ const {
const { parse } = GraphQL
const { defaultExampleOperationsDoc, extractFunctionsFromOperationDoc } = NetlifyGraph
const {
createPersistedQuery,
ensureAppForSite,
executeCreatePersistedQueryMutation,
executeMarkCliSessionActiveHeartbeat,
executeMarkCliSessionInactive,
updateCLISessionMetadata,
Expand Down Expand Up @@ -187,7 +188,7 @@ const refetchAndGenerateFromOneGraph = async (input) => {
.map((service) => service.service)
.sort((aString, bString) => aString.localeCompare(bString))

const schema = await OneGraphClient.fetchOneGraphSchema(siteId, enabledServices)
const schema = await OneGraphClient.fetchOneGraphSchemaForServices(siteId, enabledServices)

let currentOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig)
if (currentOperationsDoc.trim().length === 0) {
Expand Down Expand Up @@ -282,24 +283,84 @@ const updateGraphQLOperationsFileFromPersistedDoc = async (input) => {
witnessedIncomingDocumentHashes.push(hash)
}

const handleCliSessionEvent = async ({ event, netlifyGraphConfig, netlifyToken, schema, siteId }) => {
const handleCliSessionEvent = async ({
event,
netlifyGraphConfig,
netlifyToken,
schema,
sessionId,
siteId,
siteRoot,
}) => {
const { __typename, payload } = await event
switch (__typename) {
case 'OneGraphNetlifyCliSessionTestEvent':
await handleCliSessionEvent({ netlifyToken, event: payload, netlifyGraphConfig, schema, siteId })
await handleCliSessionEvent({
netlifyToken,
event: payload,
netlifyGraphConfig,
schema,
sessionId,
siteId,
siteRoot,
})
break
case 'OneGraphNetlifyCliSessionGenerateHandlerEvent':
if (!payload.operationId || !payload.operationId.id) {
warn(`No operation id found in payload, ${JSON.stringify(payload, null, 2)}`)
case 'OneGraphNetlifyCliSessionGenerateHandlerEvent': {
if (!payload.operationId && !payload.operation.id) {
warn(`No operation id found in payload,
${JSON.stringify(payload, null, 2)}`)
return
}
generateHandlerByOperationId({
const files = generateHandlerByOperationId({
netlifyGraphConfig,
schema,
operationId: payload.operationId.id,
operationId: payload.operationId || payload.operation.id,
handlerOptions: payload,
})

if (!files) {
warn(`No files generated for operation id: ${payload.operationId || payload.operation.id}`)
return
}

const config = loadNetlifyGraphConfig(siteRoot)
for (const file of files) {
const fileWrittenEvent = {
__typename: 'OneGraphNetlifyCliSessionFileWrittenEvent',
cliSessionId: sessionId,
payload: {
editor: config.editor,
filepath: file.filePath,
audience: 'ui',
},
}

await OneGraphClient.executeCreateCLISessionEventMutation({
nfToken: netlifyToken,
sessionId,
payload: fileWrittenEvent,
})
}
break
}
case 'OneGraphNetlifyCliSessionOpenFileEvent': {
if (!payload.filePath) {
warn(`No filePath found in payload, ${JSON.stringify(payload, null, 2)}`)
return
}
const config = loadNetlifyGraphConfig(siteRoot)
if (config.editor) {
log(`Opening ${config.editor} for ${payload.filePath}`)
execa(config.editor, [payload.filePath], {
preferLocal: true,
// windowsHide needs to be false for child process to terminate properly on Windows
windowsHide: false,
})
} else {
warn('No editor found in config')
}
break
}
case 'OneGraphNetlifyCliSessionPersistedLibraryUpdatedEvent':
await updateGraphQLOperationsFileFromPersistedDoc({
netlifyToken,
Expand Down Expand Up @@ -364,12 +425,17 @@ const detectLocalCLISessionMetadata = ({ siteRoot }) => {
const { username } = userInfo
const cliVersion = USER_AGENT

const config = loadNetlifyGraphConfig(siteRoot)

const { editor } = config

const detectedMetadata = {
gitBranch: branch,
hostname,
username,
siteRoot,
cliVersion,
editor,
}

return detectedMetadata
Expand Down Expand Up @@ -414,7 +480,7 @@ const persistNewOperationsDocForSession = async ({
document: operationsDoc,
tags: ['netlify-cli', `session:${oneGraphSessionId}`, `git-branch:${branch}`, `local-change`],
}
const persistedDoc = await createPersistedQuery(netlifyToken, payload)
const persistedDoc = await executeCreatePersistedQueryMutation(netlifyToken, payload)
const newMetadata = await { docId: persistedDoc.id }
const result = await upsertMergeCLISessionMetadata({
netlifyGraphConfig,
Expand Down Expand Up @@ -462,7 +528,7 @@ const startOneGraphCLISession = async (input) => {
})

const enabledServices = []
const schema = await OneGraphClient.fetchOneGraphSchema(site.id, enabledServices)
const schema = await OneGraphClient.fetchOneGraphSchemaForServices(site.id, enabledServices)

const opsFileWatcher = monitorOperationFile({
netlifyGraphConfig,
Expand Down Expand Up @@ -501,14 +567,32 @@ const startOneGraphCLISession = async (input) => {
sessionId: oneGraphSessionId,
site,
state,
onClose: () => {
log('CLI session closed, stopping monitoring...')
},
onEvents: async (events) => {
const ackEventIds = []

for (const event of events) {
const eventName = OneGraphClient.friendlyEventName(event)
log(`${chalk.magenta('Handling')} Netlify Graph: ${eventName}...`)
await handleCliSessionEvent({ netlifyToken, event, netlifyGraphConfig, schema, siteId: site.id })
log(`${chalk.green('Finished handling')} Netlify Graph: ${eventName}...`)
const audience = OneGraphClient.eventAudience(event)
if (audience === 'cli') {
const eventName = OneGraphClient.friendlyEventName(event)
log(`${chalk.magenta('Handling')} Netlify Graph: ${eventName}...`)
await handleCliSessionEvent({
netlifyToken,
event,
netlifyGraphConfig,
schema,
sessionId: oneGraphSessionId,
siteId: site.id,
siteRoot: site.root,
})
log(`${chalk.green('Finished handling')} Netlify Graph: ${eventName}...`)
ackEventIds.push(event.id)
}
}
return events.map((event) => event.id)

return ackEventIds
},
onError: (fetchEventError) => {
error(`Netlify Graph upstream error: ${fetchEventError}`)
Expand Down Expand Up @@ -613,7 +697,7 @@ const ensureCLISession = async ({ metadata, netlifyToken, site, state }) => {

const OneGraphCliClient = {
ackCLISessionEvents: OneGraphClient.ackCLISessionEvents,
createPersistedQuery,
createPersistedQuery: executeCreatePersistedQueryMutation,
fetchCliSessionEvents: OneGraphClient.fetchCliSessionEvents,
ensureAppForSite,
updateCLISessionMetadata,
Expand Down
34 changes: 30 additions & 4 deletions src/lib/one-graph/cli-netlify-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,10 @@ const runPrettier = async (filePath) => {
* @param {Record<string, NetlifyGraph.ExtractedFunction>} context.functions The parsed queries with metadata to use when generating library functions
* @param {Record<string, NetlifyGraph.ExtractedFragment>} context.fragments The parsed queries with metadata to use when generating library functions
* @param {(message: string) => void=} context.logger A function that if provided will be used to log messages
* @returns {void} Void, effectfully writes the generated library to the filesystem
* @returns {Promise<void>} Void, effectfully writes the generated library to the filesystem
*/
const generateFunctionsFile = ({ fragments, functions, logger, netlifyGraphConfig, operationsDoc, schema }) => {
const { clientSource, typeDefinitionsSource } = NetlifyGraph.generateFunctionsSource(
const generateFunctionsFile = async ({ fragments, functions, logger, netlifyGraphConfig, operationsDoc, schema }) => {
const { clientSource, typeDefinitionsSource } = await NetlifyGraph.generateFunctionsSource(
netlifyGraphConfig,
schema,
operationsDoc,
Expand Down Expand Up @@ -394,7 +394,7 @@ const readGraphQLSchemaFile = (netlifyGraphConfig) => {
* @param {string} input.operationId The operationId to use when generating the handler
* @param {object} input.handlerOptions The options to use when generating the handler
* @param {(message: string) => void=} input.logger A function that if provided will be used to log messages
* @returns
* @returns {Array<{filePath: string, prettierSuccess: boolean}>} An array of the generated handler filepaths
*/
const generateHandlerByOperationId = ({ handlerOptions, logger, netlifyGraphConfig, operationId, schema }) => {
let currentOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig)
Expand Down Expand Up @@ -425,6 +425,8 @@ const generateHandlerByOperationId = ({ handlerOptions, logger, netlifyGraphConf
return
}

const results = []

exportedFiles.forEach((exportedFile) => {
const { content } = exportedFile
const isNamed = exportedFile.kind === 'NamedExportedFile'
Expand Down Expand Up @@ -453,7 +455,14 @@ const generateHandlerByOperationId = ({ handlerOptions, logger, netlifyGraphConf
const relativePath = path.relative(process.cwd(), absoluteFilename)
logger && logger(`Wrote ${chalk.cyan(relativePath)}`)
runPrettier(absoluteFilename)

results.push({
filePath: absoluteFilename,
prettierSuccess: true,
})
})

return results
}

/**
Expand Down Expand Up @@ -520,6 +529,22 @@ const getGraphEditUrlBySiteId = ({ oneGraphSessionId, siteId }) => {
return url
}

/**
* Load `netlifyGraph.json` from the appropriate location
* @param {string} siteRoot The root directory of the site
* @returns {import('netlify-onegraph-internal').NetlifyGraphJsonConfig.JsonConfig}
*/
const loadNetlifyGraphConfig = (siteRoot) => {
const configPath = path.join(siteRoot, 'netlifyGraph.json')
if (fs.existsSync(configPath)) {
// eslint-disable-next-line unicorn/prefer-json-parse-buffer
const file = fs.readFileSync(configPath, 'utf-8')
return JSON.parse(file)
}

return {}
}

module.exports = {
buildSchema,
defaultExampleOperationsDoc: NetlifyGraph.defaultExampleOperationsDoc,
Expand All @@ -532,6 +557,7 @@ module.exports = {
getGraphEditUrlBySiteId,
getGraphEditUrlBySiteName,
getNetlifyGraphConfig,
loadNetlifyGraphConfig,
normalizeOperationsDoc: GraphQLHelpers.normalizeOperationsDoc,
parse,
readGraphQLOperationsSourceFile,
Expand Down
Loading

1 comment on commit 8f64f93

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📊 Benchmark results

Package size: 291 MB

Please sign in to comment.