netlify-cli 11.4.0 → 11.5.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 +2 -2
- package/package.json +2 -1
- package/src/commands/build/build.js +7 -2
- package/src/commands/dev/dev-exec.js +6 -6
- package/src/commands/dev/dev.js +6 -4
- package/src/commands/env/env-get.js +14 -6
- package/src/commands/env/env-list.js +23 -6
- package/src/commands/env/env-set.js +21 -12
- package/src/commands/env/env-unset.js +23 -16
- package/src/utils/env/index.js +56 -15
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.5.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "netlify-cli",
|
|
9
|
-
"version": "11.
|
|
9
|
+
"version": "11.5.0",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
3
|
"description": "Netlify command line tool",
|
|
4
|
-
"version": "11.
|
|
4
|
+
"version": "11.5.0",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"contributors": [
|
|
7
7
|
"@whitep4nth3r (https://twitter.com/whitep4nth3r)",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"Erez Rokah (https://www.erezro.com)",
|
|
47
47
|
"Erica Pisani <pisani.erica@gmail.com>",
|
|
48
48
|
"Evans Hauser (https://twitter.com/evanshauser)",
|
|
49
|
+
"Ewan Valentine <ewan.valentine89@gmail.com> (http://ewanvalentine.io)",
|
|
49
50
|
"Finn Woelm (https://twitter.com/FinnWoelm)",
|
|
50
51
|
"Flxbot",
|
|
51
52
|
"Gavin Henderson <gavin.henderson@hotmail.co.uk> (https://twitter.com/gavinhenderson5)",
|
|
@@ -2,7 +2,7 @@ const process = require('process')
|
|
|
2
2
|
|
|
3
3
|
// @ts-check
|
|
4
4
|
const { getBuildOptions, runBuild } = require('../../lib/build')
|
|
5
|
-
const { error, exit, generateNetlifyGraphJWT, getEnvelopeEnv, getToken } = require('../../utils')
|
|
5
|
+
const { error, exit, generateNetlifyGraphJWT, getEnvelopeEnv, getToken, normalizeContext } = require('../../utils')
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {import('../../lib/build').BuildConfig} options
|
|
@@ -85,7 +85,12 @@ const createBuildCommand = (program) =>
|
|
|
85
85
|
program
|
|
86
86
|
.command('build')
|
|
87
87
|
.description('(Beta) Build on your local machine')
|
|
88
|
-
.option(
|
|
88
|
+
.option(
|
|
89
|
+
'--context <context>',
|
|
90
|
+
'Specify a build context or branch (contexts: "production", "deploy-preview", "branch-deploy", "dev")',
|
|
91
|
+
normalizeContext,
|
|
92
|
+
process.env.CONTEXT || 'production',
|
|
93
|
+
)
|
|
89
94
|
.option('--dry', 'Dry run: show instructions without running them', false)
|
|
90
95
|
.option('-o, --offline', 'disables any features that require network access', false)
|
|
91
96
|
.addExamples(['netlify build'])
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const { Option } = require('commander')
|
|
2
1
|
const execa = require('execa')
|
|
3
2
|
|
|
4
|
-
const { getEnvelopeEnv, injectEnvVariables } = require('../../utils')
|
|
3
|
+
const { getEnvelopeEnv, injectEnvVariables, normalizeContext } = require('../../utils')
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* The dev:exec command
|
|
@@ -32,10 +31,11 @@ const createDevExecCommand = (program) =>
|
|
|
32
31
|
program
|
|
33
32
|
.command('dev:exec')
|
|
34
33
|
.argument('<...cmd>', `the command that should be executed`)
|
|
35
|
-
.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
.option(
|
|
35
|
+
'--context <context>',
|
|
36
|
+
'Specify a deploy context or branch for environment variables (contexts: "production", "deploy-preview", "branch-deploy", "dev")',
|
|
37
|
+
normalizeContext,
|
|
38
|
+
'dev',
|
|
39
39
|
)
|
|
40
40
|
.description(
|
|
41
41
|
'Exec command\nRuns a command within the netlify dev environment, e.g. with env variables from any installed addons',
|
package/src/commands/dev/dev.js
CHANGED
|
@@ -45,6 +45,7 @@ const {
|
|
|
45
45
|
injectEnvVariables,
|
|
46
46
|
log,
|
|
47
47
|
normalizeConfig,
|
|
48
|
+
normalizeContext,
|
|
48
49
|
openBrowser,
|
|
49
50
|
processOnExit,
|
|
50
51
|
startLiveTunnel,
|
|
@@ -684,10 +685,11 @@ const createDevCommand = (program) => {
|
|
|
684
685
|
`Local dev server\nThe dev command will run a local dev server with Netlify's proxy and redirect rules`,
|
|
685
686
|
)
|
|
686
687
|
.option('-c ,--command <command>', 'command to run')
|
|
687
|
-
.
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
688
|
+
.option(
|
|
689
|
+
'--context <context>',
|
|
690
|
+
'Specify a deploy context or branch for environment variables (contexts: "production", "deploy-preview", "branch-deploy", "dev")',
|
|
691
|
+
normalizeContext,
|
|
692
|
+
'dev',
|
|
691
693
|
)
|
|
692
694
|
.option('-p ,--port <port>', 'port of netlify dev', (value) => Number.parseInt(value))
|
|
693
695
|
.option('--targetPort <port>', 'port of target app server', (value) => Number.parseInt(value))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
const { Option } = require('commander')
|
|
3
3
|
|
|
4
|
-
const { chalk, error, getEnvelopeEnv, log, logJson } = require('../../utils')
|
|
4
|
+
const { AVAILABLE_CONTEXTS, chalk, error, getEnvelopeEnv, log, logJson, normalizeContext } = require('../../utils')
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The env:get command
|
|
@@ -42,7 +42,8 @@ const envGet = async (name, options, command) => {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
if (!value) {
|
|
45
|
-
const
|
|
45
|
+
const contextType = AVAILABLE_CONTEXTS.includes(context) ? 'context' : 'branch'
|
|
46
|
+
const withContext = `in the ${chalk.magenta(context)} ${contextType}`
|
|
46
47
|
const withScope = scope === 'any' ? '' : ` and the ${chalk.magenta(scope)} scope`
|
|
47
48
|
log(`No value set ${withContext}${withScope} for environment variable ${chalk.yellow(name)}`)
|
|
48
49
|
return false
|
|
@@ -60,16 +61,23 @@ const createEnvGetCommand = (program) =>
|
|
|
60
61
|
program
|
|
61
62
|
.command('env:get')
|
|
62
63
|
.argument('<name>', 'Environment variable name')
|
|
63
|
-
.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
.option(
|
|
65
|
+
'-c, --context <context>',
|
|
66
|
+
'Specify a deploy context or branch (contexts: "production", "deploy-preview", "branch-deploy", "dev")',
|
|
67
|
+
normalizeContext,
|
|
68
|
+
'dev',
|
|
67
69
|
)
|
|
68
70
|
.addOption(
|
|
69
71
|
new Option('-s, --scope <scope>', 'Specify a scope')
|
|
70
72
|
.choices(['builds', 'functions', 'post_processing', 'runtime', 'any'])
|
|
71
73
|
.default('any'),
|
|
72
74
|
)
|
|
75
|
+
.addExamples([
|
|
76
|
+
'netlify env:get MY_VAR # get value for MY_VAR in dev context',
|
|
77
|
+
'netlify env:get MY_VAR --context production',
|
|
78
|
+
'netlify env:get MY_VAR --context branch:staging',
|
|
79
|
+
'netlify env:get MY_VAR --scope functions',
|
|
80
|
+
])
|
|
73
81
|
.description('Get resolved value of specified environment variable (includes netlify.toml)')
|
|
74
82
|
.action(async (name, options, command) => {
|
|
75
83
|
await envGet(name, options, command)
|
|
@@ -5,7 +5,16 @@ const { Option } = require('commander')
|
|
|
5
5
|
const inquirer = require('inquirer')
|
|
6
6
|
const isEmpty = require('lodash/isEmpty')
|
|
7
7
|
|
|
8
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
AVAILABLE_CONTEXTS,
|
|
10
|
+
chalk,
|
|
11
|
+
error,
|
|
12
|
+
getEnvelopeEnv,
|
|
13
|
+
getHumanReadableScopes,
|
|
14
|
+
log,
|
|
15
|
+
logJson,
|
|
16
|
+
normalizeContext,
|
|
17
|
+
} = require('../../utils')
|
|
9
18
|
|
|
10
19
|
const [logUpdatePromise, ansiEscapesPromise] = [import('log-update'), import('ansi-escapes')]
|
|
11
20
|
|
|
@@ -77,7 +86,8 @@ const envList = async (options, command) => {
|
|
|
77
86
|
}
|
|
78
87
|
|
|
79
88
|
const forSite = `for site ${chalk.green(siteInfo.name)}`
|
|
80
|
-
const
|
|
89
|
+
const contextType = AVAILABLE_CONTEXTS.includes(context) ? 'context' : 'branch'
|
|
90
|
+
const withContext = isUsingEnvelope ? `in the ${chalk.magenta(options.context)} ${contextType}` : ''
|
|
81
91
|
const withScope = isUsingEnvelope && scope !== 'any' ? `and ${chalk.yellow(options.scope)} scope` : ''
|
|
82
92
|
if (isEmpty(environment)) {
|
|
83
93
|
log(`No environment variables set ${forSite} ${withContext} ${withScope}`)
|
|
@@ -122,16 +132,23 @@ const envList = async (options, command) => {
|
|
|
122
132
|
const createEnvListCommand = (program) =>
|
|
123
133
|
program
|
|
124
134
|
.command('env:list')
|
|
125
|
-
.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
.option(
|
|
136
|
+
'-c, --context <context>',
|
|
137
|
+
'Specify a deploy context or branch (contexts: "production", "deploy-preview", "branch-deploy", "dev")',
|
|
138
|
+
normalizeContext,
|
|
139
|
+
'dev',
|
|
129
140
|
)
|
|
130
141
|
.addOption(
|
|
131
142
|
new Option('-s, --scope <scope>', 'Specify a scope')
|
|
132
143
|
.choices(['builds', 'functions', 'post_processing', 'runtime', 'any'])
|
|
133
144
|
.default('any'),
|
|
134
145
|
)
|
|
146
|
+
.addExamples([
|
|
147
|
+
'netlify env:list # list variables with values in the dev context and with any scope',
|
|
148
|
+
'netlify env:list --context production',
|
|
149
|
+
'netlify env:list --context branch:staging',
|
|
150
|
+
'netlify env:list --scope functions',
|
|
151
|
+
])
|
|
135
152
|
.description('Lists resolved environment variables for site (includes netlify.toml)')
|
|
136
153
|
.action(async (options, command) => {
|
|
137
154
|
await envList(options, command)
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
const { Option } = require('commander')
|
|
3
3
|
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const {
|
|
5
|
+
AVAILABLE_CONTEXTS,
|
|
6
|
+
AVAILABLE_SCOPES,
|
|
7
|
+
chalk,
|
|
8
|
+
error,
|
|
9
|
+
log,
|
|
10
|
+
logJson,
|
|
11
|
+
normalizeContext,
|
|
12
|
+
translateFromEnvelopeToMongo,
|
|
13
|
+
} = require('../../utils')
|
|
7
14
|
|
|
8
15
|
/**
|
|
9
16
|
* The env:set command
|
|
@@ -52,10 +59,11 @@ const envSet = async (key, value, options, command) => {
|
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
const withScope = scope ? ` scoped to ${chalk.white(scope)}` : ''
|
|
62
|
+
const contextType = AVAILABLE_CONTEXTS.includes(context || 'all') ? 'context' : 'branch'
|
|
55
63
|
log(
|
|
56
64
|
`Set environment variable ${chalk.yellow(`${key}${value ? '=' : ''}${value}`)}${withScope} in the ${chalk.magenta(
|
|
57
65
|
context || 'all',
|
|
58
|
-
)}
|
|
66
|
+
)} ${contextType}`,
|
|
59
67
|
)
|
|
60
68
|
}
|
|
61
69
|
|
|
@@ -93,7 +101,10 @@ const setInEnvelope = async ({ api, context, key, scope, siteInfo, value }) => {
|
|
|
93
101
|
const contexts = context || ['all']
|
|
94
102
|
const scopes = scope || AVAILABLE_SCOPES
|
|
95
103
|
|
|
96
|
-
|
|
104
|
+
// if the passed context is unknown, it is actually a branch name
|
|
105
|
+
let values = contexts.map((ctx) =>
|
|
106
|
+
AVAILABLE_CONTEXTS.includes(ctx) ? { context: ctx, value } : { context: 'branch', context_parameter: ctx, value },
|
|
107
|
+
)
|
|
97
108
|
|
|
98
109
|
const existing = envelopeVariables.find((envVar) => envVar.key === key)
|
|
99
110
|
|
|
@@ -144,13 +155,11 @@ const createEnvSetCommand = (program) =>
|
|
|
144
155
|
.command('env:set')
|
|
145
156
|
.argument('<key>', 'Environment variable key')
|
|
146
157
|
.argument('[value]', 'Value to set to', '')
|
|
147
|
-
.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
'dev',
|
|
153
|
-
]),
|
|
158
|
+
.option(
|
|
159
|
+
'-c, --context <context...>',
|
|
160
|
+
'Specify a deploy context or branch (contexts: "production", "deploy-preview", "branch-deploy", "dev") (default: all contexts)',
|
|
161
|
+
// spread over an array for variadic options
|
|
162
|
+
(context, previous = []) => [...previous, normalizeContext(context)],
|
|
154
163
|
)
|
|
155
164
|
.addOption(
|
|
156
165
|
new Option('-s, --scope <scope...>', 'Specify a scope (default: all scopes)').choices([
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
const { Option } = require('commander')
|
|
2
|
-
|
|
3
1
|
// @ts-check
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
const {
|
|
3
|
+
AVAILABLE_CONTEXTS,
|
|
4
|
+
chalk,
|
|
5
|
+
error,
|
|
6
|
+
log,
|
|
7
|
+
logJson,
|
|
8
|
+
normalizeContext,
|
|
9
|
+
translateFromEnvelopeToMongo,
|
|
10
|
+
} = require('../../utils')
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* The env:unset command
|
|
@@ -44,7 +48,8 @@ const envUnset = async (key, options, command) => {
|
|
|
44
48
|
return false
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
const contextType = AVAILABLE_CONTEXTS.includes(context || 'all') ? 'context' : 'branch'
|
|
52
|
+
log(`Unset environment variable ${chalk.yellow(key)} in the ${chalk.magenta(context || 'all')} ${contextType}`)
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
/**
|
|
@@ -98,8 +103,10 @@ const unsetInEnvelope = async ({ api, context, key, siteInfo }) => {
|
|
|
98
103
|
const params = { accountId, siteId, key }
|
|
99
104
|
try {
|
|
100
105
|
if (context) {
|
|
101
|
-
// if context(s) are passed, delete the matching contexts, and the `all` context
|
|
102
|
-
const values = variable.values.filter((val) =>
|
|
106
|
+
// if context(s) are passed, delete the matching contexts / branches, and the `all` context
|
|
107
|
+
const values = variable.values.filter((val) =>
|
|
108
|
+
[...contexts, 'all'].includes(val.context_parameter || val.context),
|
|
109
|
+
)
|
|
103
110
|
if (values) {
|
|
104
111
|
await Promise.all(values.map((value) => api.deleteEnvVarValue({ ...params, id: value.id })))
|
|
105
112
|
// if this was the `all` context, we need to create 3 values in the other contexts
|
|
@@ -107,7 +114,9 @@ const unsetInEnvelope = async ({ api, context, key, siteInfo }) => {
|
|
|
107
114
|
const newContexts = AVAILABLE_CONTEXTS.filter((ctx) => !context.includes(ctx))
|
|
108
115
|
const allValue = values[0].value
|
|
109
116
|
await Promise.all(
|
|
110
|
-
newContexts
|
|
117
|
+
newContexts
|
|
118
|
+
.filter((ctx) => ctx !== 'all')
|
|
119
|
+
.map((ctx) => api.setEnvVarValue({ ...params, body: { context: ctx, value: allValue } })),
|
|
111
120
|
)
|
|
112
121
|
}
|
|
113
122
|
}
|
|
@@ -134,13 +143,11 @@ const createEnvUnsetCommand = (program) =>
|
|
|
134
143
|
.command('env:unset')
|
|
135
144
|
.aliases(['env:delete', 'env:remove'])
|
|
136
145
|
.argument('<key>', 'Environment variable key')
|
|
137
|
-
.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
'dev',
|
|
143
|
-
]),
|
|
146
|
+
.option(
|
|
147
|
+
'-c, --context <context...>',
|
|
148
|
+
'Specify a deploy context or branch (contexts: "production", "deploy-preview", "branch-deploy", "dev") (default: all contexts)',
|
|
149
|
+
// spread over an array for variadic options
|
|
150
|
+
(context, previous = []) => [...previous, normalizeContext(context)],
|
|
144
151
|
)
|
|
145
152
|
.addExamples([
|
|
146
153
|
'netlify env:unset VAR_NAME # unset in all contexts',
|
package/src/utils/env/index.js
CHANGED
|
@@ -1,10 +1,46 @@
|
|
|
1
|
+
const { error } = require('../command-helpers')
|
|
2
|
+
|
|
3
|
+
const AVAILABLE_CONTEXTS = ['all', 'production', 'deploy-preview', 'branch-deploy', 'dev']
|
|
4
|
+
const AVAILABLE_SCOPES = ['builds', 'functions', 'runtime', 'post_processing']
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {string|undefined} context - The deploy context or branch of the environment variable value
|
|
8
|
+
* @returns {Array<string|undefined>} The normalized context or branch name
|
|
9
|
+
*/
|
|
10
|
+
const normalizeContext = (context) => {
|
|
11
|
+
if (!context) {
|
|
12
|
+
return context
|
|
13
|
+
}
|
|
14
|
+
const CONTEXT_SYNONYMS = {
|
|
15
|
+
dp: 'deploy-preview',
|
|
16
|
+
prod: 'production',
|
|
17
|
+
}
|
|
18
|
+
context = context.toLowerCase()
|
|
19
|
+
if (context in CONTEXT_SYNONYMS) {
|
|
20
|
+
context = CONTEXT_SYNONYMS[context]
|
|
21
|
+
}
|
|
22
|
+
const forbiddenContexts = AVAILABLE_CONTEXTS.map((ctx) => `branch:${ctx}`)
|
|
23
|
+
if (forbiddenContexts.includes(context)) {
|
|
24
|
+
error(`The context ${context} includes a reserved keyword and is not allowed`)
|
|
25
|
+
}
|
|
26
|
+
context = context.replace(/^branch:/, '')
|
|
27
|
+
return context
|
|
28
|
+
}
|
|
29
|
+
|
|
1
30
|
/**
|
|
2
31
|
* Finds a matching environment variable value from a given context
|
|
3
32
|
* @param {Array<object>} values - An array of environment variable values from Envelope
|
|
4
|
-
* @param {
|
|
5
|
-
* @returns {object<context: enum<dev,branch-deploy,deploy-preview,production>, value: string>} The matching environment variable value object
|
|
33
|
+
* @param {string} context - The deploy context or branch of the environment variable value
|
|
34
|
+
* @returns {object<context: enum<dev,branch-deploy,deploy-preview,production,branch>, context_parameter: <string>, value: string>} The matching environment variable value object
|
|
6
35
|
*/
|
|
7
|
-
const
|
|
36
|
+
const findValueInValues = (values, context) =>
|
|
37
|
+
values.find((val) => {
|
|
38
|
+
if (!AVAILABLE_CONTEXTS.includes(context)) {
|
|
39
|
+
// the "context" option passed in is actually the name of a branch
|
|
40
|
+
return val.context === 'all' || val.context_parameter === context
|
|
41
|
+
}
|
|
42
|
+
return [context, 'all'].includes(val.context)
|
|
43
|
+
})
|
|
8
44
|
|
|
9
45
|
/**
|
|
10
46
|
* Finds environment variables that match a given source
|
|
@@ -45,7 +81,7 @@ const fetchEnvelopeItems = async function ({ accountId, api, key, siteId }) {
|
|
|
45
81
|
|
|
46
82
|
/**
|
|
47
83
|
* Filters and sorts data from Envelope by a given context and/or scope
|
|
48
|
-
* @param {
|
|
84
|
+
* @param {string} context - The deploy context or branch of the environment variable value
|
|
49
85
|
* @param {Array<object>} envelopeItems - An array of environment variables from the Envelope service
|
|
50
86
|
* @param {enum<any,builds,functions,runtime,post_processing>} scope - The scope of the environment variables
|
|
51
87
|
* @param {enum<general,account,addons,ui,configFile>} source - The source of the environment variable
|
|
@@ -58,7 +94,8 @@ const fetchEnvelopeItems = async function ({ accountId, api, key, siteId }) {
|
|
|
58
94
|
* value: 'bar',
|
|
59
95
|
* },
|
|
60
96
|
* BAZ: {
|
|
61
|
-
* context: '
|
|
97
|
+
* context: 'branch',
|
|
98
|
+
* branch: 'staging',
|
|
62
99
|
* scopes: ['runtime'],
|
|
63
100
|
* sources: ['account'],
|
|
64
101
|
* value: 'bang',
|
|
@@ -68,18 +105,19 @@ const fetchEnvelopeItems = async function ({ accountId, api, key, siteId }) {
|
|
|
68
105
|
const formatEnvelopeData = ({ context = 'dev', envelopeItems = [], scope = 'any', source }) =>
|
|
69
106
|
envelopeItems
|
|
70
107
|
// filter by context
|
|
71
|
-
.filter(({ values }) => Boolean(
|
|
108
|
+
.filter(({ values }) => Boolean(findValueInValues(values, context)))
|
|
72
109
|
// filter by scope
|
|
73
110
|
.filter(({ scopes }) => (scope === 'any' ? true : scopes.includes(scope)))
|
|
74
111
|
// sort alphabetically, case insensitive
|
|
75
112
|
.sort((left, right) => (left.key.toLowerCase() < right.key.toLowerCase() ? -1 : 1))
|
|
76
113
|
// format the data
|
|
77
114
|
.reduce((acc, cur) => {
|
|
78
|
-
const { context: ctx, value } =
|
|
115
|
+
const { context: ctx, context_parameter: branch, value } = findValueInValues(cur.values, context)
|
|
79
116
|
return {
|
|
80
117
|
...acc,
|
|
81
118
|
[cur.key]: {
|
|
82
119
|
context: ctx,
|
|
120
|
+
branch,
|
|
83
121
|
scopes: cur.scopes,
|
|
84
122
|
sources: [source],
|
|
85
123
|
value,
|
|
@@ -90,7 +128,7 @@ const formatEnvelopeData = ({ context = 'dev', envelopeItems = [], scope = 'any'
|
|
|
90
128
|
/**
|
|
91
129
|
* Collects env vars from multiple sources and arranges them in the correct order of precedence
|
|
92
130
|
* @param {object} api - The api singleton object
|
|
93
|
-
* @param {
|
|
131
|
+
* @param {string} context - The deploy context or branch of the environment variable
|
|
94
132
|
* @param {object} env - The dictionary of environment variables
|
|
95
133
|
* @param {string} key - If present, fetch a single key (case-sensitive)
|
|
96
134
|
* @param {enum<any,builds,functions,runtime,post_processing>} scope - The scope of the environment variables
|
|
@@ -130,7 +168,7 @@ const getEnvelopeEnv = async ({ api, context = 'dev', env, key = '', scope = 'an
|
|
|
130
168
|
* @returns {string} A human-readable, comma-separated list of scopes
|
|
131
169
|
*/
|
|
132
170
|
const getHumanReadableScopes = (scopes) => {
|
|
133
|
-
const
|
|
171
|
+
const HUMAN_SCOPES = {
|
|
134
172
|
builds: 'Builds',
|
|
135
173
|
functions: 'Functions',
|
|
136
174
|
post_processing: 'Post processing',
|
|
@@ -141,11 +179,11 @@ const getHumanReadableScopes = (scopes) => {
|
|
|
141
179
|
// env vars specified in netlify.toml are present in the `builds` and `post_processing` scope
|
|
142
180
|
return 'Builds, Post processing'
|
|
143
181
|
}
|
|
144
|
-
if (scopes.length === Object.keys(
|
|
182
|
+
if (scopes.length === Object.keys(HUMAN_SCOPES).length) {
|
|
145
183
|
// shorthand instead of listing every available scope
|
|
146
184
|
return 'All'
|
|
147
185
|
}
|
|
148
|
-
return scopes.map((scope) =>
|
|
186
|
+
return scopes.map((scope) => HUMAN_SCOPES[scope]).join(', ')
|
|
149
187
|
}
|
|
150
188
|
|
|
151
189
|
/**
|
|
@@ -156,7 +194,7 @@ const getHumanReadableScopes = (scopes) => {
|
|
|
156
194
|
const translateFromMongoToEnvelope = (env = {}) => {
|
|
157
195
|
const envVars = Object.entries(env).map(([key, value]) => ({
|
|
158
196
|
key,
|
|
159
|
-
scopes:
|
|
197
|
+
scopes: AVAILABLE_SCOPES,
|
|
160
198
|
values: [
|
|
161
199
|
{
|
|
162
200
|
context: 'all',
|
|
@@ -171,14 +209,14 @@ const translateFromMongoToEnvelope = (env = {}) => {
|
|
|
171
209
|
/**
|
|
172
210
|
* Translates an Envelope env into a Mongo env
|
|
173
211
|
* @param {Array<object>} envVars - The array of Envelope env vars
|
|
174
|
-
* @param {
|
|
212
|
+
* @param {string} context - The deploy context or branch of the environment variable
|
|
175
213
|
* @returns {object} The env object as compatible with Mongo
|
|
176
214
|
*/
|
|
177
215
|
const translateFromEnvelopeToMongo = (envVars = [], context = 'dev') =>
|
|
178
216
|
envVars
|
|
179
217
|
.sort((left, right) => (left.key.toLowerCase() < right.key.toLowerCase() ? -1 : 1))
|
|
180
218
|
.reduce((acc, cur) => {
|
|
181
|
-
const envVar = cur.values.find((val) => [context, 'all'].includes(val.context))
|
|
219
|
+
const envVar = cur.values.find((val) => [context, 'all'].includes(val.context_parameter || val.context))
|
|
182
220
|
if (envVar && envVar.value) {
|
|
183
221
|
return {
|
|
184
222
|
...acc,
|
|
@@ -189,11 +227,14 @@ const translateFromEnvelopeToMongo = (envVars = [], context = 'dev') =>
|
|
|
189
227
|
}, {})
|
|
190
228
|
|
|
191
229
|
module.exports = {
|
|
192
|
-
|
|
230
|
+
AVAILABLE_CONTEXTS,
|
|
231
|
+
AVAILABLE_SCOPES,
|
|
232
|
+
findValueInValues,
|
|
193
233
|
filterEnvBySource,
|
|
194
234
|
formatEnvelopeData,
|
|
195
235
|
getEnvelopeEnv,
|
|
196
236
|
getHumanReadableScopes,
|
|
237
|
+
normalizeContext,
|
|
197
238
|
translateFromEnvelopeToMongo,
|
|
198
239
|
translateFromMongoToEnvelope,
|
|
199
240
|
}
|