netlify-cli 15.8.0 → 15.8.1-rc.1

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.
@@ -1,24 +1,28 @@
1
1
  // @ts-check
2
2
  import { readFile } from 'fs/promises'
3
3
  import { EOL } from 'os'
4
- import path from 'path'
4
+ import path, { join } from 'path'
5
5
  import process from 'process'
6
6
 
7
- import { Project } from '@netlify/build-info'
8
- // eslint-disable-next-line import/extensions, n/no-missing-import
9
- import { NodeFS } from '@netlify/build-info/node'
10
- import { getFramework, listFrameworks } from '@netlify/framework-info'
7
+ import { getFramework, getSettings } from '@netlify/build-info'
11
8
  import fuzzy from 'fuzzy'
12
9
  import getPort from 'get-port'
13
10
 
14
11
  import { NETLIFYDEVWARN, chalk, log } from './command-helpers.mjs'
15
12
  import { acquirePort } from './dev.mjs'
16
13
  import { getInternalFunctionsDir } from './functions/functions.mjs'
17
- import { reportError } from './telemetry/report-error.mjs'
18
14
 
15
+ /** @param {string} str */
19
16
  const formatProperty = (str) => chalk.magenta(`'${str}'`)
17
+ /** @param {string} str */
20
18
  const formatValue = (str) => chalk.green(`'${str}'`)
21
19
 
