@netlify/build 18.22.0 → 18.25.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.
- package/package.json +2 -2
- package/src/error/monitor/print.js +9 -1
- package/src/error/monitor/report.js +2 -2
- package/src/error/parse/parse.js +21 -2
- package/src/error/parse/serialize_log.js +5 -3
- package/src/log/messages/mutations.js +13 -2
- package/src/plugins/child/load.js +2 -2
- package/src/plugins/child/logic.js +6 -3
- package/src/plugins/child/typescript.js +26 -1
- package/src/plugins_core/functions/feature_flags.js +1 -1
- package/src/steps/update_config.js +1 -1
- package/types/config/inputs.d.ts +5 -1
- package/types/netlify_event_handler.d.ts +17 -7
- package/types/netlify_plugin_options.d.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/build",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.25.0",
|
|
4
4
|
"description": "Netlify build module",
|
|
5
5
|
"main": "src/core/main.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@netlify/plugin-edge-handlers": "^1.11.22",
|
|
62
62
|
"@netlify/plugins-list": "^4.2.0",
|
|
63
63
|
"@netlify/run-utils": "^2.0.0",
|
|
64
|
-
"@netlify/zip-it-and-ship-it": "^4.
|
|
64
|
+
"@netlify/zip-it-and-ship-it": "^4.30.0",
|
|
65
65
|
"@sindresorhus/slugify": "^1.1.0",
|
|
66
66
|
"@ungap/from-entries": "^0.2.1",
|
|
67
67
|
"ansi-escapes": "^4.3.2",
|
|
@@ -10,7 +10,14 @@ const printEventForTest = function (
|
|
|
10
10
|
groupingHash,
|
|
11
11
|
severity,
|
|
12
12
|
unhandled,
|
|
13
|
-
_metadata: {
|
|
13
|
+
_metadata: {
|
|
14
|
+
location,
|
|
15
|
+
plugin: { packageName, homepage } = {},
|
|
16
|
+
pluginPackageJson,
|
|
17
|
+
tsConfig,
|
|
18
|
+
env: { BUILD_ID } = {},
|
|
19
|
+
other,
|
|
20
|
+
},
|
|
14
21
|
},
|
|
15
22
|
logs,
|
|
16
23
|
) {
|
|
@@ -26,6 +33,7 @@ const printEventForTest = function (
|
|
|
26
33
|
packageName,
|
|
27
34
|
pluginPackageJson: pluginPackageJson !== undefined,
|
|
28
35
|
homepage,
|
|
36
|
+
tsConfig,
|
|
29
37
|
BUILD_ID,
|
|
30
38
|
other,
|
|
31
39
|
},
|
|
@@ -60,11 +60,11 @@ const getGroupingHash = function (group, error, type) {
|
|
|
60
60
|
return `${group}\n${messageA}`
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
const getMetadata = function ({ location, plugin }, childEnv, groupingHash) {
|
|
63
|
+
const getMetadata = function ({ location, plugin, tsConfig }, childEnv, groupingHash) {
|
|
64
64
|
const pluginMetadata = getPluginMetadata({ location, plugin })
|
|
65
65
|
const envMetadata = getEnvMetadata(childEnv)
|
|
66
66
|
const locationMetadata = getLocationMetadata(location, envMetadata)
|
|
67
|
-
return { location: locationMetadata, ...pluginMetadata, env: envMetadata, other: { groupingHash } }
|
|
67
|
+
return { location: locationMetadata, ...pluginMetadata, tsConfig, env: envMetadata, other: { groupingHash } }
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
const getPluginMetadata = function ({ location, plugin }) {
|
package/src/error/parse/parse.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { serializeObject } = require('../../log/serialize')
|
|
3
4
|
const { getErrorInfo } = require('../info')
|
|
4
5
|
const { getTypeInfo } = require('../type')
|
|
5
6
|
|
|
@@ -17,7 +18,7 @@ const getFullErrorInfo = function ({ error, colors, debug }) {
|
|
|
17
18
|
stack,
|
|
18
19
|
errorProps,
|
|
19
20
|
errorInfo,
|
|
20
|
-
errorInfo: { location = {}, plugin = {} },
|
|
21
|
+
errorInfo: { location = {}, plugin = {}, tsConfig },
|
|
21
22
|
severity,
|
|
22
23
|
title,
|
|
23
24
|
stackType,
|
|
@@ -31,10 +32,28 @@ const getFullErrorInfo = function ({ error, colors, debug }) {
|
|
|
31
32
|
const { message: messageA, stack: stackA } = getStackInfo({ message, stack, stackType, rawStack, severity, debug })
|
|
32
33
|
|
|
33
34
|
const pluginInfo = getPluginInfo(plugin, location)
|
|
35
|
+
const tsConfigInfo = getTsConfigInfo(tsConfig)
|
|
34
36
|
const locationInfo = getLocationInfo({ stack: stackA, location, locationType })
|
|
35
37
|
const errorPropsA = getErrorProps({ errorProps, showErrorProps, colors })
|
|
36
38
|
|
|
37
|
-
return {
|
|
39
|
+
return {
|
|
40
|
+
...basicErrorInfo,
|
|
41
|
+
title: titleA,
|
|
42
|
+
message: messageA,
|
|
43
|
+
tsConfigInfo,
|
|
44
|
+
pluginInfo,
|
|
45
|
+
locationInfo,
|
|
46
|
+
errorProps: errorPropsA,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Serialize the `tsConfig` error information
|
|
51
|
+
const getTsConfigInfo = function (tsConfig) {
|
|
52
|
+
if (tsConfig === undefined) {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return serializeObject(tsConfig)
|
|
38
57
|
}
|
|
39
58
|
|
|
40
59
|
// Parse error instance into all the basic properties containing information
|
|
@@ -4,19 +4,20 @@ const { THEME } = require('../../log/theme')
|
|
|
4
4
|
|
|
5
5
|
// Serialize an error object into a title|body string to print in logs
|
|
6
6
|
const serializeLogError = function ({
|
|
7
|
-
fullErrorInfo: { title, severity, message, pluginInfo, locationInfo, errorProps },
|
|
7
|
+
fullErrorInfo: { title, severity, message, pluginInfo, locationInfo, tsConfigInfo, errorProps },
|
|
8
8
|
}) {
|
|
9
|
-
const body = getBody({ message, pluginInfo, locationInfo, errorProps, severity })
|
|
9
|
+
const body = getBody({ message, pluginInfo, locationInfo, tsConfigInfo, errorProps, severity })
|
|
10
10
|
return { title, body }
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const getBody = function ({ message, pluginInfo, locationInfo, errorProps, severity }) {
|
|
13
|
+
const getBody = function ({ message, pluginInfo, locationInfo, tsConfigInfo, errorProps, severity }) {
|
|
14
14
|
if (severity === 'none') {
|
|
15
15
|
return message
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
return Object.entries({
|
|
19
19
|
message,
|
|
20
|
+
tsConfigInfo,
|
|
20
21
|
pluginInfo,
|
|
21
22
|
locationInfo,
|
|
22
23
|
errorProps,
|
|
@@ -38,6 +39,7 @@ const LOG_BLOCK_NAMES = {
|
|
|
38
39
|
message: 'Error message',
|
|
39
40
|
pluginInfo: 'Plugin details',
|
|
40
41
|
locationInfo: 'Error location',
|
|
42
|
+
tsConfigInfo: 'TypeScript configuration',
|
|
41
43
|
errorProps: 'Error properties',
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -9,12 +9,23 @@ const { log, logMessage, logSubHeader } = require('../logger')
|
|
|
9
9
|
|
|
10
10
|
const pReadFile = promisify(readFile)
|
|
11
11
|
|
|
12
|
-
const logConfigMutations = function (logs, newConfigMutations) {
|
|
13
|
-
|
|
12
|
+
const logConfigMutations = function (logs, newConfigMutations, debug) {
|
|
13
|
+
const configMutationsToLog = debug ? newConfigMutations : newConfigMutations.filter(shouldLogConfigMutation)
|
|
14
|
+
configMutationsToLog.forEach(({ keysString, value }) => {
|
|
14
15
|
logConfigMutation(logs, keysString, value)
|
|
15
16
|
})
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
// Some configuration mutations are only logged in debug mode
|
|
20
|
+
const shouldLogConfigMutation = function ({ keysString }) {
|
|
21
|
+
return !HIDDEN_PROPS.some((hiddenProp) => keysString.startsWith(hiddenProp))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// `functions` is an object which can have thousands of properties, one per
|
|
25
|
+
// function file. This can be very verbose, especially for plugins which create
|
|
26
|
+
// many function files like Essential Next.js
|
|
27
|
+
const HIDDEN_PROPS = ['functions']
|
|
28
|
+
|
|
18
29
|
const logConfigMutation = function (logs, keysString, value) {
|
|
19
30
|
const newValue = shouldHideConfigValue(keysString) ? '' : ` to ${inspect(value, { colors: false })}`
|
|
20
31
|
log(logs, `Netlify configuration property "${keysString}" value changed${newValue}.`)
|
|
@@ -9,9 +9,9 @@ const { validatePlugin } = require('./validate')
|
|
|
9
9
|
// This also validates the plugin.
|
|
10
10
|
// Do it when parent requests it using the `load` event.
|
|
11
11
|
// Also figure out the list of plugin steps. This is also passed to the parent.
|
|
12
|
-
const load = function ({ pluginPath, inputs, packageJson }) {
|
|
12
|
+
const load = async function ({ pluginPath, inputs, packageJson }) {
|
|
13
13
|
registerTypeScript(pluginPath)
|
|
14
|
-
const logic = getLogic({ pluginPath, inputs })
|
|
14
|
+
const logic = await getLogic({ pluginPath, inputs })
|
|
15
15
|
|
|
16
16
|
validatePlugin(logic)
|
|
17
17
|
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { addTsErrorInfo } = require('./typescript')
|
|
4
|
+
|
|
3
5
|
// Require the plugin file and fire its top-level function.
|
|
4
6
|
// The returned object is the `logic` which includes all event handlers.
|
|
5
|
-
const getLogic = function ({ pluginPath, inputs }) {
|
|
6
|
-
const logic = requireLogic(pluginPath)
|
|
7
|
+
const getLogic = async function ({ pluginPath, inputs }) {
|
|
8
|
+
const logic = await requireLogic(pluginPath)
|
|
7
9
|
const logicA = loadLogic({ logic, inputs })
|
|
8
10
|
return logicA
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
const requireLogic = function (pluginPath) {
|
|
13
|
+
const requireLogic = async function (pluginPath) {
|
|
12
14
|
try {
|
|
13
15
|
// eslint-disable-next-line node/global-require, import/no-dynamic-require
|
|
14
16
|
return require(pluginPath)
|
|
15
17
|
} catch (error) {
|
|
18
|
+
await addTsErrorInfo(error, pluginPath)
|
|
16
19
|
error.message = `Could not import plugin:\n${error.message}`
|
|
17
20
|
throw error
|
|
18
21
|
}
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const { extname } = require('path')
|
|
4
4
|
|
|
5
|
+
const execa = require('execa')
|
|
5
6
|
const { register } = require('ts-node')
|
|
6
7
|
|
|
8
|
+
const { addErrorInfo } = require('../../error/info')
|
|
9
|
+
|
|
7
10
|
// Allow local plugins to be written with TypeScript.
|
|
8
11
|
// Local plugins cannot be transpiled by the build command since they can be run
|
|
9
12
|
// before it. Therefore, we type-check and transpile them automatically using
|
|
@@ -16,10 +19,32 @@ const registerTypeScript = function (pluginPath) {
|
|
|
16
19
|
register()
|
|
17
20
|
}
|
|
18
21
|
|
|
22
|
+
// On TypeScript errors, adds information about the `ts-node` configuration,
|
|
23
|
+
// which includes the resolved `tsconfig.json`.
|
|
24
|
+
const addTsErrorInfo = async function (error, pluginPath) {
|
|
25
|
+
if (!isTypeScriptPlugin(pluginPath)) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { stdout } = await execa.command('ts-node --show-config')
|
|
30
|
+
const tsConfig = safeJsonParse(stdout)
|
|
31
|
+
addErrorInfo(error, { tsConfig })
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// The output of `ts-node --show-config` should be JSON.
|
|
35
|
+
// This is just a failsafe.
|
|
36
|
+
const safeJsonParse = function (stdout) {
|
|
37
|
+
try {
|
|
38
|
+
return JSON.parse(stdout)
|
|
39
|
+
} catch (error) {
|
|
40
|
+
return { stdout, parsingError: error.message }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
19
44
|
const isTypeScriptPlugin = function (pluginPath) {
|
|
20
45
|
return TYPESCRIPT_EXTENSIONS.has(extname(pluginPath))
|
|
21
46
|
}
|
|
22
47
|
|
|
23
48
|
const TYPESCRIPT_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts'])
|
|
24
49
|
|
|
25
|
-
module.exports = { registerTypeScript }
|
|
50
|
+
module.exports = { registerTypeScript, addTsErrorInfo }
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const getZisiFeatureFlags = (featureFlags) => ({
|
|
4
4
|
buildGoSource: featureFlags.buildbot_build_go_functions,
|
|
5
5
|
defaultEsModulesToEsbuild: featureFlags.buildbot_es_modules_esbuild,
|
|
6
|
-
nftTranspile: featureFlags.buildbot_zisi_trace_nft,
|
|
6
|
+
nftTranspile: featureFlags.buildbot_nft_transpile_esm || featureFlags.buildbot_zisi_trace_nft,
|
|
7
7
|
parseWithEsbuild: featureFlags.buildbot_zisi_esbuild_parser,
|
|
8
8
|
traceWithNft: featureFlags.buildbot_zisi_trace_nft,
|
|
9
9
|
})
|
|
@@ -29,7 +29,7 @@ const updateNetlifyConfig = async function ({
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
validateConfigMutations(newConfigMutations)
|
|
32
|
-
logConfigMutations(logs, newConfigMutations)
|
|
32
|
+
logConfigMutations(logs, newConfigMutations, debug)
|
|
33
33
|
const configMutationsA = [...configMutations, ...newConfigMutations]
|
|
34
34
|
const {
|
|
35
35
|
config: netlifyConfigA,
|
package/types/config/inputs.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { JSONValue } from '../utils/json_value'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// Helper type to be used as a workaround for the fact that `interface`s don't have implicit
|
|
4
|
+
// index signatures: https://github.com/microsoft/TypeScript/issues/15300
|
|
5
|
+
export type StringKeys<TObject extends object> = keyof TObject & string
|
|
6
|
+
|
|
7
|
+
export type PluginInputs<Keys extends string = string> = Partial<Record<Keys, JSONValue>>
|
|
@@ -1,19 +1,29 @@
|
|
|
1
|
-
import { PluginInputs } from './config/inputs'
|
|
1
|
+
import { PluginInputs, StringKeys } from './config/inputs'
|
|
2
2
|
import { NetlifyPluginOptions } from './netlify_plugin_options'
|
|
3
3
|
|
|
4
4
|
interface NetlifyEventHandler<PluginOptions extends NetlifyPluginOptions = NetlifyPluginOptions> {
|
|
5
5
|
(options: PluginOptions): void | Promise<void>
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
// To allow interfaces to be used as generics, since they lack implicit index signatures, we have to do some type shenanigans
|
|
9
|
+
// to get TypeScript to behave as we want - only letting the keys of `TInputs` through, and thus not requiring a full index
|
|
10
|
+
// signature on `TInputs`.
|
|
11
|
+
// Related issues: https://github.com/microsoft/TypeScript/issues/15300, https://github.com/netlify/build/issues/3838
|
|
12
|
+
export type OnPreBuild<TInputs extends PluginInputs<StringKeys<TInputs>> = PluginInputs> = NetlifyEventHandler<
|
|
11
13
|
NetlifyPluginOptions<TInputs>
|
|
12
14
|
>
|
|
13
|
-
export type
|
|
15
|
+
export type OnBuild<TInputs extends PluginInputs<StringKeys<TInputs>> = PluginInputs> = NetlifyEventHandler<
|
|
16
|
+
NetlifyPluginOptions<TInputs>
|
|
17
|
+
>
|
|
18
|
+
export type OnPostBuild<TInputs extends PluginInputs<StringKeys<TInputs>> = PluginInputs> = NetlifyEventHandler<
|
|
19
|
+
NetlifyPluginOptions<TInputs>
|
|
20
|
+
>
|
|
21
|
+
export type OnError<TInputs extends PluginInputs<StringKeys<TInputs>> = PluginInputs> = NetlifyEventHandler<
|
|
14
22
|
NetlifyPluginOptions<TInputs> & { error: Error }
|
|
15
23
|
>
|
|
16
|
-
export type OnSuccess<TInputs extends PluginInputs = PluginInputs> = NetlifyEventHandler<
|
|
17
|
-
|
|
24
|
+
export type OnSuccess<TInputs extends PluginInputs<StringKeys<TInputs>> = PluginInputs> = NetlifyEventHandler<
|
|
25
|
+
NetlifyPluginOptions<TInputs>
|
|
26
|
+
>
|
|
27
|
+
export type OnEnd<TInputs extends PluginInputs<StringKeys<TInputs>> = PluginInputs> = NetlifyEventHandler<
|
|
18
28
|
NetlifyPluginOptions<TInputs> & { error?: Error }
|
|
19
29
|
>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { PluginInputs } from './config/inputs'
|
|
1
|
+
import { PluginInputs, StringKeys } from './config/inputs'
|
|
2
2
|
import { NetlifyConfig } from './config/netlify_config'
|
|
3
3
|
import { NetlifyPluginConstants } from './netlify_plugin_constants'
|
|
4
4
|
import { NetlifyPluginUtils } from './options/netlify_plugin_utils'
|
|
5
5
|
import { JSONValue } from './utils/json_value'
|
|
6
6
|
|
|
7
|
-
export interface NetlifyPluginOptions<TInputs extends PluginInputs = PluginInputs> {
|
|
7
|
+
export interface NetlifyPluginOptions<TInputs extends PluginInputs<StringKeys<TInputs>> = PluginInputs> {
|
|
8
8
|
/**
|
|
9
9
|
* If your plugin requires additional values from the user, you can specify these requirements in an `inputs` array in the plugin’s [`manifest.yml` file](https://docs.netlify.com/configure-builds/build-plugins/create-plugins/#anatomy-of-a-plugin).
|
|
10
10
|
*/
|