netlify-cli 10.14.0 → 10.17.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/README.md +1 -1
- package/npm-shrinkwrap.json +856 -1603
- package/package.json +7 -6
- package/src/commands/dev/dev.js +31 -4
- package/src/commands/env/env-get.js +31 -4
- package/src/commands/env/env-list.js +59 -16
- package/src/commands/graph/graph-edit.js +4 -2
- package/src/commands/graph/graph-handler.js +41 -63
- package/src/commands/graph/graph-init.js +5 -1
- package/src/commands/graph/graph-library.js +30 -8
- package/src/commands/graph/graph-operations.js +6 -1
- package/src/commands/graph/graph-pull.js +79 -23
- package/src/commands/init/init.js +1 -1
- package/src/functions-templates/go/hello-world/go.mod +1 -1
- package/src/lib/edge-functions/proxy.js +4 -0
- package/src/lib/edge-functions/registry.js +29 -3
- package/src/lib/one-graph/cli-client.js +723 -118
- package/src/lib/one-graph/cli-netlify-graph.js +519 -50
- package/src/utils/dev.js +2 -2
- package/src/utils/env/index.js +156 -1
- package/src/utils/proxy.js +2 -0
package/src/utils/dev.js
CHANGED
|
@@ -14,7 +14,7 @@ const { loadDotEnvFiles } = require('./dot-env')
|
|
|
14
14
|
// Possible sources of environment variables. For the purpose of printing log messages only. Order does not matter.
|
|
15
15
|
const ENV_VAR_SOURCES = {
|
|
16
16
|
account: {
|
|
17
|
-
name: 'shared
|
|
17
|
+
name: 'shared',
|
|
18
18
|
printFn: chalk.magenta,
|
|
19
19
|
},
|
|
20
20
|
addons: {
|
|
@@ -34,7 +34,7 @@ const ENV_VAR_SOURCES = {
|
|
|
34
34
|
printFn: chalk.red,
|
|
35
35
|
},
|
|
36
36
|
ui: {
|
|
37
|
-
name: '
|
|
37
|
+
name: 'site settings',
|
|
38
38
|
printFn: chalk.blue,
|
|
39
39
|
},
|
|
40
40
|
}
|
package/src/utils/env/index.js
CHANGED
|
@@ -1,3 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds a matching environment variable value from a given context
|
|
3
|
+
* @param {Array<object>} values - An array of environment variable values from Envelope
|
|
4
|
+
* @param {enum<dev,branch-deploy,deploy-preview,production>} context - The deploy context of the environment variable value
|
|
5
|
+
* @returns {object<context: enum<dev,branch-deploy,deploy-preview,production>, value: string>} The matching environment variable value object
|
|
6
|
+
*/
|
|
7
|
+
const findValueFromContext = (values, context) => values.find((val) => [context, 'all'].includes(val.context))
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Finds environment variables that match a given source
|
|
11
|
+
* @param {object} env - The dictionary of environment variables
|
|
12
|
+
* @param {enum<general,account,addons,ui,configFile>} source - The source of the environment variable
|
|
13
|
+
* @returns {object} The dictionary of env vars that match the given source
|
|
14
|
+
*/
|
|
15
|
+
const filterEnvBySource = (env, source) =>
|
|
16
|
+
Object.fromEntries(Object.entries(env).filter(([, variable]) => variable.sources[0] === source))
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Fetches data from Envelope
|
|
20
|
+
* @param {string} accountId - The account id
|
|
21
|
+
* @param {object} api - The api singleton object
|
|
22
|
+
* @param {string} key - If present, fetch a single key (case-sensitive)
|
|
23
|
+
* @param {string} siteId - The site id
|
|
24
|
+
* @returns {Array<object>} An array of environment variables from the Envelope service
|
|
25
|
+
*/
|
|
26
|
+
const fetchEnvelopeItems = async function ({ accountId, api, key, siteId }) {
|
|
27
|
+
if (accountId === undefined) {
|
|
28
|
+
return {}
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
// if a single key is passed, fetch that single env var
|
|
32
|
+
if (key) {
|
|
33
|
+
const envelopeItem = await api.getEnvVar({ accountId, key, siteId })
|
|
34
|
+
return [envelopeItem]
|
|
35
|
+
}
|
|
36
|
+
// otherwise, fetch the entire list of env vars
|
|
37
|
+
const envelopeItems = await api.getEnvVars({ accountId, siteId })
|
|
38
|
+
return envelopeItems
|
|
39
|
+
} catch {
|
|
40
|
+
// Collaborators aren't allowed to read shared env vars,
|
|
41
|
+
// so return an empty array silently in that case
|
|
42
|
+
return []
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Filters and sorts data from Envelope by a given context and/or scope
|
|
48
|
+
* @param {enum<dev,branch-deploy,deploy-preview,production>} context - The deploy context of the environment variable value
|
|
49
|
+
* @param {Array<object>} envelopeItems - An array of environment variables from the Envelope service
|
|
50
|
+
* @param {enum<any,builds,functions,runtime,post_processing>} scope - The scope of the environment variables
|
|
51
|
+
* @param {enum<general,account,addons,ui,configFile>} source - The source of the environment variable
|
|
52
|
+
* @returns {object} A dicionary in the following format:
|
|
53
|
+
* {
|
|
54
|
+
* FOO: {
|
|
55
|
+
* context: 'dev',
|
|
56
|
+
* scopes: ['builds', 'functions'],
|
|
57
|
+
* sources: ['ui'],
|
|
58
|
+
* value: 'bar',
|
|
59
|
+
* },
|
|
60
|
+
* BAZ: {
|
|
61
|
+
* context: 'dev',
|
|
62
|
+
* scopes: ['runtime'],
|
|
63
|
+
* sources: ['account'],
|
|
64
|
+
* value: 'bang',
|
|
65
|
+
* },
|
|
66
|
+
* }
|
|
67
|
+
*/
|
|
68
|
+
const formatEnvelopeData = ({ context = 'dev', envelopeItems = [], scope = 'any', source }) =>
|
|
69
|
+
envelopeItems
|
|
70
|
+
// filter by context
|
|
71
|
+
.filter(({ values }) => Boolean(findValueFromContext(values, context)))
|
|
72
|
+
// filter by scope
|
|
73
|
+
.filter(({ scopes }) => (scope === 'any' ? true : scopes.includes(scope)))
|
|
74
|
+
// sort alphabetically, case insensitive
|
|
75
|
+
.sort((left, right) => (left.key.toLowerCase() < right.key.toLowerCase() ? -1 : 1))
|
|
76
|
+
// format the data
|
|
77
|
+
.reduce((acc, cur) => {
|
|
78
|
+
const { context: ctx, value } = findValueFromContext(cur.values, context)
|
|
79
|
+
return {
|
|
80
|
+
...acc,
|
|
81
|
+
[cur.key]: {
|
|
82
|
+
context: ctx,
|
|
83
|
+
scopes: cur.scopes,
|
|
84
|
+
sources: [source],
|
|
85
|
+
value,
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
}, {})
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Collects env vars from multiple sources and arranges them in the correct order of precedence
|
|
92
|
+
* @param {object} api - The api singleton object
|
|
93
|
+
* @param {enum<dev,branch-deploy,deploy-preview,production>} context - The deploy context of the environment variable
|
|
94
|
+
* @param {object} env - The dictionary of environment variables
|
|
95
|
+
* @param {string} key - If present, fetch a single key (case-sensitive)
|
|
96
|
+
* @param {enum<any,builds,functions,runtime,post_processing>} scope - The scope of the environment variables
|
|
97
|
+
* @param {object} siteInfo - The site object
|
|
98
|
+
* @returns {object} An object of environment variables keys and their metadata
|
|
99
|
+
*/
|
|
100
|
+
const getEnvelopeEnv = async ({ api, context = 'dev', env, key = '', scope = 'any', siteInfo }) => {
|
|
101
|
+
const { account_slug: accountId, id: siteId } = siteInfo
|
|
102
|
+
|
|
103
|
+
const [accountEnvelopeItems, siteEnvelopeItems] = await Promise.all([
|
|
104
|
+
fetchEnvelopeItems({ api, accountId, key }),
|
|
105
|
+
fetchEnvelopeItems({ api, accountId, key, siteId }),
|
|
106
|
+
])
|
|
107
|
+
|
|
108
|
+
const accountEnv = formatEnvelopeData({ context, envelopeItems: accountEnvelopeItems, scope, source: 'account' })
|
|
109
|
+
const siteEnv = formatEnvelopeData({ context, envelopeItems: siteEnvelopeItems, scope, source: 'ui' })
|
|
110
|
+
const generalEnv = filterEnvBySource(env, 'general')
|
|
111
|
+
const addonsEnv = filterEnvBySource(env, 'addons')
|
|
112
|
+
const configFileEnv = filterEnvBySource(env, 'configFile')
|
|
113
|
+
|
|
114
|
+
// filter out configFile env vars if a non-configFile scope is passed
|
|
115
|
+
const includeConfigEnvVars = ['any', 'builds', 'post_processing'].includes(scope)
|
|
116
|
+
|
|
117
|
+
// Sources of environment variables, in ascending order of precedence.
|
|
118
|
+
return {
|
|
119
|
+
...generalEnv,
|
|
120
|
+
...accountEnv,
|
|
121
|
+
...(includeConfigEnvVars ? addonsEnv : {}),
|
|
122
|
+
...siteEnv,
|
|
123
|
+
...(includeConfigEnvVars ? configFileEnv : {}),
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Returns a human-readable, comma-separated list of scopes
|
|
129
|
+
* @param {Array<enum<builds,functions,runtime,post_processing>>} scopes - An array of scopes
|
|
130
|
+
* @returns {string} A human-readable, comma-separated list of scopes
|
|
131
|
+
*/
|
|
132
|
+
const getHumanReadableScopes = (scopes) => {
|
|
133
|
+
const AVAILABLE_SCOPES = {
|
|
134
|
+
builds: 'Builds',
|
|
135
|
+
functions: 'Functions',
|
|
136
|
+
post_processing: 'Post processing',
|
|
137
|
+
runtime: 'Runtime',
|
|
138
|
+
}
|
|
139
|
+
if (!scopes) {
|
|
140
|
+
// if `scopes` is not available, the env var comes from netlify.toml
|
|
141
|
+
// env vars specified in netlify.toml are present in the `builds` and `post_processing` scope
|
|
142
|
+
return 'Builds, Post processing'
|
|
143
|
+
}
|
|
144
|
+
if (scopes.length === Object.keys(AVAILABLE_SCOPES).length) {
|
|
145
|
+
// shorthand instead of listing every available scope
|
|
146
|
+
return 'All'
|
|
147
|
+
}
|
|
148
|
+
return scopes.map((scope) => AVAILABLE_SCOPES[scope]).join(', ')
|
|
149
|
+
}
|
|
150
|
+
|
|
1
151
|
/**
|
|
2
152
|
* Translates a Mongo env into an Envelope env
|
|
3
153
|
* @param {object} env - The site's env as it exists in Mongo
|
|
@@ -38,6 +188,11 @@ const translateFromEnvelopeToMongo = (envVars = []) =>
|
|
|
38
188
|
}, {})
|
|
39
189
|
|
|
40
190
|
module.exports = {
|
|
41
|
-
|
|
191
|
+
findValueFromContext,
|
|
192
|
+
filterEnvBySource,
|
|
193
|
+
formatEnvelopeData,
|
|
194
|
+
getEnvelopeEnv,
|
|
195
|
+
getHumanReadableScopes,
|
|
42
196
|
translateFromEnvelopeToMongo,
|
|
197
|
+
translateFromMongoToEnvelope,
|
|
43
198
|
}
|
package/src/utils/proxy.js
CHANGED
|
@@ -465,6 +465,7 @@ const startProxy = async function ({
|
|
|
465
465
|
addonsUrls,
|
|
466
466
|
config,
|
|
467
467
|
configPath,
|
|
468
|
+
env,
|
|
468
469
|
geoCountry,
|
|
469
470
|
geolocationMode,
|
|
470
471
|
getUpdatedConfig,
|
|
@@ -479,6 +480,7 @@ const startProxy = async function ({
|
|
|
479
480
|
const edgeFunctionsProxy = await edgeFunctions.initializeProxy({
|
|
480
481
|
config,
|
|
481
482
|
configPath,
|
|
483
|
+
env,
|
|
482
484
|
geolocationMode,
|
|
483
485
|
geoCountry,
|
|
484
486
|
getUpdatedConfig,
|