@netlify/build 27.20.4 → 27.20.6

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.
Files changed (133) hide show
  1. package/lib/core/bin.js +42 -59
  2. package/lib/core/build.js +333 -536
  3. package/lib/core/config.js +94 -159
  4. package/lib/core/constants.js +95 -135
  5. package/lib/core/dev.js +26 -30
  6. package/lib/core/dry.js +18 -36
  7. package/lib/core/feature_flags.js +13 -16
  8. package/lib/core/flags.js +168 -169
  9. package/lib/core/lingering.js +44 -61
  10. package/lib/core/main.js +94 -136
  11. package/lib/core/missing_side_file.js +12 -24
  12. package/lib/core/normalize_flags.js +52 -63
  13. package/lib/core/severity.js +13 -15
  14. package/lib/core/user_node_version.js +26 -35
  15. package/lib/env/changes.js +29 -37
  16. package/lib/env/main.js +10 -15
  17. package/lib/env/metadata.js +63 -76
  18. package/lib/error/api.js +31 -40
  19. package/lib/error/build.js +27 -38
  20. package/lib/error/cancel.js +5 -6
  21. package/lib/error/colors.js +7 -9
  22. package/lib/error/handle.js +38 -49
  23. package/lib/error/info.js +26 -35
  24. package/lib/error/monitor/location.js +12 -17
  25. package/lib/error/monitor/normalize.js +75 -85
  26. package/lib/error/monitor/print.js +19 -41
  27. package/lib/error/monitor/report.js +102 -121
  28. package/lib/error/monitor/start.js +43 -56
  29. package/lib/error/parse/clean_stack.js +52 -69
  30. package/lib/error/parse/location.js +40 -52
  31. package/lib/error/parse/normalize.js +18 -23
  32. package/lib/error/parse/parse.js +59 -93
  33. package/lib/error/parse/plugin.js +42 -57
  34. package/lib/error/parse/properties.js +13 -20
  35. package/lib/error/parse/serialize_log.js +29 -37
  36. package/lib/error/parse/serialize_status.js +15 -23
  37. package/lib/error/parse/stack.js +29 -38
  38. package/lib/error/type.js +132 -150
  39. package/lib/install/functions.js +16 -24
  40. package/lib/install/local.js +31 -48
  41. package/lib/install/main.js +52 -66
  42. package/lib/install/missing.js +40 -53
  43. package/lib/log/colors.js +15 -22
  44. package/lib/log/description.js +16 -21
  45. package/lib/log/header.js +11 -13
  46. package/lib/log/header_func.js +11 -15
  47. package/lib/log/logger.js +88 -119
  48. package/lib/log/messages/compatibility.js +100 -158
  49. package/lib/log/messages/config.js +76 -92
  50. package/lib/log/messages/core.js +40 -60
  51. package/lib/log/messages/core_steps.js +63 -92
  52. package/lib/log/messages/dry.js +31 -53
  53. package/lib/log/messages/install.js +21 -28
  54. package/lib/log/messages/ipc.js +21 -30
  55. package/lib/log/messages/mutations.js +51 -71
  56. package/lib/log/messages/plugins.js +18 -31
  57. package/lib/log/messages/status.js +12 -14
  58. package/lib/log/messages/steps.js +14 -18
  59. package/lib/log/old_version.js +23 -32
  60. package/lib/log/serialize.js +7 -10
  61. package/lib/log/stream.js +48 -65
  62. package/lib/log/theme.js +22 -23
  63. package/lib/plugins/child/diff.js +31 -40
  64. package/lib/plugins/child/error.js +20 -26
  65. package/lib/plugins/child/lazy.js +11 -14
  66. package/lib/plugins/child/load.js +15 -22
  67. package/lib/plugins/child/logic.js +51 -58
  68. package/lib/plugins/child/main.js +32 -46
  69. package/lib/plugins/child/run.js +18 -27
  70. package/lib/plugins/child/status.js +52 -63
  71. package/lib/plugins/child/typescript.js +19 -36
  72. package/lib/plugins/child/utils.js +36 -49
  73. package/lib/plugins/child/validate.js +25 -28
  74. package/lib/plugins/compatibility.js +64 -92
  75. package/lib/plugins/error.js +29 -35
  76. package/lib/plugins/events.js +7 -12
  77. package/lib/plugins/expected_version.js +61 -99
  78. package/lib/plugins/ipc.js +79 -102
  79. package/lib/plugins/list.js +49 -62
  80. package/lib/plugins/load.js +44 -64
  81. package/lib/plugins/manifest/check.js +64 -85
  82. package/lib/plugins/manifest/load.js +34 -37
  83. package/lib/plugins/manifest/main.js +16 -21
  84. package/lib/plugins/manifest/path.js +18 -25
  85. package/lib/plugins/manifest/validate.js +77 -94
  86. package/lib/plugins/node_version.js +22 -42
  87. package/lib/plugins/options.js +45 -78
  88. package/lib/plugins/pinned_version.js +58 -106
  89. package/lib/plugins/resolve.js +91 -133
  90. package/lib/plugins/spawn.js +43 -61
  91. package/lib/plugins_core/add.js +26 -40
  92. package/lib/plugins_core/build_command.js +47 -72
  93. package/lib/plugins_core/deploy/buildbot_client.js +61 -87
  94. package/lib/plugins_core/deploy/index.js +47 -71
  95. package/lib/plugins_core/edge_functions/index.js +73 -116
  96. package/lib/plugins_core/edge_functions/lib/error.js +13 -17
  97. package/lib/plugins_core/edge_functions/lib/internal_manifest.js +45 -55
  98. package/lib/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.js +65 -80
  99. package/lib/plugins_core/functions/error.js +88 -128
  100. package/lib/plugins_core/functions/feature_flags.js +5 -5
  101. package/lib/plugins_core/functions/index.js +98 -145
  102. package/lib/plugins_core/functions/utils.js +36 -57
  103. package/lib/plugins_core/functions/zisi.js +35 -52
  104. package/lib/plugins_core/functions_install/index.js +8 -11
  105. package/lib/plugins_core/list.js +15 -22
  106. package/lib/status/add.js +26 -32
  107. package/lib/status/colors.js +14 -19
  108. package/lib/status/load_error.js +8 -9
  109. package/lib/status/report.js +72 -126
  110. package/lib/status/success.js +10 -14
  111. package/lib/steps/core_step.js +54 -89
  112. package/lib/steps/error.js +50 -87
  113. package/lib/steps/get.js +33 -41
  114. package/lib/steps/plugin.js +53 -83
  115. package/lib/steps/return.js +24 -51
  116. package/lib/steps/run_core_steps.js +119 -171
  117. package/lib/steps/run_step.js +154 -270
  118. package/lib/steps/run_steps.js +91 -174
  119. package/lib/steps/update_config.js +45 -72
  120. package/lib/telemetry/main.js +89 -128
  121. package/lib/time/aggregate.js +84 -110
  122. package/lib/time/main.js +23 -34
  123. package/lib/time/measure.js +11 -15
  124. package/lib/time/report.js +32 -44
  125. package/lib/utils/errors.js +10 -9
  126. package/lib/utils/json.js +11 -15
  127. package/lib/utils/omit.js +3 -4
  128. package/lib/utils/package.js +19 -22
  129. package/lib/utils/remove_falsy.js +5 -7
  130. package/lib/utils/resolve.js +30 -34
  131. package/lib/utils/runtime.js +4 -4
  132. package/lib/utils/semver.js +19 -25
  133. package/package.json +14 -7
