netlify-cli 10.13.0 → 10.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +3 -2
  2. package/npm-shrinkwrap.json +1739 -2024
  3. package/package.json +8 -7
  4. package/src/commands/dev/dev.js +18 -3
  5. package/src/commands/functions/functions-invoke.js +4 -4
  6. package/src/commands/graph/graph-edit.js +4 -2
  7. package/src/commands/graph/graph-handler.js +41 -63
  8. package/src/commands/graph/graph-init.js +152 -0
  9. package/src/commands/graph/graph-library.js +30 -8
  10. package/src/commands/graph/graph-operations.js +6 -1
  11. package/src/commands/graph/graph-pull.js +79 -23
  12. package/src/commands/graph/graph.js +2 -0
  13. package/src/commands/login/login.js +1 -1
  14. package/src/commands/main.js +1 -1
  15. package/src/functions-templates/go/hello-world/go.mod +2 -2
  16. package/src/functions-templates/javascript/graphql-gateway/{{name}}.js +1 -1
  17. package/src/functions-templates/javascript/hello-world/{{name}}.js +1 -1
  18. package/src/functions-templates/javascript/identity-signup/{{name}}.js +1 -1
  19. package/src/functions-templates/javascript/serverless-ssr/app/index.js +1 -1
  20. package/src/functions-templates/javascript/stripe-charge/package-lock.json +6 -6
  21. package/src/functions-templates/javascript/stripe-subscription/package-lock.json +6 -6
  22. package/src/functions-templates/rust/hello-world/Cargo.toml +1 -1
  23. package/src/functions-templates/typescript/hello-world/package-lock.json +6 -6
  24. package/src/lib/edge-functions/proxy.js +4 -0
  25. package/src/lib/edge-functions/registry.js +29 -3
  26. package/src/lib/one-graph/cli-client.js +813 -170
  27. package/src/lib/one-graph/cli-netlify-graph.js +519 -50
  28. package/src/utils/dot-env.js +1 -1
  29. package/src/utils/init/utils.js +1 -1
  30. package/src/utils/proxy.js +2 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
3
  "description": "Netlify command line tool",
4
- "version": "10.13.0",
4
+ "version": "10.16.0",
5
5
  "author": "Netlify Inc.",
6
6
  "contributors": [
7
7
  "Abraham Schilling <AbrahamSchilling@gmail.com> (https://gitlab.com/n4bb12)",
@@ -26,6 +26,7 @@
26
26
  "Charlie Depman <cdepman@gmail.com> (depman.dev)",
27
27
  "Charlie Depman <cdepman@gmail.com> (depman.dev)",
28
28
  "Charlie Depman <cdepman@gmail.com> (depman.dev)",
29
+ "Chris Templin <ctemplin@gmail.com>",
29
30
  "Cole Bosmann",
30
31
  "Dan Croak (https://twitter.com/croaky)",
31
32
  "Dan Loewenherz <dan@lionheartsw.com> (https://twitter.com/dwlz)",
@@ -219,13 +220,13 @@
219
220
  "prettier": "--ignore-path .gitignore --loglevel=warn \"{src,tools,scripts,site,tests,.github}/**/*.{mjs,cjs,js,md,yml,json,html}\" \"*.{mjs,cjs,js,yml,json,html}\" \".*.{mjs,cjs,js,yml,json,html}\" \"!CHANGELOG.md\" \"!npm-shrinkwrap.json\" \"!**/*/package-lock.json\" \"!.github/**/*.md\""
220
221
  },
