netlify-cli 15.1.1 → 15.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.
- package/npm-shrinkwrap.json +448 -265
- package/package.json +8 -8
- package/src/commands/base-command.mjs +36 -3
- package/src/commands/deploy/deploy.mjs +6 -28
- package/src/commands/dev/dev.mjs +1 -1
- package/src/commands/functions/functions-list.mjs +5 -25
- package/src/commands/link/link.mjs +5 -9
- package/src/commands/open/open-admin.mjs +7 -33
- package/src/commands/open/open-site.mjs +7 -25
- package/src/commands/serve/serve.mjs +1 -1
- package/src/commands/status/status-hooks.mjs +12 -29
- package/src/commands/unlink/unlink.mjs +2 -8
- package/src/functions-templates/javascript/auth-fetch/package-lock.json +6 -6
- package/src/functions-templates/javascript/google-analytics/package-lock.json +7 -7
- package/src/utils/get-site.mjs +16 -0
- package/src/utils/hooks/requires-site-info.mjs +29 -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": "15.
|
|
4
|
+
"version": "15.3.0",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@bugsnag/js": "7.20.2",
|
|
46
|
-
"@fastify/static": "6.10.
|
|
47
|
-
"@netlify/build": "29.11.
|
|
48
|
-
"@netlify/build-info": "7.0.
|
|
46
|
+
"@fastify/static": "6.10.2",
|
|
47
|
+
"@netlify/build": "29.11.7",
|
|
48
|
+
"@netlify/build-info": "7.0.3",
|
|
49
49
|
"@netlify/config": "20.4.3",
|
|
50
|
-
"@netlify/edge-bundler": "8.
|
|
51
|
-
"@netlify/framework-info": "9.8.
|
|
50
|
+
"@netlify/edge-bundler": "8.15.0",
|
|
51
|
+
"@netlify/framework-info": "9.8.8",
|
|
52
52
|
"@netlify/local-functions-proxy": "1.1.1",
|
|
53
|
-
"@netlify/zip-it-and-ship-it": "9.
|
|
54
|
-
"@octokit/rest": "19.0.
|
|
53
|
+
"@netlify/zip-it-and-ship-it": "9.7.0",
|
|
54
|
+
"@octokit/rest": "19.0.11",
|
|
55
55
|
"@skn0tt/lambda-local": "2.0.3",
|
|
56
56
|
"ansi-escapes": "6.2.0",
|
|
57
57
|
"ansi-styles": "6.2.1",
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import process from 'process'
|
|
3
3
|
import { format } from 'util'
|
|
4
4
|
|
|
5
|
+
import { Project } from '@netlify/build-info'
|
|
6
|
+
// eslint-disable-next-line import/extensions, n/no-missing-import
|
|
7
|
+
import { NodeFS } from '@netlify/build-info/node'
|
|
5
8
|
import { resolveConfig } from '@netlify/config'
|
|
6
9
|
import { Command, Option } from 'commander'
|
|
7
10
|
import debug from 'debug'
|
|
@@ -24,6 +27,7 @@ import {
|
|
|
24
27
|
warn,
|
|
25
28
|
} from '../utils/command-helpers.mjs'
|
|
26
29
|
import getGlobalConfig from '../utils/get-global-config.mjs'
|
|
30
|
+
import { getSiteByName } from '../utils/get-site.mjs'
|
|
27
31
|
import openBrowser from '../utils/open-browser.mjs'
|
|
28
32
|
import StateConfig from '../utils/state-config.mjs'
|
|
29
33
|
import { identify, track } from '../utils/telemetry/index.mjs'
|
|
@@ -440,11 +444,40 @@ export default class BaseCommand extends Command {
|
|
|
440
444
|
certificateFile: options.httpProxyCertificateFilename,
|
|
441
445
|
})
|
|
442
446
|
const apiOpts = { ...apiUrlOpts, agent }
|
|
447
|
+
const api = new NetlifyAPI(token || '', apiOpts)
|
|
448
|
+
|
|
449
|
+
// If a user passes a site name as an option instead of a site ID to options.site, the siteInfo object
|
|
450
|
+
// will only have the property siteInfo.id. Checking for one of the other properties ensures that we can do
|
|
451
|
+
// a re-call of the api.getSite() that is done in @netlify/config so we have the proper site object in all
|
|
452
|
+
// commands.
|
|
453
|
+
// options.site as a site name (and not just site id) was introduced for the deploy command, so users could
|
|
454
|
+
// deploy by name along with by id
|
|
455
|
+
let siteData = siteInfo
|
|
456
|
+
if (!siteData.url && options.site) {
|
|
457
|
+
siteData = await getSiteByName(api, options.site)
|
|
458
|
+
}
|
|
459
|
+
|
|
443
460
|
const globalConfig = await getGlobalConfig()
|
|
444
461
|
|
|
462
|
+
// Get framework, add to analytics payload for every command, if a framework is set
|
|
463
|
+
const fs = new NodeFS()
|
|
464
|
+
const project = new Project(fs, buildDir)
|
|
465
|
+
const frameworks = await project.detectFrameworks()
|
|
466
|
+
|
|
467
|
+
const frameworkIDs = frameworks?.map((framework) => framework.id)
|
|
468
|
+
|
|
469
|
+
if (frameworkIDs?.length !== 0) {
|
|
470
|
+
this.setAnalyticsPayload({ frameworks: frameworkIDs })
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
this.setAnalyticsPayload({
|
|
474
|
+
packageManager: project.packageManager?.name,
|
|
475
|
+
buildSystem: project.buildSystems.map(({ id }) => id),
|
|
476
|
+
})
|
|
477
|
+
|
|
445
478
|
actionCommand.netlify = {
|
|
446
479
|
// api methods
|
|
447
|
-
api
|
|
480
|
+
api,
|
|
448
481
|
apiOpts,
|
|
449
482
|
repositoryRoot,
|
|
450
483
|
// current site context
|
|
@@ -458,8 +491,8 @@ export default class BaseCommand extends Command {
|
|
|
458
491
|
state.set('siteId', id)
|
|
459
492
|
},
|
|
460
493
|
},
|
|
461
|
-
// Site information retrieved using the API
|
|
462
|
-
siteInfo,
|
|
494
|
+
// Site information retrieved using the API (api.getSite())
|
|
495
|
+
siteInfo: siteData,
|
|
463
496
|
// Configuration from netlify.[toml/yml]
|
|
464
497
|
config: normalizedConfig,
|
|
465
498
|
// Used to avoid calling @netlify/config again
|
|
@@ -7,6 +7,7 @@ import { runCoreSteps } from '@netlify/build'
|
|
|
7
7
|
import { restoreConfig, updateConfig } from '@netlify/config'
|
|
8
8
|
import { Option } from 'commander'
|
|
9
9
|
import inquirer from 'inquirer'
|
|
10
|
+
import isEmpty from 'lodash/isEmpty.js'
|
|
10
11
|
import isObject from 'lodash/isObject.js'
|
|
11
12
|
import prettyjson from 'prettyjson'
|
|
12
13
|
|
|
@@ -488,7 +489,7 @@ const printResults = ({ deployToProduction, json, results, runBuildCommand }) =>
|
|
|
488
489
|
* @param {import('../base-command.mjs').default} command
|
|
489
490
|
*/
|
|
490
491
|
const deploy = async (options, command) => {
|
|
491
|
-
const { api, site } = command.netlify
|
|
492
|
+
const { api, site, siteInfo } = command.netlify
|
|
492
493
|
const alias = options.alias || options.branch
|
|
493
494
|
|
|
494
495
|
command.setAnalyticsPayload({ open: options.open, prod: options.prod, json: options.json, alias: Boolean(alias) })
|
|
@@ -503,35 +504,12 @@ const deploy = async (options, command) => {
|
|
|
503
504
|
|
|
504
505
|
await command.authenticate(options.auth)
|
|
505
506
|
|
|
506
|
-
let siteId =
|
|
507
|
+
let siteId = site.id || options.site
|
|
507
508
|
|
|
508
509
|
let siteData = {}
|
|
509
|
-
if (siteId) {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
api
|
|
513
|
-
.getSite({ siteId })
|
|
514
|
-
.then((data) => ({ siteFoundById: data }))
|
|
515
|
-
.catch((error_) => ({ siteError: error_ })),
|
|
516
|
-
api.listSites({ name: options.site, filter: 'all' }),
|
|
517
|
-
])
|
|
518
|
-
const siteFoundByName = sites.find((filteredSite) => filteredSite.name === options.site)
|
|
519
|
-
if (siteFoundById) {
|
|
520
|
-
siteData = siteFoundById
|
|
521
|
-
} else if (siteFoundByName) {
|
|
522
|
-
siteData = siteFoundByName
|
|
523
|
-
siteId = siteFoundByName.id
|
|
524
|
-
} else {
|
|
525
|
-
throw siteError
|
|
526
|
-
}
|
|
527
|
-
} catch (error_) {
|
|
528
|
-
// TODO specifically handle known cases (e.g. no account access)
|
|
529
|
-
if (error_.status === 404) {
|
|
530
|
-
error('Site not found')
|
|
531
|
-
} else {
|
|
532
|
-
error(error_.message)
|
|
533
|
-
}
|
|
534
|
-
}
|
|
510
|
+
if (siteId && !isEmpty(siteInfo)) {
|
|
511
|
+
siteData = siteInfo
|
|
512
|
+
siteId = siteData.id
|
|
535
513
|
} else {
|
|
536
514
|
log("This folder isn't linked to a site yet")
|
|
537
515
|
const NEW_SITE = '+ Create & configure a new site'
|
package/src/commands/dev/dev.mjs
CHANGED
|
@@ -123,7 +123,7 @@ const dev = async (options, command) => {
|
|
|
123
123
|
exit(1)
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
command.setAnalyticsPayload({
|
|
126
|
+
command.setAnalyticsPayload({ live: options.live })
|
|
127
127
|
|
|
128
128
|
const liveTunnelUrl = await handleLiveTunnel({ options, site, api, settings })
|
|
129
129
|
const url = liveTunnelUrl || getProxyUrl(settings)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import AsciiTable from 'ascii-table'
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { exit, log, logJson } from '../../utils/command-helpers.mjs'
|
|
5
5
|
import { getFunctions, getFunctionsDir } from '../../utils/functions/index.mjs'
|
|
6
|
+
import requiresSiteInfo from '../../utils/hooks/requires-site-info.mjs'
|
|
6
7
|
|
|
7
8
|
const normalizeFunction = function (deployedFunctions, { name, urlPath: url }) {
|
|
8
9
|
const isDeployed = deployedFunctions.some((deployedFunction) => deployedFunction.n === name)
|
|
@@ -15,31 +16,9 @@ const normalizeFunction = function (deployedFunctions, { name, urlPath: url }) {
|
|
|
15
16
|
* @param {import('../base-command.mjs').default} command
|
|
16
17
|
*/
|
|
17
18
|
const functionsList = async (options, command) => {
|
|
18
|
-
const {
|
|
19
|
+
const { config, siteInfo } = command.netlify
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
// copied from `netlify status`
|
|
22
|
-
const siteId = site.id
|
|
23
|
-
if (!siteId) {
|
|
24
|
-
warn('Did you run `netlify link` yet?')
|
|
25
|
-
error(`You don't appear to be in a folder that is linked to a site`)
|
|
26
|
-
}
|
|
27
|
-
let siteData
|
|
28
|
-
try {
|
|
29
|
-
siteData = await api.getSite({ siteId })
|
|
30
|
-
} catch (error_) {
|
|
31
|
-
// unauthorized
|
|
32
|
-
if (error_.status === 401) {
|
|
33
|
-
warn(`Log in with a different account or re-link to a site you have permission for`)
|
|
34
|
-
error(`Not authorized to view the currently linked site (${siteId})`)
|
|
35
|
-
}
|
|
36
|
-
// missing
|
|
37
|
-
if (error_.status === 404) {
|
|
38
|
-
error(`The site this folder is linked to can't be found`)
|
|
39
|
-
}
|
|
40
|
-
error(error_)
|
|
41
|
-
}
|
|
42
|
-
const deploy = siteData.published_deploy || {}
|
|
21
|
+
const deploy = siteInfo.published_deploy || {}
|
|
43
22
|
const deployedFunctions = deploy.available_functions || []
|
|
44
23
|
|
|
45
24
|
const functionsDir = getFunctionsDir({ options, config })
|
|
@@ -91,4 +70,5 @@ NOT the same as listing the functions that have been deployed. For that info you
|
|
|
91
70
|
)
|
|
92
71
|
.option('-f, --functions <dir>', 'Specify a functions directory to list')
|
|
93
72
|
.option('--json', 'Output function data as JSON')
|
|
73
|
+
.hook('preAction', requiresSiteInfo)
|
|
94
74
|
.action(functionsList)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { Option } from 'commander'
|
|
3
3
|
import inquirer from 'inquirer'
|
|
4
|
+
import isEmpty from 'lodash/isEmpty.js'
|
|
4
5
|
|
|
5
6
|
import { listSites } from '../../lib/api.mjs'
|
|
6
7
|
import { chalk, error, exit, log } from '../../utils/command-helpers.mjs'
|
|
@@ -250,28 +251,23 @@ export const link = async (options, command) => {
|
|
|
250
251
|
api,
|
|
251
252
|
repositoryRoot,
|
|
252
253
|
site: { id: siteId },
|
|
254
|
+
siteInfo,
|
|
253
255
|
state,
|
|
254
256
|
} = command.netlify
|
|
255
257
|
|
|
256
|
-
let siteData
|
|
257
|
-
try {
|
|
258
|
-
// @ts-ignore types from API are wrong they cannot recognize `getSite` of API
|
|
259
|
-
siteData = await api.getSite({ siteId })
|
|
260
|
-
} catch {
|
|
261
|
-
// silent api error
|
|
262
|
-
}
|
|
258
|
+
let siteData = siteInfo
|
|
263
259
|
|
|
264
260
|
// Add .netlify to .gitignore file
|
|
265
261
|
await ensureNetlifyIgnore(repositoryRoot)
|
|
266
262
|
|
|
267
263
|
// Site id is incorrect
|
|
268
|
-
if (siteId &&
|
|
264
|
+
if (siteId && isEmpty(siteData)) {
|
|
269
265
|
log(`"${siteId}" was not found in your Netlify account.`)
|
|
270
266
|
log(`Please double check your siteID and which account you are logged into via \`netlify status\`.`)
|
|
271
267
|
return exit()
|
|
272
268
|
}
|
|
273
269
|
|
|
274
|
-
if (
|
|
270
|
+
if (!isEmpty(siteInfo)) {
|
|
275
271
|
// If already linked to site. exit and prompt for unlink
|
|
276
272
|
log(`Site already linked to "${siteData.name}"`)
|
|
277
273
|
log(`Admin url: ${siteData.admin_url}`)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { exit, log } from '../../utils/command-helpers.mjs'
|
|
2
|
+
import requiresSiteInfo from '../../utils/hooks/requires-site-info.mjs'
|
|
2
3
|
import openBrowser from '../../utils/open-browser.mjs'
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -7,42 +8,14 @@ import openBrowser from '../../utils/open-browser.mjs'
|
|
|
7
8
|
* @param {import('../base-command.mjs').default} command
|
|
8
9
|
*/
|
|
9
10
|
export const openAdmin = async (options, command) => {
|
|
10
|
-
const {
|
|
11
|
+
const { siteInfo } = command.netlify
|
|
11
12
|
|
|
12
13
|
await command.authenticate()
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
log(`Opening "${siteInfo.name}" site admin UI:`)
|
|
16
|
+
log(`> ${siteInfo.admin_url}`)
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
warn(`No Site ID found in current directory.
|
|
18
|
-
Run \`netlify link\` to connect to this folder to a site`)
|
|
19
|
-
return false
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let siteData
|
|
23
|
-
try {
|
|
24
|
-
siteData = await api.getSite({ siteId })
|
|
25
|
-
log(`Opening "${siteData.name}" site admin UI:`)
|
|
26
|
-
log(`> ${siteData.admin_url}`)
|
|
27
|
-
} catch (error_) {
|
|
28
|
-
// unauthorized
|
|
29
|
-
if (error_.status === 401) {
|
|
30
|
-
warn(`Log in with a different account or re-link to a site you have permission for`)
|
|
31
|
-
error(`Not authorized to view the currently linked site (${siteId})`)
|
|
32
|
-
}
|
|
33
|
-
// site not found
|
|
34
|
-
if (error_.status === 404) {
|
|
35
|
-
log()
|
|
36
|
-
log('Please double check this ID and verify you are logged in with the correct account')
|
|
37
|
-
log()
|
|
38
|
-
log('To fix this, run `netlify unlink` then `netlify link` to reconnect to the correct site ID')
|
|
39
|
-
log()
|
|
40
|
-
error(`Site "${siteId}" not found in account`)
|
|
41
|
-
}
|
|
42
|
-
error(error_)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
await openBrowser({ url: siteData.admin_url })
|
|
18
|
+
await openBrowser({ url: siteInfo.admin_url })
|
|
46
19
|
exit()
|
|
47
20
|
}
|
|
48
21
|
|
|
@@ -56,4 +29,5 @@ export const createOpenAdminCommand = (program) =>
|
|
|
56
29
|
.command('open:admin')
|
|
57
30
|
.description('Opens current site admin UI in Netlify')
|
|
58
31
|
.addExamples(['netlify open:admin'])
|
|
32
|
+
.hook('preAction', requiresSiteInfo)
|
|
59
33
|
.action(openAdmin)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { exit, log } from '../../utils/command-helpers.mjs'
|
|
2
|
+
import requiresSiteInfo from '../../utils/hooks/requires-site-info.mjs'
|
|
2
3
|
import openBrowser from '../../utils/open-browser.mjs'
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -7,33 +8,13 @@ import openBrowser from '../../utils/open-browser.mjs'
|
|
|
7
8
|
* @param {import('../base-command.mjs').default} command
|
|
8
9
|
*/
|
|
9
10
|
export const openSite = async (options, command) => {
|
|
10
|
-
const {
|
|
11
|
+
const { siteInfo } = command.netlify
|
|
11
12
|
|
|
12
13
|
await command.authenticate()
|
|
13
14
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
warn(`No Site ID found in current directory.
|
|
18
|
-
Run \`netlify link\` to connect to this folder to a site`)
|
|
19
|
-
return false
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let siteData
|
|
23
|
-
let url
|
|
24
|
-
try {
|
|
25
|
-
siteData = await api.getSite({ siteId })
|
|
26
|
-
url = siteData.ssl_url || siteData.url
|
|
27
|
-
log(`Opening "${siteData.name}" site url:`)
|
|
28
|
-
log(`> ${url}`)
|
|
29
|
-
} catch (error_) {
|
|
30
|
-
// unauthorized
|
|
31
|
-
if (error_.status === 401) {
|
|
32
|
-
warn(`Log in with a different account or re-link to a site you have permission for`)
|
|
33
|
-
error(`Not authorized to view the currently linked site (${siteId})`)
|
|
34
|
-
}
|
|
35
|
-
error(error_)
|
|
36
|
-
}
|
|
15
|
+
const url = siteInfo.ssl_url || siteInfo.url
|
|
16
|
+
log(`Opening "${siteInfo.name}" site url:`)
|
|
17
|
+
log(`> ${url}`)
|
|
37
18
|
|
|
38
19
|
await openBrowser({ url })
|
|
39
20
|
exit()
|
|
@@ -49,4 +30,5 @@ export const createOpenSiteCommand = (program) =>
|
|
|
49
30
|
.command('open:site')
|
|
50
31
|
.description('Opens current site url in browser')
|
|
51
32
|
.addExamples(['netlify open:site'])
|
|
33
|
+
.hook('preAction', requiresSiteInfo)
|
|
52
34
|
.action(openSite)
|
|
@@ -80,7 +80,7 @@ const serve = async (options, command) => {
|
|
|
80
80
|
exit(1)
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
command.setAnalyticsPayload({
|
|
83
|
+
command.setAnalyticsPayload({ live: options.live })
|
|
84
84
|
|
|
85
85
|
log(`${NETLIFYDEVLOG} Building site for production`)
|
|
86
86
|
log(
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import prettyjson from 'prettyjson'
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { log } from '../../utils/command-helpers.mjs'
|
|
5
|
+
import requiresSiteInfo from '../../utils/hooks/requires-site-info.mjs'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* The status:hooks command
|
|
@@ -9,35 +10,13 @@ import { error, log, warn } from '../../utils/command-helpers.mjs'
|
|
|
9
10
|
* @param {import('../base-command.mjs').default} command
|
|
10
11
|
*/
|
|
11
12
|
const statusHooks = async (options, command) => {
|
|
12
|
-
const { api,
|
|
13
|
+
const { api, siteInfo } = command.netlify
|
|
13
14
|
|
|
14
15
|
await command.authenticate()
|
|
15
16
|
|
|
16
|
-
const
|
|
17
|
-
if (!siteId) {
|
|
18
|
-
warn('Did you run `netlify link` yet?')
|
|
19
|
-
error(`You don't appear to be in a folder that is linked to a site`)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let siteData
|
|
23
|
-
try {
|
|
24
|
-
siteData = await api.getSite({ siteId })
|
|
25
|
-
} catch (error_) {
|
|
26
|
-
// unauthorized
|
|
27
|
-
if (error_.status === 401) {
|
|
28
|
-
warn(`Log in with a different account or re-link to a site you have permission for`)
|
|
29
|
-
error(`Not authorized to view the currently linked site (${siteId})`)
|
|
30
|
-
}
|
|
31
|
-
// missing
|
|
32
|
-
if (error_.status === 404) {
|
|
33
|
-
error(`The site this folder is linked to can't be found`)
|
|
34
|
-
}
|
|
35
|
-
error(error_)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const ntlHooks = await api.listHooksBySiteId({ siteId: siteData.id })
|
|
17
|
+
const ntlHooks = await api.listHooksBySiteId({ siteId: siteInfo.id })
|
|
39
18
|
const data = {
|
|
40
|
-
site:
|
|
19
|
+
site: siteInfo.name,
|
|
41
20
|
hooks: {},
|
|
42
21
|
}
|
|
43
22
|
ntlHooks.forEach((hook) => {
|
|
@@ -47,8 +26,8 @@ const statusHooks = async (options, command) => {
|
|
|
47
26
|
id: hook.id,
|
|
48
27
|
disabled: hook.disabled,
|
|
49
28
|
}
|
|
50
|
-
if (
|
|
51
|
-
data.hooks[hook.id].repo_url =
|
|
29
|
+
if (siteInfo.build_settings?.repo_url) {
|
|
30
|
+
data.hooks[hook.id].repo_url = siteInfo.build_settings.repo_url
|
|
52
31
|
}
|
|
53
32
|
})
|
|
54
33
|
log(`─────────────────┐
|
|
@@ -63,4 +42,8 @@ Site Hook Status │
|
|
|
63
42
|
* @returns
|
|
64
43
|
*/
|
|
65
44
|
export const createStatusHooksCommand = (program) =>
|
|
66
|
-
program
|
|
45
|
+
program
|
|
46
|
+
.command('status:hooks')
|
|
47
|
+
.description('Print hook information of the linked site')
|
|
48
|
+
.hook('preAction', requiresSiteInfo)
|
|
49
|
+
.action(statusHooks)
|
|
@@ -8,7 +8,7 @@ import { track } from '../../utils/telemetry/index.mjs'
|
|
|
8
8
|
* @param {import('../base-command.mjs').default} command
|
|
9
9
|
*/
|
|
10
10
|
const unlink = async (options, command) => {
|
|
11
|
-
const { site, state } = command.netlify
|
|
11
|
+
const { site, siteInfo, state } = command.netlify
|
|
12
12
|
const siteId = site.id
|
|
13
13
|
|
|
14
14
|
if (!siteId) {
|
|
@@ -16,13 +16,7 @@ const unlink = async (options, command) => {
|
|
|
16
16
|
return exit()
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
// @ts-ignore types from API are wrong they cannot recognize `getSite` of API
|
|
22
|
-
siteData = await command.netlify.api.getSite({ siteId })
|
|
23
|
-
} catch {
|
|
24
|
-
// ignore errors if we can't get the site
|
|
25
|
-
}
|
|
19
|
+
const siteData = siteInfo
|
|
26
20
|
|
|
27
21
|
state.delete('siteId')
|
|
28
22
|
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"node_modules/node-fetch": {
|
|
16
|
-
"version": "2.6.
|
|
17
|
-
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.
|
|
18
|
-
"integrity": "sha512-
|
|
16
|
+
"version": "2.6.11",
|
|
17
|
+
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
|
|
18
|
+
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"whatwg-url": "^5.0.0"
|
|
21
21
|
},
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"node-fetch": {
|
|
56
|
-
"version": "2.6.
|
|
57
|
-
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.
|
|
58
|
-
"integrity": "sha512-
|
|
56
|
+
"version": "2.6.11",
|
|
57
|
+
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
|
|
58
|
+
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
|
|
59
59
|
"requires": {
|
|
60
60
|
"whatwg-url": "^5.0.0"
|
|
61
61
|
}
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
"uuid": "^9.0.0"
|
|
14
14
|
},
|
|
15
15
|
"engines": {
|
|
16
|
-
"node": "^14.
|
|
16
|
+
"node": "^14.18.0 || >=16.0.0"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"node_modules/node-fetch": {
|
|
20
|
-
"version": "2.6.
|
|
21
|
-
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.
|
|
22
|
-
"integrity": "sha512-
|
|
20
|
+
"version": "2.6.11",
|
|
21
|
+
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
|
|
22
|
+
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"whatwg-url": "^5.0.0"
|
|
25
25
|
},
|
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"node-fetch": {
|
|
68
|
-
"version": "2.6.
|
|
69
|
-
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.
|
|
70
|
-
"integrity": "sha512-
|
|
68
|
+
"version": "2.6.11",
|
|
69
|
+
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
|
|
70
|
+
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
|
|
71
71
|
"requires": {
|
|
72
72
|
"whatwg-url": "^5.0.0"
|
|
73
73
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { error } from './command-helpers.mjs'
|
|
2
|
+
|
|
3
|
+
export const getSiteByName = async (api, siteName) => {
|
|
4
|
+
try {
|
|
5
|
+
const sites = await api.listSites({ name: siteName, filter: 'all' })
|
|
6
|
+
const siteFoundByName = sites.find((filteredSite) => filteredSite.name === siteName)
|
|
7
|
+
|
|
8
|
+
if (!siteFoundByName) {
|
|
9
|
+
throw Error
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return siteFoundByName
|
|
13
|
+
} catch {
|
|
14
|
+
error('Site not found. Please rerun "netlify link"')
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { error, warn } from '../command-helpers.mjs'
|
|
2
|
+
/**
|
|
3
|
+
* A preAction hook that errors out if siteInfo is an empty object
|
|
4
|
+
* @param {*} command
|
|
5
|
+
*/
|
|
6
|
+
const requiresSiteInfo = async (command) => {
|
|
7
|
+
const { api, site } = command.netlify
|
|
8
|
+
const siteId = site.id
|
|
9
|
+
if (!siteId) {
|
|
10
|
+
warn('Did you run `netlify link` yet?')
|
|
11
|
+
return error(`You don't appear to be in a folder that is linked to a site`)
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
await api.getSite({ siteId })
|
|
15
|
+
} catch (error_) {
|
|
16
|
+
// unauthorized
|
|
17
|
+
if (error_.status === 401) {
|
|
18
|
+
warn(`Log in with a different account or re-link to a site you have permission for`)
|
|
19
|
+
return error(`Not authorized to view the currently linked site (${siteId})`)
|
|
20
|
+
}
|
|
21
|
+
// missing
|
|
22
|
+
if (error_.status === 404) {
|
|
23
|
+
return error(`The site this folder is linked to can't be found`)
|
|
24
|
+
}
|
|
25
|
+
return error(error_)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default requiresSiteInfo
|