@@ -1,10 +1,8 @@
1
- import pEvery from 'p-every'
2
- import pLocate from 'p-locate'
3
- import semver from 'semver'
4
-
5
- import { importJsonFile } from '../utils/json.js'
6
- import { resolvePath } from '../utils/resolve.js'
7
-
1
+ import pEvery from 'p-every';
2
+ import pLocate from 'p-locate';
3
+ import semver from 'semver';
4
+ import { importJsonFile } from '../utils/json.js';
5
+ import { resolvePath } from '../utils/resolve.js';
8
6
  // Retrieve the `expectedVersion` of a plugin:
9
7
  // - This is the version which should be run
10
8
  // - This takes version pinning into account
@@ -15,17 +13,16 @@ import { resolvePath } from '../utils/resolve.js'
15
13
  // - This is only used to print a warning message when the `compatibleVersion`
16
14
  // is older than the currently used version.
17
15
  export const getExpectedVersion = async function ({ versions, nodeVersion, packageJson, buildDir, pinnedVersion }) {
18
- const { version, conditions } = await getCompatibleEntry({
19
- versions,
20
- nodeVersion,
21
- packageJson,
22
- buildDir,
23
- pinnedVersion,
24
- })
25
- const compatWarning = getCompatWarning(conditions)
26
- return { version, compatWarning }
27
- }
28
-
16
+ const { version, conditions } = await getCompatibleEntry({
17
+ versions,
18
+ nodeVersion,
19
+ packageJson,
20
+ buildDir,
21
+ pinnedVersion,
22
+ });
23
+ const compatWarning = getCompatWarning(conditions);
24
+ return { version, compatWarning };
25
+ };
29
26
  // This function finds the right `compatibility` entry to use with the plugin.