221
222
  "dependencies": {
222
- "@netlify/build": "^27.7.0",
223
+ "@netlify/build": "^27.8.1",
223
224
  "@netlify/config": "^18.1.2",
224
- "@netlify/edge-bundler": "^1.8.0",
225
- "@netlify/framework-info": "^9.1.1",
225
+ "@netlify/edge-bundler": "^1.12.1",
226
+ "@netlify/framework-info": "^9.2.0",
226
227
  "@netlify/local-functions-proxy": "^1.1.1",
227
- "@netlify/plugins-list": "^6.35.0",
228
- "@netlify/zip-it-and-ship-it": "^5.13.2",
228
+ "@netlify/plugins-list": "^6.37.0",
229
+ "@netlify/zip-it-and-ship-it": "^5.13.4",
229
230
  "@octokit/rest": "^18.0.0",
230
231
  "@sindresorhus/slugify": "^1.1.0",
231
232
  "ansi-escapes": "^5.0.0",
@@ -290,7 +291,7 @@
290
291
  "multiparty": "^4.2.1",
291
292
  "netlify": "^12.0.0",
292
293
  "netlify-headers-parser": "^6.0.2",
293
- "netlify-onegraph-internal": "0.3.10",
294
+ "netlify-onegraph-internal": "0.8.1",
294
295
  "netlify-redirect-parser": "^13.0.5",
295
296
  "netlify-redirector": "^0.2.1",
296
297
  "node-fetch": "^2.6.0",
@@ -233,6 +233,7 @@ const FRAMEWORK_PORT_TIMEOUT = 6e5
233
233
  * @param {object} params
234
234
  * @param {*} params.addonsUrls
235
235
  * @param {import('../base-command').NetlifyOptions["config"]} params.config
236
+ * @param {import('../base-command').NetlifyOptions["cachedConfig"]['env']} params.env
236
237
  * @param {InspectSettings} params.inspectSettings
237
238
  * @param {() => Promise<object>} params.getUpdatedConfig
238
239
  * @param {string} params.geolocationMode
@@ -247,6 +248,7 @@ const FRAMEWORK_PORT_TIMEOUT = 6e5
247
248
  const startProxyServer = async ({
248
249
  addonsUrls,
249
250
  config,
251
+ env,
250
252
  geoCountry,
251
253
  geolocationMode,
252
254
  getUpdatedConfig,
@@ -261,6 +263,7 @@ const startProxyServer = async ({
261
263
  addonsUrls,
262
264
  config,
263
265
  configPath: site.configPath,
266
+ env,
264
267
  geolocationMode,
265
268
  geoCountry,
266
269
  getUpdatedConfig,
@@ -479,6 +482,7 @@ const dev = async (options, command) => {
479
482
  let url = await startProxyServer({
480
483
  addonsUrls,
481
484
  config,
485
+ env: command.netlify.cachedConfig.env,
482
486
  geolocationMode: options.geo,
483
487
  geoCountry: options.country,
484
488
  getUpdatedConfig,
@@ -514,6 +518,9 @@ const dev = async (options, command) => {
514
518
 
515
519
  let stopWatchingCLISessions
516
520
 
521
+ let liveConfig = { ...config }
522
+ let isRestartingSession = false
523
+
517
524
  const createOrResumeSession = async function () {
518
525
  const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options, settings })
519
526
 
@@ -524,6 +531,7 @@ const dev = async (options, command) => {
524
531
  }
525
532
 
526
533
  stopWatchingCLISessions = await startOneGraphCLISession({
534
+ config: liveConfig,
527
535
  netlifyGraphConfig,
528
536
  netlifyToken,
529
537
  site,
@@ -535,6 +543,7 @@ const dev = async (options, command) => {
535
543
  const oneGraphSessionId = loadCLISession(state)
536
544
 
537
545
  await persistNewOperationsDocForSession({
546
+ config: liveConfig,
538
547
  netlifyGraphConfig,
539
548
  netlifyToken,
540
549
  oneGraphSessionId,
@@ -570,10 +579,16 @@ const dev = async (options, command) => {
570
579
  }
571
580
 
572
581
  // Set up a handler for config changes.
573
- configWatcher.on('change', (newConfig) => {
582
+ configWatcher.on('change', async (newConfig) => {
574
583
  command.netlify.config = newConfig
575
- stopWatchingCLISessions()
576
- createOrResumeSession()
584
+ liveConfig = newConfig
585
+ if (isRestartingSession) {
586
+ return
587
+ }
588
+ stopWatchingCLISessions && stopWatchingCLISessions()
589
+ isRestartingSession = true
590
+ await createOrResumeSession()
591
+ isRestartingSession = false
577
592
  })
578
593
 
579
594
  const oneGraphSessionId = await createOrResumeSession()
@@ -8,7 +8,7 @@ const fetch = require('node-fetch')
8
8
 
9
9
  const { BACKGROUND, CLOCKWORK_USERAGENT, NETLIFYDEVWARN, chalk, error, exit, getFunctions } = require('../../utils')
10
10
 
11
- // https://www.netlify.com/docs/functions/#event-triggered-functions
11
+ // https://docs.netlify.com/functions/trigger-on-events/
12
12
  const events = [
13
13
  'deploy-building',
14
14
  'deploy-succeeded',
@@ -161,10 +161,10 @@ const functionsInvoke = async (nameArgument, options, command) => {
161
161
  }
162
162
  } else if (eventTriggeredFunctions.has(functionToTrigger)) {
163
163
  /** handle event triggered fns */
164
- // https://www.netlify.com/docs/functions/#event-triggered-functions
164
+ // https://docs.netlify.com/functions/trigger-on-events/
165
165
  const [name, event] = functionToTrigger.split('-')
166
166
  if (name === 'identity') {
167
- // https://www.netlify.com/docs/functions/#identity-event-functions
167
+ // https://docs.netlify.com/functions/functions-and-identity/#trigger-functions-on-identity-events
168
168
  body.event = event
169
169
  body.user = {
170
170
  id: '1111a1a1-a11a-1111-aa11-aaa11111a11a',
@@ -182,7 +182,7 @@ const functionsInvoke = async (nameArgument, options, command) => {
182
182
  }
183
183
  } else {
184
184
  // non identity functions seem to have a different shape
185
- // https://www.netlify.com/docs/functions/#event-function-payloads
185
+ // https://docs.netlify.com/functions/trigger-on-events/#payload
186
186
  body.payload = {
187
187
  TODO: 'mock up payload data better',
188
188
  }
@@ -21,7 +21,7 @@ const { ensureAppForSite, executeCreatePersistedQueryMutation } = OneGraphCliCli
21
21
  * @returns
22
22
  */
23
23
  const graphEdit = async (options, command) => {
24
- const { site, state } = command.netlify
24
+ const { config, site, state } = command.netlify
25
25
  const siteId = site.id
26
26
 
27
27
  if (!site.id) {
@@ -44,10 +44,12 @@ const graphEdit = async (options, command) => {
44
44
  await ensureAppForSite(netlifyToken, siteId)
45
45
 
46
46
  const oneGraphSessionId = await ensureCLISession({
47
+ config,
47
48
  metadata: {},
48
49
  netlifyToken,
49
50
  site,
50
51
  state,
52
+ netlifyGraphConfig,
51
53
  })
52
54
 
53
55
  const { branch } = gitRepoInfo()
@@ -76,7 +78,7 @@ const graphEdit = async (options, command) => {
76
78
 
77
79
  const { jwt } = await OneGraphClient.getGraphJwtForSite({ siteId, nfToken: netlifyToken })
78
80
  await upsertMergeCLISessionMetadata({
79
- netlifyGraphConfig,
81
+ config,
80
82
  jwt,
81
83
  siteId,
82
84
  siteRoot: site.root,
@@ -1,29 +1,27 @@
1
+ /* eslint-disable eslint-comments/disable-enable-pair */
1
2
  // @ts-check
2
- const inquirer = require('inquirer')
3
- const { GraphQL } = require('netlify-onegraph-internal')
4
3
 
5
4
  const {
5
+ autocompleteCodegenModules,
6
+ autocompleteOperationNames,
6
7
  buildSchema,
7
- defaultExampleOperationsDoc,
8
- extractFunctionsFromOperationDoc,
9
8
  generateHandlerByOperationName,
9
+ getCodegenFunctionById,
10
+ getCodegenModule,
10
11
  getNetlifyGraphConfig,
11
- readGraphQLOperationsSourceFile,
12
12
  readGraphQLSchemaFile,
13
13
  } = require('../../lib/one-graph/cli-netlify-graph')
14
14
  const { error, log } = require('../../utils')
15
15
 
16
- const { parse } = GraphQL
17
-
18
16
  /**
19
17
  * Creates the `netlify graph:handler` command
20
- * @param {string} userOperationName
21
18
  * @param {import('commander').OptionValues} options
22
19
  * @param {import('../base-command').BaseCommand} command
23
20
  * @returns
24
21
  */
25
- const graphHandler = async (userOperationName, options, command) => {
22
+ const graphHandler = async (args, options, command) => {
26
23
  const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
24
+ const { config } = command.netlify
27
25
 
28
26
  const schemaString = readGraphQLSchemaFile(netlifyGraphConfig)
29
27
 
@@ -35,69 +33,48 @@ const graphHandler = async (userOperationName, options, command) => {
35
33
  error(`Error parsing schema: ${buildSchemaError}`)
36
34
  }
37
35
 
38
- if (!schema) {
39
- error(`Failed to parse Netlify GraphQL schema`)
40
- }
36
+ const userOperationName = args.operationName
37
+ const userCodegenId = options.codegen
41
38
 
42
39
  let operationName = userOperationName
43
40
  if (!operationName) {
44
- try {
45
- let currentOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig)
46
- if (currentOperationsDoc.trim().length === 0) {
47
- currentOperationsDoc = defaultExampleOperationsDoc
48
- }
49
-
50
- const parsedDoc = parse(currentOperationsDoc)
51
- const { functions } = extractFunctionsFromOperationDoc(parsedDoc)
52
-
53
- const sorted = Object.values(functions).sort((aItem, bItem) =>
54
- aItem.operationName.localeCompare(bItem.operationName),
55
- )
56
-
57
- const perPage = 50
58
-
59
- const allOperationChoices = sorted.map((operation) => ({
60
- name: `${operation.operationName} (${operation.kind})`,
61
- value: operation.operationName,
62
- }))
63
-
64
- const filterOperationNames = (operationChoices, input) =>
65
- operationChoices.filter((operation) => operation.value.toLowerCase().match(input.toLowerCase()))
66
-
67
- // eslint-disable-next-line n/global-require
68
- const inquirerAutocompletePrompt = require('inquirer-autocomplete-prompt')
69
- /** multiple matching detectors, make the user choose */
70
- inquirer.registerPrompt('autocomplete', inquirerAutocompletePrompt)
41
+ operationName = await autocompleteOperationNames({ netlifyGraphConfig })
42
+ }
71
43
 
72
- const { selectedOperationName } = await inquirer.prompt({
73
- name: 'selectedOperationName',
74
- message: `For which operation would you like to generate a handler?`,
75
- type: 'autocomplete',
76
- pageSize: perPage,
77
- source(_, input) {
78
- if (!input || input === '') {
79
- return allOperationChoices
80
- }
44
+ if (!operationName) {
45
+ error(`No operation name provided`)
46
+ }
81
47
 
82
- const filteredChoices = filterOperationNames(allOperationChoices, input)
83
- // only show filtered results
84
- return filteredChoices
85
- },
86
- })
48
+ const codegenModule = await getCodegenModule({ config })
49
+ if (!codegenModule) {
50
+ error(
51
+ `No Netlify Graph codegen module specified in netlify.toml under the [graph] header. Please specify 'codeGenerator' field and try again.`,
52
+ )
53
+ return
54
+ }
87
55
 
88
- if (selectedOperationName) {
89
- operationName = selectedOperationName
90
- }
91
- } catch (parseError) {
92
- parseError(`Error parsing operations library: ${parseError}`)
93
- }
56
+ let codeGenerator = userCodegenId ? await getCodegenFunctionById({ config, id: userCodegenId }) : null
57
+ if (!codeGenerator) {
58
+ codeGenerator = await autocompleteCodegenModules({ config })
94
59
  }
95
60
 
96
- if (!operationName) {
97
- error(`No operation name provided`)
61
+ if (!codeGenerator) {
62
+ error(`Unable to select appropriate Netlify Graph code generator`)
63
+ return
98
64
  }
99
65
 
100
- generateHandlerByOperationName({ logger: log, netlifyGraphConfig, schema, operationName, handlerOptions: {} })
66
+ if (schema) {
67
+ generateHandlerByOperationName({
68
+ generate: codeGenerator.generateHandler,
69
+ logger: log,
70
+ netlifyGraphConfig,
71
+ schema,
72
+ operationName,
73
+ handlerOptions: {},
74
+ })
75
+ } else {
76
+ error(`Failed to parse Netlify GraphQL schema`)
77
+ }
101
78
  }
102
79
 
103
80
  /**
@@ -109,11 +86,12 @@ const createGraphHandlerCommand = (program) =>
109
86
  program
110
87
  .command('graph:handler')
111
88
  .argument('[name]', 'Operation name')
89
+ .option('-c, --codegen <id>', 'The id of the specific code generator to use')
112
90
  .description(
113
91
  'Generate a handler for a Graph operation given its name. See `graph:operations` for a list of operations.',
114
92
  )
115
93
  .action(async (operationName, options, command) => {
116
- await graphHandler(operationName, options, command)
94
+ await graphHandler({ operationName }, options, command)
117
95
  })
118
96
 
119
97
  module.exports = { createGraphHandlerCommand }
@@ -0,0 +1,152 @@
1
+ // @ts-check
2
+ const { Buffer } = require('buffer')
3
+
4
+ const { OneGraphClient } = require('netlify-onegraph-internal')
5
+ const { v4: uuidv4 } = require('uuid')
6
+
7
+ const { OneGraphCliClient, ensureCLISession } = require('../../lib/one-graph/cli-client')
8
+ const { getNetlifyGraphConfig } = require('../../lib/one-graph/cli-netlify-graph')
9
+ const { NETLIFYDEVERR, chalk, error, exit, getToken, log } = require('../../utils')
10
+ const { msg } = require('../login/login')
11
+
12
+ const { ensureAppForSite, executeCreateApiTokenMutation } = OneGraphCliClient
13
+
14
+ /**
15
+ * Creates the `netlify graph:init` command
16
+ * @param {import('commander').OptionValues} options
17
+ * @param {import('../base-command').BaseCommand} command
18
+ * @returns
19
+ */
20
+ const graphInit = async (options, command) => {
21
+ const { api, config, site, state } = command.netlify
22
+ const siteId = site.id
23
+
24
+ if (!siteId) {
25
+ error(
26
+ `${NETLIFYDEVERR} Warning: no siteId defined, unable to start Netlify Graph. To enable, run ${chalk.yellow(
27
+ 'netlify init',
28
+ )} or ${chalk.yellow('netlify link')}`,
29
+ )
30
+ }
31
+
32
+ let [netlifyToken, loginLocation] = await getToken()
33
+ if (!netlifyToken) {
34
+ netlifyToken = await command.authenticate()
35
+ }
36
+
37
+ let siteData = null
38
+ try {
39
+ // @ts-ignore: we need better types for our api object
40
+ siteData = await api.getSite({ siteId })
41
+ } catch (error_) {
42
+ if (netlifyToken && error_.status === 401) {
43
+ log(`Already logged in ${msg(loginLocation)}`)
44
+ log()
45
+ log(`Run ${chalk.cyanBright('netlify status')} for account details`)
46
+ log()
47
+ log(`or run ${chalk.cyanBright('netlify switch')} to switch accounts`)
48
+ log()
49
+ log(`To see all available commands run: ${chalk.cyanBright('netlify help')}`)
50
+ log()
51
+ return exit()
52
+ }
53
+ throw error_
54
+ }
55
+
56
+ if (netlifyToken == null) {
57
+ error(
58
+ `${NETLIFYDEVERR} Error: Unable to start Netlify Graph without a login. To enable, run ${chalk.yellow(
59
+ 'netlify login',
60
+ )} first`,
61
+ )
62
+ return exit()
63
+ }
64
+
65
+ await ensureAppForSite(netlifyToken, siteId)
66
+
67
+ const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
68
+ await ensureCLISession({
69
+ config,
70
+ metadata: {},
71
+ netlifyToken,
72
+ site,
73
+ state,
74
+ netlifyGraphConfig,
75
+ })
76
+
77
+ let envChanged = false
78
+
79
+ // Get current environment variables set in the UI
80
+ const {
81
+ build_settings: { env = {} },
82
+ } = siteData
83
+
84
+ const newEnv = {
85
+ ...env,
86
+ }
87
+
88
+ if (!env.NETLIFY_GRAPH_WEBHOOK_SECRET) {
89
+ envChanged = true
90
+ const secret = Buffer.from(uuidv4()).toString('base64')
91
+ newEnv.NETLIFY_GRAPH_WEBHOOK_SECRET = secret
92
+ }
93
+
94
+ if (!env.NETLIFY_GRAPH_PERSIST_QUERY_TOKEN) {
95
+ const variables = {
96
+ input: {
97
+ appId: siteId,
98
+ scopes: ['MODIFY_SCHEMA', 'PERSIST_QUERY'],
99
+ },
100
+ }
101
+
102
+ const { jwt } = await OneGraphClient.getGraphJwtForSite({ siteId, nfToken: netlifyToken })
103
+ const result = await executeCreateApiTokenMutation(variables, {
104
+ siteId,
105
+ accessToken: jwt,
106
+ })
107
+
108
+ const token =
109
+ result.data &&
110
+ result.data.oneGraph &&
111
+ result.data.oneGraph.createApiToken &&
112
+ result.data.oneGraph.createApiToken.accessToken &&
113
+ result.data.oneGraph.createApiToken.accessToken.token
114
+
115
+ if (token) {
116
+ envChanged = true
117
+ newEnv.NETLIFY_GRAPH_PERSIST_QUERY_TOKEN = token
118
+ } else {
119
+ error(`Unable to create Netlify Graph persist query token: ${JSON.stringify(result.errors, null, 2)}`)
120
+ }
121
+ }
122
+
123
+ if (envChanged) {
124
+ // Apply environment variable updates
125
+ // @ts-ignore
126
+ await api.updateSite({
127
+ siteId,
128
+ body: {
129
+ build_settings: {
130
+ env: newEnv,
131
+ },
132
+ },
133
+ })
134
+
135
+ log(`Finished updating Graph-related environment variables for site ${siteData.name}`)
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Creates the `netlify graph:init` command
141
+ * @param {import('../base-command').BaseCommand} program
142
+ * @returns
143
+ */
144
+ const createGraphInitCommand = (program) =>
145
+ program
146
+ .command('graph:init')
147
+ .description('Initialize all the resources for Netlify Graph')
148
+ .action(async (options, command) => {
149
+ await graphInit(options, command)
150
+ })
151
+
152
+ module.exports = { createGraphInitCommand }
@@ -1,4 +1,7 @@
1
1
  // @ts-check
2
+ const { GraphQL } = require('netlify-onegraph-internal')
3
+
4
+ const { readLockfile } = require('../../lib/one-graph/cli-client')
2
5
  const {
3
6
  buildSchema,
4
7
  defaultExampleOperationsDoc,
@@ -9,7 +12,7 @@ const {
9
12
  readGraphQLOperationsSourceFile,
10
13
  readGraphQLSchemaFile,
11
14
  } = require('../../lib/one-graph/cli-netlify-graph')
12
- const { error, log } = require('../../utils')
15
+ const { NETLIFYDEVERR, chalk, error, log } = require('../../utils')
13
16
 
14
17
  /**
15
18
  * Creates the `netlify graph:library` command
@@ -18,10 +21,19 @@ const { error, log } = require('../../utils')
18
21
  * @returns
19
22
  */
20
23
  const graphLibrary = async (options, command) => {
24
+ const { config } = command.netlify
21
25
  const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
22
26
 
23
27
  const schemaString = readGraphQLSchemaFile(netlifyGraphConfig)
24
28
 
29
+ let currentOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig)
30
+ if (currentOperationsDoc.trim().length === 0) {
31
+ currentOperationsDoc = defaultExampleOperationsDoc
32
+ }
33
+
34
+ const parsedDoc = parse(currentOperationsDoc)
35
+ const { fragments, functions } = extractFunctionsFromOperationDoc(GraphQL, parsedDoc)
36
+
25
37
  let schema
26
38
 
27
39
  try {
@@ -32,24 +44,34 @@ const graphLibrary = async (options, command) => {
32
44
 
33
45
  if (!schema) {
34
46
  error(`Failed to parse Netlify GraphQL schema`)
47
+ return
35
48
  }
36
49
 
37
- let currentOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig)
38
- if (currentOperationsDoc.trim().length === 0) {
39
- currentOperationsDoc = defaultExampleOperationsDoc
50
+ const lockfile = readLockfile({ siteRoot: command.netlify.site.root })
51
+
52
+ if (lockfile === undefined) {
53
+ error(
54
+ `${NETLIFYDEVERR} Error: no lockfile found, unable to run \`netlify graph:library\`. To pull a remote schema (and create a lockfile), run ${chalk.yellow(
55
+ 'netlify graph:pull',
56
+ )} `,
57
+ )
58
+ return
40
59
  }
41
60
 
42
- const parsedDoc = parse(currentOperationsDoc)
43
- const { fragments, functions } = extractFunctionsFromOperationDoc(parsedDoc)
61
+ const { schemaId } = lockfile.locked
44
62
 
45
- generateFunctionsFile({
63
+ const payload = {
64
+ config,
46
65
  logger: log,
47
66
  netlifyGraphConfig,
48
67
  schema,
68
+ schemaId,
49
69
  operationsDoc: currentOperationsDoc,
50
70
  functions,
51
71
  fragments,
52
- })
72
+ }
73
+
74
+ generateFunctionsFile(payload)
53
75
  }
54
76
 
55
77
  /**
@@ -26,13 +26,18 @@ const graphOperations = async (options, command) => {
26
26
  }
27
27
 
28
28
  const parsedDoc = parse(currentOperationsDoc)
29
- const { fragments, functions } = extractFunctionsFromOperationDoc(parsedDoc)
29
+ const { fragments, functions } = extractFunctionsFromOperationDoc(GraphQL, parsedDoc)
30
30
 
31
31
  const sorted = {
32
+ /** @type {import('netlify-onegraph-internal/dist/netlifyGraph').ExtractedFunction[]} */
32
33
  queries: [],
34
+ /** @type {import('netlify-onegraph-internal/dist/netlifyGraph').ExtractedFunction[]} */
33
35
  mutations: [],
36
+ /** @type {import('netlify-onegraph-internal/dist/netlifyGraph').ExtractedFunction[]} */
34
37
  subscriptions: [],
38
+ /** @type {import('netlify-onegraph-internal/dist/netlifyGraph').ExtractedFragment[]} */
35
39
  fragments: [],
40
+ /** @type {any[]} */
36
41
  other: [],
37
42
  }
38
43