netlify-cli 8.10.2 → 8.13.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.
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
3
  "description": "Netlify command line tool",
4
- "version": "8.10.2",
4
+ "version": "8.13.0",
5
5
  "author": "Netlify Inc.",
6
6
  "contributors": [
7
7
  "Mathias Biilmann <matt@netlify.com> (https://twitter.com/biilmann)",
8
8
  "David Calavera <david@netlify.com> (https://twitter.com/calavera)",
9
9
  "David Wells <david.wells@netlify.com> (https://davidwells.io/)",
10
10
  "Raees Iqbal <raees@netlify.com> (https://raeesbhatti.com/)",
11
- "Bret Comnes <bcomnes@gmail.com> (https://bret.io)"
11
+ "Bret Comnes <bcomnes@gmail.com> (https://bret.io)",
12
+ "Sean Grove <sean.s.grove@netlify.com> (https://twitter.com/sgrove)"
12
13
  ],
13
14
  "engines": {
14
15
  "node": "^12.20.0 || ^14.14.0 || >=16.0.0"
@@ -76,14 +77,14 @@
76
77
  "prettier": "--ignore-path .gitignore --loglevel=warn \"{src,tools,scripts,site,tests,.github}/**/*.{js,md,yml,json,html}\" \"*.{js,yml,json,html}\" \".*.{js,yml,json,html}\" \"!CHANGELOG.md\" \"!npm-shrinkwrap.json\" \"!.github/**/*.md\""
77
78
  },
78
79
  "dependencies": {
79
- "@netlify/build": "^26.1.7",
80
+ "@netlify/build": "^26.2.0",
80
81
  "@netlify/config": "^17.0.3",
81
82
  "@netlify/framework-info": "^9.0.0",
82
83
  "@netlify/local-functions-proxy": "^1.1.1",
83
84
  "@netlify/plugin-edge-handlers": "^3.0.4",
84
- "@netlify/plugins-list": "^6.3.0",
85
+ "@netlify/plugins-list": "^6.3.1",
85
86
  "@netlify/routing-local-proxy": "^0.34.1",
86
- "@netlify/zip-it-and-ship-it": "^5.4.1",
87
+ "@netlify/zip-it-and-ship-it": "^5.5.0",
87
88
  "@octokit/rest": "^18.0.0",
88
89
  "@sindresorhus/slugify": "^1.1.0",
89
90
  "ansi-escapes": "^5.0.0",
@@ -121,6 +122,7 @@
121
122
  "gh-release-fetch": "^3.0.0",
122
123
  "git-repo-info": "^2.1.0",
123
124
  "gitconfiglocal": "^2.1.0",
125
+ "graphql": "^16.1.0",
124
126
  "hasbin": "^1.2.3",
125
127
  "hasha": "^5.2.2",
126
128
  "http-proxy": "^1.18.0",
@@ -144,6 +146,7 @@
144
146
  "multiparty": "^4.2.1",
145
147
  "netlify": "^10.1.2",
146
148
  "netlify-headers-parser": "^6.0.1",
149
+ "netlify-onegraph-internal": "0.0.15",
147
150
  "netlify-redirect-parser": "^13.0.1",
148
151
  "netlify-redirector": "^0.2.1",
149
152
  "node-fetch": "^2.6.0",
@@ -182,7 +185,7 @@
182
185
  },