30
27
  // - `compatibitlity` entries are meant for backward compatibility
31
28
  // Plugins should define each major version in `compatibility`.
@@ -41,92 +38,67 @@ export const getExpectedVersion = async function ({ versions, nodeVersion, packa
41
38
  // - If there is a `pinnedVersion`, use it unless `latestVersion` matches it
42
39
  // - Otherwise, use `latestVersion`
43
40
  const getCompatibleEntry = async function ({ versions, nodeVersion, packageJson, buildDir, pinnedVersion }) {
44
- if (pinnedVersion !== undefined) {
45
- const matchingVersion = versions.find(({ version }) =>
46
- semver.satisfies(version, pinnedVersion, { includePrerelease: true }),
47
- )
48
-
49
- return matchingVersion || { version: pinnedVersion }
50
- }
51
-
52
- const versionsWithConditions = versions.filter(hasConditions)
53
- const compatibleEntry = await pLocate(versionsWithConditions, ({ conditions }) =>
54
- matchesCompatField({ conditions, nodeVersion, packageJson, buildDir }),
55
- )
56
- return compatibleEntry || { version: versions[0].version }
57
- }
58
-
41
+ if (pinnedVersion !== undefined) {
42
+ const matchingVersion = versions.find(({ version }) => semver.satisfies(version, pinnedVersion, { includePrerelease: true }));
43
+ return matchingVersion || { version: pinnedVersion };
44
+ }
45
+ const versionsWithConditions = versions.filter(hasConditions);
46
+ const compatibleEntry = await pLocate(versionsWithConditions, ({ conditions }) => matchesCompatField({ conditions, nodeVersion, packageJson, buildDir }));
47
+ return compatibleEntry || { version: versions[0].version };
48
+ };
59
49
  // Ignore entries without conditions. Those are used to specify breaking
60
50
  // changes, i.e. meant to be used for version pinning instead.
61
51
  const hasConditions = function ({ conditions }) {
62
- return conditions.length !== 0
63
- }
64
-
52
+ return conditions.length !== 0;
53
+ };
65
54
  const matchesCompatField = async function ({ conditions, nodeVersion, packageJson, buildDir }) {
66
- return await pEvery(conditions, ({ type, condition }) =>
67
- CONDITIONS[type].test(condition, { nodeVersion, packageJson, buildDir }),
68
- )
69
- }
70
-
55
+ return await pEvery(conditions, ({ type, condition }) => CONDITIONS[type].test(condition, { nodeVersion, packageJson, buildDir }));
56
+ };
71
57
  // Retrieve warning message shown when using an older version with `compatibility`
72
58
  const getCompatWarning = function (conditions = []) {
73
- return conditions.map(getConditionWarning).join(', ')
74
- }
75
-
59
+ return conditions.map(getConditionWarning).join(', ');
60
+ };
76
61
  const getConditionWarning = function ({ type, condition }) {
77
- return CONDITIONS[type].warning(condition)
78
- }
79
-
62
+ return CONDITIONS[type].warning(condition);
63
+ };
80
64
  // Plugins can use `compatibility.{version}.nodeVersion: 'allowedNodeVersion'`
81
65
  // to deliver different plugin versions based on the Node.js version
