@netlify/build 29.0.1-rc → 29.0.2
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/bin.js +5 -0
- package/lib/core/bin.js +66 -0
- package/lib/core/build.js +356 -0
- package/lib/core/config.js +121 -0
- package/lib/core/constants.js +116 -0
- package/lib/core/dev.js +27 -0
- package/lib/core/dry.js +21 -0
- package/lib/core/feature_flags.js +21 -0
- package/lib/core/flags.js +201 -0
- package/lib/core/lingering.js +68 -0
- package/lib/core/main.js +110 -0
- package/lib/core/missing_side_file.js +17 -0
- package/lib/core/normalize_flags.js +59 -0
- package/lib/core/severity.js +21 -0
- package/lib/core/types.js +8 -0
- package/lib/core/user_node_version.js +32 -0
- package/lib/env/changes.js +43 -0
- package/lib/env/main.js +14 -0
- package/lib/env/metadata.js +68 -0
- package/lib/error/api.js +37 -0
- package/lib/error/build.js +36 -0
- package/{src → lib}/error/cancel.js +5 -6
- package/lib/error/colors.js +9 -0
- package/lib/error/handle.js +46 -0
- package/lib/error/info.js +37 -0
- package/lib/error/monitor/location.js +16 -0
- package/lib/error/monitor/normalize.js +86 -0
- package/lib/error/monitor/print.js +20 -0
- package/lib/error/monitor/report.js +120 -0
- package/lib/error/monitor/start.js +61 -0
- package/lib/error/parse/clean_stack.js +70 -0
- package/lib/error/parse/location.js +50 -0
- package/lib/error/parse/normalize.js +24 -0
- package/lib/error/parse/parse.js +67 -0
- package/lib/error/parse/plugin.js +55 -0
- package/lib/error/parse/properties.js +16 -0
- package/lib/error/parse/serialize_log.js +34 -0
- package/lib/error/parse/serialize_status.js +18 -0
- package/lib/error/parse/stack.js +34 -0
- package/lib/error/report.js +27 -0
- package/lib/error/type.js +177 -0
- package/lib/install/functions.js +20 -0
- package/lib/install/local.js +45 -0
- package/lib/install/main.js +67 -0
- package/lib/install/missing.js +54 -0
- package/lib/log/colors.js +28 -0
- package/lib/log/description.js +21 -0
- package/lib/log/header.js +14 -0
- package/lib/log/header_func.js +13 -0
- package/lib/log/logger.js +140 -0
- package/lib/log/messages/compatibility.js +146 -0
- package/lib/log/messages/config.js +91 -0
- package/lib/log/messages/core.js +51 -0
- package/lib/log/messages/core_steps.js +75 -0
- package/lib/log/messages/dry.js +41 -0
- package/lib/log/messages/install.js +25 -0
- package/lib/log/messages/ipc.js +29 -0
- package/lib/log/messages/mutations.js +62 -0
- package/{src → lib}/log/messages/plugins.js +18 -32
- package/lib/log/messages/status.js +14 -0
- package/lib/log/messages/steps.js +18 -0
- package/lib/log/old_version.js +32 -0
- package/lib/log/serialize.js +10 -0
- package/lib/log/stream.js +68 -0
- package/lib/log/theme.js +27 -0
- package/lib/plugins/child/diff.js +46 -0
- package/lib/plugins/child/error.js +26 -0
- package/lib/plugins/child/lazy.js +15 -0
- package/lib/plugins/child/load.js +22 -0
- package/lib/plugins/child/logic.js +57 -0
- package/lib/plugins/child/main.js +37 -0
- package/lib/plugins/child/run.js +19 -0
- package/lib/plugins/child/status.js +63 -0
- package/lib/plugins/child/typescript.js +28 -0
- package/lib/plugins/child/utils.js +42 -0
- package/lib/plugins/child/validate.js +31 -0
- package/lib/plugins/compatibility.js +104 -0
- package/{src → lib}/plugins/error.js +31 -35
- package/{src → lib}/plugins/events.js +7 -12
- package/lib/plugins/expected_version.js +81 -0
- package/lib/plugins/internal.js +10 -0
- package/lib/plugins/ipc.js +120 -0
- package/lib/plugins/list.js +73 -0
- package/lib/plugins/load.js +50 -0
- package/lib/plugins/manifest/check.js +85 -0
- package/lib/plugins/manifest/load.js +38 -0
- package/lib/plugins/manifest/main.js +19 -0
- package/lib/plugins/manifest/path.js +24 -0
- package/lib/plugins/manifest/validate.js +91 -0
- package/lib/plugins/node_version.js +35 -0
- package/lib/plugins/options.js +70 -0
- package/lib/plugins/pinned_version.js +83 -0
- package/lib/plugins/resolve.js +110 -0
- package/lib/plugins/spawn.js +58 -0
- package/lib/plugins_core/add.js +35 -0
- package/lib/plugins_core/build_command.js +50 -0
- package/lib/plugins_core/deploy/buildbot_client.js +87 -0
- package/lib/plugins_core/deploy/index.js +49 -0
- package/{src → lib}/plugins_core/deploy/manifest.yml +0 -0
- package/lib/plugins_core/edge_functions/index.js +76 -0
- package/{src → lib}/plugins_core/edge_functions/lib/error.js +13 -17
- package/lib/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.js +21 -0
- package/lib/plugins_core/functions/error.js +123 -0
- package/lib/plugins_core/functions/feature_flags.js +6 -0
- package/lib/plugins_core/functions/index.js +114 -0
- package/lib/plugins_core/functions/utils.js +45 -0
- package/lib/plugins_core/functions/zisi.js +39 -0
- package/{src → lib}/plugins_core/functions_install/index.js +8 -11
- package/{src → lib}/plugins_core/functions_install/manifest.yml +0 -0
- package/lib/plugins_core/list.js +20 -0
- package/lib/report/statsd.js +31 -0
- package/lib/status/add.js +30 -0
- package/lib/status/colors.js +18 -0
- package/lib/status/load_error.js +10 -0
- package/lib/status/report.js +83 -0
- package/lib/status/success.js +14 -0
- package/lib/steps/core_step.js +59 -0
- package/lib/steps/error.js +65 -0
- package/lib/steps/get.js +43 -0
- package/lib/steps/plugin.js +55 -0
- package/lib/steps/return.js +25 -0
- package/lib/steps/run_core_steps.js +117 -0
- package/lib/steps/run_step.js +190 -0
- package/lib/steps/run_steps.js +96 -0
- package/lib/steps/update_config.js +66 -0
- package/lib/telemetry/main.js +97 -0
- package/lib/time/aggregate.js +109 -0
- package/lib/time/main.js +31 -0
- package/lib/time/measure.js +16 -0
- package/lib/time/report.js +24 -0
- package/lib/utils/errors.js +13 -0
- package/lib/utils/json.js +15 -0
- package/lib/utils/omit.js +3 -0
- package/lib/utils/package.js +24 -0
- package/lib/utils/remove_falsy.js +8 -0
- package/lib/utils/resolve.js +41 -0
- package/lib/utils/runtime.js +5 -0
- package/lib/utils/semver.js +28 -0
- package/package.json +41 -24
- package/types/config/netlify_config.d.ts +4 -4
- package/types/netlify_plugin_constants.d.ts +8 -8
- package/src/core/bin.js +0 -83
- package/src/core/build.js +0 -554
- package/src/core/config.js +0 -186
- package/src/core/constants.js +0 -156
- package/src/core/dev.js +0 -31
- package/src/core/dry.js +0 -39
- package/src/core/feature_flags.js +0 -22
- package/src/core/flags.js +0 -204
- package/src/core/lingering.js +0 -85
- package/src/core/main.js +0 -165
- package/src/core/missing_side_file.js +0 -29
- package/src/core/normalize_flags.js +0 -70
- package/src/core/severity.js +0 -22
- package/src/core/user_node_version.js +0 -41
- package/src/env/changes.js +0 -52
- package/src/env/main.js +0 -19
- package/src/env/metadata.js +0 -81
- package/src/error/api.js +0 -46
- package/src/error/build.js +0 -50
- package/src/error/colors.js +0 -11
- package/src/error/handle.js +0 -57
- package/src/error/info.js +0 -46
- package/src/error/monitor/location.js +0 -21
- package/src/error/monitor/normalize.js +0 -96
- package/src/error/monitor/print.js +0 -42
- package/src/error/monitor/report.js +0 -138
- package/src/error/monitor/start.js +0 -69
- package/src/error/parse/clean_stack.js +0 -87
- package/src/error/parse/location.js +0 -62
- package/src/error/parse/normalize.js +0 -29
- package/src/error/parse/parse.js +0 -97
- package/src/error/parse/plugin.js +0 -70
- package/src/error/parse/properties.js +0 -23
- package/src/error/parse/serialize_log.js +0 -42
- package/src/error/parse/serialize_status.js +0 -23
- package/src/error/parse/stack.js +0 -43
- package/src/error/type.js +0 -189
- package/src/install/functions.js +0 -28
- package/src/install/local.js +0 -62
- package/src/install/main.js +0 -81
- package/src/install/missing.js +0 -67
- package/src/log/colors.js +0 -34
- package/src/log/description.js +0 -26
- package/src/log/header.js +0 -16
- package/src/log/header_func.js +0 -17
- package/src/log/logger.js +0 -161
- package/src/log/messages/compatibility.js +0 -164
- package/src/log/messages/config.js +0 -107
- package/src/log/messages/core.js +0 -70
- package/src/log/messages/core_steps.js +0 -104
- package/src/log/messages/dry.js +0 -63
- package/src/log/messages/install.js +0 -20
- package/src/log/messages/ipc.js +0 -38
- package/src/log/messages/mutations.js +0 -82
- package/src/log/messages/status.js +0 -16
- package/src/log/messages/steps.js +0 -22
- package/src/log/old_version.js +0 -41
- package/src/log/serialize.js +0 -13
- package/src/log/stream.js +0 -85
- package/src/log/theme.js +0 -26
- package/src/plugins/child/diff.js +0 -55
- package/src/plugins/child/error.js +0 -32
- package/src/plugins/child/lazy.js +0 -18
- package/src/plugins/child/load.js +0 -29
- package/src/plugins/child/logic.js +0 -57
- package/src/plugins/child/main.js +0 -51
- package/src/plugins/child/run.js +0 -28
- package/src/plugins/child/status.js +0 -74
- package/src/plugins/child/typescript.js +0 -45
- package/src/plugins/child/utils.js +0 -56
- package/src/plugins/child/validate.js +0 -34
- package/src/plugins/compatibility.js +0 -128
- package/src/plugins/expected_version.js +0 -119
- package/src/plugins/ipc.js +0 -145
- package/src/plugins/list.js +0 -86
- package/src/plugins/load.js +0 -70
- package/src/plugins/manifest/check.js +0 -106
- package/src/plugins/manifest/load.js +0 -41
- package/src/plugins/manifest/main.js +0 -22
- package/src/plugins/manifest/path.js +0 -31
- package/src/plugins/manifest/validate.js +0 -108
- package/src/plugins/node_version.js +0 -50
- package/src/plugins/options.js +0 -88
- package/src/plugins/pinned_version.js +0 -131
- package/src/plugins/resolve.js +0 -152
- package/src/plugins/spawn.js +0 -66
- package/src/plugins_core/add.js +0 -49
- package/src/plugins_core/build_command.js +0 -75
- package/src/plugins_core/deploy/buildbot_client.js +0 -102
- package/src/plugins_core/deploy/index.js +0 -73
- package/src/plugins_core/edge_functions/index.js +0 -123
- package/src/plugins_core/edge_functions/lib/internal_manifest.js +0 -54
- package/src/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.js +0 -89
- package/src/plugins_core/functions/error.js +0 -163
- package/src/plugins_core/functions/feature_flags.js +0 -6
- package/src/plugins_core/functions/index.js +0 -160
- package/src/plugins_core/functions/utils.js +0 -66
- package/src/plugins_core/functions/zisi.js +0 -53
- package/src/plugins_core/list.js +0 -27
- package/src/status/add.js +0 -36
- package/src/status/colors.js +0 -23
- package/src/status/load_error.js +0 -11
- package/src/status/report.js +0 -137
- package/src/status/success.js +0 -18
- package/src/steps/core_step.js +0 -92
- package/src/steps/error.js +0 -102
- package/src/steps/get.js +0 -51
- package/src/steps/plugin.js +0 -85
- package/src/steps/return.js +0 -52
- package/src/steps/run_core_steps.js +0 -200
- package/src/steps/run_step.js +0 -304
- package/src/steps/run_steps.js +0 -179
- package/src/steps/update_config.js +0 -93
- package/src/telemetry/main.js +0 -136
- package/src/time/aggregate.js +0 -146
- package/src/time/main.js +0 -48
- package/src/time/measure.js +0 -22
- package/src/time/report.js +0 -59
- package/src/utils/errors.js +0 -12
- package/src/utils/json.js +0 -19
- package/src/utils/omit.js +0 -6
- package/src/utils/package.js +0 -23
- package/src/utils/remove_falsy.js +0 -10
- package/src/utils/resolve.js +0 -46
- package/src/utils/semver.js +0 -34
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import { zipFunctions } from '@netlify/zip-it-and-ship-it';
|
|
3
|
+
import { pathExists } from 'path-exists';
|
|
4
|
+
import { log } from '../../log/logger.js';
|
|
5
|
+
import { logBundleResults, logFunctionsNonExistingDir, logFunctionsToBundle } from '../../log/messages/core_steps.js';
|
|
6
|
+
import { getZipError } from './error.js';
|
|
7
|
+
import { getUserAndInternalFunctions, validateFunctionsSrc } from './utils.js';
|
|
8
|
+
import { getZisiParameters } from './zisi.js';
|
|
9
|
+
// Returns `true` if at least one of the functions has been configured to use
|
|
10
|
+
// esbuild.
|
|
11
|
+
const isUsingEsbuild = (functionsConfig = {}) => Object.values(functionsConfig).some((configObject) => configObject.node_bundler === 'esbuild');
|
|
12
|
+
const zipFunctionsAndLogResults = async ({ buildDir, childEnv, featureFlags, functionsConfig, functionsDist, functionsSrc, internalFunctionsSrc, isRunningLocally, logs, repositoryRoot, }) => {
|
|
13
|
+
const zisiParameters = getZisiParameters({
|
|
14
|
+
buildDir,
|
|
15
|
+
childEnv,
|
|
16
|
+
featureFlags,
|
|
17
|
+
functionsConfig,
|
|
18
|
+
functionsDist,
|
|
19
|
+
internalFunctionsSrc,
|
|
20
|
+
isRunningLocally,
|
|
21
|
+
repositoryRoot,
|
|
22
|
+
});
|
|
23
|
+
const bundler = isUsingEsbuild(functionsConfig) ? 'esbuild' : 'zisi';
|
|
24
|
+
try {
|
|
25
|
+
// Printing an empty line before bundling output.
|
|
26
|
+
log(logs, '');
|
|
27
|
+
const sourceDirectories = [internalFunctionsSrc, functionsSrc].filter(Boolean);
|
|
28
|
+
const results = await zipItAndShipIt.zipFunctions(sourceDirectories, functionsDist, zisiParameters);
|
|
29
|
+
logBundleResults({ logs, results });
|
|
30
|
+
return { bundler };
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
throw await getZipError(error, functionsSrc);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
// Plugin to package Netlify functions with @netlify/zip-it-and-ship-it
|
|
37
|
+
const coreStep = async function ({ childEnv, constants: { INTERNAL_FUNCTIONS_SRC: relativeInternalFunctionsSrc, IS_LOCAL: isRunningLocally, FUNCTIONS_SRC: relativeFunctionsSrc, FUNCTIONS_DIST: relativeFunctionsDist, }, buildDir, logs, netlifyConfig, featureFlags, repositoryRoot, }) {
|
|
38
|
+
const functionsSrc = relativeFunctionsSrc === undefined ? undefined : resolve(buildDir, relativeFunctionsSrc);
|
|
39
|
+
const functionsDist = resolve(buildDir, relativeFunctionsDist);
|
|
40
|
+
const internalFunctionsSrc = resolve(buildDir, relativeInternalFunctionsSrc);
|
|
41
|
+
const internalFunctionsSrcExists = await pathExists(internalFunctionsSrc);
|
|
42
|
+
const functionsSrcExists = await validateFunctionsSrc({ functionsSrc, logs, relativeFunctionsSrc });
|
|
43
|
+
const [userFunctions = [], internalFunctions = []] = await getUserAndInternalFunctions({
|
|
44
|
+
featureFlags,
|
|
45
|
+
functionsSrc,
|
|
46
|
+
functionsSrcExists,
|
|
47
|
+
internalFunctionsSrc,
|
|
48
|
+
internalFunctionsSrcExists,
|
|
49
|
+
});
|
|
50
|
+
if (functionsSrc && !functionsSrcExists) {
|
|
51
|
+
logFunctionsNonExistingDir(logs, relativeFunctionsSrc);
|
|
52
|
+
if (internalFunctions.length !== 0) {
|
|
53
|
+
log(logs, '');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
logFunctionsToBundle({
|
|
57
|
+
logs,
|
|
58
|
+
userFunctions,
|
|
59
|
+
userFunctionsSrc: relativeFunctionsSrc,
|
|
60
|
+
userFunctionsSrcExists: functionsSrcExists,
|
|
61
|
+
internalFunctions,
|
|
62
|
+
internalFunctionsSrc: relativeInternalFunctionsSrc,
|
|
63
|
+
});
|
|
64
|
+
if (userFunctions.length === 0 && internalFunctions.length === 0) {
|
|
65
|
+
return {};
|
|
66
|
+
}
|
|
67
|
+
const { bundler } = await zipFunctionsAndLogResults({
|
|
68
|
+
buildDir,
|
|
69
|
+
childEnv,
|
|
70
|
+
featureFlags,
|
|
71
|
+
functionsConfig: netlifyConfig.functions,
|
|
72
|
+
functionsDist,
|
|
73
|
+
functionsSrc,
|
|
74
|
+
internalFunctionsSrc,
|
|
75
|
+
isRunningLocally,
|
|
76
|
+
logs,
|
|
77
|
+
repositoryRoot,
|
|
78
|
+
});
|
|
79
|
+
return {
|
|
80
|
+
tags: {
|
|
81
|
+
bundler,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
// We run this core step if at least one of the functions directories (the
|
|
86
|
+
// one configured by the user or the internal one) exists. We use a dynamic
|
|
87
|
+
// `condition` because the directories might be created by the build command
|
|
88
|
+
// or plugins.
|
|
89
|
+
const hasFunctionsDirectories = async function ({ buildDir, constants: { INTERNAL_FUNCTIONS_SRC, FUNCTIONS_SRC } }) {
|
|
90
|
+
const hasFunctionsSrc = FUNCTIONS_SRC !== undefined && FUNCTIONS_SRC !== '';
|
|
91
|
+
if (hasFunctionsSrc) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
const internalFunctionsSrc = resolve(buildDir, INTERNAL_FUNCTIONS_SRC);
|
|
95
|
+
return await pathExists(internalFunctionsSrc);
|
|
96
|
+
};
|
|
97
|
+
export const bundleFunctions = {
|
|
98
|
+
event: 'onBuild',
|
|
99
|
+
coreStep,
|
|
100
|
+
coreStepId: 'functions_bundling',
|
|
101
|
+
coreStepName: 'Functions bundling',
|
|
102
|
+
coreStepDescription: () => 'Functions bundling',
|
|
103
|
+
condition: hasFunctionsDirectories,
|
|
104
|
+
};
|
|
105
|
+
// Named imports with ES modules cannot be mocked (unlike CommonJS) because
|
|
106
|
+
// they are bound at load time.
|
|
107
|
+
// However, some of our tests are asserting which arguments are passed to
|
|
108
|
+
// `zip-it-and-ship-it` methods. Therefore, we need to use an intermediary
|
|
109
|
+
// function and export them so tests can use it.
|
|
110
|
+
export const zipItAndShipIt = {
|
|
111
|
+
async zipFunctions(...args) {
|
|
112
|
+
return await zipFunctions(...args);
|
|
113
|
+
},
|
|
114
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import { relative } from 'path';
|
|
3
|
+
import { listFunctions } from '@netlify/zip-it-and-ship-it';
|
|
4
|
+
import { addErrorInfo } from '../../error/info.js';
|
|
5
|
+
import { getZisiFeatureFlags } from './feature_flags.js';
|
|
6
|
+
// Returns the `mainFile` of each function found in `functionsSrc`, relative to
|
|
7
|
+
// `functionsSrc`.
|
|
8
|
+
const getRelativeFunctionMainFiles = async function ({ featureFlags, functionsSrc }) {
|
|
9
|
+
if (functionsSrc === undefined) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
const zisiFeatureFlags = getZisiFeatureFlags(featureFlags);
|
|
13
|
+
const functions = await listFunctions(functionsSrc, { featureFlags: zisiFeatureFlags });
|
|
14
|
+
return functions.map(({ mainFile }) => relative(functionsSrc, mainFile));
|
|
15
|
+
};
|
|
16
|
+
export const getUserAndInternalFunctions = ({ featureFlags, functionsSrc, functionsSrcExists, internalFunctionsSrc, internalFunctionsSrcExists, }) => {
|
|
17
|
+
const paths = [
|
|
18
|
+
functionsSrcExists ? functionsSrc : undefined,
|
|
19
|
+
internalFunctionsSrcExists ? internalFunctionsSrc : undefined,
|
|
20
|
+
];
|
|
21
|
+
return Promise.all(paths.map((path) => path && getRelativeFunctionMainFiles({ featureFlags, functionsSrc: path })));
|
|
22
|
+
};
|
|
23
|
+
// Returns `true` if the functions directory exists and is valid. Returns
|
|
24
|
+
// `false` if it doesn't exist. Throws an error if it's invalid or can't
|
|
25
|
+
// be accessed.
|
|
26
|
+
export const validateFunctionsSrc = async function ({ functionsSrc, relativeFunctionsSrc }) {
|
|
27
|
+
if (functionsSrc === undefined) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const stats = await fs.stat(functionsSrc);
|
|
32
|
+
if (stats.isDirectory()) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
const error = new Error(`The Netlify Functions setting should target a directory, not a regular file: ${relativeFunctionsSrc}`);
|
|
36
|
+
addErrorInfo(error, { type: 'resolveConfig' });
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error.code === 'ENOENT') {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { join, resolve } from 'path';
|
|
2
|
+
import mapObject from 'map-obj';
|
|
3
|
+
import { getZisiFeatureFlags } from './feature_flags.js';
|
|
4
|
+
export const getZisiParameters = ({ buildDir, childEnv, featureFlags, functionsConfig, functionsDist, internalFunctionsSrc, isRunningLocally, repositoryRoot, }) => {
|
|
5
|
+
const nodeVersion = childEnv.AWS_LAMBDA_JS_RUNTIME;
|
|
6
|
+
const manifest = join(functionsDist, 'manifest.json');
|
|
7
|
+
const config = mapObject(functionsConfig, (expression, object) => [
|
|
8
|
+
expression,
|
|
9
|
+
normalizeFunctionConfig({ buildDir, featureFlags, functionConfig: object, isRunningLocally, nodeVersion }),
|
|
10
|
+
]);
|
|
11
|
+
const zisiFeatureFlags = getZisiFeatureFlags(featureFlags);
|
|
12
|
+
// Only internal functions are allowed to have a json config file
|
|
13
|
+
const configFileDirectories = [resolve(internalFunctionsSrc)];
|
|
14
|
+
return { basePath: buildDir, config, manifest, featureFlags: zisiFeatureFlags, repositoryRoot, configFileDirectories };
|
|
15
|
+
};
|
|
16
|
+
// The function configuration keys returned by @netlify/config are not an exact
|
|
17
|
+
// match to the properties that @netlify/zip-it-and-ship-it expects. We do that
|
|
18
|
+
// translation here.
|
|
19
|
+
export const normalizeFunctionConfig = ({ buildDir, functionConfig = {}, isRunningLocally, nodeVersion }) => ({
|
|
20
|
+
externalNodeModules: functionConfig.external_node_modules,
|
|
21
|
+
includedFiles: functionConfig.included_files,
|
|
22
|
+
includedFilesBasePath: buildDir,
|
|
23
|
+
ignoredNodeModules: functionConfig.ignored_node_modules,
|
|
24
|
+
nodeVersion,
|
|
25
|
+
schedule: functionConfig.schedule,
|
|
26
|
+
// When the user selects esbuild as the Node bundler, we still want to use
|
|
27
|
+
// the legacy ZISI bundler as a fallback. Rather than asking the user to
|
|
28
|
+
// make this decision, we abstract that complexity away by injecting the
|
|
29
|
+
// fallback behavior ourselves. We do this by transforming the value
|
|
30
|
+
// `esbuild` into `esbuild_zisi`, which zip-it-and-ship-it understands.
|
|
31
|
+
nodeBundler: functionConfig.node_bundler === 'esbuild' ? 'esbuild_zisi' : functionConfig.node_bundler,
|
|
32
|
+
// If the build is running in buildbot, we set the Rust target directory to a
|
|
33
|
+
// path that will get cached in between builds, allowing us to speed up the
|
|
34
|
+
// build process.
|
|
35
|
+
rustTargetDirectory: isRunningLocally ? undefined : resolve(buildDir, '.netlify', 'rust-functions-cache', '[name]'),
|
|
36
|
+
// Go functions should be zipped only when building locally. When running in
|
|
37
|
+
// buildbot, the Go API client will handle the zipping.
|
|
38
|
+
zipGo: isRunningLocally ? true : undefined,
|
|
39
|
+
});
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { pathExists } from 'path-exists'
|
|
2
|
-
|
|
3
|
-
import { installFunctionDependencies } from '../../install/functions.js'
|
|
4
|
-
|
|
1
|
+
import { pathExists } from 'path-exists';
|
|
2
|
+
import { installFunctionDependencies } from '../../install/functions.js';
|
|
5
3
|
// Plugin to package Netlify functions with @netlify/zip-it-and-ship-it
|
|
6
4
|
export const onPreBuild = async function ({ constants: { FUNCTIONS_SRC, IS_LOCAL } }) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
5
|
+
if (!(await pathExists(FUNCTIONS_SRC))) {
|
|
6
|
+
return {};
|
|
7
|
+
}
|
|
8
|
+
await installFunctionDependencies(FUNCTIONS_SRC, IS_LOCAL);
|
|
9
|
+
return {};
|
|
10
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { fileURLToPath } from 'url';
|
|
2
|
+
import { LOCAL_INSTALL_PLUGIN_NAME } from '../install/local.js';
|
|
3
|
+
const FUNCTIONS_INSTALL_PLUGIN = fileURLToPath(new URL('functions_install/index.js', import.meta.url));
|
|
4
|
+
// List of core plugin names
|
|
5
|
+
const FUNCTIONS_INSTALL_PLUGIN_NAME = '@netlify/plugin-functions-install-core';
|
|
6
|
+
const CORE_PLUGINS = new Set([FUNCTIONS_INSTALL_PLUGIN_NAME, LOCAL_INSTALL_PLUGIN_NAME]);
|
|
7
|
+
// Plugins that are installed and enabled by default
|
|
8
|
+
export const listCorePlugins = function ({ FUNCTIONS_SRC }) {
|
|
9
|
+
const functionsInstallPlugin = getFunctionsInstallPlugin(FUNCTIONS_SRC);
|
|
10
|
+
return [functionsInstallPlugin].filter(Boolean);
|
|
11
|
+
};
|
|
12
|
+
const getFunctionsInstallPlugin = function (FUNCTIONS_SRC) {
|
|
13
|
+
if (FUNCTIONS_SRC === undefined) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
return { package: FUNCTIONS_INSTALL_PLUGIN_NAME, pluginPath: FUNCTIONS_INSTALL_PLUGIN, optional: true };
|
|
17
|
+
};
|
|
18
|
+
export const isCorePlugin = function (packageName) {
|
|
19
|
+
return CORE_PLUGINS.has(packageName);
|
|
20
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { promisify } from 'util';
|
|
2
|
+
import slugify from '@sindresorhus/slugify';
|
|
3
|
+
import StatsdClient from 'statsd-client';
|
|
4
|
+
// TODO: replace with `timers/promises` after dropping Node < 15.0.0
|
|
5
|
+
const pSetTimeout = promisify(setTimeout);
|
|
6
|
+
// See https://github.com/msiebuhr/node-statsd-client/blob/45a93ee4c94ca72f244a40b06cb542d4bd7c3766/lib/EphemeralSocket.js#L81
|
|
7
|
+
const CLOSE_TIMEOUT = 11;
|
|
8
|
+
// The socket creation is delayed until the first packet is sent. In our
|
|
9
|
+
// case, this happens just before `client.close()` is called, which is too
|
|
10
|
+
// late and make it not send anything. We need to manually create it using
|
|
11
|
+
// the internal API.
|
|
12
|
+
export const startClient = async function (host, port) {
|
|
13
|
+
const client = new StatsdClient({ host, port, socketTimeout: 0 });
|
|
14
|
+
// @ts-expect-error using internals :D
|
|
15
|
+
await promisify(client._socket._createSocket.bind(client._socket))();
|
|
16
|
+
return client;
|
|
17
|
+
};
|
|
18
|
+
// UDP packets are buffered and flushed at regular intervals by statsd-client.
|
|
19
|
+
// Closing force flushing all of them.
|
|
20
|
+
export const closeClient = async function (client) {
|
|
21
|
+
client.close();
|
|
22
|
+
// statsd-client does not provide a way of knowing when the socket is done
|
|
23
|
+
// closing, so we need to use the following hack.
|
|
24
|
+
await pSetTimeout(CLOSE_TIMEOUT);
|
|
25
|
+
await pSetTimeout(CLOSE_TIMEOUT);
|
|
26
|
+
};
|
|
27
|
+
// Make sure the timer name does not include special characters.
|
|
28
|
+
// For example, the `packageName` of local plugins includes dots.
|
|
29
|
+
export const normalizeTagName = function (name) {
|
|
30
|
+
return slugify(name, { separator: '_' });
|
|
31
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Merge plugin status to the list of plugin statuses.
|
|
2
|
+
export const addStatus = function ({ newStatus, statuses, event, packageName, pluginPackageJson: { version } = {} }) {
|
|
3
|
+
// Either:
|
|
4
|
+
// - `build.command`
|
|
5
|
+
// - no status was set
|
|
6
|
+
if (newStatus === undefined) {
|
|
7
|
+
return statuses;
|
|
8
|
+
}
|
|
9
|
+
const formerStatus = statuses.find((status) => status.packageName === packageName);
|
|
10
|
+
if (!canOverrideStatus(formerStatus, newStatus)) {
|
|
11
|
+
return statuses;
|
|
12
|
+
}
|
|
13
|
+
// Overrides plugin's previous status and add more information
|
|
14
|
+
const newStatuses = statuses.filter((status) => status !== formerStatus);
|
|
15
|
+
return [...newStatuses, { ...newStatus, event, packageName, version }];
|
|
16
|
+
};
|
|
17
|
+
const canOverrideStatus = function (formerStatus, newStatus) {
|
|
18
|
+
// No previous status
|
|
19
|
+
if (formerStatus === undefined) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
// Implicit statuses can never override
|
|
23
|
+
if (newStatus.implicit) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
// Error statuses can only be overwritten by more severe error statuses
|
|
27
|
+
return STATES.indexOf(formerStatus.state) <= STATES.indexOf(newStatus.state);
|
|
28
|
+
};
|
|
29
|
+
// Possible status states, ordered by severity.
|
|
30
|
+
const STATES = ['success', 'canceled_plugin', 'failed_plugin', 'failed_build'];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import stripAnsi from 'strip-ansi';
|
|
2
|
+
// Remove colors from statuses
|
|
3
|
+
export const removeStatusesColors = function (statuses) {
|
|
4
|
+
return statuses.map(removeStatusColors);
|
|
5
|
+
};
|
|
6
|
+
const removeStatusColors = function (status) {
|
|
7
|
+
const attributes = COLOR_ATTRIBUTES.map((attribute) => removeAttrColor(status, attribute));
|
|
8
|
+
return Object.assign({}, status, ...attributes);
|
|
9
|
+
};
|
|
10
|
+
const COLOR_ATTRIBUTES = ['title', 'summary', 'text'];
|
|
11
|
+
const removeAttrColor = function (status, attribute) {
|
|
12
|
+
const value = status[attribute];
|
|
13
|
+
if (value === undefined) {
|
|
14
|
+
return {};
|
|
15
|
+
}
|
|
16
|
+
const valueA = stripAnsi(value);
|
|
17
|
+
return { [attribute]: valueA };
|
|
18
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { addErrorInfo } from '../error/info.js';
|
|
2
|
+
import { getFullErrorInfo } from '../error/parse/parse.js';
|
|
3
|
+
import { serializeErrorStatus } from '../error/parse/serialize_status.js';
|
|
4
|
+
// Errors that happen during plugin loads should be reported as error statuses
|
|
5
|
+
export const addPluginLoadErrorStatus = function ({ error, packageName, version, debug }) {
|
|
6
|
+
const fullErrorInfo = getFullErrorInfo({ error, colors: false, debug });
|
|
7
|
+
const errorStatus = serializeErrorStatus({ fullErrorInfo, state: 'failed_build' });
|
|
8
|
+
const statuses = [{ ...errorStatus, event: 'load', packageName, version }];
|
|
9
|
+
addErrorInfo(error, { statuses });
|
|
10
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { handleBuildError } from '../error/handle.js';
|
|
2
|
+
import { logStatuses } from '../log/messages/status.js';
|
|
3
|
+
import { removeStatusesColors } from './colors.js';
|
|
4
|
+
// Report plugin statuses to the console and API
|
|
5
|
+
export const reportStatuses = async function ({ statuses, childEnv, api, mode, pluginsOptions, netlifyConfig, errorMonitor, deployId, logs, debug, sendStatus, testOpts, }) {
|
|
6
|
+
const finalStatuses = getFinalStatuses({ statuses, pluginsOptions });
|
|
7
|
+
if (finalStatuses.length === 0) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const statusesA = removeStatusesColors(finalStatuses);
|
|
11
|
+
printStatuses({ statuses: statusesA, mode, logs });
|
|
12
|
+
await sendApiStatuses({
|
|
13
|
+
statuses: statusesA,
|
|
14
|
+
childEnv,
|
|
15
|
+
api,
|
|
16
|
+
mode,
|
|
17
|
+
netlifyConfig,
|
|
18
|
+
errorMonitor,
|
|
19
|
+
deployId,
|
|
20
|
+
logs,
|
|
21
|
+
debug,
|
|
22
|
+
sendStatus,
|
|
23
|
+
testOpts,
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
// Some plugins might not have completed due to a build error.
|
|
27
|
+
// In that case, we add a dummy plugin run with state "skipped".
|
|
28
|
+
// This allows the API to know both plugins that have completed and only started
|
|
29
|
+
const getFinalStatuses = function ({ statuses = [], pluginsOptions }) {
|
|
30
|
+
return pluginsOptions.map(({ packageName }) => getPluginStatus(packageName, statuses));
|
|
31
|
+
};
|
|
32
|
+
const getPluginStatus = function (packageName, statuses) {
|
|
33
|
+
const pluginStatus = statuses.find((status) => status.packageName === packageName);
|
|
34
|
+
if (pluginStatus !== undefined) {
|
|
35
|
+
return pluginStatus;
|
|
36
|
+
}
|
|
37
|
+
return { packageName, state: 'skipped' };
|
|
38
|
+
};
|
|
39
|
+
// When not in production, print statuses to console.
|
|
40
|
+
// Only print successful ones, since errors are logged afterwards.
|
|
41
|
+
const printStatuses = function ({ statuses, mode, logs }) {
|
|
42
|
+
if (mode === 'buildbot') {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const successStatuses = statuses.filter(shouldPrintStatus);
|
|
46
|
+
if (successStatuses.length === 0) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
logStatuses(logs, successStatuses);
|
|
50
|
+
};
|
|
51
|
+
const shouldPrintStatus = function ({ state, summary }) {
|
|
52
|
+
return state === 'success' && summary !== undefined;
|
|
53
|
+
};
|
|
54
|
+
// In production, send statuses to the API
|
|
55
|
+
const sendApiStatuses = async function ({ statuses, childEnv, api, mode, netlifyConfig, errorMonitor, deployId, logs, debug, sendStatus, testOpts, }) {
|
|
56
|
+
if ((mode !== 'buildbot' && !sendStatus) || api === undefined || !deployId) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
await Promise.all(statuses.map((status) => sendApiStatus({ api, status, childEnv, mode, netlifyConfig, errorMonitor, deployId, logs, debug, testOpts })));
|
|
60
|
+
};
|
|
61
|
+
const sendApiStatus = async function ({ api, status: { packageName, version, state, event, title, summary, text, extraData }, childEnv, mode, netlifyConfig, errorMonitor, deployId, logs, debug, testOpts, }) {
|
|
62
|
+
try {
|
|
63
|
+
await api.createPluginRun({
|
|
64
|
+
deploy_id: deployId,
|
|
65
|
+
body: {
|
|
66
|
+
package: packageName,
|
|
67
|
+
version,
|
|
68
|
+
state,
|
|
69
|
+
reporting_event: event,
|
|
70
|
+
title,
|
|
71
|
+
summary,
|
|
72
|
+
text,
|
|
73
|
+
extra_data: extraData,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
// Bitballoon API randomly fails with 502.
|
|
77
|
+
// Builds should be successful when this API call fails, but we still want
|
|
78
|
+
// to report the error both in logs and in error monitoring.
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
await handleBuildError(error, { errorMonitor, netlifyConfig, childEnv, mode, logs, debug, testOpts });
|
|
82
|
+
}
|
|
83
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { runsOnlyOnBuildFailure } from '../plugins/events.js';
|
|
2
|
+
// The last event handler of a plugin (except for `onError` and `onEnd`)
|
|
3
|
+
// defaults to `utils.status.show({ state: 'success' })` without any `summary`.
|
|
4
|
+
export const getSuccessStatus = function (newStatus, { steps, event, packageName }) {
|
|
5
|
+
if (newStatus === undefined && isLastNonErrorStep({ steps, event, packageName })) {
|
|
6
|
+
return IMPLICIT_STATUS;
|
|
7
|
+
}
|
|
8
|
+
return newStatus;
|
|
9
|
+
};
|
|
10
|
+
const isLastNonErrorStep = function ({ steps, event, packageName }) {
|
|
11
|
+
const nonErrorSteps = steps.filter((step) => step.packageName === packageName && !runsOnlyOnBuildFailure(step.event));
|
|
12
|
+
return nonErrorSteps.length === 0 || nonErrorSteps[nonErrorSteps.length - 1].event === event;
|
|
13
|
+
};
|
|
14
|
+
const IMPLICIT_STATUS = { state: 'success', implicit: true };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { setEnvChanges } from '../env/changes.js';
|
|
2
|
+
import { addErrorInfo, isBuildError } from '../error/info.js';
|
|
3
|
+
import { updateNetlifyConfig, listConfigSideFiles } from './update_config.js';
|
|
4
|
+
// Fire a core step
|
|
5
|
+
export const fireCoreStep = async function ({ coreStep, coreStepId, coreStepName, configPath, buildDir, repositoryRoot, constants, buildbotServerSocket, events, logs, nodePath, childEnv, context, branch, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, featureFlags, debug, systemLog, saveConfig, }) {
|
|
6
|
+
try {
|
|
7
|
+
const configSideFiles = await listConfigSideFiles([headersPath, redirectsPath]);
|
|
8
|
+
const childEnvA = setEnvChanges(envChanges, { ...childEnv });
|
|
9
|
+
const { newEnvChanges = {}, configMutations: newConfigMutations = [], tags, } = await coreStep({
|
|
10
|
+
configPath,
|
|
11
|
+
buildDir,
|
|
12
|
+
repositoryRoot,
|
|
13
|
+
constants,
|
|
14
|
+
buildbotServerSocket,
|
|
15
|
+
events,
|
|
16
|
+
logs,
|
|
17
|
+
context,
|
|
18
|
+
branch,
|
|
19
|
+
childEnv: childEnvA,
|
|
20
|
+
netlifyConfig,
|
|
21
|
+
nodePath,
|
|
22
|
+
configMutations,
|
|
23
|
+
headersPath,
|
|
24
|
+
redirectsPath,
|
|
25
|
+
featureFlags,
|
|
26
|
+
debug,
|
|
27
|
+
systemLog,
|
|
28
|
+
saveConfig,
|
|
29
|
+
});
|
|
30
|
+
const { netlifyConfig: netlifyConfigA, configMutations: configMutationsA, headersPath: headersPathA, redirectsPath: redirectsPathA, } = await updateNetlifyConfig({
|
|
31
|
+
configOpts,
|
|
32
|
+
netlifyConfig,
|
|
33
|
+
headersPath,
|
|
34
|
+
redirectsPath,
|
|
35
|
+
configMutations,
|
|
36
|
+
newConfigMutations,
|
|
37
|
+
configSideFiles,
|
|
38
|
+
errorParams,
|
|
39
|
+
logs,
|
|
40
|
+
debug,
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
newEnvChanges,
|
|
44
|
+
netlifyConfig: netlifyConfigA,
|
|
45
|
+
configMutations: configMutationsA,
|
|
46
|
+
headersPath: headersPathA,
|
|
47
|
+
redirectsPath: redirectsPathA,
|
|
48
|
+
tags,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
catch (newError) {
|
|
52
|
+
if (!isBuildError(newError)) {
|
|
53
|
+
addErrorInfo(newError, { type: 'coreStep', location: { coreStepName } });
|
|
54
|
+
}
|
|
55
|
+
// always add the current stage
|
|
56
|
+
addErrorInfo(newError, { stage: coreStepId });
|
|
57
|
+
return { newError };
|
|
58
|
+
}
|
|
59
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { cancelBuild } from '../error/cancel.js';
|
|
2
|
+
import { handleBuildError } from '../error/handle.js';
|
|
3
|
+
import { getFullErrorInfo, parseErrorInfo } from '../error/parse/parse.js';
|
|
4
|
+
import { serializeErrorStatus } from '../error/parse/serialize_status.js';
|
|
5
|
+
import { isSoftFailEvent } from '../plugins/events.js';
|
|
6
|
+
// Handle build command errors and plugin errors:
|
|
7
|
+
// - usually, propagate the error to make the build stop.
|
|
8
|
+
// - `utils.build.cancelBuild()` also cancels the build by calling the API
|
|
9
|
+
// - `utils.build.failPlugin()` or post-deploy errors do not make the build
|
|
10
|
+
// stop, but are still reported, and prevent future events from the same
|
|
11
|
+
// plugin.
|
|
12
|
+
// This also computes error statuses that are sent to the API.
|
|
13
|
+
export const handleStepError = function ({ event, newError, childEnv, mode, api, errorMonitor, deployId, coreStep, netlifyConfig, logs, debug, testOpts, }) {
|
|
14
|
+
// Core steps do not report error statuses
|
|
15
|
+
if (coreStep !== undefined) {
|
|
16
|
+
return { newError };
|
|
17
|
+
}
|
|
18
|
+
const fullErrorInfo = getFullErrorInfo({ error: newError, colors: false, debug });
|
|
19
|
+
const { type } = fullErrorInfo;
|
|
20
|
+
if (type === 'failPlugin' || isSoftFailEvent(event)) {
|
|
21
|
+
return handleFailPlugin({
|
|
22
|
+
fullErrorInfo,
|
|
23
|
+
newError,
|
|
24
|
+
childEnv,
|
|
25
|
+
mode,
|
|
26
|
+
errorMonitor,
|
|
27
|
+
netlifyConfig,
|
|
28
|
+
logs,
|
|
29
|
+
debug,
|
|
30
|
+
testOpts,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (type === 'cancelBuild') {
|
|
34
|
+
return handleCancelBuild({ fullErrorInfo, newError, api, deployId });
|
|
35
|
+
}
|
|
36
|
+
return handleFailBuild({ fullErrorInfo, newError });
|
|
37
|
+
};
|
|
38
|
+
// On `utils.build.failPlugin()` or during `onSuccess` or `onEnd`
|
|
39
|
+
const handleFailPlugin = async function ({ fullErrorInfo, fullErrorInfo: { errorInfo: { location: { packageName } = {} }, }, newError, childEnv, mode, errorMonitor, netlifyConfig, logs, debug, testOpts, }) {
|
|
40
|
+
const newStatus = serializeErrorStatus({ fullErrorInfo, state: 'failed_plugin' });
|
|
41
|
+
await handleBuildError(newError, { errorMonitor, netlifyConfig, childEnv, mode, logs, debug, testOpts });
|
|
42
|
+
return { failedPlugin: [packageName], newStatus };
|
|
43
|
+
};
|
|
44
|
+
// On `utils.build.cancelBuild()`
|
|
45
|
+
const handleCancelBuild = async function ({ fullErrorInfo, newError, api, deployId }) {
|
|
46
|
+
const newStatus = serializeErrorStatus({ fullErrorInfo, state: 'canceled_build' });
|
|
47
|
+
await cancelBuild({ api, deployId });
|
|
48
|
+
return { newError, newStatus };
|
|
49
|
+
};
|
|
50
|
+
// On `utils.build.failBuild()` or uncaught exception
|
|
51
|
+
const handleFailBuild = function ({ fullErrorInfo, newError }) {
|
|
52
|
+
const newStatus = serializeErrorStatus({ fullErrorInfo, state: 'failed_build' });
|
|
53
|
+
return { newError, newStatus };
|
|
54
|
+
};
|
|
55
|
+
// Unlike community plugins, core plugin bugs should be handled as system errors
|
|
56
|
+
export const getPluginErrorType = function (error, loadedFrom) {
|
|
57
|
+
if (!isCorePluginBug(error, loadedFrom)) {
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
return { type: 'corePlugin' };
|
|
61
|
+
};
|
|
62
|
+
const isCorePluginBug = function (error, loadedFrom) {
|
|
63
|
+
const { severity } = parseErrorInfo(error);
|
|
64
|
+
return severity === 'warning' && loadedFrom === 'core';
|
|
65
|
+
};
|
package/lib/steps/get.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { DEV_EVENTS, EVENTS } from '../plugins/events.js';
|
|
2
|
+
import { buildCommandCore } from '../plugins_core/build_command.js';
|
|
3
|
+
import { deploySite } from '../plugins_core/deploy/index.js';
|
|
4
|
+
import { bundleEdgeFunctions } from '../plugins_core/edge_functions/index.js';
|
|
5
|
+
import { bundleFunctions } from '../plugins_core/functions/index.js';
|
|
6
|
+
// Get all build steps
|
|
7
|
+
export const getSteps = function (steps) {
|
|
8
|
+
const stepsA = addCoreSteps(steps);
|
|
9
|
+
const stepsB = sortSteps(stepsA, EVENTS);
|
|
10
|
+
const events = getEvents(stepsB);
|
|
11
|
+
return { steps: stepsB, events };
|
|
12
|
+
};
|
|
13
|
+
// Get all dev steps
|
|
14
|
+
export const getDevSteps = function (command, steps) {
|
|
15
|
+
const devCommandStep = {
|
|
16
|
+
event: 'onDev',
|
|
17
|
+
coreStep: async () => {
|
|
18
|
+
await command();
|
|
19
|
+
return {};
|
|
20
|
+
},
|
|
21
|
+
coreStepId: 'dev_command',
|
|
22
|
+
coreStepName: 'dev.command',
|
|
23
|
+
coreStepDescription: () => 'Run command for local development',
|
|
24
|
+
};
|
|
25
|
+
const sortedSteps = sortSteps([...steps, devCommandStep], DEV_EVENTS);
|
|
26
|
+
const events = getEvents(sortedSteps);
|
|
27
|
+
return { steps: sortedSteps, events };
|
|
28
|
+
};
|
|
29
|
+
const addCoreSteps = function (steps) {
|
|
30
|
+
return [buildCommandCore, ...steps, bundleFunctions, bundleEdgeFunctions, deploySite];
|
|
31
|
+
};
|
|
32
|
+
// Sort plugin steps by event order.
|
|
33
|
+
const sortSteps = function (steps, events) {
|
|
34
|
+
return events.flatMap((event) => steps.filter((step) => step.event === event));
|
|
35
|
+
};
|
|
36
|
+
// Retrieve list of unique events
|
|
37
|
+
const getEvents = function (steps) {
|
|
38
|
+
const events = steps.map(getEvent);
|
|
39
|
+
return [...new Set(events)];
|
|
40
|
+
};
|
|
41
|
+
const getEvent = function ({ event }) {
|
|
42
|
+
return event;
|
|
43
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { addErrorInfo } from '../error/info.js';
|
|
2
|
+
import { logStepCompleted } from '../log/messages/ipc.js';
|
|
3
|
+
import { pipePluginOutput, unpipePluginOutput } from '../log/stream.js';
|
|
4
|
+
import { callChild } from '../plugins/ipc.js';
|
|
5
|
+
import { getSuccessStatus } from '../status/success.js';
|
|
6
|
+
import { getPluginErrorType } from './error.js';
|
|
7
|
+
import { updateNetlifyConfig, listConfigSideFiles } from './update_config.js';
|
|
8
|
+
// Fire a plugin step
|
|
9
|
+
export const firePluginStep = async function ({ event, childProcess, packageName, pluginPackageJson, loadedFrom, origin, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, constants, steps, error, logs, debug, verbose, }) {
|
|
10
|
+
const listeners = pipePluginOutput(childProcess, logs);
|
|
11
|
+
try {
|
|
12
|
+
const configSideFiles = await listConfigSideFiles([headersPath, redirectsPath]);
|
|
13
|
+
const { newEnvChanges, configMutations: newConfigMutations, status, } = await callChild({
|
|
14
|
+
childProcess,
|
|
15
|
+
eventName: 'run',
|
|
16
|
+
payload: { event, error, envChanges, netlifyConfig, constants },
|
|
17
|
+
logs,
|
|
18
|
+
verbose,
|
|
19
|
+
});
|
|
20
|
+
const { netlifyConfig: netlifyConfigA, configMutations: configMutationsA, headersPath: headersPathA, redirectsPath: redirectsPathA, } = await updateNetlifyConfig({
|
|
21
|
+
configOpts,
|
|
22
|
+
netlifyConfig,
|
|
23
|
+
headersPath,
|
|
24
|
+
redirectsPath,
|
|
25
|
+
configMutations,
|
|
26
|
+
newConfigMutations,
|
|
27
|
+
configSideFiles,
|
|
28
|
+
errorParams,
|
|
29
|
+
logs,
|
|
30
|
+
debug,
|
|
31
|
+
});
|
|
32
|
+
const newStatus = getSuccessStatus(status, { steps, event, packageName });
|
|
33
|
+
return {
|
|
34
|
+
newEnvChanges,
|
|
35
|
+
netlifyConfig: netlifyConfigA,
|
|
36
|
+
configMutations: configMutationsA,
|
|
37
|
+
headersPath: headersPathA,
|
|
38
|
+
redirectsPath: redirectsPathA,
|
|
39
|
+
newStatus,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch (newError) {
|
|
43
|
+
const errorType = getPluginErrorType(newError, loadedFrom);
|
|
44
|
+
addErrorInfo(newError, {
|
|
45
|
+
...errorType,
|
|
46
|
+
plugin: { pluginPackageJson, packageName },
|
|
47
|
+
location: { event, packageName, loadedFrom, origin },
|
|
48
|
+
});
|
|
49
|
+
return { newError };
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
await unpipePluginOutput(childProcess, logs, listeners);
|
|
53
|
+
logStepCompleted(logs, verbose);
|
|
54
|
+
}
|
|
55
|
+
};
|