183
186
  "devDependencies": {
184
187
  "@babel/preset-react": "^7.12.13",
185
- "@netlify/eslint-config-node": "^4.1.5",
188
+ "@netlify/eslint-config-node": "^4.1.6",
186
189
  "ava": "^3.15.0",
187
190
  "c8": "^7.11.0",
188
191
  "eslint-plugin-sort-destructure-keys": "^1.3.5",
@@ -11,6 +11,8 @@ const stripAnsiCc = require('strip-ansi-control-characters')
11
11
  const waitPort = require('wait-port')
12
12
 
13
13
  const { startFunctionsServer } = require('../../lib/functions/server')
14
+ const { OneGraphCliClient, startOneGraphCLISession } = require('../../lib/one-graph/cli-client')
15
+ const { getNetlifyGraphConfig } = require('../../lib/one-graph/cli-netlify-graph')
14
16
  const {
15
17
  NETLIFYDEV,
16
18
  NETLIFYDEVERR,
@@ -18,6 +20,7 @@ const {
18
20
  NETLIFYDEVWARN,
19
21
  chalk,
20
22
  detectServerSettings,
23
+ error,
21
24
  exit,
22
25
  getSiteInformation,
23
26
  injectEnvVariables,
@@ -46,10 +49,10 @@ const startStaticServer = async ({ settings }) => {
46
49
  log(`\n${NETLIFYDEVLOG} Static server listening to`, settings.frameworkPort)
47
50
  }
48
51
 
49
- const isNonExistingCommandError = ({ command, error }) => {
52
+ const isNonExistingCommandError = ({ command, error: commandError }) => {
50
53
  // `ENOENT` is only returned for non Windows systems
51
54
  // See https://github.com/sindresorhus/execa/pull/447
52
- if (error.code === 'ENOENT') {
55
+ if (commandError.code === 'ENOENT') {
53
56
  return true
54
57
  }
55
58
 
@@ -60,7 +63,8 @@ const isNonExistingCommandError = ({ command, error }) => {
60
63
 
61
64
  // this only works on English versions of Windows
62
65
  return (
63
- typeof error.message === 'string' && error.message.includes('is not recognized as an internal or external command')
66
+ typeof commandError.message === 'string' &&
67
+ commandError.message.includes('is not recognized as an internal or external command')
64
68
  )
65
69
  }
66
70
 
@@ -231,7 +235,7 @@ const printBanner = ({ url }) => {
231
235
  */
232
236
  const dev = async (options, command) => {
233
237
  log(`${NETLIFYDEV}`)
234
- const { api, config, site, siteInfo } = command.netlify
238
+ const { api, config, site, siteInfo, state } = command.netlify
235
239
  config.dev = { ...config.dev }
236
240
  config.build = { ...config.build }
237
241
  /** @type {import('./types').DevConfig} */
@@ -262,8 +266,8 @@ const dev = async (options, command) => {
262
266
  let settings = {}
263
267
  try {
264
268
  settings = await detectServerSettings(devConfig, options, site.root)
265
- } catch (error) {
266
- log(NETLIFYDEVERR, error.message)
269
+ } catch (error_) {
270
+ log(NETLIFYDEVERR, error_.message)
267
271
  exit(1)
268
272
  }
269
273
 
@@ -291,6 +295,26 @@ const dev = async (options, command) => {
291
295
  process.env.URL = url
292
296
  process.env.DEPLOY_URL = url
293
297
 
298
+ const startNetlifyGraphWatcher = Boolean(options.graph)
299
+
300
+ if (startNetlifyGraphWatcher && options.offline) {
301
+ warn(`Unable to start Netlify Graph in offline mode`)
302
+ } else if (startNetlifyGraphWatcher && !site.id) {
303
+ error(
304
+ `No siteId defined, unable to start Netlify Graph. To enable, run ${chalk.yellow(
305
+ 'netlify init',
306
+ )} or ${chalk.yellow('netlify link')}.`,
307
+ )
308
+ } else if (startNetlifyGraphWatcher) {
309
+ const netlifyToken = await command.authenticate()
310
+ await OneGraphCliClient.ensureAppForSite(netlifyToken, site.id)
311
+ const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
312
+
313
+ log(`Starting Netlify Graph session, to edit your library run \`netlify graph:edit\` in another tab`)
314
+
315
+ startOneGraphCLISession({ netlifyGraphConfig, netlifyToken, site, state })
316
+ }
317
+
294
318
  printBanner({ url })
295
319
  }
296
320
 
@@ -335,7 +359,13 @@ const createDevCommand = (program) => {
335
359
  'specify the path to a local GeoIP location database in MMDB format',
336
360
  ).hideHelp(),
337
361
  )
338
- .addExamples(['netlify dev', 'netlify dev -d public', 'netlify dev -c "hugo server -w" --targetPort 1313'])
362
+ .addOption(new Option('--graph', 'enable Netlify Graph support').hideHelp())
363
+ .addExamples([
364
+ 'netlify dev',
365
+ 'netlify dev -d public',
366
+ 'netlify dev -c "hugo server -w" --targetPort 1313',
367
+ 'BROWSER=none netlify dev # disable browser auto opening',
368
+ ])
339
369
  .action(dev)
340
370
  }
341
371
  module.exports = { createDevCommand }
@@ -0,0 +1,91 @@
1
+ const gitRepoInfo = require('git-repo-info')
2
+
3
+ const { OneGraphCliClient, generateSessionName, loadCLISession } = require('../../lib/one-graph/cli-client')
4
+ const {
5
+ defaultExampleOperationsDoc,
6
+ getGraphEditUrlBySiteName,
7
+ getNetlifyGraphConfig,
8
+ readGraphQLOperationsSourceFile,
9
+ } = require('../../lib/one-graph/cli-netlify-graph')
10
+ const { NETLIFYDEVERR, chalk, error } = require('../../utils')
11
+ const { openBrowser } = require('../../utils/open-browser')
12
+
13
+ const { createCLISession, createPersistedQuery, ensureAppForSite, updateCLISessionMetadata } = OneGraphCliClient
14
+
15
+ /**
16
+ * Creates the `netlify graph:edit` command
17
+ * @param {import('commander').OptionValues} options
18
+ * @param {import('../base-command').BaseCommand} program
19
+ * @returns
20
+ */
21
+ const graphEdit = async (options, command) => {
22
+ const { api, site, siteInfo, state } = command.netlify
23
+ const siteId = site.id
24
+
25
+ if (!site.id) {
26
+ error(
27
+ `${NETLIFYDEVERR} Warning: no siteId defined, unable to start Netlify Graph. To enable, run ${chalk.yellow(
28
+ 'netlify init',
29
+ )} or ${chalk.yellow('netlify link')}`,
30
+ )
31
+ }
32
+ const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
33
+
34
+ const { branch } = gitRepoInfo()
35
+
36
+ let graphqlDocument = readGraphQLOperationsSourceFile(netlifyGraphConfig)
37
+
38
+ if (graphqlDocument.trim().length === 0) {
39
+ graphqlDocument = defaultExampleOperationsDoc
40
+ }
41
+
42
+ const netlifyToken = await command.authenticate()
43
+
44
+ await ensureAppForSite(netlifyToken, siteId)
45
+
46
+ let oneGraphSessionId = loadCLISession(state)
47
+ if (!oneGraphSessionId) {
48
+ const sessionName = generateSessionName()
49
+ const oneGraphSession = await createCLISession(netlifyToken, site.id, sessionName)
50
+ state.set('oneGraphSessionId', oneGraphSession.id)
51
+ oneGraphSessionId = state.get('oneGraphSessionId')
52
+ }
53
+
54
+ const persistedDoc = await createPersistedQuery(netlifyToken, {
55
+ appId: siteId,
56
+ description: 'Temporary snapshot of local queries',
57
+ document: graphqlDocument,
58
+ tags: ['netlify-cli', `session:${oneGraphSessionId}`, `git-branch:${branch}`],
59
+ })
60
+
61
+ await updateCLISessionMetadata(netlifyToken, siteId, oneGraphSessionId, { docId: persistedDoc.id })
62
+
63
+ let siteName = siteInfo.name
64
+
65
+ if (!siteName) {
66
+ const siteData = await api.getSite({ siteId })
67
+ siteName = siteData.name
68
+ if (!siteName) {
69
+ error(`No site name found for siteId ${siteId}`)
70
+ }
71
+ }
72
+
73
+ const graphEditUrl = getGraphEditUrlBySiteName({ siteName, oneGraphSessionId })
74
+
75
+ await openBrowser({ url: graphEditUrl })
76
+ }
77
+
78
+ /**
79
+ * Creates the `netlify graph:edit` command
80
+ * @param {import('../base-command').BaseCommand} program
81
+ * @returns
82
+ */
83
+ const createGraphEditCommand = (program) =>
84
+ program
85
+ .command('graph:edit')
86
+ .description('Launch the browser to edit your local graph functions from Netlify')
87
+ .action(async (options, command) => {
88
+ await graphEdit(options, command)
89
+ })
90
+
91
+ module.exports = { createGraphEditCommand }
@@ -0,0 +1,95 @@
1
+ /* eslint-disable eslint-comments/disable-enable-pair */
2
+ /* eslint-disable fp/no-loops */
3
+ const {
4
+ OneGraphCliClient,
5
+ handleCliSessionEvent,
6
+ loadCLISession,
7
+ refetchAndGenerateFromOneGraph,
8
+ } = require('../../lib/one-graph/cli-client')
9
+ const { buildSchema, getNetlifyGraphConfig, readGraphQLSchemaFile } = require('../../lib/one-graph/cli-netlify-graph')
10
+ const { chalk, error, warn } = require('../../utils')
11
+
12
+ /**
13
+ * Creates the `netlify graph:pull` command
14
+ * @param {import('commander').OptionValues} options
15
+ * @param {import('../base-command').BaseCommand} program
16
+ * @returns
17
+ */
18
+ const graphPull = async (options, command) => {
19
+ const { site, state } = command.netlify
20
+
21
+ if (!site.id) {
22
+ error(
23
+ `No siteId defined, unable to start Netlify Graph. To enable, run ${chalk.yellow(
24
+ 'netlify init',
25
+ )} or ${chalk.yellow('netlify link')}`,
26
+ )
27
+ }
28
+
29
+ const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
30
+ const netlifyToken = await command.authenticate()
31
+ const siteId = site.id
32
+
33
+ await refetchAndGenerateFromOneGraph({ netlifyGraphConfig, netlifyToken, state, siteId })
34
+
35
+ const oneGraphSessionId = loadCLISession(state)
36
+
37
+ if (!oneGraphSessionId) {
38
+ warn('No local Netlify Graph session found, skipping command queue drain')
39
+ return
40
+ }
41
+
42
+ const schemaString = readGraphQLSchemaFile(netlifyGraphConfig)
43
+
44
+ let schema
45
+
46
+ try {
47
+ schema = buildSchema(schemaString)
48
+ } catch (buildSchemaError) {
49
+ error(`Error parsing schema: ${buildSchemaError}`)
50
+ }
51
+
52
+ if (!schema) {
53
+ error(`Failed to fetch and update Netlify GraphQL schema`)
54
+ }
55
+
56
+ const next = await OneGraphCliClient.fetchCliSessionEvents({
57
+ appId: siteId,
58
+ authToken: netlifyToken,
59
+ sessionId: oneGraphSessionId,
60
+ })
61
+
62
+ if (next.errors) {
63
+ error(`Failed to fetch Netlify Graph cli session events`, next.errors)
64
+ }
65
+
66
+ if (next.events) {
67
+ const ackIds = []
68
+ for (const event of next.events) {
69
+ await handleCliSessionEvent({ netlifyToken, event, netlifyGraphConfig, schema, siteId: site.id })
70
+ ackIds.push(event.id)
71
+ }
72
+
73
+ await OneGraphCliClient.ackCLISessionEvents({
74
+ appId: siteId,
75
+ authToken: netlifyToken,
76
+ sessionId: oneGraphSessionId,
77
+ eventIds: ackIds,
78
+ })
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Creates the `netlify graph:pull` command
84
+ * @param {import('../base-command').BaseCommand} program
85
+ * @returns
86
+ */
87
+ const createGraphPullCommand = (program) =>
88
+ program
89
+ .command('graph:pull')
90
+ .description('Pull down your local Netlify Graph schema, and process pending Graph edit events')
91
+ .action(async (options, command) => {
92
+ await graphPull(options, command)
93
+ })
94
+
95
+ module.exports = { createGraphPullCommand }
@@ -0,0 +1,30 @@
1
+ // @ts-check
2
+ const { createGraphEditCommand } = require('./graph-edit')
3
+ const { createGraphPullCommand } = require('./graph-pull')
4
+
5
+ /**
6
+ * The graph command
7
+ * @param {import('commander').OptionValues} options
8
+ * @param {import('../base-command').BaseCommand} command
9
+ */
10
+ const graph = (options, command) => {
11
+ command.help()
12
+ }
13
+
14
+ /**
15
+ * Creates the `netlify graph` command
16
+ * @param {import('../base-command').BaseCommand} program
17
+ * @returns
18
+ */
19
+ const createGraphCommand = (program) => {
20
+ createGraphEditCommand(program)
21
+ createGraphPullCommand(program)
22
+
23
+ return program
24
+ .command('graph')
25
+ .description('(Beta) Control the Netlify Graph functions for the current site')
26
+ .addExamples(['netlify graph:pull', 'netlify graph:edit'])
27
+ .action(graph)
28
+ }
29
+
30
+ module.exports = { createGraphCommand }
@@ -0,0 +1,5 @@
1
+ const { createGraphCommand } = require('./graph')
2
+
3
+ module.exports = {
4
+ createGraphCommand,
5
+ }
@@ -29,6 +29,7 @@ const { createDeployCommand } = require('./deploy')
29
29
  const { createDevCommand } = require('./dev')
30
30
  const { createEnvCommand } = require('./env')
31
31
  const { createFunctionsCommand } = require('./functions')
32
+ const { createGraphCommand } = require('./graph')
32
33
  const { createInitCommand } = require('./init')
33
34
  const { createLinkCommand } = require('./link')
34
35
  const { createLmCommand } = require('./lm')
@@ -170,6 +171,7 @@ const createMainCommand = () => {
170
171
  createDevCommand(program)
171
172
  createEnvCommand(program)
172
173
  createFunctionsCommand(program)
174
+ createGraphCommand(program)
173
175
  createInitCommand(program)
174
176
  createLinkCommand(program)
175
177
  createLmCommand(program)
@@ -9,15 +9,15 @@
9
9
  "version": "1.0.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@netlify/functions": "^0.10.0",
13
- "@types/node": "^14.18.5",
12
+ "@netlify/functions": "^0.11.0",
13
+ "@types/node": "^14.0.0",
14
14
  "typescript": "^4.0.0"
15
15
  }
16
16
  },
17
17
  "node_modules/@netlify/functions": {
18
- "version": "0.10.0",
19
- "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-0.10.0.tgz",
20
- "integrity": "sha512-NNFADTPnokuoMY1OUhaXlE/Jrzk5lHOl1uB4L/8pw1UJ/CaectZJACMExijbJnqaKIhOQG0WmbBQUh1lgnK/Qg==",
18
+ "version": "0.11.0",
19
+ "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-0.11.0.tgz",
20
+ "integrity": "sha512-+WWX081UCkLZYkfh1Ru+PH5HTujNXugeskATGhZLTyS1U3Cqh2gYLArdG1a/vU8WWopu/wjpxEOdWq8/T5Nw5Q==",
21
21
  "dependencies": {
22
22
  "is-promise": "^4.0.0"
23
23
  },
@@ -50,9 +50,9 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@netlify/functions": {
53
- "version": "0.10.0",
54
- "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-0.10.0.tgz",
55
- "integrity": "sha512-NNFADTPnokuoMY1OUhaXlE/Jrzk5lHOl1uB4L/8pw1UJ/CaectZJACMExijbJnqaKIhOQG0WmbBQUh1lgnK/Qg==",
53
+ "version": "0.11.0",
54
+ "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-0.11.0.tgz",
55
+ "integrity": "sha512-+WWX081UCkLZYkfh1Ru+PH5HTujNXugeskATGhZLTyS1U3Cqh2gYLArdG1a/vU8WWopu/wjpxEOdWq8/T5Nw5Q==",
56
56
  "requires": {
57
57
  "is-promise": "^4.0.0"
58
58
  }
@@ -14,7 +14,7 @@
14
14
  "author": "Netlify",
15
15
  "license": "MIT",
16
16
  "dependencies": {
17
- "@netlify/functions": "^0.10.0",
17
+ "@netlify/functions": "^0.11.0",
18
18
  "@types/node": "^14.0.0",
19
19
  "typescript": "^4.0.0"
20
20
  }
@@ -13,6 +13,7 @@ const normalizeFunctionsConfig = ({ functionsConfig = {}, projectRoot }) =>
13
13
  nodeBundler: config.node_bundler === 'esbuild' ? 'esbuild_zisi' : config.node_bundler,
14
14
  processDynamicNodeImports: true,
15
15
  schedule: config.schedule,
16
+ zipGo: true,
16
17
  },
17
18
  }),
18
19
  {},