82
66
  const nodeVersionTest = function (allowedNodeVersion, { nodeVersion }) {
83
- return semver.satisfies(nodeVersion, allowedNodeVersion)
84
- }
85
-
67
+ return semver.satisfies(nodeVersion, allowedNodeVersion);
68
+ };
86
69
  const nodeVersionWarning = function (allowedNodeVersion) {
87
- return `Node.js ${allowedNodeVersion}`
88
- }
89
-
90
- const siteDependenciesTest = async function (
91
- allowedSiteDependencies,
92
- { packageJson: { devDependencies, dependencies }, buildDir },
93
- ) {
94
- const siteDependencies = { ...devDependencies, ...dependencies }
95
- return await pEvery(Object.entries(allowedSiteDependencies), ([dependencyName, allowedVersion]) =>
96
- siteDependencyTest({ dependencyName, allowedVersion, siteDependencies, buildDir }),
97
- )
98
- }
99
-
70
+ return `Node.js ${allowedNodeVersion}`;
71
+ };
72
+ const siteDependenciesTest = async function (allowedSiteDependencies, { packageJson: { devDependencies, dependencies }, buildDir }) {
73
+ const siteDependencies = { ...devDependencies, ...dependencies };
74
+ return await pEvery(Object.entries(allowedSiteDependencies), ([dependencyName, allowedVersion]) => siteDependencyTest({ dependencyName, allowedVersion, siteDependencies, buildDir }));
75
+ };
100
76
  const siteDependencyTest = async function ({ dependencyName, allowedVersion, siteDependencies, buildDir }) {
101
- const siteDependency = siteDependencies[dependencyName]
102
- if (typeof siteDependency !== 'string') {
103
- return false
104
- }
105
-
106
- // if this is a valid version we can apply the rule directly
107
- if (semver.clean(siteDependency) !== null) {
108
- return semver.satisfies(siteDependency, allowedVersion)
109
- }
110
-
111
- try {
112
- // if this is a range we need to get the exact version
113
- const packageJsonPath = await resolvePath(`${dependencyName}/package.json`, buildDir)
114
- const { version } = await importJsonFile(packageJsonPath)
115
- return semver.satisfies(version, allowedVersion)
116
- } catch {
117
- return false
118
- }
119
- }
120
-
77
+ const siteDependency = siteDependencies[dependencyName];
78
+ if (typeof siteDependency !== 'string') {
79
+ return false;
80
+ }
81
+ // if this is a valid version we can apply the rule directly
82
+ if (semver.clean(siteDependency) !== null) {
83
+ return semver.satisfies(siteDependency, allowedVersion);
84
+ }
85
+ try {
86
+ // if this is a range we need to get the exact version
87
+ const packageJsonPath = await resolvePath(`${dependencyName}/package.json`, buildDir);
88
+ const { version } = await importJsonFile(packageJsonPath);
89
+ return semver.satisfies(version, allowedVersion);
90
+ }
91
+ catch {
92
+ return false;
93
+ }
94
+ };
121
95
  const siteDependenciesWarning = function (allowedSiteDependencies) {
122
- return Object.entries(allowedSiteDependencies).map(siteDependencyWarning).join(',')
123
- }
124
-
96
+ return Object.entries(allowedSiteDependencies).map(siteDependencyWarning).join(',');
97
+ };
125
98
  const siteDependencyWarning = function ([dependencyName, allowedVersion]) {
126
- return `${dependencyName}@${allowedVersion}`
127
- }
128
-
99
+ return `${dependencyName}@${allowedVersion}`;
100
+ };
129
101
  export const CONDITIONS = {
130
- nodeVersion: { test: nodeVersionTest, warning: nodeVersionWarning },
131
- siteDependencies: { test: siteDependenciesTest, warning: siteDependenciesWarning },
132
- }
102
+ nodeVersion: { test: nodeVersionTest, warning: nodeVersionWarning },
103
+ siteDependencies: { test: siteDependenciesTest, warning: siteDependenciesWarning },
104
+ };
@@ -1,52 +1,46 @@
1
- import { addErrorInfo } from '../error/info.js'
2
- import { logFailPluginWarning } from '../log/messages/plugins.js'
3
-
1
+ import { addErrorInfo } from '../error/info.js';
2
+ import { logFailPluginWarning } from '../log/messages/plugins.js';
4
3
  // Stop build.
5
4
  // As opposed to throwing an error directly or to uncaught exceptions, this is
6
5
  // displayed as a user error, not an implementation error.
7
6
  export const failBuild = function (message, opts) {
8
- throw normalizeError('failBuild', failBuild, message, opts)
9
- }
10
-
7
+ throw normalizeError('failBuild', failBuild, message, opts);
8
+ };
11
9
  // Stop plugin. Same as `failBuild` but only stops plugin not whole build
