netlify-cli 9.2.0 → 9.3.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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
- "version": "9.2.0",
3
+ "version": "9.3.0",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "netlify-cli",
9
- "version": "9.2.0",
9
+ "version": "9.3.0",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
@@ -82,7 +82,7 @@
82
82
  "multiparty": "^4.2.1",
83
83
  "netlify": "^11.0.0",
84
84
  "netlify-headers-parser": "^6.0.1",
85
- "netlify-onegraph-internal": "0.0.39",
85
+ "netlify-onegraph-internal": "0.0.42",
86
86
  "netlify-redirect-parser": "^13.0.2",
87
87
  "netlify-redirector": "^0.2.1",
88
88
  "node-fetch": "^2.6.0",
@@ -16484,9 +16484,9 @@
16484
16484
  }
16485
16485
  },
16486
16486
  "node_modules/netlify-onegraph-internal": {
16487
- "version": "0.0.39",
16488
- "resolved": "https://registry.npmjs.org/netlify-onegraph-internal/-/netlify-onegraph-internal-0.0.39.tgz",
16489
- "integrity": "sha512-ekx1INpJGTU2t6TkvlnzFXuaFGrf5PM9we13Oq4mFbynhfuwN3NmnDRSIGl2g6ae9ZpvzTCVSIr13u/HMWjxpA==",
16487
+ "version": "0.0.42",
16488
+ "resolved": "https://registry.npmjs.org/netlify-onegraph-internal/-/netlify-onegraph-internal-0.0.42.tgz",
16489
+ "integrity": "sha512-p9pxhXRmDtwxIcLE/H5iq+NfsjaoOQrBs00Ynac+0XWg3UoSsFenhTiY4lWBK3RbwpZqtkv+v4Z8eO+10YDr5w==",
16490
16490
  "dependencies": {
16491
16491
  "graphql": "16.0.0",
16492
16492
  "node-fetch": "^2.6.0",
@@ -35806,9 +35806,9 @@
35806
35806
  }
35807
35807
  },
