netlify-cli 14.0.0-rc → 14.1.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/src/utils/dev.mjs CHANGED
@@ -137,30 +137,40 @@ const getEnvSourceName = (source) => {
137
137
  return printFn(name)
138
138
  }
139
139
 
140
- // Takes a set of environment variables in the format provided by @netlify/config, augments it with variables from both
141
- // dot-env files and the process itself, and injects into `process.env`.
142
- export const injectEnvVariables = async ({ devConfig, env, site }) => {
143
- const environment = new Map(Object.entries(env))
140
+ /**
141
+ * @param {{devConfig: any, env: Record<string, { sources: string[], value: string}>, site: any}} param0
142
+ * @returns {Promise<Record<string, { sources: string[], value: string}>>}
143
+ */
144
+ export const getDotEnvVariables = async ({ devConfig, env, site }) => {
144
145
  const dotEnvFiles = await loadDotEnvFiles({ envFiles: devConfig.envFiles, projectDir: site.root })
145
-
146
146
  dotEnvFiles.forEach(({ env: fileEnv, file }) => {
147
+ const newSourceName = `${file} file`
148
+
147
149
  Object.keys(fileEnv).forEach((key) => {
148
- const newSourceName = `${file} file`
149
- const sources = environment.has(key) ? [newSourceName, ...environment.get(key).sources] : [newSourceName]
150
+ const sources = key in env ? [newSourceName, ...env[key].sources] : [newSourceName]
150
151
 
151
152
  if (sources.includes('internal')) {
152
153
  return
153
154
  }
154
155
 
155
- environment.set(key, {
156
+ env[key] = {
156
157
  sources,
157
158
  value: fileEnv[key],
158
- })
159
+ }
159
160
  })
160
161
  })
161
162
 
163
+ return env
164
+ }
165
+
166
+ /**
167
+ * Takes a set of environment variables in the format provided by @netlify/config and injects them into `process.env`
168
+ * @param {Record<string, { sources: string[], value: string}>} env
169
+ * @return {void}
170
+ */
171
+ export const injectEnvVariables = (env) => {
162
172
  // eslint-disable-next-line fp/no-loops
163
- for (const [key, variable] of environment) {
173
+ for (const [key, variable] of Object.entries(env)) {
164
174
  const existsInProcess = process.env[key] !== undefined
165
175
  const [usedSource, ...overriddenSources] = existsInProcess ? ['process', ...variable.sources] : variable.sources
166
176
  const usedSourceName = getEnvSourceName(usedSource)
@@ -2,6 +2,10 @@ import { env } from 'process'
2
2
  // This is a thin layer on top of `execa` that allows consumers to provide an
3
3
  // alternative path to the module location, making it easier to mock its logic
4
4
  // in tests (see `tests/utils/mock-execa.js`).
5
+
6
+ /**
7
+ * @type {import('execa')}
8
+ */
5
9
  // eslint-disable-next-line import/no-mutable-exports
6
10
  let execa
7
11
 
@@ -1,7 +1,6 @@
1
1
  // @ts-check
2
2
  import { readFile } from 'fs/promises'
3
3
 
4
- import { get } from 'dot-prop'
5
4
  import { locatePath } from 'locate-path'
6
5
  import nodeVersionAlias from 'node-version-alias'
7
6
 
@@ -18,10 +17,10 @@ export const detectNodeVersion = async ({ baseDirectory, env }) => {
18
17
  try {
19
18
  const nodeVersionFile = await locatePath(['.nvmrc', '.node-version'], { cwd: baseDirectory })
20
19
  const configuredVersion =
21
- nodeVersionFile === undefined ? get(env, 'NODE_VERSION.value') : await readFile(nodeVersionFile, 'utf8')
20
+ nodeVersionFile === undefined ? env.NODE_VERSION?.value : await readFile(nodeVersionFile, 'utf8')
22
21
 
23
22
  const version =
24
- configuredVersion === undefined
23
+ configuredVersion === undefined || configuredVersion === null
25
24
  ? DEFAULT_NODE_VERSION
26
25
  : await nodeVersionAlias(normalizeConfiguredVersion(configuredVersion))
27
26
 
@@ -111,7 +111,7 @@ export const startLiveTunnel = async ({ localPort, netlifyApiToken, siteId }) =>
111
111
  return data.state === 'online'
112
112
  }
113
113
 
114
- await connectTunnel({ session, netlifyApiToken, localPort })
114
+ connectTunnel({ session, netlifyApiToken, localPort })
115
115
 
116
116
  // Waiting for the live session to have a state of `online`.
117
117
  await pWaitFor(isLiveTunnelReady, {
@@ -1 +1,2 @@
1
1
  export { track, identify } from './telemetry.mjs'
2
+ export { reportError } from './report-error.mjs'
@@ -0,0 +1,44 @@
1
+ import { dirname, join } from 'path'
2
+ import process, { version as nodejsVersion } from 'process'
3
+ import { fileURLToPath } from 'url'
4
+
5
+ import execa from '../execa.mjs'
6
+ import getGlobalConfig from '../get-global-config.mjs'
7
+
8
+ import { cliVersion } from './utils.mjs'
9
+
10
+ const dirPath = dirname(fileURLToPath(import.meta.url))
11
+
12
+ /**
13
+ *
14
+ * @param {import('@bugsnag/js').NotifiableError} error
15
+ * @param {object} config
16
+ * @param {import('@bugsnag/js').Event['severity']} config.severity
17
+ * @returns {Promise<void>}
18
+ */
19
+ export const reportError = async function (error, config = {}) {
20
+ const globalConfig = await getGlobalConfig()
21
+
22
+ const options = JSON.stringify({
23
+ type: 'error',
24
+ data: {
25
+ message: error.message,
26
+ name: error.name,
27
+ stack: error.stack,
28
+ cause: error.cause,
29
+ severity: config.severity,
30
+ user: {
31
+ id: globalConfig.get('userId'),
32
+ },
33
+ osName: process.platform,
34
+ cliVersion,
35
+ nodejsVersion,
36
+ },
37
+ })
38
+
39
+ // spawn detached child process to handle send
40
+ execa(process.execPath, [join(dirPath, 'request.mjs'), options], {
41
+ detached: true,
42
+ stdio: 'ignore',
43
+ }).unref()
44
+ }
@@ -14,13 +14,23 @@ const options = JSON.parse(process.argv[2])
14
14
  const CLIENT_ID = 'NETLIFY_CLI'
15
15
  const TRACK_URL = process.env.NETLIFY_TEST_TRACK_URL || 'https://cli.netlify.com/telemetry/track'
16
16
  const IDENTIFY_URL = process.env.NETLIFY_TEST_IDENTIFY_URL || 'https://cli.netlify.com/telemetry/identify'
17
-
18
- const API_URL = options.type && options.type === 'track' ? TRACK_URL : IDENTIFY_URL
17
+ const REPORT_ERROR_URL = process.env.NETLIFY_TEST_ERROR_REPORT_URL || 'https://cli.netlify.com/report-error'
18
+
19
+ const getApiUrl = () => {
20
+ switch (options.type) {
21
+ case 'track':
22
+ return TRACK_URL
23
+ case 'error':
24
+ return REPORT_ERROR_URL
25
+ default:
26
+ return IDENTIFY_URL
27
+ }
28
+ }
19
29
 
20
30
  // Make telemetry call
21
31
  const makeRequest = async function () {
22
32
  try {
23
- await fetch(API_URL, {
33
+ await fetch(getApiUrl(), {
24
34
  method: 'POST',
25
35
  headers: {
26
36
  'Content-Type': 'application/json',
@@ -7,16 +7,10 @@ import { isCI } from 'ci-info'
7
7
 
8
8
  import execa from '../execa.mjs'
9
9
  import getGlobalConfig from '../get-global-config.mjs'
10
- import getPackageJson from '../get-package-json.mjs'
11
10
 
11
+ import { isTelemetryDisabled, cliVersion } from './utils.mjs'
12
12
  import isValidEventName from './validation.mjs'
13
13
 
14
- const { version: cliVersion } = await getPackageJson()
15
-
16
- const isTelemetryDisabled = function (config) {
17
- return config.get('telemetryDisabled')
18
- }
19
-
20
14
  const dirPath = dirname(fileURLToPath(import.meta.url))
21
15
 
22
16
  const send = function (type, payload) {
@@ -0,0 +1,7 @@
1
+ import getPackageJson from '../get-package-json.mjs'
2
+
3
+ export const { version: cliVersion } = await getPackageJson()
4
+
5
+ export const isTelemetryDisabled = function (config) {
6
+ return config.get('telemetryDisabled')
7
+ }