12
10
  export const failPlugin = function (message, opts) {
13
- throw normalizeError('failPlugin', failPlugin, message, opts)
14
- }
15
-
11
+ throw normalizeError('failPlugin', failPlugin, message, opts);
12
+ };
16
13
  // Cancel build. Same as `failBuild` except it marks the build as "canceled".
17
14
  export const cancelBuild = function (message, opts) {
18
- throw normalizeError('cancelBuild', cancelBuild, message, opts)
19
- }
20
-
15
+ throw normalizeError('cancelBuild', cancelBuild, message, opts);
16
+ };
21
17
  // `onSuccess`, `onEnd` and `onError` cannot cancel the build since they are run
22
18
  // or might be run after deployment. When calling `failBuild()` or
23
19
  // `cancelBuild()`, `failPlugin()` is run instead and a warning is printed.
24
20
  export const failPluginWithWarning = function (methodName, event, message, opts) {
25
- logFailPluginWarning(methodName, event)
26
- failPlugin(message, opts)
27
- }
28
-
21
+ logFailPluginWarning(methodName, event);
22
+ failPlugin(message, opts);
23
+ };
29
24
  // An `error` option can be passed to keep the original error message and
30
25
  // stack trace. An additional `message` string is always required.
31
26
  const normalizeError = function (type, func, message, { error, errorMetadata } = {}) {
32
- const errorA = getError(error, message, func)
33
- addErrorInfo(errorA, { type, errorMetadata })
34
- return errorA
35
- }
36
-
27
+ const errorA = getError(error, message, func);
28
+ addErrorInfo(errorA, { type, errorMetadata });
29
+ return errorA;
30
+ };
37
31
  const getError = function (error, message, func) {
38
- if (error instanceof Error) {
39
- // This might fail if `name` is a getter or is non-writable.
40
- try {
41
- error.message = `${message}\n${error.message}`
42
- } catch {
43
- // continue regardless error
32
+ if (error instanceof Error) {
33
+ // This might fail if `name` is a getter or is non-writable.
34
+ try {
35
+ error.message = `${message}\n${error.message}`;
36
+ }
37
+ catch {
38
+ // continue regardless error
39
+ }
40
+ return error;
44
41
  }
45
- return error
46
- }
47
-
48
- const errorA = new Error(message)
49
- // Do not include function itself in the stack trace
50
- Error.captureStackTrace(errorA, func)
51
- return errorA
52
- }
42
+ const errorA = new Error(message);
43
+ // Do not include function itself in the stack trace
44
+ Error.captureStackTrace(errorA, func);
45
+ return errorA;
46
+ };
@@ -1,17 +1,12 @@
1
- export { DEV_EVENTS, EVENTS } from '@netlify/config'
2
-
1
+ export { DEV_EVENTS, EVENTS } from '@netlify/config';
3
2
  const isAmongEvents = function (events, event) {
4
- return events.includes(event)
5
- }
6
-
3
+ return events.includes(event);
4
+ };
7
5
  // Check if failure of the event should not make the build fail
8
- export const isSoftFailEvent = isAmongEvents.bind(null, ['onSuccess', 'onError', 'onEnd'])
9
-
6
+ export const isSoftFailEvent = isAmongEvents.bind(null, ['onSuccess', 'onError', 'onEnd']);
10
7
  // Check if the event is triggered even when the build fails
11
- export const runsAlsoOnBuildFailure = isAmongEvents.bind(null, ['onError', 'onEnd'])
12
-
8
+ export const runsAlsoOnBuildFailure = isAmongEvents.bind(null, ['onError', 'onEnd']);
13
9
  // Check if the event is only triggered when the build fails
14
- export const runsOnlyOnBuildFailure = isAmongEvents.bind(null, ['onError'])
15
-
10
+ export const runsOnlyOnBuildFailure = isAmongEvents.bind(null, ['onError']);
16
11
  // Check if the event is happening after deploy
