@netlify/build 34.3.0 → 35.0.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.
@@ -1,9 +1,8 @@
1
- import { promises as fs } from 'fs';
2
- import { normalize, resolve } from 'path';
3
- import { execa } from 'execa';
1
+ import { promises as fs } from 'node:fs';
2
+ import { normalize } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
4
  import { pathExists } from 'path-exists';
5
5
  import { isFile } from 'path-type';
6
- import { logArray, logSubHeader } from '../log/logger.js';
7
6
  import { logInstallMissingPlugins, logInstallIntegrations } from '../log/messages/install.js';
8
7
  import { addExactDependencies } from './main.js';
9
8
  // Automatically install plugins if not already installed.
@@ -21,40 +20,28 @@ export const installMissingPlugins = async function ({ missingPlugins, autoPlugi
21
20
  await addExactDependencies({ packageRoot: autoPluginsDir, isLocal: mode !== 'buildbot', packages });
22
21
  };
23
22
  export const installIntegrationPlugins = async function ({ integrations, autoPluginsDir, mode, logs, context, testOpts, pluginsEnv, buildDir, }) {
24
- const integrationsToBuild = integrations.filter((integration) => typeof integration.dev !== 'undefined' && context === 'dev');
25
- if (integrationsToBuild.length) {
26
- logSubHeader(logs, 'Building extensions');
27
- logArray(logs, integrationsToBuild.map(({ slug, dev: { path } }) => `${slug} from ${path}`));
28
- }
29
23
  const packages = (await Promise.all(integrations.map((integration) => getIntegrationPackage({ integration, context, testOpts, buildDir, pluginsEnv })))).filter(Boolean);
30
- logInstallIntegrations(logs, integrations.filter((integration) => integrationsToBuild.every((compiledIntegration) => integration.slug !== compiledIntegration.slug)));
24
+ logInstallIntegrations(logs, integrations);
31
25
  if (packages.length === 0) {
32
26
  return;
33
27
  }
34
28
  await createAutoPluginsDir(logs, autoPluginsDir);
35
29
  await addExactDependencies({ packageRoot: autoPluginsDir, isLocal: mode !== 'buildbot', packages });
36
30
  };
37
- const getIntegrationPackage = async function ({ integration: { version, dev }, context, testOpts = {}, buildDir, pluginsEnv, }) {
38
- if (typeof version !== 'undefined') {
39
- return `${version}/packages/buildhooks.tgz`;
40
- }
41
- if (typeof dev !== 'undefined' && context === 'dev') {
42
- const { path } = dev;
43
- const integrationDir = testOpts.cwd ? resolve(testOpts.cwd, path) : resolve(buildDir, path);
44
- try {
45
- const res = await execa('npm', ['run', 'build'], { cwd: integrationDir, env: pluginsEnv });
46
- // This is horrible and hacky, but `npm run build` will
47
- // return status code 0 even if it fails
48
- if (!res.stdout.includes('Build complete!')) {
49
- throw new Error(res.stdout);
50
- }
51
- }
52
- catch (e) {
53
- throw new Error(`Failed to build integration. Error:\n\n${e.stack}`);
54
- }
31
+ const getIntegrationPackage = async function ({ integration: { buildPlugin } }) {
32
+ if (buildPlugin === null) {
55
33
  return undefined;
56
34
  }
57
- return undefined;
35
+ switch (buildPlugin.packageURL.protocol) {
36
+ case 'http:':
37
+ // fallthrough
38
+ case 'https:':
39
+ return buildPlugin.packageURL.toString();
40
+ case 'file:':
41
+ return fileURLToPath(buildPlugin.packageURL);
42
+ default:
43
+ throw new Error(`unsupported build plugin package URL: ${buildPlugin.packageURL.toString()}`);
44
+ }
58
45
  };
59
46
  // We pin the version without using semver ranges ^ nor ~
60
47
  const getPackage = function ({ packageName, expectedVersion }) {
@@ -1,19 +1,20 @@
1
+ import * as colors from 'ansis';
1
2
  /**
2
- * Color theme. Please use this instead of requiring chalk directly,
3
+ * Color theme. Please use this instead of requiring ansis directly,
3
4
  * to ensure consistent colors.
4
5
  */
5
6
  export declare const THEME: {
6
- header: import("chalk").ChalkInstance;
7
- subHeader: import("chalk").ChalkInstance;
8
- highlightWords: import("chalk").ChalkInstance;
9
- errorHeader: import("chalk").ChalkInstance;
10
- errorSubHeader: import("chalk").ChalkInstance;
11
- errorLine: import("chalk").ChalkInstance;
12
- errorHighlightWords: import("chalk").ChalkInstance;
13
- warningHeader: import("chalk").ChalkInstance;
14
- warningSubHeader: import("chalk").ChalkInstance;
15
- warningLine: import("chalk").ChalkInstance;
16
- warningHighlightWords: import("chalk").ChalkInstance;
17
- dimWords: import("chalk").ChalkInstance;
7
+ header: colors.Ansis;
8
+ subHeader: colors.Ansis;
9
+ highlightWords: colors.Ansis;
10
+ errorHeader: colors.Ansis;
11
+ errorSubHeader: colors.Ansis;
12
+ errorLine: colors.Ansis;
13
+ errorHighlightWords: colors.Ansis;
14
+ warningHeader: colors.Ansis;
15
+ warningSubHeader: colors.Ansis;
16
+ warningLine: colors.Ansis;
17
+ warningHighlightWords: colors.Ansis;
18
+ dimWords: colors.Ansis;
18
19
  none: (string: any) => any;
19
20
  };
package/lib/log/theme.js CHANGED
@@ -1,27 +1,27 @@
1
- import chalk from 'chalk';
1
+ import * as colors from 'ansis';
2
2
  /**
3
- * Color theme. Please use this instead of requiring chalk directly,
3
+ * Color theme. Please use this instead of requiring ansis directly,
4
4
  * to ensure consistent colors.
5
5
  */
6
6
  export const THEME = {
7
7
  // Main headers
8
- header: chalk.cyanBright.bold,
8
+ header: colors.cyanBright.bold,
9
9
  // Single lines used as sub-headers
10
- subHeader: chalk.cyan.bold,
10
+ subHeader: colors.cyan.bold,
11
11
  // One of several words that should be highlighted inside a line
12
- highlightWords: chalk.cyan,
12
+ highlightWords: colors.cyan,
13
13
  // Same for errors
14
- errorHeader: chalk.redBright.bold,
15
- errorSubHeader: chalk.red.bold,
16
- errorLine: chalk.redBright,
17
- errorHighlightWords: chalk.redBright.bold,
14
+ errorHeader: colors.redBright.bold,
15
+ errorSubHeader: colors.red.bold,
16
+ errorLine: colors.redBright,
17
+ errorHighlightWords: colors.redBright.bold,
18
18
  // Same for warnings
19
- warningHeader: chalk.yellowBright.bold,
20
- warningSubHeader: chalk.yellow.bold,
21
- warningLine: chalk.yellowBright,
22
- warningHighlightWords: chalk.yellowBright.bold,
19
+ warningHeader: colors.yellowBright.bold,
20
+ warningSubHeader: colors.yellow.bold,
21
+ warningLine: colors.yellowBright,
22
+ warningHighlightWords: colors.yellowBright.bold,
23
23
  // One of several words that should be dimmed inside a line
24
- dimWords: chalk.gray,
24
+ dimWords: colors.gray,
25
25
  // No colors
26
26
  none: (string) => string,
27
27
  };
@@ -1,4 +1,4 @@
1
- import { join, resolve } from 'path';
1
+ import { join } from 'node:path';
2
2
  import { addErrorInfo } from '../error/info.js';
3
3
  import { installMissingPlugins, installIntegrationPlugins } from '../install/missing.js';
4
4
  import { resolvePath, tryResolvePath } from '../utils/resolve.js';
@@ -39,8 +39,7 @@ export const resolvePluginsPath = async function ({ pluginsOptions, siteInfo, bu
39
39
  mode,
40
40
  logs,
41
41
  });
42
- let integrationPluginOptions = [];
43
- integrationPluginOptions = await handleIntegrations({
42
+ const integrationPluginOptions = await handleIntegrations({
44
43
  integrations,
45
44
  autoPluginsDir,
46
45
  mode,
@@ -118,9 +117,9 @@ const handleMissingPlugins = async function ({ pluginsOptions, autoPluginsDir, m
118
117
  return Promise.all(pluginsOptions.map((pluginOptions) => resolveMissingPluginPath({ pluginOptions, autoPluginsDir })));
119
118
  };
120
119
  const handleIntegrations = async function ({ integrations, autoPluginsDir, mode, logs, buildDir, context, testOpts, pluginsEnv, }) {
121
- const toInstall = integrations.filter((integration) => integration.has_build);
120
+ const integrationsWithBuildPlugins = integrations.filter((integration) => integration.has_build);
122
121
  await installIntegrationPlugins({
123
- integrations: toInstall,
122
+ integrations: integrationsWithBuildPlugins,
124
123
  autoPluginsDir,
125
124
  mode,
126
125
  logs,
@@ -129,26 +128,25 @@ const handleIntegrations = async function ({ integrations, autoPluginsDir, mode,
129
128
  buildDir,
130
129
  pluginsEnv,
131
130
  });
132
- if (toInstall.length === 0) {
133
- return [];
134
- }
135
- return Promise.all(toInstall.map((integration) => resolveIntegration({
136
- integration,
137
- autoPluginsDir,
138
- buildDir,
139
- context,
140
- testOpts,
141
- })));
142
- };
143
- const resolveIntegration = async function ({ integration, autoPluginsDir, buildDir, context, testOpts }) {
144
- if (typeof integration.dev !== 'undefined' && context === 'dev') {
145
- const { path } = integration.dev;
146
- const integrationDir = testOpts.cwd ? resolve(testOpts.cwd, path) : resolve(buildDir, path);
147
- const pluginPath = await resolvePath(`${integrationDir}/.ntli/build`, buildDir);
148
- return { pluginPath, packageName: `${integration.slug}`, isIntegration: true, integration, loadedFrom: 'local' };
149
- }
150
- const pluginPath = await resolvePath(`${integration.slug}-buildhooks`, autoPluginsDir);
151
- return { pluginPath, packageName: `${integration.slug}-buildhooks`, isIntegration: true, integration };
131
+ return Promise.all(integrationsWithBuildPlugins.map(async (integration) => {
132
+ // TODO(ndhoule): When developing locally, the user can accidentally set an extension name in
133
+ // their netlify.toml that points to a build plugin package that has a mismatched name. This
134
+ // will result in a failed install here. The solution is non-obvious: make sure your
135
+ // `netlify.toml#integrations[].name` matches the extension that `netlify.toml#integrations[].dev.path`
136
+ // points at.
137
+ //
138
+ // (We could, for example, detect a mismatch by untarring the local build plugin package in
139
+ // memory and comparing its `package.json#name` to `integration.slug`, and throw a descriptive
140
+ // error if they don't match.)
141
+ const packageName = `${integration.slug}-buildhooks`;
142
+ return {
143
+ integration,
144
+ isIntegration: true,
145
+ loadedFrom: integration.buildPlugin.origin === 'local' ? 'local' : undefined,
146
+ packageName,
147
+ pluginPath: await resolvePath(packageName, autoPluginsDir),
148
+ };
149
+ }));
152
150
  };
153
151
  // Resolve the plugins that just got automatically installed
154
152
  const resolveMissingPluginPath = async function ({ pluginOptions, pluginOptions: { packageName }, autoPluginsDir }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/build",
3
- "version": "34.3.0",
3
+ "version": "35.0.0",
4
4
  "description": "Netlify build module",
5
5
  "type": "module",
6
6
  "exports": "./lib/index.js",
@@ -67,9 +67,9 @@
67
67
  "license": "MIT",
68
68
  "dependencies": {
69
69
  "@bugsnag/js": "^8.0.0",
70
- "@netlify/blobs": "^10.0.6",
70
+ "@netlify/blobs": "^10.0.7",
71
71
  "@netlify/cache-utils": "^6.0.3",
72
- "@netlify/config": "^23.2.0",
72
+ "@netlify/config": "^24.0.0",
73
73
  "@netlify/edge-bundler": "14.2.2",
74
74
  "@netlify/functions-utils": "^6.2.0",
75
75
  "@netlify/git-utils": "^6.0.2",
@@ -79,7 +79,7 @@
79
79
  "@netlify/zip-it-and-ship-it": "14.1.0",
80
80
  "@sindresorhus/slugify": "^2.0.0",
81
81
  "ansi-escapes": "^7.0.0",
82
- "chalk": "^5.0.0",
82
+ "ansis": "^4.1.0",
83
83
  "clean-stack": "^5.0.0",
84
84
  "execa": "^8.0.0",
85
85
  "fdir": "^6.0.1",
@@ -156,5 +156,5 @@
156
156
  "engines": {
157
157
  "node": ">=18.14.0"
158
158
  },
159
- "gitHead": "2a186393af7f577cc6bafa5d3962ea0833cd084c"
159
+ "gitHead": "5100d463cb9b606b91a6a9b5c3fbe9c143716701"
160
160
  }