20
+ /**
21
+ * @param {object} options
22
+ * @param {string} options.keyFile
23
+ * @param {string} options.certFile
24
+ * @returns {Promise<{ key: string, cert: string, keyFilePath: string, certFilePath: string }>}
25
+ */
22
26
  const readHttpsSettings = async (options) => {
23
27
  if (typeof options !== 'object' || !options.keyFile || !options.certFile) {
24
28
  throw new TypeError(
@@ -51,6 +55,11 @@ const readHttpsSettings = async (options) => {
51
55
  return { key, cert, keyFilePath: path.resolve(keyFile), certFilePath: path.resolve(certFile) }
52
56
  }
53
57
 
58
+ /**
59
+ * @param {object} config
60
+ * @param {import('../commands/dev/types.js').DevConfig} config.devConfig
61
+ * @param {keyof import('../commands/dev/types.js').DevConfig} config.property
62
+ */
54
63
  const validateStringProperty = ({ devConfig, property }) => {
55
64
  if (devConfig[property] && typeof devConfig[property] !== 'string') {
56
65
  const formattedProperty = formatProperty(property)
@@ -60,6 +69,11 @@ const validateStringProperty = ({ devConfig, property }) => {
60
69
  }
61
70
  }
62
71
 
72
+ /**
73
+ * @param {object} config
74
+ * @param {import('../commands/dev/types.js').DevConfig} config.devConfig
75
+ * @param {keyof import('../commands/dev/types.js').DevConfig} config.property
76
+ */
63
77
  const validateNumberProperty = ({ devConfig, property }) => {
64
78
  if (devConfig[property] && typeof devConfig[property] !== 'number') {
65
79
  const formattedProperty = formatProperty(property)
@@ -69,6 +83,11 @@ const validateNumberProperty = ({ devConfig, property }) => {
69
83
  }
70
84
  }
71
85
 
86
+ /**
87
+ *
88
+ * @param {object} config
89
+ * @param {import('../commands/dev/types.js').DevConfig} config.devConfig
90
+ */
72
91
  const validateFrameworkConfig = ({ devConfig }) => {
73
92
  validateStringProperty({ devConfig, property: 'command' })
74
93
  validateNumberProperty({ devConfig, property: 'port' })
@@ -83,6 +102,11 @@ const validateFrameworkConfig = ({ devConfig }) => {
83
102
  }
84
103
  }
85
104
 
105
+ /**
106
+ * @param {object} config
107
+ * @param {import('../commands/dev/types.js').DevConfig} config.devConfig
108
+ * @param {number=} config.detectedPort
109
+ */
86
110
  const validateConfiguredPort = ({ detectedPort, devConfig }) => {
87
111
  if (devConfig.port && devConfig.port === detectedPort) {
88
112
  const formattedPort = formatProperty('port')
@@ -102,6 +126,11 @@ const getDefaultDist = () => {
102
126
  return process.cwd()
103
127
  }
104
128
 
129
+ /**
130
+ * @param {object} config
131
+ * @param {import('../commands/dev/types.js').DevConfig} config.devConfig
132
+ * @returns {Promise<number>}
133
+ */
105
134
  const getStaticServerPort = async ({ devConfig }) => {
106
135
  const port = await acquirePort({
107
136
  configuredPort: devConfig.staticServerPort,
@@ -114,10 +143,10 @@ const getStaticServerPort = async ({ devConfig }) => {
114
143
 
115
144
  /**
116
145
  *
117
- * @param {object} param0
118
- * @param {import('../commands/dev/types.js').DevConfig} param0.devConfig
119
- * @param {import('commander').OptionValues} param0.options
120
- * @param {string} param0.projectDir
146
+ * @param {object} config
147
+ * @param {import('../commands/dev/types.js').DevConfig} config.devConfig
148
+ * @param {import('commander').OptionValues} config.options
149
+ * @param {string} config.projectDir
121
150
  * @returns {Promise<import('./types.js').BaseServerSettings>}
122
151
  */
123
152
  const handleStaticServer = async ({ devConfig, options, projectDir }) => {
@@ -153,120 +182,84 @@ const handleStaticServer = async ({ devConfig, options, projectDir }) => {
153
182
  }
154
183
  }
155
184
 
185
+ // these plugins represent runtimes that are
186
+ // expected to be "automatically" installed. Even though
187
+ // they can be installed on package/toml, we always
188
+ // want them installed in the site settings. When installed
189
+ // there our build will automatically install the latest without
190
+ // user management of the versioning.
191
+ const pluginsToAlwaysInstall = new Set(['@netlify/plugin-nextjs'])
192
+
193
+ /**
194
+ * Retrieve a list of plugins to auto install
195
+ * @param {string[]=} pluginsInstalled
196
+ * @param {string[]=} pluginsRecommended
197
+ * @returns
198
+ */
199
+ const getPluginsToAutoInstall = (pluginsInstalled = [], pluginsRecommended = []) =>
200
+ pluginsRecommended.reduce(
201
+ (acc, plugin) =>
202
+ pluginsInstalled.includes(plugin) && !pluginsToAlwaysInstall.has(plugin) ? acc : [...acc, plugin],
203
+ // eslint-disable-next-line no-inline-comments
204
+ /** @type {string[]} */ ([]),
205
+ )
206
+
156
207
  /**
157
208
  * Retrieves the settings from a framework
158
- * @param {import('./types.js').FrameworkInfo} framework
209
+ * @param {import('@netlify/build-info').Settings} settings
159
210
  * @returns {import('./types.js').BaseServerSettings}
160
211
  */
161
- const getSettingsFromFramework = (framework) => {
212
+ const getSettingsFromDetectedSettings = (settings) => {
162
213
  const {
163
- build: { directory: dist },
164
- dev: {
165
- commands: [command],
166
- pollingStrategies = [],
167
- port: frameworkPort,
168
- },
169
- env = {},
170
- name: frameworkName,
171
- plugins,
172
- staticAssetsDirectory: staticDir,
173
- } = framework
214
+ devCommand: command,
215
+ dist,
216
+ env,
217
+ framework: { name: frameworkName },
218
+ frameworkPort,
219
+ // eslint-disable-next-line camelcase
220
+ plugins_from_config_file,
221
+ // eslint-disable-next-line camelcase
222
+ plugins_recommended,
223
+ pollingStrategies,
224
+ } = settings
174
225
 
175
226
  return {
176
227
  command,
177
228
  frameworkPort,
178
- dist: staticDir || dist,
229
+ dist,
179
230
  framework: frameworkName,
180
231
  env,
181
- pollingStrategies: pollingStrategies.map(({ name }) => name),
182
- plugins,
232
+ pollingStrategies,
233
+ plugins: getPluginsToAutoInstall(plugins_from_config_file, plugins_recommended),
183
234
  }
184
235
  }
185
236
 
186
- const hasDevCommand = (framework) => Array.isArray(framework.dev.commands) && framework.dev.commands.length !== 0
187
-
188
237
  /**
189
- * The new build setting detection with build systems and frameworks combined
190
- * @param {string} projectDir
238
+ * @param {import('@netlify/build-info').Project} project
191
239
  */
192
- const detectSettings = async (projectDir) => {
193
- const fs = new NodeFS()
194
- const project = new Project(fs, projectDir)
195
-
196
- return await project.getBuildSettings()
197
- }
198
-
199
- /**
200
- *
201
- * @param {import('./types.js').BaseServerSettings | undefined} frameworkSettings
202
- * @param {import('@netlify/build-info').Settings[]} newSettings
203
- * @param {Record<string, Record<string, any>>} [metadata]
204
- */
205
- const detectChangesInNewSettings = (frameworkSettings, newSettings, metadata) => {
206
- /** @type {string[]} */
207
- const message = ['']
208
- const [setting] = newSettings
209
-
210
- if (frameworkSettings?.framework !== setting?.framework) {
211
- message.push(
212
- `- Framework does not match:`,
213
- ` [old]: ${frameworkSettings?.framework}`,
214
- ` [new]: ${setting?.framework}`,
215
- '',
216
- )
217
- }
218
-
219
- if (frameworkSettings?.command !== setting?.devCommand) {
220
- message.push(
221
- `- command does not match:`,
222
- ` [old]: ${frameworkSettings?.command}`,
223
- ` [new]: ${setting?.devCommand}`,
224
- '',
225
- )
226
- }
227
-
228
- if (frameworkSettings?.dist !== setting?.dist) {
229
- message.push(`- dist does not match:`, ` [old]: ${frameworkSettings?.dist}`, ` [new]: ${setting?.dist}`, '')
230
- }
231
-
232
- if (frameworkSettings?.frameworkPort !== setting?.frameworkPort) {
233
- message.push(
234
- `- frameworkPort does not match:`,
235
- ` [old]: ${frameworkSettings?.frameworkPort}`,
236
- ` [new]: ${setting?.frameworkPort}`,
237
- '',
238
- )
239
- }
240
-
241
- if (message.length !== 0) {
242
- reportError(
243
- {
244
- name: 'NewSettingsDetectionMismatch',
245
- errorMessage: 'New Settings detection does not match old one',
246
- message: message.join('\n'),
247
- },
248
- { severity: 'info', metadata },
240
+ const detectFrameworkSettings = async (project) => {
241
+ const projectSettings = await project.getBuildSettings()
242
+ const settings = projectSettings
243
+ .filter((setting) =>
244
+ project.workspace && !project.workspace.isRoot
245
+ ? process.cwd().startsWith(join(project.jsWorkspaceRoot, setting.packagePath ?? ''))
246
+ : true,
249
247
  )
250
- }
251
- }
252
-
253
- const detectFrameworkSettings = async ({ projectDir }) => {
254
- const projectFrameworks = await listFrameworks({ projectDir })
255
- const frameworks = projectFrameworks.filter((framework) => hasDevCommand(framework))
248
+ .filter((setting) => setting.devCommand)
256
249
 
257
- if (frameworks.length === 1) {
258
- return getSettingsFromFramework(frameworks[0])
250
+ if (settings.length === 1) {
251
+ return getSettingsFromDetectedSettings(settings[0])
259
252
  }
260
253
 
261
- if (frameworks.length > 1) {
254
+ if (settings.length > 1) {
262
255
  // performance optimization, load inquirer on demand
263
256
  const { default: inquirer } = await import('inquirer')
264
257
  const { default: inquirerAutocompletePrompt } = await import('inquirer-autocomplete-prompt')
265
258
  /** multiple matching detectors, make the user choose */
266
259
  inquirer.registerPrompt('autocomplete', inquirerAutocompletePrompt)
267
- const scriptInquirerOptions = formatSettingsArrForInquirer(frameworks)
268
- const { chosenFramework } = await inquirer.prompt({
269
- name: 'chosenFramework',
260
+ const scriptInquirerOptions = formatSettingsArrForInquirer(settings)
261
+ const { chosenSettings } = await inquirer.prompt({
262
+ name: 'chosenSettings',
270
263
  message: `Multiple possible start commands found`,
271
264
  type: 'autocomplete',
272
265
  source(_, input) {
@@ -279,19 +272,24 @@ const detectFrameworkSettings = async ({ projectDir }) => {
279
272
  })
280
273
  log(
281
274
  `Add ${formatProperty(
282
- `framework = "${chosenFramework.id}"`,
275
+ `framework = "${chosenSettings.framework.id}"`,
283
276
  )} to the [dev] section of your netlify.toml to avoid this selection prompt next time`,
284
277
  )
285
278
 
286
- return getSettingsFromFramework(chosenFramework)
279
+ return getSettingsFromDetectedSettings(chosenSettings)
287
280
  }
288
281
  }
289
282
 
283
+ /**
284
+ * @param {object} config
285
+ * @param {import('../commands/dev/types.js').DevConfig} config.devConfig
286
+ */
290
287
  const hasCommandAndTargetPort = ({ devConfig }) => devConfig.command && devConfig.targetPort
291
288
 
292
289
  /**
293
290
  * Creates settings for the custom framework
294
- * @param {*} param0
291
+ * @param {object} config
292
+ * @param {import('../commands/dev/types.js').DevConfig} config.devConfig
295
293
  * @returns {import('./types.js').BaseServerSettings}
296
294
  */
297
295
  const handleCustomFramework = ({ devConfig }) => {
@@ -311,6 +309,9 @@ const handleCustomFramework = ({ devConfig }) => {
311
309
  }
312
310
  }
313
311
 
312
+ /**
313
+ * @param {{ devConfig: any, frameworkSettings: import('./types.js').BaseServerSettings }} param0
314
+ */
314
315
  const mergeSettings = async ({ devConfig, frameworkSettings = {} }) => {
315
316
  const {
316
317
  command: frameworkCommand,
@@ -338,12 +339,14 @@ const mergeSettings = async ({ devConfig, frameworkSettings = {} }) => {
338
339
 
339
340
  /**
340
341
  * Handles a forced framework and retrieves the settings for it
341
- * @param {*} param0
342
+ * @param {{ devConfig: any, project: import('@netlify/build-info').Project }} config
342
343
  * @returns {Promise<import('./types.js').BaseServerSettings>}
343
344
  */
344
- const handleForcedFramework = async ({ devConfig, projectDir }) => {
345
+ const handleForcedFramework = async ({ devConfig, project }) => {
345
346
  // this throws if `devConfig.framework` is not a supported framework
346
- const frameworkSettings = getSettingsFromFramework(await getFramework(devConfig.framework, { projectDir }))
347
+ const framework = await getFramework(devConfig.framework, project)
348
+ const settings = await getSettings(framework, project, '')
349
+ const frameworkSettings = getSettingsFromDetectedSettings(settings)
347
350
  return mergeSettings({ devConfig, frameworkSettings })
348
351
  }
349
352
 
@@ -351,11 +354,12 @@ const handleForcedFramework = async ({ devConfig, projectDir }) => {
351
354
  * Get the server settings based on the flags and the devConfig
352
355
  * @param {import('../commands/dev/types.js').DevConfig} devConfig
353
356
  * @param {import('commander').OptionValues} options
357
+ * @param {import('@netlify/build-info').Project} project
354
358
  * @param {string} projectDir
355
- * @param {Record<string, Record<string, any>>} [metadata]
356
359
  * @returns {Promise<import('./types.js').ServerSettings>}
357
360
  */
358
- const detectServerSettings = async (devConfig, options, projectDir, metadata) => {
361
+
362
+ const detectServerSettings = async (devConfig, options, project, projectDir) => {
359
363
  validateStringProperty({ devConfig, property: 'framework' })
360
364
 
361
365
  /** @type {Partial<import('./types.js').BaseServerSettings>} */
@@ -368,22 +372,9 @@ const detectServerSettings = async (devConfig, options, projectDir, metadata) =>
368
372
  // this is the default CLI behavior
369
373
 
370
374
  const runDetection = !hasCommandAndTargetPort({ devConfig })
371
- const frameworkSettings = runDetection ? await detectFrameworkSettings({ projectDir }) : undefined
372
- const newSettings = runDetection ? await detectSettings(projectDir) : undefined
373
-
374
- // just report differences in the settings
375
- detectChangesInNewSettings(frameworkSettings, newSettings || [], {
376
- ...metadata,
377
- settings: {
378
- projectDir,
379
- devConfig,
380
- options,
381
- old: frameworkSettings,
382
- settings: newSettings,
383
- },
384
- })
375
+ const frameworkSettings = runDetection ? await detectFrameworkSettings(project) : undefined
385
376
 
386
- if (frameworkSettings === undefined && runDetection) {
377
+ if (frameworkSettings === undefined) {
387
378
  log(`${NETLIFYDEVWARN} No app server detected. Using simple static server`)
388
379
  settings = await handleStaticServer({ options, devConfig, projectDir })
389
380
  } else {
@@ -399,7 +390,7 @@ const detectServerSettings = async (devConfig, options, projectDir, metadata) =>
399
390
  } else if (devConfig.framework) {
400
391
  validateFrameworkConfig({ devConfig })
401
392
  // this is when the user explicitly configures a framework, e.g. `framework = "gatsby"`
402
- settings = await handleForcedFramework({ devConfig, projectDir })
393
+ settings = await handleForcedFramework({ devConfig, project })
403
394
  }
404
395
 
405
396
  validateConfiguredPort({ devConfig, detectedPort: settings.frameworkPort })
@@ -435,15 +426,16 @@ const filterSettings = function (scriptInquirerOptions, input) {
435
426
  return scriptInquirerOptions.filter((t) => filteredSettingNames.has(t.name))
436
427
  }
437
428
 
438
- const formatSettingsArrForInquirer = function (frameworks) {
439
- const formattedArr = frameworks.map((framework) =>
440
- framework.dev.commands.map((command) => ({
441
- name: `[${chalk.yellow(framework.name)}] '${command}'`,
442
- value: { ...framework, commands: [command] },
443
- short: `${framework.name}-${command}`,
444
- })),
445
- )
446
- return formattedArr.flat()
429
+ /**
430
+ * @param {import('@netlify/build-info').Settings[]} settings
431
+ * @returns
432
+ */
433
+ const formatSettingsArrForInquirer = function (settings) {
434
+ return settings.map((setting) => ({
435
+ name: `[${chalk.yellow(setting.framework.name)}] '${setting.devCommand}'`,
436
+ value: { ...setting, commands: [setting.devCommand] },
437
+ short: `${setting.name}-${setting.devCommand}`,
438
+ }))
447
439
  }
448
440
 
449
441
  /**
package/src/utils/dev.mjs CHANGED
@@ -107,6 +107,7 @@ export const getSiteInformation = async ({ api, offline, site, siteInfo }) => {
107
107
  return {
108
108
  addonsUrls,
109
109
  siteUrl: siteInfo.ssl_url,
110
+ accountId: account.id,
110
111
  capabilities: {
111
112
  backgroundFunctions: supportsBackgroundFunctions(account),
112
113
  },
@@ -18,7 +18,7 @@ const FRAMEWORK_PORT_TIMEOUT = 6e5
18
18
  /**
19
19
  * Start a static server if the `useStaticServer` is provided or a framework specific server
20
20
  * @param {object} config
21
- * @param {Partial<import('./types').ServerSettings>} config.settings
21
+ * @param {import('./types.js').ServerSettings} config.settings
22
22
  * @returns {Promise<StartReturnObject>}
23
23
  */
24
24
  export const startFrameworkServer = async function ({ settings }) {
@@ -46,7 +46,7 @@ export const startFrameworkServer = async function ({ settings }) {
46
46
  host: 'localhost',
47
47
  output: 'silent',
48
48
  timeout: FRAMEWORK_PORT_TIMEOUT,
49
- ...(settings.pollingStrategies.includes('HTTP') && { protocol: 'http' }),
49
+ ...(settings.pollingStrategies?.includes('HTTP') && { protocol: 'http' }),
50
50
  })
51
51
 
52
52
  if (!port.open) {
@@ -207,7 +207,7 @@ export const configGithub = async ({ command, repoName, repoOwner, siteId }) =>
207
207
  const { netlify } = command
208
208
  const {
209
209
  api,
210
- cachedConfig: { configPath, env },
210
+ cachedConfig: { configPath },
211
211
  config,
212
212
  globalConfig,
213
213
  repositoryRoot,
@@ -220,7 +220,7 @@ export const configGithub = async ({ command, repoName, repoOwner, siteId }) =>
220
220
  repositoryRoot,
221
221
  siteRoot,
222
222
  config,
223
- env,
223
+ project: command.project,
224
224
  })
225
225
  await saveNetlifyToml({ repositoryRoot, config, configPath, baseDir, buildCmd, buildDir, functionsDir })
226
226
 
@@ -5,7 +5,12 @@ import { exit, log } from '../command-helpers.mjs'
5
5
 
6
6
  import { createDeployKey, getBuildSettings, saveNetlifyToml, setupSite } from './utils.mjs'
7
7
 
8
- const addDeployKey = async ({ deployKey }) => {
8
+ /**
9
+ * Prompts for granting the netlify ssh public key access to your repo
10
+ * @param {object} deployKey
11
+ * @param {string} deployKey.public_key
12
+ */
13
+ const addDeployKey = async (deployKey) => {
9
14
  log('\nGive this Netlify SSH public key access to your repository:\n')
10
15
  log(`\n${deployKey.public_key}\n\n`)
11
16
 
@@ -23,6 +28,11 @@ const addDeployKey = async ({ deployKey }) => {
23
28
  }
24
29
  }
25
30
 
31
+ /**
32
+ * @param {object} config
33
+ * @param {Awaited<ReturnType<import('../../utils/get-repo-data.mjs').default>>} config.repoData
34
+ * @returns {Promise<string>}
35
+ */
26
36
  const getRepoPath = async ({ repoData }) => {
27
37
  const { repoPath } = await inquirer.prompt([
28
38
  {
@@ -30,6 +40,9 @@ const getRepoPath = async ({ repoData }) => {
30
40
  name: 'repoPath',
31
41
  message: 'The SSH URL of the remote git repo:',
32
42
  default: repoData.url,
43
+ /**
44
+ * @param {string} url
45
+ */
33
46
  validate: (url) => SSH_URL_REGEXP.test(url) || 'The URL provided does not use the SSH protocol',
34
47
  },
35
48
  ])
@@ -37,7 +50,11 @@ const getRepoPath = async ({ repoData }) => {
37
50
  return repoPath
38
51
  }
39
52
 
40
- const addDeployHook = async ({ deployHook }) => {
53
+ /**
54
+ * @param {string} deployHook
55
+ * @returns
56
+ */
57
+ const addDeployHook = async (deployHook) => {
41
58
  log('\nConfigure the following webhook for your repository:\n')
42
59
  log(`\n${deployHook}\n\n`)
43
60
  const { deployHookAdded } = await inquirer.prompt([
@@ -55,14 +72,14 @@ const addDeployHook = async ({ deployHook }) => {
55
72
  /**
56
73
  * @param {object} config
57
74
  * @param {import('../../commands/base-command.mjs').default} config.command
58
- * @param {*} config.repoData
75
+ * @param {Awaited<ReturnType<import('../../utils/get-repo-data.mjs').default>>} config.repoData
59
76
  * @param {string} config.siteId
60
77
  */
61
78
  export default async function configManual({ command, repoData, siteId }) {
62
79
  const { netlify } = command
63
80
  const {
64
81
  api,
65
- cachedConfig: { configPath, env },
82
+ cachedConfig: { configPath },
66
83
  config,
67
84
  repositoryRoot,
68
85
  site: { root: siteRoot },
@@ -72,12 +89,12 @@ export default async function configManual({ command, repoData, siteId }) {
72
89
  repositoryRoot,
73
90
  siteRoot,
74
91
  config,
75
- env,
92
+ project: command.project,
76
93
  })
77
94
  await saveNetlifyToml({ repositoryRoot, config, configPath, baseDir, buildCmd, buildDir, functionsDir })
78
95
 
79
96
  const deployKey = await createDeployKey({ api })
80
- await addDeployKey({ deployKey })
97
+ await addDeployKey(deployKey)
81
98
 
82
99
  const repoPath = await getRepoPath({ repoData })
83
100
  const repo = {
@@ -99,7 +116,7 @@ export default async function configManual({ command, repoData, siteId }) {
99
116
  configPlugins: config.plugins,
100
117
  pluginsToInstall,
101
118
  })
102
- const deployHookAdded = await addDeployHook({ deployHook: updatedSite.deploy_hook })
119
+ const deployHookAdded = await addDeployHook(updatedSite.deploy_hook)
103
120
  if (!deployHookAdded) {
104
121
  exit()
105
122
  }
@@ -1,22 +1,18 @@
1
1
  // @ts-check
2
- import { listFrameworks } from '@netlify/framework-info'
3
2
 
4
- export const getFrameworkInfo = async ({ baseDirectory, nodeVersion }) => {
5
- const frameworks = await listFrameworks({ projectDir: baseDirectory, nodeVersion })
3
+ /**
4
+ * @param {{ project: import("@netlify/build-info").Project }} param0
5
+ * @returns
6
+ */
7
+ export const getFrameworkInfo = async ({ project }) => {
8
+ const settings = await project.getBuildSettings()
6
9
  // several frameworks can be detected - first one has highest priority
7
- if (frameworks.length !== 0) {
8
- const [
9
- {
10
- build: { commands, directory },
11
- name,
12
- plugins,
13
- },
14
- ] = frameworks
10
+ if (settings?.length) {
15
11
  return {
16
- frameworkName: name,
17
- frameworkBuildCommand: commands[0],
18
- frameworkBuildDir: directory,
19
- frameworkPlugins: plugins,
12
+ frameworkName: settings[0].framework?.name,
13
+ frameworkBuildCommand: settings[0].buildCommand,
14
+ frameworkBuildDir: settings[0].dist,
15
+ frameworkPlugins: settings[0].plugins_recommended,
20
16
  }
21
17
  }
22
18
  return {}
@@ -11,7 +11,6 @@ import { normalizeBackslash } from '../../lib/path.mjs'
11
11
  import { chalk, error as failAndExit, log, warn } from '../command-helpers.mjs'
12
12
 
13
13
  import { getFrameworkInfo } from './frameworks.mjs'
14
- import { detectNodeVersion } from './node-version.mjs'
15
14
  import { getRecommendPlugins, getUIPlugins } from './plugins.mjs'
16
15
 
17
16
  const normalizeDir = ({ baseDirectory, defaultValue, dir }) => {
@@ -83,17 +82,19 @@ const getPromptInputs = ({ defaultBaseDir, defaultBuildCmd, defaultBuildDir }) =
83
82
  const getBaseDirectory = ({ repositoryRoot, siteRoot }) =>
84
83
  path.normalize(repositoryRoot) === path.normalize(siteRoot) ? process.cwd() : siteRoot
85
84
 
86
- export const getBuildSettings = async ({ config, env, repositoryRoot, siteRoot }) => {
85
+ /**
86
+ * @param {{ config: any, repositoryRoot: any, siteRoot: any, project: import("@netlify/build-info").Project }} param0
87
+ * @returns
88
+ */
89
+ export const getBuildSettings = async ({ config, project, repositoryRoot, siteRoot }) => {
87
90
  const baseDirectory = getBaseDirectory({ repositoryRoot, siteRoot })
88
- const nodeVersion = await detectNodeVersion({ baseDirectory, env })
89
91
  const {
90
92
  frameworkBuildCommand,
91
93
  frameworkBuildDir,
92
94
  frameworkName,
93
95
  frameworkPlugins = [],
94
96
  } = await getFrameworkInfo({
95
- baseDirectory,
96
- nodeVersion,
97
+ project,
97
98
  })
98
99
  const { defaultBaseDir, defaultBuildCmd, defaultBuildDir, defaultFunctionsDir, recommendedPlugins } =
99
100
  await getDefaultSettings({
@@ -53,6 +53,7 @@ export const generateInspectSettings = (edgeInspect, edgeInspectBrk) => {
53
53
  * @returns
54
54
  */
55
55
  export const startProxyServer = async ({
56
+ accountId,
56
57
  addonsUrls,
57
58
  config,
58
59
  configPath,
@@ -83,6 +84,7 @@ export const startProxyServer = async ({
83
84
  settings,
84
85
  state,
85
86
  siteInfo,
87
+ accountId,
86
88
  })
87
89
  if (!url) {
88
90
  log(NETLIFYDEVERR, `Unable to start proxy server on port '${settings.port}'`)