17
- export const runsAfterDeploy = isAmongEvents.bind(null, ['onSuccess', 'onEnd'])
12
+ export const runsAfterDeploy = isAmongEvents.bind(null, ['onSuccess', 'onEnd']);
@@ -1,119 +1,81 @@
1
- import semver from 'semver'
2
-
3
- import { addErrorInfo } from '../error/info.js'
4
- import { importJsonFile } from '../utils/json.js'
5
- import { resolvePath } from '../utils/resolve.js'
6
-
7
- import { getExpectedVersion } from './compatibility.js'
8
- import { getPluginsList } from './list.js'
9
-
1
+ import semver from 'semver';
2
+ import { addErrorInfo } from '../error/info.js';
3
+ import { importJsonFile } from '../utils/json.js';
4
+ import { resolvePath } from '../utils/resolve.js';
5
+ import { getExpectedVersion } from './compatibility.js';
6
+ import { getPluginsList } from './list.js';
10
7
  // When using plugins in our official list, those are installed in .netlify/plugins/
11
8
  // We ensure that the last version that's been approved is always the one being used.
12
9
  // We also ensure that the plugin is our official list.
13
- export const addExpectedVersions = async function ({
14
- pluginsOptions,
15
- autoPluginsDir,
16
- packageJson,
17
- debug,
18
- logs,
19
- buildDir,
20
- testOpts,
21
- featureFlags,
22
- }) {
23
- if (!pluginsOptions.some(needsExpectedVersion)) {
24
- return pluginsOptions
25
- }
26
-
27
- const pluginsList = await getPluginsList({ debug, logs, testOpts })
28
- return await Promise.all(
29
- pluginsOptions.map((pluginOptions) =>
30
- addExpectedVersion({ pluginsList, autoPluginsDir, packageJson, pluginOptions, buildDir, featureFlags }),
31
- ),
32
- )
33
- }
34
-
10
+ export const addExpectedVersions = async function ({ pluginsOptions, autoPluginsDir, packageJson, debug, logs, buildDir, testOpts, featureFlags, }) {
11
+ if (!pluginsOptions.some(needsExpectedVersion)) {
12
+ return pluginsOptions;
13
+ }
14
+ const pluginsList = await getPluginsList({ debug, logs, testOpts });
15
+ return await Promise.all(pluginsOptions.map((pluginOptions) => addExpectedVersion({ pluginsList, autoPluginsDir, packageJson, pluginOptions, buildDir, featureFlags })));
16
+ };
35
17
  // Any `pluginOptions` with `expectedVersion` set will be automatically installed
36
- const addExpectedVersion = async function ({
37
- pluginsList,
38
- autoPluginsDir,
39
- packageJson,
40
- pluginOptions,
41
- pluginOptions: { packageName, pluginPath, loadedFrom, nodeVersion, pinnedVersion },
42
- buildDir,
43
- featureFlags,
44
- }) {
45
- if (!needsExpectedVersion(pluginOptions)) {
46
- return pluginOptions
47
- }
48
-
49
- if (pluginsList[packageName] === undefined) {
50
- validateUnlistedPlugin(packageName, loadedFrom)
51
- return pluginOptions
52
- }
53
-
54
- const unfilteredVersions = pluginsList[packageName]
55
- const versions = filterVersions(unfilteredVersions, featureFlags)
56
- const [{ version: latestVersion, migrationGuide }] = versions
57
- const [{ version: expectedVersion }, { version: compatibleVersion, compatWarning }] = await Promise.all([
58
- getExpectedVersion({ versions, nodeVersion, packageJson, buildDir, pinnedVersion }),
59
- getExpectedVersion({ versions, nodeVersion, packageJson, buildDir }),
60
- ])
61
-
62
- const isMissing = await isMissingVersion({ autoPluginsDir, packageName, pluginPath, loadedFrom, expectedVersion })
63
- return {
64
- ...pluginOptions,
65
- latestVersion,
66
- expectedVersion,
67
- compatibleVersion,
68
- migrationGuide,
69
- compatWarning,
70
- isMissing,
71
- }
72
- }
73
-
18
+ const addExpectedVersion = async function ({ pluginsList, autoPluginsDir, packageJson, pluginOptions, pluginOptions: { packageName, pluginPath, loadedFrom, nodeVersion, pinnedVersion }, buildDir, featureFlags, }) {
19
+ if (!needsExpectedVersion(pluginOptions)) {
20
+ return pluginOptions;
21
+ }
22
+ if (pluginsList[packageName] === undefined) {
23
+ validateUnlistedPlugin(packageName, loadedFrom);
24
+ return pluginOptions;
25
+ }
26
+ const unfilteredVersions = pluginsList[packageName];
27
+ const versions = filterVersions(unfilteredVersions, featureFlags);
28
+ const [{ version: latestVersion, migrationGuide }] = versions;
29
+ const [{ version: expectedVersion }, { version: compatibleVersion, compatWarning }] = await Promise.all([
30
+ getExpectedVersion({ versions, nodeVersion, packageJson, buildDir, pinnedVersion }),
31
+ getExpectedVersion({ versions, nodeVersion, packageJson, buildDir }),
32
+ ]);
33
+ const isMissing = await isMissingVersion({ autoPluginsDir, packageName, pluginPath, loadedFrom, expectedVersion });
34
+ return {
35
+ ...pluginOptions,
36
+ latestVersion,
37
+ expectedVersion,
38
+ compatibleVersion,
39
+ migrationGuide,
40
+ compatWarning,
41
+ isMissing,
42
+ };
43
+ };
74
44
  // Feature flagged versions are removed unless the feature flag is present.
