netlify-cli 8.4.3 → 8.6.2
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/README.md +1 -0
- package/npm-shrinkwrap.json +795 -441
- package/package.json +5 -3
- package/src/commands/env/env-list.js +42 -8
- package/src/commands/env/env-migrate.js +108 -0
- package/src/commands/env/env.js +3 -0
- package/src/functions-templates/rust/hello-world/Cargo.toml +1 -1
- package/src/functions-templates/typescript/hello-world/package-lock.json +7 -7
- package/src/utils/deploy/upload-files.js +1 -1
- package/src/utils/rules-proxy.js +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
3
|
"description": "Netlify command line tool",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.6.2",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"contributors": [
|
|
7
7
|
"Mathias Biilmann <matt@netlify.com> (https://twitter.com/biilmann)",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"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\""
|
|
79
79
|
},
|
|
80
80
|
"dependencies": {
|
|
81
|
-
"@netlify/build": "^26.0
|
|
81
|
+
"@netlify/build": "^26.1.0",
|
|
82
82
|
"@netlify/config": "^17.0.2",
|
|
83
83
|
"@netlify/framework-info": "^7.0.0",
|
|
84
84
|
"@netlify/local-functions-proxy": "^1.1.1",
|
|
@@ -88,6 +88,7 @@
|
|
|
88
88
|
"@netlify/zip-it-and-ship-it": "5.3.1",
|
|
89
89
|
"@octokit/rest": "^18.0.0",
|
|
90
90
|
"@sindresorhus/slugify": "^1.1.0",
|
|
91
|
+
"ansi-escapes": "^5.0.0",
|
|
91
92
|
"ansi-styles": "^5.0.0",
|
|
92
93
|
"ascii-table": "0.0.9",
|
|
93
94
|
"backoff": "^2.5.0",
|
|
@@ -140,6 +141,7 @@
|
|
|
140
141
|
"locate-path": "^6.0.0",
|
|
141
142
|
"lodash": "^4.17.20",
|
|
142
143
|
"log-symbols": "^4.0.0",
|
|
144
|
+
"log-update": "^5.0.0",
|
|
143
145
|
"make-dir": "^3.0.0",
|
|
144
146
|
"memoize-one": "^6.0.0",
|
|
145
147
|
"minimist": "^1.2.5",
|
|
@@ -192,7 +194,7 @@
|
|
|
192
194
|
"@babel/preset-react": "^7.12.13",
|
|
193
195
|
"@commitlint/cli": "^16.0.0",
|
|
194
196
|
"@commitlint/config-conventional": "^16.0.0",
|
|
195
|
-
"@netlify/eslint-config-node": "^4.0.
|
|
197
|
+
"@netlify/eslint-config-node": "^4.0.5",
|
|
196
198
|
"ava": "^3.15.0",
|
|
197
199
|
"eslint-plugin-sort-destructure-keys": "^1.3.5",
|
|
198
200
|
"fast-glob": "^3.2.7",
|
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
const AsciiTable = require('ascii-table')
|
|
3
|
+
const { isCI } = require('ci-info')
|
|
4
|
+
const inquirer = require('inquirer')
|
|
3
5
|
const isEmpty = require('lodash/isEmpty')
|
|
4
6
|
|
|
5
|
-
const { log, logJson } = require('../../utils')
|
|
7
|
+
const { chalk, log, logJson } = require('../../utils')
|
|
8
|
+
|
|
9
|
+
const [logUpdatePromise, ansiEscapesPromise] = [import('log-update'), import('ansi-escapes')]
|
|
10
|
+
|
|
11
|
+
const MASK_LENGTH = 50
|
|
12
|
+
const MASK = '*'.repeat(MASK_LENGTH)
|
|
13
|
+
|
|
14
|
+
const getTable = ({ environment, hideValues }) => {
|
|
15
|
+
const table = new AsciiTable(`Environment variables`)
|
|
16
|
+
table.setHeading('Key', 'Value')
|
|
17
|
+
table.addRowMatrix(Object.entries(environment).map(([key, value]) => [key, hideValues ? MASK : value]))
|
|
18
|
+
return table.toString()
|
|
19
|
+
}
|
|
6
20
|
|
|
7
21
|
/**
|
|
8
22
|
* The env:list command
|
|
@@ -34,17 +48,37 @@ const envList = async (options, command) => {
|
|
|
34
48
|
}
|
|
35
49
|
|
|
36
50
|
if (isEmpty(environment)) {
|
|
37
|
-
log(`No environment variables set for site ${siteData.name}`)
|
|
51
|
+
log(`No environment variables set for site ${chalk.greenBright(siteData.name)}`)
|
|
38
52
|
return false
|
|
39
53
|
}
|
|
40
54
|
|
|
41
|
-
// List environment
|
|
42
|
-
log(`site: ${siteData.name}`)
|
|
43
|
-
const table = new AsciiTable(`Environment variables`)
|
|
55
|
+
// List environment in a table
|
|
56
|
+
log(`Listing environment variables for site: ${chalk.greenBright(siteData.name)}`)
|
|
44
57
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
58
|
+
if (isCI) {
|
|
59
|
+
log(getTable({ environment, hideValues: false }))
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { default: logUpdate } = await logUpdatePromise
|
|
64
|
+
|
|
65
|
+
logUpdate(getTable({ environment, hideValues: true }))
|
|
66
|
+
const { showValues } = await inquirer.prompt([
|
|
67
|
+
{
|
|
68
|
+
type: 'confirm',
|
|
69
|
+
name: 'showValues',
|
|
70
|
+
message: 'Show values?',
|
|
71
|
+
default: false,
|
|
72
|
+
},
|
|
73
|
+
])
|
|
74
|
+
|
|
75
|
+
if (showValues) {
|
|
76
|
+
const { default: ansiEscapes } = await ansiEscapesPromise
|
|
77
|
+
// since inquirer adds a prompt, we need to account for it when printing the table again
|
|
78
|
+
log(ansiEscapes.eraseLines(3))
|
|
79
|
+
logUpdate(getTable({ environment, hideValues: false }))
|
|
80
|
+
log(`${chalk.cyan('?')} Show values? ${chalk.cyan('Yes')}`)
|
|
81
|
+
}
|
|
48
82
|
}
|
|
49
83
|
|
|
50
84
|
/**
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
const { isEmpty } = require('lodash')
|
|
4
|
+
|
|
5
|
+
const { chalk, error: logError, log } = require('../../utils')
|
|
6
|
+
|
|
7
|
+
const safeGetSite = async (api, siteId) => {
|
|
8
|
+
try {
|
|
9
|
+
const data = await api.getSite({ siteId })
|
|
10
|
+
return { data }
|
|
11
|
+
} catch (error) {
|
|
12
|
+
return { error }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The env:migrate command
|
|
18
|
+
* @param {string} siteIdA Site (From)
|
|
19
|
+
* @param {string} siteIdB Site (To)
|
|
20
|
+
* @param {import('commander').OptionValues} options
|
|
21
|
+
* @param {import('../base-command').BaseCommand} command
|
|
22
|
+
* @returns {Promise<boolean>}
|
|
23
|
+
*/
|
|
24
|
+
const envMigrate = async (options, command) => {
|
|
25
|
+
const { api, site } = command.netlify
|
|
26
|
+
|
|
27
|
+
if (!site.id && !options.from) {
|
|
28
|
+
log(
|
|
29
|
+
'Please include the source site Id as the `--from` option, or run `netlify link` to link this folder to a Netlify site',
|
|
30
|
+
)
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const siteId = {
|
|
35
|
+
from: options.from || site.id,
|
|
36
|
+
to: options.to,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const [{ data: siteFrom, error: errorFrom }, { data: siteTo, error: errorTo }] = await Promise.all([
|
|
40
|
+
safeGetSite(api, siteId.from),
|
|
41
|
+
safeGetSite(api, siteId.to),
|
|
42
|
+
])
|
|
43
|
+
|
|
44
|
+
if (errorFrom) {
|
|
45
|
+
logError(`Can't find site with id ${chalk.bold(siteId.from)}. Please make sure the site exists.`)
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (errorTo) {
|
|
50
|
+
logError(`Can't find site with id ${chalk.bold(siteId.to)}. Please make sure the site exists.`)
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const [
|
|
55
|
+
{
|
|
56
|
+
build_settings: { env: envFrom = {} },
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
build_settings: { env: envTo = {} },
|
|
60
|
+
},
|
|
61
|
+
] = [siteFrom, siteTo]
|
|
62
|
+
|
|
63
|
+
if (isEmpty(envFrom)) {
|
|
64
|
+
log(`${chalk.greenBright(siteFrom.name)} has no environment variables, nothing to migrate`)
|
|
65
|
+
return false
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Merge from site A to site B
|
|
69
|
+
const mergedEnv = {
|
|
70
|
+
...envTo,
|
|
71
|
+
...envFrom,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Apply environment variable updates
|
|
75
|
+
await api.updateSite({
|
|
76
|
+
siteId: siteId.to,
|
|
77
|
+
body: {
|
|
78
|
+
build_settings: {
|
|
79
|
+
env: mergedEnv,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
log(
|
|
85
|
+
`Successfully migrated environment variables from ${chalk.greenBright(siteFrom.name)} to ${chalk.greenBright(
|
|
86
|
+
siteTo.name,
|
|
87
|
+
)}`,
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Creates the `netlify env:migrate` command
|
|
93
|
+
* @param {import('../base-command').BaseCommand} program
|
|
94
|
+
* @returns
|
|
95
|
+
*/
|
|
96
|
+
const createEnvMigrateCommand = (program) =>
|
|
97
|
+
program
|
|
98
|
+
.command('env:migrate')
|
|
99
|
+
.option('-f, --from <from>', 'Site ID (From)')
|
|
100
|
+
.requiredOption('-t, --to <to>', 'Site ID (To)')
|
|
101
|
+
.description(`Migrate environment variables from one site to another`)
|
|
102
|
+
.addExamples([
|
|
103
|
+
'netlify env:migrate --to <to-site-id>',
|
|
104
|
+
'netlify env:migrate --to <to-site-id> --from <from-site-id>',
|
|
105
|
+
])
|
|
106
|
+
.action(envMigrate)
|
|
107
|
+
|
|
108
|
+
module.exports = { createEnvMigrateCommand }
|
package/src/commands/env/env.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const { createEnvGetCommand } = require('./env-get')
|
|
3
3
|
const { createEnvImportCommand } = require('./env-import')
|
|
4
4
|
const { createEnvListCommand } = require('./env-list')
|
|
5
|
+
const { createEnvMigrateCommand } = require('./env-migrate')
|
|
5
6
|
const { createEnvSetCommand } = require('./env-set')
|
|
6
7
|
const { createEnvUnsetCommand } = require('./env-unset')
|
|
7
8
|
|
|
@@ -25,6 +26,7 @@ const createEnvCommand = (program) => {
|
|
|
25
26
|
createEnvListCommand(program)
|
|
26
27
|
createEnvSetCommand(program)
|
|
27
28
|
createEnvUnsetCommand(program)
|
|
29
|
+
createEnvMigrateCommand(program)
|
|
28
30
|
|
|
29
31
|
return program
|
|
30
32
|
.command('env')
|
|
@@ -35,6 +37,7 @@ const createEnvCommand = (program) => {
|
|
|
35
37
|
'netlify env:set VAR_NAME value',
|
|
36
38
|
'netlify env:unset VAR_NAME',
|
|
37
39
|
'netlify env:import fileName',
|
|
40
|
+
'netlify env:migrate --to <to-site-id>',
|
|
38
41
|
])
|
|
39
42
|
.action(env)
|
|
40
43
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@netlify/functions": "^0.10.0",
|
|
13
|
-
"@types/node": "^14.18.
|
|
13
|
+
"@types/node": "^14.18.4",
|
|
14
14
|
"typescript": "^4.0.0"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"node_modules/@types/node": {
|
|
29
|
-
"version": "14.18.
|
|
30
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.
|
|
31
|
-
"integrity": "sha512-
|
|
29
|
+
"version": "14.18.4",
|
|
30
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.4.tgz",
|
|
31
|
+
"integrity": "sha512-swe3lD4izOJWHuxvsZdDFRq6S9i6koJsXOnQKYekhSO5JTizMVirUFgY/bUsaOJQj8oSD4oxmRYPBM/0b6jpdw=="
|
|
32
32
|
},
|
|
33
33
|
"node_modules/is-promise": {
|
|
34
34
|
"version": "4.0.0",
|
|
@@ -58,9 +58,9 @@
|
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
"@types/node": {
|
|
61
|
-
"version": "14.18.
|
|
62
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.
|
|
63
|
-
"integrity": "sha512-
|
|
61
|
+
"version": "14.18.4",
|
|
62
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.4.tgz",
|
|
63
|
+
"integrity": "sha512-swe3lD4izOJWHuxvsZdDFRq6S9i6koJsXOnQKYekhSO5JTizMVirUFgY/bUsaOJQj8oSD4oxmRYPBM/0b6jpdw=="
|
|
64
64
|
},
|
|
65
65
|
"is-promise": {
|
|
66
66
|
"version": "4.0.0",
|
package/src/utils/rules-proxy.js
CHANGED
|
@@ -73,7 +73,7 @@ const createRewriter = async function ({ configPath, distDir, jwtRoleClaim, jwtS
|
|
|
73
73
|
const cookieValues = cookie.parse(req.headers.cookie || '')
|
|
74
74
|
const headers = {
|
|
75
75
|
'x-language': cookieValues.nf_lang || getLanguage(req.headers),
|
|
76
|
-
'x-country': cookieValues.nf_country || getCountry(
|
|
76
|
+
'x-country': cookieValues.nf_country || getCountry(),
|
|
77
77
|
...req.headers,
|
|
78
78
|
}
|
|
79
79
|
|