@netlify/build 36.4.6 → 36.4.8

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.
@@ -45,7 +45,7 @@ export const loadConfig: ({ timers, ...opts }: {
45
45
  [x: string]: any;
46
46
  timers: any;
47
47
  }, ...args: any[]) => Promise<any>;
48
- export function resolveUpdatedConfig(configOpts: any, configMutations: any, defaultConfig: any): Promise<import("packages/config/lib/main.js").Config>;
48
+ export function resolveUpdatedConfig(configOpts: any, configMutations: any, defaultConfig: any, configMutationsOrigin: any, errorType: any): Promise<import("packages/config/lib/main.js").Config>;
49
49
  export function saveUpdatedConfig({ configMutations, buildDir, repositoryRoot, configPath, outputConfigPath, headersPath, redirectsPath, logs, featureFlags, context, branch, debug, saveConfig, }: {
50
50
  configMutations: any;
51
51
  buildDir: any;
@@ -84,20 +84,20 @@ const logConfigInfo = function ({ logs, configPath, buildDir, netlifyConfig, con
84
84
  // normalized.
85
85
  // We use `debug: false` to avoid any debug logs. Otherwise, every configuration
86
86
  // change would create debug logs which would be too verbose.
87
- // Errors are propagated and assigned to the specific plugin or core step
88
- // which changed the configuration.
89
- export const resolveUpdatedConfig = async function (configOpts, configMutations, defaultConfig) {
87
+ // Configuration errors are assigned the type given by the caller, which knows
88
+ // whether a plugin or a core step changed the configuration.
89
+ export const resolveUpdatedConfig = async function (configOpts, configMutations, defaultConfig, configMutationsOrigin, errorType) {
90
90
  try {
91
- const resolved = await resolveConfig({
91
+ return await resolveConfig({
92
92
  ...configOpts,
93
93
  configMutations,
94
+ configMutationsOrigin,
94
95
  defaultConfig,
95
96
  debug: false,
96
97
  });
97
- return resolved;
98
98
  }
99
99
  catch (error) {
100
- changeErrorType(error, 'resolveConfig', 'pluginValidation');
100
+ changeErrorType(error, 'resolveConfig', errorType);
101
101
  throw error;
102
102
  }
103
103
  };
@@ -1,4 +1,7 @@
1
1
  import type { BufferedLogs } from '../log/logger.js';
2
+ import type { ConfigMutation } from '../plugins/child/diff.js';
3
+ import type { NetlifyConfig } from '../types/config/netlify_config.js';
4
+ import { type GeneratedFunction } from '../steps/return_values.js';
2
5
  import { BuildFlags } from './types.js';
3
6
  /**
4
7
  * Main entry point of Netlify Build.
@@ -10,6 +13,7 @@ export declare function buildSite(flags?: Partial<BuildFlags>): Promise<{
10
13
  success: boolean;
11
14
  severityCode: number;
12
15
  logs: BufferedLogs | undefined;
13
- netlifyConfig?: any;
14
- configMutations?: any;
16
+ netlifyConfig?: NetlifyConfig;
17
+ configMutations?: ConfigMutation[];
18
+ generatedFunctions?: GeneratedFunction[];
15
19
  }>;
@@ -1,6 +1,6 @@
1
1
  import { serializeObject } from '../../log/serialize.js';
2
2
  import { getErrorInfo } from '../info.js';
3
- import { getTypeInfo } from '../types.js';
3
+ import { DEFAULT_TITLE, getTypeInfo } from '../types.js';
4
4
  import { getLocationInfo } from './location.js';
5
5
  import { normalizeError } from './normalize.js';
6
6
  import { getPluginInfo } from './plugin.js';
@@ -66,5 +66,11 @@ const getTitle = function (title, errorInfo) {
66
66
  if (typeof title !== 'function') {
67
67
  return title;
68
68
  }
69
- return title(errorInfo);
69
+ try {
70
+ return title(errorInfo);
71
+ }
72
+ catch {
73
+ // A title built from missing error information must not lose the error.
74
+ return DEFAULT_TITLE;
75
+ }
70
76
  };
@@ -165,4 +165,5 @@ type ErrorTypeMap =
165
165
  */
166
166
  'cancelBuild' | 'resolveConfig' | 'dependencies' | 'pluginInput' | 'pluginUnsupportedVersion' | 'buildCommand' | 'functionsBundling' | 'secretScanningFoundSecrets' | 'failPlugin' | 'failBuild' | 'pluginValidation' | 'pluginInternal' | 'ipc' | 'corePlugin' | 'trustedPlugin' | 'coreStep' | 'api' | 'deploy' | 'deployInternal' | 'exception' | 'telemetry';
167
167
  export type ErrorTypes = ErrorTypeMap;
168
+ export declare const DEFAULT_TITLE: string;
168
169
  export {};
@@ -320,3 +320,5 @@ const TYPES = {
320
320
  };
321
321
  // When no error type matches, it's an uncaught exception, i.e. a bug
322
322
  const DEFAULT_TYPE = 'exception';
323
+ // Fallback when a title cannot be built from the error information
324
+ export const DEFAULT_TITLE = TYPES[DEFAULT_TYPE].title;
@@ -1,5 +1,28 @@
1
1
  import { BufferedLogs } from '../log/logger.js';
2
2
  import { CONDITIONS } from './plugin_conditions.js';
3
+ /**
4
+ * Internal type from the `plugins.json`
5
+ */
6
+ export type PluginCompatiblityEntry = {
7
+ version: string;
8
+ featureFlag?: string;
9
+ overridePinnedVersion?: string;
10
+ migrationGuide?: string;
11
+ nodeVersion?: string;
12
+ siteDependencies?: Record<string, string>;
13
+ };
14
+ /**
15
+ * Internal type from the `plugins.json`
16
+ */
17
+ export type PluginListEntry = {
18
+ author: string;
19
+ description: string;
20
+ name: string;
21
+ package: string;
22
+ repo: string;
23
+ version: string;
24
+ compatibility: PluginCompatiblityEntry[];
25
+ };
3
26
  /**
4
27
  * The resolved and normalized Plugin list
5
28
  */
@@ -56,7 +56,7 @@ const coreStep = async function ({ buildDir, netlifyConfig, packagePath, systemL
56
56
  }
57
57
  catch (err) {
58
58
  systemLog(`Failed to read Frameworks API: ${err.message}`);
59
- throw new Error('An error occured while processing the platform configurarion defined by your framework');
59
+ throw new Error('An error occurred while processing the platform configuration defined by your framework');
60
60
  }
61
61
  if (!config) {
62
62
  return {};
@@ -83,6 +83,7 @@ const coreStep = async function ({ buildDir, netlifyConfig, packagePath, systemL
83
83
  const configMutations = getConfigMutations(netlifyConfig, newConfig, applyDeployConfig.event);
84
84
  return {
85
85
  configMutations,
86
+ configMutationsOrigin: 'the Frameworks API',
86
87
  };
87
88
  };
88
89
  export const applyDeployConfig = {
@@ -68,7 +68,7 @@ export declare function findLikelySecrets({ text, omitValuesFromEnhancedScan, }:
68
68
  /**
69
69
  * Text to check
70
70
  */
71
- text: string;
71
+ text: string | null | undefined;
72
72
  /**
73
73
  * Optional array of values to exclude from matching
74
74
  */
@@ -8,7 +8,7 @@ export const fireCoreStep = async function ({ deployEnvVars, coreStep, coreStepI
8
8
  try {
9
9
  const configSideFiles = await listConfigSideFiles([headersPath, redirectsPath]);
10
10
  const childEnvA = setEnvChanges(envChanges, { ...childEnv });
11
- const { newEnvChanges = {}, configMutations: newConfigMutations = [], tags, metrics, } = await coreStep({
11
+ const { newEnvChanges = {}, configMutations: newConfigMutations = [], configMutationsOrigin, tags, metrics, } = await coreStep({
12
12
  deployEnvVars,
13
13
  api,
14
14
  configPath,
@@ -54,6 +54,7 @@ export const fireCoreStep = async function ({ deployEnvVars, coreStep, coreStepI
54
54
  logs: logsA,
55
55
  systemLog,
56
56
  debug,
57
+ configMutationsOrigin: configMutationsOrigin ?? coreStepName,
57
58
  });
58
59
  return {
59
60
  newEnvChanges,
@@ -49,6 +49,7 @@ export const firePluginStep = async function ({ event, childProcess, packageName
49
49
  systemLog,
50
50
  debug,
51
51
  source: packageName,
52
+ configErrorType: 'pluginValidation',
52
53
  });
53
54
  const newStatus = getSuccessStatus(status, { steps, event, packageName });
54
55
  return {
@@ -1,4 +1,4 @@
1
- export function updateNetlifyConfig({ configOpts, netlifyConfig, defaultConfig, headersPath, redirectsPath, configMutations, newConfigMutations, configSideFiles, errorParams, logs, systemLog, debug, source, }: {
1
+ export function updateNetlifyConfig({ configOpts, netlifyConfig, defaultConfig, headersPath, redirectsPath, configMutations, newConfigMutations, configSideFiles, errorParams, logs, systemLog, debug, source, configMutationsOrigin, configErrorType, }: {
2
2
  configOpts: any;
3
3
  netlifyConfig: any;
4
4
  defaultConfig: any;
@@ -12,6 +12,8 @@ export function updateNetlifyConfig({ configOpts, netlifyConfig, defaultConfig,
12
12
  systemLog: any;
13
13
  debug: any;
14
14
  source?: string | undefined;
15
+ configMutationsOrigin?: any;
16
+ configErrorType?: string | undefined;
15
17
  }): Promise<{
16
18
  netlifyConfig: any;
17
19
  configMutations: any;
@@ -6,11 +6,11 @@ import { logConfigMutations, systemLogConfigMutations } from '../log/messages/mu
6
6
  import { pathExists } from '../utils/path_exists.js';
7
7
  // If `netlifyConfig` was updated or `_redirects` was created, the configuration
8
8
  // is updated by calling `@netlify/config` again.
9
- export const updateNetlifyConfig = async function ({ configOpts, netlifyConfig, defaultConfig, headersPath, redirectsPath, configMutations, newConfigMutations, configSideFiles, errorParams, logs, systemLog, debug, source = '', }) {
9
+ export const updateNetlifyConfig = async function ({ configOpts, netlifyConfig, defaultConfig, headersPath, redirectsPath, configMutations, newConfigMutations, configSideFiles, errorParams, logs, systemLog, debug, source = '', configMutationsOrigin = source || undefined, configErrorType = 'resolveConfig', }) {
10
10
  if (!(await shouldUpdateConfig({ newConfigMutations, configSideFiles, headersPath, redirectsPath }))) {
11
11
  return { netlifyConfig, configMutations };
12
12
  }
13
- validateConfigMutations(newConfigMutations);
13
+ validateConfigMutations(newConfigMutations, configErrorType);
14
14
  // Don't log configuration mutations performed by code that has been authored
15
15
  // by Netlify (i.e. core steps or build plugins in the `@netlify/` scope),
16
16
  // since that won't give users any useful or actionable information. For
@@ -23,7 +23,7 @@ export const updateNetlifyConfig = async function ({ configOpts, netlifyConfig,
23
23
  systemLogConfigMutations(systemLog, newConfigMutations);
24
24
  }
25
25
  const mergedConfigMutations = [...configMutations, ...newConfigMutations];
26
- const { config: netlifyConfigA, headersPath: headersPathA, redirectsPath: redirectsPathA, } = await resolveUpdatedConfig(configOpts, mergedConfigMutations, defaultConfig);
26
+ const { config: netlifyConfigA, headersPath: headersPathA, redirectsPath: redirectsPathA, } = await resolveUpdatedConfig(configOpts, mergedConfigMutations, defaultConfig, configMutationsOrigin, configErrorType);
27
27
  logConfigOnUpdate({ logs, netlifyConfig: netlifyConfigA, debug });
28
28
  errorParams.netlifyConfig = netlifyConfigA;
29
29
  return {
@@ -54,12 +54,12 @@ export const listConfigSideFiles = async function (sideFiles) {
54
54
  return existingSideFiles.filter(Boolean).sort();
55
55
  };
56
56
  // Validate each new configuration change
57
- const validateConfigMutations = function (newConfigMutations) {
57
+ const validateConfigMutations = function (newConfigMutations, errorType) {
58
58
  try {
59
59
  newConfigMutations.forEach(validateConfigMutation);
60
60
  }
61
61
  catch (error) {
62
- addErrorInfo(error, { type: 'pluginValidation' });
62
+ addErrorInfo(error, { type: errorType });
63
63
  throw error;
64
64
  }
65
65
  };
@@ -1,8 +1,7 @@
1
- import type { PackageJson } from 'read-package-up';
2
1
  export type RootPackageJson = {
3
2
  name: string;
4
3
  version: string;
5
4
  };
6
- export declare const importJsonFile: (filePath: string) => Promise<PackageJson>;
5
+ export declare const importJsonFile: <T>(filePath: string) => Promise<T>;
7
6
  export declare const ROOT_PACKAGE_JSON: RootPackageJson;
8
7
  export declare const getVersion: () => string;
package/lib/utils/json.js CHANGED
@@ -7,5 +7,5 @@ export const importJsonFile = async function (filePath) {
7
7
  const fileContents = await readFile(filePath, 'utf-8');
8
8
  return JSON.parse(fileContents);
9
9
  };
10
- export const ROOT_PACKAGE_JSON = (await importJsonFile(ROOT_PACKAGE_JSON_PATH));
10
+ export const ROOT_PACKAGE_JSON = await importJsonFile(ROOT_PACKAGE_JSON_PATH);
11
11
  export const getVersion = () => ROOT_PACKAGE_JSON.version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/build",
3
- "version": "36.4.6",
3
+ "version": "36.4.8",
4
4
  "description": "Netlify build module",
5
5
  "type": "module",
6
6
  "exports": "./lib/index.js",
@@ -26,12 +26,9 @@
26
26
  "postbuild": "npx cpy \"src/**/*.yml\" \"lib/\"",
27
27
  "build": "tsc --project tsconfig.build.json",
28
28
  "test:types": "tsd",
29
- "test": "ava && tsd && vitest run",
30
- "test:dev": "ava -w",
31
- "test:ci": "run-p test:ci:*",
32
- "test:ci:types": "tsd",
33
- "test:ci:ava": "c8 -r lcovonly -r text -r json ava",
34
- "test:ci:vitest": "vitest run"
29
+ "test": "tsd && vitest run",
30
+ "test:dev": "vitest",
31
+ "test:ci": "tsd && vitest run --coverage"
35
32
  },
36
33
  "keywords": [
37
34
  "nodejs",
@@ -69,14 +66,14 @@
69
66
  "@bugsnag/js": "^8.0.0",
70
67
  "@netlify/blobs": "^11.0.3",
71
68
  "@netlify/cache-utils": "^7.1.2",
72
- "@netlify/config": "^25.2.3",
69
+ "@netlify/config": "^25.2.5",
73
70
  "@netlify/edge-bundler": "16.0.4",
74
- "@netlify/functions-utils": "^7.1.8",
71
+ "@netlify/functions-utils": "^7.1.9",
75
72
  "@netlify/git-utils": "^7.1.1",
76
73
  "@netlify/opentelemetry-utils": "^3.1.0",
77
74
  "@netlify/plugins-list": "^6.81.6",
78
75
  "@netlify/run-utils": "^7.1.0",
79
- "@netlify/zip-it-and-ship-it": "15.5.0",
76
+ "@netlify/zip-it-and-ship-it": "15.5.1",
80
77
  "@sindresorhus/slugify": "^2.0.0",
81
78
  "ansis": "^4.1.0",
82
79
  "execa": "^8.0.0",
@@ -114,18 +111,15 @@
114
111
  "@opentelemetry/api": "~1.8.0",
115
112
  "@opentelemetry/sdk-trace-base": "~1.24.0",
116
113
  "@types/node": "^22.12.0",
114
+ "@vitest/coverage-v8": "^3.2.6",
117
115
  "atob": "^2.1.2",
118
- "ava": "^5.0.0",
119
- "c8": "^10.0.0",
120
116
  "cpy": "^11.0.0",
121
117
  "cpy-cli": "^5.0.0",
122
118
  "get-node": "^14.2.1",
123
119
  "get-port": "^7.0.0",
124
120
  "has-ansi": "^6.0.0",
125
121
  "micro-memoize": "^5.1.1",
126
- "npm-run-all2": "^6.0.0",
127
122
  "process-exists": "^5.0.0",
128
- "tinyspy": "^4.0.3",
129
123
  "tmp-promise": "^3.0.2",
130
124
  "tsd": "^0.33.0",
131
125
  "vitest": "^3.0.0",
@@ -143,5 +137,5 @@
143
137
  "engines": {
144
138
  "node": ">=22.12.0"
145
139
  },
146
- "gitHead": "2c0f59f4ff6e24d495a9bb46f641fdba5efedd49"
140
+ "gitHead": "ff2974e358a0d36f213a9a24e844cd0c3ca44c18"
147
141
  }