75
45
  // - This is done before conditions are applied since, unlike conditions,
76
46
  // users cannot always choose to enable a feature flag.
77
47
  const filterVersions = function (unfilteredVersions, featureFlags) {
78
- return unfilteredVersions.filter(({ featureFlag }) => featureFlag === undefined || featureFlags[featureFlag])
79
- }
80
-
48
+ return unfilteredVersions.filter(({ featureFlag }) => featureFlag === undefined || featureFlags[featureFlag]);
49
+ };
81
50
  // Checks whether plugin should be installed due to the wrong version being used
82
51
  // (either outdated, or mismatching compatibility requirements)
83
52
  const isMissingVersion = async function ({ autoPluginsDir, packageName, pluginPath, loadedFrom, expectedVersion }) {
84
- return (
53
+ return (
85
54
  // We always respect the versions specified in `package.json`, as opposed
86
55
  // to auto-installed plugins
87
56
  loadedFrom !== 'package.json' &&
88
- // Plugin was not previously installed
89
- (pluginPath === undefined ||
90
- // Plugin was previously installed but a different version should be used
91
- !semver.satisfies(await getAutoPluginVersion(packageName, autoPluginsDir), expectedVersion))
92
- )
93
- }
94
-
57
+ // Plugin was not previously installed
58
+ (pluginPath === undefined ||
59
+ // Plugin was previously installed but a different version should be used
60
+ !semver.satisfies(await getAutoPluginVersion(packageName, autoPluginsDir), expectedVersion)));
61
+ };
95
62
  const getAutoPluginVersion = async function (packageName, autoPluginsDir) {
96
- const packageJsonPath = await resolvePath(`${packageName}/package.json`, autoPluginsDir)
97
- const { version } = await importJsonFile(packageJsonPath)
98
- return version
99
- }
100
-
63
+ const packageJsonPath = await resolvePath(`${packageName}/package.json`, autoPluginsDir);
64
+ const { version } = await importJsonFile(packageJsonPath);
65
+ return version;
66
+ };
101
67
  const needsExpectedVersion = function ({ loadedFrom }) {
102
- return loadedFrom === 'auto_install' || loadedFrom === 'package.json'
103
- }
104
-
68
+ return loadedFrom === 'auto_install' || loadedFrom === 'package.json';
69
+ };
105
70
  // Plugins that are not in our official list can only be specified in
106
71
  // `netlify.toml` providing they are also installed in the site's package.json.
107
72
  // Otherwise, the build should fail.
108
73
  const validateUnlistedPlugin = function (packageName, loadedFrom) {
109
- if (loadedFrom === 'package.json') {
110
- return
111
- }
112
-
113
- const error = new Error(
114
- `Plugins must be installed either in the Netlify App or in "package.json".
115
- Please run "npm install -D ${packageName}" or "yarn add -D ${packageName}".`,
116
- )
117
- addErrorInfo(error, { type: 'resolveConfig' })
118
- throw error
119
- }
74
+ if (loadedFrom === 'package.json') {
75
+ return;
76
+ }
77
+ const error = new Error(`Plugins must be installed either in the Netlify App or in "package.json".
78
+ Please run "npm install -D ${packageName}" or "yarn add -D ${packageName}".`);
79
+ addErrorInfo(error, { type: 'resolveConfig' });
80
+ throw error;
81
+ };