35808
35808
  "netlify-onegraph-internal": {
35809
- "version": "0.0.39",
35810
- "resolved": "https://registry.npmjs.org/netlify-onegraph-internal/-/netlify-onegraph-internal-0.0.39.tgz",
35811
- "integrity": "sha512-ekx1INpJGTU2t6TkvlnzFXuaFGrf5PM9we13Oq4mFbynhfuwN3NmnDRSIGl2g6ae9ZpvzTCVSIr13u/HMWjxpA==",
35809
+ "version": "0.0.42",
35810
+ "resolved": "https://registry.npmjs.org/netlify-onegraph-internal/-/netlify-onegraph-internal-0.0.42.tgz",
35811
+ "integrity": "sha512-p9pxhXRmDtwxIcLE/H5iq+NfsjaoOQrBs00Ynac+0XWg3UoSsFenhTiY4lWBK3RbwpZqtkv+v4Z8eO+10YDr5w==",
35812
35812
  "requires": {
35813
35813
  "graphql": "16.0.0",
35814
35814
  "node-fetch": "^2.6.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": "9.2.0",
4
+ "version": "9.3.0",
5
5
  "author": "Netlify Inc.",
6
6
  "contributors": [
7
7
  "Abraham Schilling <AbrahamSchilling@gmail.com> (https://gitlab.com/n4bb12)",
@@ -164,7 +164,6 @@
164
164
  "url": "https://github.com/netlify/cli/issues"
165
165
  },
166
166
  "scripts": {
167
- "snap": "ava --verbose -u tests/integration/**/*graph*.test.js",
168
167
  "prepare": "husky install node_modules/@netlify/eslint-config-node/.husky/",
169
168
  "start": "node ./bin/run",
170
169
  "test": "run-s format test:dev",
@@ -271,7 +270,7 @@
271
270
  "multiparty": "^4.2.1",
272
271
  "netlify": "^11.0.0",
273
272
  "netlify-headers-parser": "^6.0.1",
274
- "netlify-onegraph-internal": "0.0.39",
273
+ "netlify-onegraph-internal": "0.0.42",
275
274
  "netlify-redirect-parser": "^13.0.2",
276
275
  "netlify-redirector": "^0.2.1",
277
276
  "node-fetch": "^2.6.0",
@@ -1,7 +1,13 @@
1
1
  // @ts-check
2
2
  const gitRepoInfo = require('git-repo-info')
3
3
 
4
- const { OneGraphCliClient, generateSessionName, loadCLISession } = require('../../lib/one-graph/cli-client')
4
+ const {
5
+ OneGraphCliClient,
6
+ createCLISession,
7
+ generateSessionName,
8
+ loadCLISession,
9
+ upsertMergeCLISessionMetadata,
10
+ } = require('../../lib/one-graph/cli-client')
5
11
  const {
6
12
  defaultExampleOperationsDoc,
7
13
  getGraphEditUrlBySiteId,
@@ -11,7 +17,7 @@ const {
11
17
  const { NETLIFYDEVERR, chalk, error } = require('../../utils')
12
18
  const { openBrowser } = require('../../utils/open-browser')
13
19
 
14
- const { createCLISession, createPersistedQuery, ensureAppForSite, updateCLISessionMetadata } = OneGraphCliClient
20
+ const { createPersistedQuery, ensureAppForSite } = OneGraphCliClient
15
21
 
16
22
  /**
17
23
  * Creates the `netlify graph:edit` command
@@ -32,8 +38,6 @@ const graphEdit = async (options, command) => {
32
38
  }
33
39
  const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
34
40
 
35
- const { branch } = gitRepoInfo()
36
-
37
41
  let graphqlDocument = readGraphQLOperationsSourceFile(netlifyGraphConfig)
38
42
 
39
43
  if (graphqlDocument.trim().length === 0) {
@@ -47,11 +51,12 @@ const graphEdit = async (options, command) => {
47
51
  let oneGraphSessionId = loadCLISession(state)
48
52
  if (!oneGraphSessionId) {
49
53
  const sessionName = generateSessionName()
50
- const oneGraphSession = await createCLISession(netlifyToken, site.id, sessionName, null)
54
+ const oneGraphSession = await createCLISession({ netlifyToken, siteId: site.id, sessionName, metadata: {} })
51
55
  state.set('oneGraphSessionId', oneGraphSession.id)
52
56
  oneGraphSessionId = state.get('oneGraphSessionId')
53
57
  }
54
58
 
59
+ const { branch } = gitRepoInfo()
55
60
  const persistedDoc = await createPersistedQuery(netlifyToken, {
56
61
  appId: siteId,
57
62
  description: 'Temporary snapshot of local queries',
@@ -59,7 +64,16 @@ const graphEdit = async (options, command) => {
59
64
  tags: ['netlify-cli', `session:${oneGraphSessionId}`, `git-branch:${branch}`],
60
65
  })
61
66
 
62
- await updateCLISessionMetadata(netlifyToken, siteId, oneGraphSessionId, { docId: persistedDoc.id })
67
+ const newMetadata = { docId: persistedDoc.id }
68
+
69
+ await upsertMergeCLISessionMetadata({
70
+ netlifyGraphConfig,
71
+ netlifyToken,
72
+ siteId,
73
+ siteRoot: site.root,
74
+ oneGraphSessionId,
75
+ newMetadata,
76
+ })
63
77
 
64
78
  const graphEditUrl = getGraphEditUrlBySiteId({ siteId, oneGraphSessionId })
65
79
 
@@ -24,7 +24,7 @@ const {
24
24
 
25
25
  const { parse } = GraphQL
26
26
  const { defaultExampleOperationsDoc, extractFunctionsFromOperationDoc } = NetlifyGraph
27
- const { createCLISession, createPersistedQuery, ensureAppForSite, updateCLISessionMetadata } = OneGraphClient
27
+ const { createPersistedQuery, ensureAppForSite, updateCLISessionMetadata } = OneGraphClient
28
28
 
29
29
  const internalConsole = {
30
30
  log,
@@ -284,9 +284,89 @@ const handleCliSessionEvent = async ({ event, netlifyGraphConfig, netlifyToken,
284
284
  }
285
285
  }
286
286
 
287
- const persistNewOperationsDocForSession = async ({ netlifyToken, oneGraphSessionId, operationsDoc, siteId }) => {
287
+ /**
288
+ *
289
+ * @param {object} input
290
+ * @param {string} input.netlifyToken The (typically netlify) access token that is used for authentication, if any
291
+ * @param {string} input.oneGraphSessionId The id of the cli session to fetch the current metadata for
292
+ * @param {object} input.siteId The site object that contains the root file path for the site
293
+ */
294
+ const getCLISession = async ({ netlifyToken, oneGraphSessionId, siteId }) => {
295
+ const input = {
296
+ appId: siteId,
297
+ sessionId: oneGraphSessionId,
298
+ authToken: netlifyToken,
299
+ desiredEventCount: 1,
300
+ }
301
+ return await OneGraphClient.fetchCliSession(input)
302
+ }
303
+
304
+ /**
305
+ *
306
+ * @param {object} input
307
+ * @param {string} input.netlifyToken The (typically netlify) access token that is used for authentication, if any
308
+ * @param {string} input.oneGraphSessionId The id of the cli session to fetch the current metadata for
309
+ * @param {string} input.siteId The site object that contains the root file path for the site
310
+ */
311
+ const getCLISessionMetadata = async ({ netlifyToken, oneGraphSessionId, siteId }) => {
312
+ const { errors, session } = await getCLISession({ netlifyToken, oneGraphSessionId, siteId })
313
+ return { metadata: session && session.metadata, errors }
314
+ }
315
+
316
+ /**
317
+ * Look at the current project, filesystem, etc. and determine relevant metadata for a cli session
318
+ * @param {object} input
319
+ * @param {string} input.siteRoot The root file path for the site
320
+ * @returns {Record<string, any>} Any locally detected facts that are relevant to include in the cli session metadata
321
+ */
322
+ const detectLocalCLISessionMetadata = ({ siteRoot }) => {
288
323
  const { branch } = gitRepoInfo()
324
+ const hostname = os.hostname()
325
+ const userInfo = os.userInfo({ encoding: 'utf-8' })
326
+ const { username } = userInfo
327
+
328
+ const detectedMetadata = {
329
+ gitBranch: branch,
330
+ hostname,
331
+ username,
332
+ siteRoot,
333
+ }
289
334
 
335
+ return detectedMetadata
336
+ }
337
+
338
+ /**
339
+ * Fetch the existing cli session metadata if it exists, and mutate it remotely with the passed in metadata
340
+ * @param {object} input
341
+ * @param {NetlifyGraph.NetlifyGraphConfig} input.netlifyGraphConfig The (typically netlify) access token that is used for authentication, if any
342
+ * @param {string} input.netlifyToken The (typically netlify) access token that is used for authentication, if any
343
+ * @param {string} input.oneGraphSessionId The id of the cli session to fetch the current metadata for
344
+ * @param {string} input.siteId The site object that contains the root file path for the site
345
+ * @param {string} input.siteRoot The root file path for the site
346
+ * @param {object} input.newMetadata The metadata to merge into (with priority) the existing metadata
347
+ * @returns {Promise<object>}
348
+ */
349
+ const upsertMergeCLISessionMetadata = async ({ netlifyToken, newMetadata, oneGraphSessionId, siteId, siteRoot }) => {
350
+ const { errors, metadata } = await getCLISessionMetadata({ netlifyToken, oneGraphSessionId, siteId })
351
+ if (errors) {
352
+ warn(`Error fetching cli session metadata: ${JSON.stringify(errors, null, 2)}`)
353
+ }
354
+
355
+ const detectedMetadata = detectLocalCLISessionMetadata({ siteRoot })
356
+
357
+ const finalMetadata = { ...metadata, ...detectedMetadata, ...newMetadata }
358
+ return OneGraphClient.updateCLISessionMetadata(netlifyToken, siteId, oneGraphSessionId, finalMetadata)
359
+ }
360
+
361
+ const persistNewOperationsDocForSession = async ({
362
+ netlifyGraphConfig,
363
+ netlifyToken,
364
+ oneGraphSessionId,
365
+ operationsDoc,
366
+ siteId,
367
+ siteRoot,
368
+ }) => {
369
+ const { branch } = gitRepoInfo()
290
370
  const payload = {
291
371
  appId: siteId,
292
372
  description: 'Temporary snapshot of local queries',
@@ -295,13 +375,25 @@ const persistNewOperationsDocForSession = async ({ netlifyToken, oneGraphSession
295
375
  }
296
376
  const persistedDoc = await createPersistedQuery(netlifyToken, payload)
297
377
  const newMetadata = await { docId: persistedDoc.id }
298
- const result = await OneGraphClient.updateCLISessionMetadata(netlifyToken, siteId, oneGraphSessionId, newMetadata)
378
+ const result = await upsertMergeCLISessionMetadata({
379
+ netlifyGraphConfig,
380
+ netlifyToken,
381
+ siteId,
382
+ oneGraphSessionId,
383
+ newMetadata,
384
+ siteRoot,
385
+ })
299
386
 
300
387
  if (result.errors) {
301
388
  warn(`Unable to update session metadata with updated operations doc ${JSON.stringify(result.errors, null, 2)}`)
302
389
  }
303
390
  }
304
391
 
392
+ const createCLISession = ({ metadata, netlifyToken, sessionName, siteId }) => {
393
+ const result = OneGraphClient.createCLISession(netlifyToken, siteId, sessionName, metadata)
394
+ return result
395
+ }
396
+
305
397
  /**
306
398
  * Load the CLI session id from the local state
307
399
  * @param {StateConfig} state
@@ -324,7 +416,12 @@ const startOneGraphCLISession = async (input) => {
324
416
  if (!oneGraphSessionId) {
325
417
  const sessionName = generateSessionName()
326
418
  const sessionMetadata = {}
327
- const oneGraphSession = await OneGraphClient.createCLISession(netlifyToken, site.id, sessionName, sessionMetadata)
419
+ const oneGraphSession = await createCLISession({
420
+ netlifyToken,
421
+ siteId: site.id,
422
+ sessionName,
423
+ metadata: sessionMetadata,
424
+ })
328
425
  state.set('oneGraphSessionId', oneGraphSession.id)
329
426
  oneGraphSessionId = state.get('oneGraphSessionId')
330
427
  }
@@ -339,10 +436,12 @@ const startOneGraphCLISession = async (input) => {
339
436
  regenerateFunctionsFileFromOperationsFile({ netlifyGraphConfig, schema })
340
437
  const newOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig)
341
438
  await persistNewOperationsDocForSession({
439
+ netlifyGraphConfig,
342
440
  netlifyToken,
343
441
  oneGraphSessionId,
344
442
  operationsDoc: newOperationsDoc,
345
443
  siteId: site.id,
444
+ siteRoot: site.root,
346
445
  })
347
446
  },
348
447
  onAdd: async (filePath) => {
@@ -350,10 +449,12 @@ const startOneGraphCLISession = async (input) => {
350
449
  regenerateFunctionsFileFromOperationsFile({ netlifyGraphConfig, schema })
351
450
  const newOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig)
352
451
  await persistNewOperationsDocForSession({
452
+ netlifyGraphConfig,
353
453
  netlifyToken,
354
454
  oneGraphSessionId,
355
455
  operationsDoc: newOperationsDoc,
356
456
  siteId: site.id,
457
+ siteRoot: site.root,
357
458
  })
358
459
  },
359
460
  })
@@ -395,7 +496,6 @@ const generateSessionName = () => {
395
496
 
396
497
  const OneGraphCliClient = {
397
498
  ackCLISessionEvents: OneGraphClient.ackCLISessionEvents,
398
- createCLISession,
399
499
  createPersistedQuery,
400
500
  fetchCliSessionEvents: OneGraphClient.fetchCliSessionEvents,
401
501
  ensureAppForSite,
@@ -404,6 +504,7 @@ const OneGraphCliClient = {
404
504
 
405
505
  module.exports = {
406
506
  OneGraphCliClient,
507
+ createCLISession,
407
508
  extractFunctionsFromOperationDoc,
408
509
  handleCliSessionEvent,
409
510
  generateSessionName,
@@ -412,4 +513,5 @@ module.exports = {
412
513
  persistNewOperationsDocForSession,
413
514
  refetchAndGenerateFromOneGraph,
414
515
  startOneGraphCLISession,
516
+ upsertMergeCLISessionMetadata,
415
517
  }
@@ -167,6 +167,8 @@ const getNetlifyGraphConfig = async ({ command, options, settings }) => {
167
167
  }
168
168
  }
169
169
 
170
+ const defaulFunctionsPath = ['netlify', 'functions']
171
+
170
172
  const siteRoot = [path.sep, ...filterRelativePathItems(site.root.split(path.sep))]
171
173
 
172
174
  const tsConfig = 'tsconfig.json'
@@ -178,7 +180,7 @@ const getNetlifyGraphConfig = async ({ command, options, settings }) => {
178
180
  const detectedFunctionsPathString = getFunctionsDir({ config, options })
179
181
  const detectedFunctionsPath = detectedFunctionsPathString
180
182
  ? [path.sep, ...detectedFunctionsPathString.split(path.sep)]
181
- : null
183
+ : defaulFunctionsPath
182
184
  const baseConfig = { ...NetlifyGraph.defaultNetlifyGraphConfig, ...userSpecifiedConfig }
183
185
  const defaultFrameworkConfig = makeDefaultFrameworkConfig({ baseConfig, detectedFunctionsPath, siteRoot })
184
186