@netlify/build 0.4.48 → 1.0.0-dl-test

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 (243) hide show
  1. package/bin.js +5 -0
  2. package/lib/core/bin.js +66 -0
  3. package/lib/core/build.js +392 -0
  4. package/lib/core/config.js +124 -0
  5. package/lib/core/constants.js +116 -0
  6. package/lib/core/dev.js +27 -0
  7. package/lib/core/dry.js +21 -0
  8. package/lib/core/feature_flags.js +17 -0
  9. package/lib/core/flags.js +206 -0
  10. package/lib/core/lingering.js +68 -0
  11. package/lib/core/main.js +114 -0
  12. package/lib/core/missing_side_file.js +17 -0
  13. package/lib/core/normalize_flags.js +62 -0
  14. package/lib/core/report_metrics.js +17 -0
  15. package/lib/core/severity.js +21 -0
  16. package/lib/core/types.js +8 -0
  17. package/lib/core/user_node_version.js +32 -0
  18. package/lib/env/changes.js +43 -0
  19. package/lib/env/main.js +14 -0
  20. package/lib/env/metadata.js +68 -0
  21. package/lib/error/api.js +37 -0
  22. package/lib/error/build.js +36 -0
  23. package/lib/error/cancel.js +7 -0
  24. package/lib/error/colors.js +9 -0
  25. package/lib/error/handle.js +44 -0
  26. package/lib/error/info.js +37 -0
  27. package/lib/error/monitor/location.js +16 -0
  28. package/lib/error/monitor/normalize.js +86 -0
  29. package/lib/error/monitor/print.js +20 -0
  30. package/lib/error/monitor/report.js +120 -0
  31. package/lib/error/monitor/start.js +61 -0
  32. package/lib/error/parse/clean_stack.js +70 -0
  33. package/lib/error/parse/location.js +50 -0
  34. package/lib/error/parse/normalize.js +24 -0
  35. package/lib/error/parse/parse.js +67 -0
  36. package/lib/error/parse/plugin.js +55 -0
  37. package/lib/error/parse/properties.js +16 -0
  38. package/lib/error/parse/serialize_log.js +34 -0
  39. package/lib/error/parse/serialize_status.js +18 -0
  40. package/lib/error/parse/stack.js +34 -0
  41. package/lib/error/report.js +29 -0
  42. package/lib/error/type.js +177 -0
  43. package/lib/install/functions.js +20 -0
  44. package/lib/install/local.js +45 -0
  45. package/lib/install/main.js +67 -0
  46. package/lib/install/missing.js +54 -0
  47. package/lib/log/colors.js +28 -0
  48. package/lib/log/description.js +21 -0
  49. package/lib/log/header.js +12 -0
  50. package/lib/log/header_func.js +13 -0
  51. package/lib/log/logger.js +140 -0
  52. package/lib/log/messages/compatibility.js +120 -0
  53. package/lib/log/messages/config.js +91 -0
  54. package/lib/log/messages/core.js +49 -0
  55. package/lib/log/messages/core_steps.js +75 -0
  56. package/lib/log/messages/dry.js +41 -0
  57. package/lib/log/messages/install.js +25 -0
  58. package/lib/log/messages/ipc.js +29 -0
  59. package/lib/log/messages/mutations.js +62 -0
  60. package/lib/log/messages/plugins.js +25 -0
  61. package/lib/log/messages/status.js +14 -0
  62. package/lib/log/messages/steps.js +18 -0
  63. package/lib/log/serialize.js +10 -0
  64. package/lib/log/stream.js +68 -0
  65. package/lib/log/theme.js +27 -0
  66. package/lib/plugins/child/diff.js +46 -0
  67. package/lib/plugins/child/error.js +26 -0
  68. package/lib/plugins/child/lazy.js +15 -0
  69. package/lib/plugins/child/load.js +22 -0
  70. package/lib/plugins/child/logic.js +57 -0
  71. package/lib/plugins/child/main.js +37 -0
  72. package/lib/plugins/child/run.js +19 -0
  73. package/lib/plugins/child/status.js +63 -0
  74. package/lib/plugins/child/typescript.js +28 -0
  75. package/lib/plugins/child/utils.js +42 -0
  76. package/lib/plugins/child/validate.js +31 -0
  77. package/lib/plugins/compatibility.js +104 -0
  78. package/lib/plugins/error.js +46 -0
  79. package/lib/plugins/events.js +12 -0
  80. package/lib/plugins/expected_version.js +81 -0
  81. package/lib/plugins/internal.js +10 -0
  82. package/lib/plugins/ipc.js +120 -0
  83. package/lib/plugins/list.js +73 -0
  84. package/lib/plugins/load.js +50 -0
  85. package/lib/plugins/manifest/check.js +85 -0
  86. package/lib/plugins/manifest/load.js +38 -0
  87. package/lib/plugins/manifest/main.js +19 -0
  88. package/lib/plugins/manifest/path.js +24 -0
  89. package/lib/plugins/manifest/validate.js +91 -0
  90. package/lib/plugins/node_version.js +35 -0
  91. package/lib/plugins/options.js +70 -0
  92. package/lib/plugins/pinned_version.js +83 -0
  93. package/lib/plugins/resolve.js +110 -0
  94. package/lib/plugins/spawn.js +55 -0
  95. package/lib/plugins_core/add.js +35 -0
  96. package/lib/plugins_core/build_command.js +50 -0
  97. package/lib/plugins_core/deploy/buildbot_client.js +87 -0
  98. package/lib/plugins_core/deploy/index.js +49 -0
  99. package/lib/plugins_core/deploy/manifest.yml +1 -0
  100. package/lib/plugins_core/edge_functions/index.js +106 -0
  101. package/lib/plugins_core/edge_functions/lib/error.js +17 -0
  102. package/lib/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.js +14 -0
  103. package/lib/plugins_core/functions/error.js +123 -0
  104. package/lib/plugins_core/functions/feature_flags.js +5 -0
  105. package/lib/plugins_core/functions/index.js +137 -0
  106. package/lib/plugins_core/functions/utils.js +45 -0
  107. package/lib/plugins_core/functions/zisi.js +64 -0
  108. package/lib/plugins_core/functions_install/index.js +10 -0
  109. package/lib/plugins_core/list.js +20 -0
  110. package/lib/plugins_core/save_artifacts/index.js +33 -0
  111. package/lib/report/statsd.js +56 -0
  112. package/lib/status/add.js +30 -0
  113. package/lib/status/colors.js +18 -0
  114. package/lib/status/load_error.js +10 -0
  115. package/lib/status/report.js +83 -0
  116. package/lib/status/success.js +14 -0
  117. package/lib/steps/core_step.js +62 -0
  118. package/lib/steps/error.js +65 -0
  119. package/lib/steps/get.js +44 -0
  120. package/lib/steps/plugin.js +55 -0
  121. package/lib/steps/return.js +27 -0
  122. package/lib/steps/run_core_steps.js +117 -0
  123. package/lib/steps/run_step.js +200 -0
  124. package/lib/steps/run_steps.js +102 -0
  125. package/lib/steps/update_config.js +66 -0
  126. package/lib/telemetry/main.js +94 -0
  127. package/lib/time/aggregate.js +109 -0
  128. package/lib/time/main.js +31 -0
  129. package/lib/time/measure.js +16 -0
  130. package/lib/time/report.js +30 -0
  131. package/lib/utils/errors.js +13 -0
  132. package/lib/utils/json.js +10 -0
  133. package/lib/utils/omit.js +3 -0
  134. package/lib/utils/package.js +24 -0
  135. package/lib/utils/remove_falsy.js +8 -0
  136. package/lib/utils/resolve.js +41 -0
  137. package/lib/utils/runtime.js +5 -0
  138. package/lib/utils/semver.js +28 -0
  139. package/package.json +119 -56
  140. package/types/config/build.d.ts +52 -0
  141. package/types/config/functions.d.ts +36 -0
  142. package/types/config/inputs.d.ts +7 -0
  143. package/types/config/netlify_config.d.ts +58 -0
  144. package/types/index.d.ts +7 -0
  145. package/types/netlify_event_handler.d.ts +29 -0
  146. package/types/netlify_plugin.d.ts +29 -0
  147. package/types/netlify_plugin_constants.d.ts +51 -0
  148. package/types/netlify_plugin_options.d.ts +23 -0
  149. package/types/options/index.d.ts +1 -0
  150. package/types/options/netlify_plugin_build_util.d.ts +7 -0
  151. package/types/options/netlify_plugin_cache_util.d.ts +39 -0
  152. package/types/options/netlify_plugin_functions_util.d.ts +32 -0
  153. package/types/options/netlify_plugin_git_util.d.ts +41 -0
  154. package/types/options/netlify_plugin_run_util.d.ts +24 -0
  155. package/types/options/netlify_plugin_status_util.d.ts +24 -0
  156. package/types/options/netlify_plugin_utils.d.ts +15 -0
  157. package/types/utils/json_value.d.ts +1 -0
  158. package/types/utils/many.d.ts +6 -0
  159. package/README.md +0 -3
  160. package/src/core/bin.js +0 -139
  161. package/src/core/commands.js +0 -304
  162. package/src/core/config.js +0 -130
  163. package/src/core/constants.js +0 -88
  164. package/src/core/dry.js +0 -23
  165. package/src/core/main.js +0 -196
  166. package/src/env/changes.js +0 -49
  167. package/src/env/git.js +0 -27
  168. package/src/env/main.js +0 -97
  169. package/src/env/metadata.js +0 -81
  170. package/src/error/api.js +0 -32
  171. package/src/error/build.js +0 -32
  172. package/src/error/cancel.js +0 -22
  173. package/src/error/colors.js +0 -13
  174. package/src/error/info.js +0 -12
  175. package/src/error/monitor/normalize.js +0 -50
  176. package/src/error/monitor/print.js +0 -43
  177. package/src/error/monitor/report.js +0 -140
  178. package/src/error/monitor/start.js +0 -50
  179. package/src/error/parse/clean_stack.js +0 -86
  180. package/src/error/parse/location.js +0 -50
  181. package/src/error/parse/parse.js +0 -87
  182. package/src/error/parse/plugin.js +0 -68
  183. package/src/error/parse/properties.js +0 -20
  184. package/src/error/parse/serialize_log.js +0 -46
  185. package/src/error/parse/serialize_status.js +0 -28
  186. package/src/error/parse/stack.js +0 -45
  187. package/src/error/process.js +0 -13
  188. package/src/error/type.js +0 -143
  189. package/src/install/functions.js +0 -52
  190. package/src/install/local.js +0 -65
  191. package/src/install/main.js +0 -103
  192. package/src/install/missing.js +0 -86
  193. package/src/log/colors.js +0 -59
  194. package/src/log/description.js +0 -38
  195. package/src/log/header.js +0 -19
  196. package/src/log/logger.js +0 -55
  197. package/src/log/main.js +0 -348
  198. package/src/log/old_version.js +0 -45
  199. package/src/log/serialize.js +0 -15
  200. package/src/log/stream.js +0 -15
  201. package/src/log/theme.js +0 -32
  202. package/src/log/timer.js +0 -28
  203. package/src/plugins/child/api.js +0 -59
  204. package/src/plugins/child/error.js +0 -39
  205. package/src/plugins/child/load.js +0 -40
  206. package/src/plugins/child/logic.js +0 -31
  207. package/src/plugins/child/main.js +0 -48
  208. package/src/plugins/child/normalize.js +0 -20
  209. package/src/plugins/child/run.js +0 -34
  210. package/src/plugins/child/status.js +0 -53
  211. package/src/plugins/child/utils.js +0 -43
  212. package/src/plugins/child/validate.js +0 -46
  213. package/src/plugins/error.js +0 -44
  214. package/src/plugins/events.js +0 -77
  215. package/src/plugins/ipc.js +0 -136
  216. package/src/plugins/load.js +0 -66
  217. package/src/plugins/manifest/check.js +0 -80
  218. package/src/plugins/manifest/load.js +0 -47
  219. package/src/plugins/manifest/main.js +0 -28
  220. package/src/plugins/manifest/path.js +0 -12
  221. package/src/plugins/manifest/validate.js +0 -136
  222. package/src/plugins/node_version.js +0 -74
  223. package/src/plugins/options.js +0 -78
  224. package/src/plugins/package.js +0 -17
  225. package/src/plugins/resolve.js +0 -159
  226. package/src/plugins/spawn.js +0 -82
  227. package/src/plugins_core/cache/manifest.yml +0 -1
  228. package/src/plugins_core/cache/plugin.js +0 -75
  229. package/src/plugins_core/functions/manifest.yml +0 -1
  230. package/src/plugins_core/functions/plugin.js +0 -37
  231. package/src/plugins_core/functions_install/plugin.js +0 -14
  232. package/src/plugins_core/main.js +0 -38
  233. package/src/status/add.js +0 -56
  234. package/src/status/colors.js +0 -25
  235. package/src/status/report.js +0 -57
  236. package/src/telemetry/complete.js +0 -49
  237. package/src/telemetry/request.js +0 -28
  238. package/src/telemetry/track.js +0 -33
  239. package/src/utils/omit.js +0 -8
  240. package/src/utils/polyfills.js +0 -3
  241. package/src/utils/remove_falsy.js +0 -12
  242. package/src/utils/resolve.js +0 -39
  243. /package/{src → lib}/plugins_core/functions_install/manifest.yml +0 -0
@@ -1,48 +0,0 @@
1
- require('../../utils/polyfills')
2
-
3
- // This needs to be done before `chalk` is loaded
4
- // Note: `chalk` is also required by some of our dependencies.
5
- // eslint-disable-next-line import/order
6
- const { setColorLevel } = require('../../log/colors')
7
- setColorLevel()
8
-
9
- const { sendEventToParent, getEventsFromParent } = require('../ipc')
10
-
11
- const { handleProcessErrors, handleError } = require('./error')
12
- const { load } = require('./load')
13
- const { run } = require('./run')
14
-
15
- // Boot plugin child process.
16
- const bootPlugin = async function() {
17
- try {
18
- handleProcessErrors()
19
-
20
- const state = {}
21
- // We need to fire them in parallel because `process.send()` can be slow
22
- // to await, i.e. parent might send `load` event before child `ready` event
23
- // returns.
24
- await Promise.all([handleEvents(state), sendEventToParent('ready')])
25
- } catch (error) {
26
- await handleError(error)
27
- }
28
- }
29
-
30
- // Wait for events from parent to perform plugin methods
31
- const handleEvents = async function(state) {
32
- await getEventsFromParent((callId, eventName, payload) => handleEvent(callId, eventName, payload, state))
33
- }
34
-
35
- // Each event can pass `context` information to the next event
36
- const handleEvent = async function(callId, eventName, payload, state) {
37
- try {
38
- const { context, ...response } = await EVENTS[eventName](payload, state.context)
39
- state.context = { ...state.context, ...context }
40
- await sendEventToParent(callId, response)
41
- } catch (error) {
42
- await handleError(error)
43
- }
44
- }
45
-
46
- const EVENTS = { load, run }
47
-
48
- bootPlugin()
@@ -1,20 +0,0 @@
1
- const mapObj = require('map-obj')
2
-
3
- const { LEGACY_EVENTS } = require('../events')
4
-
5
- // Normalize plugin shape
6
- const normalizePlugin = function(logic) {
7
- return mapObj(logic, normalizeProperty)
8
- }
9
-
10
- const normalizeProperty = function(key, value) {
11
- const newKey = LEGACY_EVENTS[key]
12
-
13
- if (newKey === undefined) {
14
- return [key, value]
15
- }
16
-
17
- return [newKey, value]
18
- }
19
-
20
- module.exports = { normalizePlugin }
@@ -1,34 +0,0 @@
1
- const { getNewEnvChanges, setEnvChanges } = require('../../env/changes.js')
2
-
3
- const { getUtils } = require('./utils')
4
-
5
- // Run a specific plugin event handler
6
- const run = async function(
7
- { event, error, envChanges },
8
- { pluginCommands, api, utilsData, constants, inputs, netlifyConfig },
9
- ) {
10
- const { method } = pluginCommands.find(pluginCommand => pluginCommand.event === event)
11
- const runState = {}
12
- const utils = getUtils({ utilsData, constants, runState })
13
- const runOptions = { api, utils, constants, inputs, netlifyConfig, error }
14
- addBackwardCompatibility(runOptions)
15
-
16
- const envBefore = setEnvChanges(envChanges)
17
- await method(runOptions)
18
- const newEnvChanges = getNewEnvChanges(envBefore)
19
- return { ...runState, newEnvChanges }
20
- }
21
-
22
- // Add older names, kept for backward compatibility. Non-enumerable.
23
- // TODO: remove after being out of beta
24
- const addBackwardCompatibility = function(runOptions) {
25
- Object.defineProperties(runOptions, {
26
- pluginConfig: { value: runOptions.inputs },
27
- })
28
- // Make `constants.BUILD_DIR` non-enumerable
29
- Object.defineProperty(runOptions.constants, 'BUILD_DIR', {
30
- value: runOptions.constants.BUILD_DIR,
31
- })
32
- }
33
-
34
- module.exports = { run }
@@ -1,53 +0,0 @@
1
- const isPlainObj = require('is-plain-obj')
2
-
3
- const { ERROR_TYPE_SYM } = require('../error')
4
-
5
- // Retrieve `utils.status.*` methods
6
- const getStatusUtil = function(runState) {
7
- return { show: show.bind(undefined, runState) }
8
- }
9
-
10
- // Report status information to the UI
11
- const show = function(runState, showArgs) {
12
- validateShowArgs(showArgs)
13
- const { title, summary, text } = showArgs
14
- runState.status = { state: 'success', title, summary, text }
15
- }
16
-
17
- // Validate arguments of `utils.status.show()`
18
- const validateShowArgs = function(showArgs) {
19
- try {
20
- if (showArgs === undefined) {
21
- throw new Error('requires an argument')
22
- }
23
-
24
- if (!isPlainObj(showArgs)) {
25
- throw new Error('argument must be a plain object')
26
- }
27
-
28
- const { title, summary, text, ...otherArgs } = showArgs
29
- const otherKeys = Object.keys(otherArgs).map(arg => `"${arg}"`)
30
-
31
- if (otherKeys.length !== 0) {
32
- throw new Error(`must only contain "title", "summary" or "text" properties, not ${otherKeys.join(', ')}`)
33
- }
34
-
35
- if (summary === undefined) {
36
- throw new Error('requires specifying a "summary" property')
37
- }
38
-
39
- Object.entries({ title, summary, text }).forEach(validateStringArg)
40
- } catch (error) {
41
- error.message = `utils.status.show() ${error.message}`
42
- error[ERROR_TYPE_SYM] = 'pluginValidation'
43
- throw error
44
- }
45
- }
46
-
47
- const validateStringArg = function([key, value]) {
48
- if (value !== undefined && (typeof value !== 'string' || value.trim() === '')) {
49
- throw new Error(`"${key}" property must be a non-empty string`)
50
- }
51
- }
52
-
53
- module.exports = { getStatusUtil }
@@ -1,43 +0,0 @@
1
- const cacheUtils = require('@netlify/cache-utils')
2
- const functionsUtils = require('@netlify/functions-utils')
3
- const gitUtils = require('@netlify/git-utils')
4
- const runUtils = require('@netlify/run-utils')
5
-
6
- const { failBuild, failPlugin, cancelBuild } = require('../error')
7
-
8
- const { getStatusUtil } = require('./status')
9
-
10
- // Some utilities need to perform some async initialization logic first.
11
- // We do it once for all plugins in the parent process then pass it to the child
12
- // processes.
13
- const startUtils = async function(buildDir) {
14
- const git = await gitUtils({ cwd: buildDir })
15
- return { git }
16
- }
17
-
18
- // Retrieve the `utils` argument.
19
- const getUtils = function({ utilsData: { git }, constants: { FUNCTIONS_SRC, CACHE_DIR }, runState }) {
20
- const buildUtils = { failBuild, failPlugin, cancelBuild }
21
- const gitA = gitUtils.load(git)
22
- const cache = cacheUtils.bindOpts({ cacheDir: CACHE_DIR })
23
- const add = src => functionsUtils.add(src, FUNCTIONS_SRC, { fail: failBuild })
24
- const functions = { add }
25
- const status = getStatusUtil(runState)
26
- const utils = {
27
- build: buildUtils,
28
- git: gitA,
29
- cache,
30
- run: runUtils,
31
- functions,
32
- status,
33
- }
34
-
35
- // Older names, kept for backward compatibility. Non-enumerable.
36
- // TODO: remove after beta is done
37
- Object.defineProperty(utils.build, 'fail', { value: utils.build.failBuild })
38
- Object.defineProperty(utils.build, 'cancel', { value: utils.build.cancelBuild })
39
-
40
- return utils
41
- }
42
-
43
- module.exports = { startUtils, getUtils }
@@ -1,46 +0,0 @@
1
- const isPlainObj = require('is-plain-obj')
2
-
3
- const { serializeArray } = require('../../log/serialize')
4
- const { ERROR_TYPE_SYM } = require('../error')
5
- const { EVENTS, LEGACY_EVENTS } = require('../events')
6
-
7
- // Validate the shape of a plugin return value
8
- const validatePlugin = function(logic) {
9
- try {
10
- if (!isPlainObj(logic)) {
11
- throw new Error('Plugin must be an object or a function')
12
- }
13
-
14
- Object.entries(logic).forEach(([propName, value]) => validateProperty(value, propName))
15
- } catch (error) {
16
- error[ERROR_TYPE_SYM] = 'pluginValidation'
17
- throw error
18
- }
19
- }
20
-
21
- const validateProperty = function(value, propName) {
22
- if (DEPRECATED_PROPERTIES.includes(propName)) {
23
- return
24
- }
25
-
26
- // All other properties are event handlers
27
- validateEventHandler(value, propName)
28
- }
29
-
30
- // Backward compatibility. This is now in manifest.yml
31
- // TODO: remove after migrating existing plugins
32
- const DEPRECATED_PROPERTIES = ['name', 'inputs', 'config', 'scopes']
33
-
34
- const validateEventHandler = function(value, propName) {
35
- if (!EVENTS.includes(propName) && LEGACY_EVENTS[propName] === undefined) {
36
- throw new Error(`Invalid event '${propName}'.
37
- Please use a valid event name. One of:
38
- ${serializeArray(EVENTS)}`)
39
- }
40
-
41
- if (typeof value !== 'function') {
42
- throw new Error(`Invalid event handler '${propName}': must be a function`)
43
- }
44
- }
45
-
46
- module.exports = { validatePlugin }
@@ -1,44 +0,0 @@
1
- // Stop build.
2
- // As opposed to throwing an error directly or to uncaught exceptions, this is
3
- // displayed as a user error, not an implementation error.
4
- const failBuild = function(message, opts) {
5
- throw normalizeError('failBuild', failBuild, message, opts)
6
- }
7
-
8
- // Stop plugin. Same as `failBuild` but only stops plugin not whole build
9
- const failPlugin = function(message, opts) {
10
- throw normalizeError('failPlugin', failPlugin, message, opts)
11
- }
12
-
13
- // Cancel build. Same as `failBuild` except it marks the build as "canceled".
14
- const cancelBuild = function(message, opts) {
15
- throw normalizeError('cancelBuild', cancelBuild, message, opts)
16
- }
17
-
18
- // An `error` option can be passed to keep the original error message and
19
- // stack trace. An additional `message` string is always required.
20
- const normalizeError = function(type, func, message, { error } = {}) {
21
- const errorA = getError(error, message, func)
22
- errorA[ERROR_TYPE_SYM] = type
23
- return errorA
24
- }
25
-
26
- const getError = function(error, message, func) {
27
- if (error instanceof Error) {
28
- error.message = `${message}\n${error.message}`
29
- return error
30
- }
31
-
32
- const errorA = new Error(message)
33
- // Do not include function itself in the stack trace
34
- Error.captureStackTrace(errorA, func)
35
- return errorA
36
- }
37
-
38
- const isBuildError = function(error) {
39
- return error instanceof Error && error[ERROR_TYPE_SYM] !== undefined
40
- }
41
-
42
- const ERROR_TYPE_SYM = Symbol('errorType')
43
-
44
- module.exports = { failBuild, failPlugin, cancelBuild, isBuildError, ERROR_TYPE_SYM }
@@ -1,77 +0,0 @@
1
- const EVENTS = [
2
- /**
3
- * `onPreBuild` - Before build commands are executed
4
- */
5
- 'onPreBuild',
6
- /**
7
- * `onBuild` - Build commands are executed
8
- */
9
- 'onBuild',
10
- /**
11
- * `onPostBuild` - After Build commands are executed
12
- */
13
- 'onPostBuild',
14
-
15
- /**
16
- * `onSuccess` - Runs on build success
17
- */
18
- 'onSuccess',
19
- /**
20
- * `onError` - Runs on build error
21
- */
22
- 'onError',
23
- /**
24
- * `onEnd` - Runs on build error or success
25
- */
26
- 'onEnd',
27
- ]
28
-
29
- // TODO: remove after going out of beta
30
- const LEGACY_EVENTS = {
31
- init: 'onPreBuild',
32
- onInit: 'onPreBuild',
33
- preBuild: 'onPreBuild',
34
- preGetCache: 'onPreBuild',
35
- onPreGetCache: 'onPreBuild',
36
- getCache: 'onPreBuild',
37
- onGetCache: 'onPreBuild',
38
- postGetCache: 'onPreBuild',
39
- onPostGetCache: 'onPreBuild',
40
- preInstall: 'onPreBuild',
41
- onPreInstall: 'onPreBuild',
42
- install: 'onPreBuild',
43
- onInstall: 'onPreBuild',
44
- postInstall: 'onPreBuild',
45
- onPostInstall: 'onPreBuild',
46
- build: 'onBuild',
47
- postBuild: 'onPostBuild',
48
- preFunctionsBuild: 'onPostBuild',
49
- onPreFunctionsBuild: 'onPostBuild',
50
- functionsBuild: 'onPostBuild',
51
- onFunctionsBuild: 'onPostBuild',
52
- postFunctionsBuild: 'onPostBuild',
53
- onPostFunctionsBuild: 'onPostBuild',
54
- preFunctionsPackage: 'onPostBuild',
55
- onPreFunctionsPackage: 'onPostBuild',
56
- functionsPackage: 'onPostBuild',
57
- onFunctionsPackage: 'onPostBuild',
58
- postFunctionsPackage: 'onPostBuild',
59
- onPostFunctionsPackage: 'onPostBuild',
60
- prePackage: 'onPostBuild',
61
- package: 'onPostBuild',
62
- postPackage: 'onPostBuild',
63
- preDeploy: 'onPostBuild',
64
- onPreDeploy: 'onPostBuild',
65
- preSaveCache: 'onPostBuild',
66
- onPreSaveCache: 'onPostBuild',
67
- saveCache: 'onPostBuild',
68
- onSaveCache: 'onPostBuild',
69
- postSaveCache: 'onPostBuild',
70
- onPostSaveCache: 'onPostBuild',
71
- success: 'onSuccess',
72
- error: 'onError',
73
- end: 'onEnd',
74
- finally: 'onEnd',
75
- }
76
-
77
- module.exports = { EVENTS, LEGACY_EVENTS }
@@ -1,136 +0,0 @@
1
- const { promisify } = require('util')
2
-
3
- const pEvent = require('p-event')
4
- const { v4: uuidv4 } = require('uuid')
5
-
6
- const { buildError } = require('../error/build')
7
- const { addErrorInfo } = require('../error/info')
8
-
9
- // Send event from child to parent process then wait for response
10
- // We need to fire them in parallel because `process.send()` can be slow
11
- // to await, i.e. child might send response before parent start listening for it
12
- const callChild = async function(childProcess, eventName, payload, { plugin, location }) {
13
- const callId = uuidv4()
14
- const [response] = await Promise.all([
15
- getEventFromChild(childProcess, callId, { plugin, location }),
16
- sendEventToChild(childProcess, callId, eventName, payload),
17
- ])
18
- return response
19
- }
20
-
21
- // Receive event from child to parent process
22
- // Wait for either:
23
- // - `message` event with a specific `callId`
24
- // - `message` event with an `error` `callId` indicating an exception in the
25
- // child process
26
- // - child process `exit`
27
- // In the later two cases, we propagate the error.
28
- // We need to make `p-event` listeners are properly cleaned up too.
29
- const getEventFromChild = async function(childProcess, callId, { plugin, location }) {
30
- if (!childProcess.connected) {
31
- const error = new Error(`Could not receive event from child process because it already exited.
32
- ${EXIT_WARNING}`)
33
- addErrorInfo(error, { type: 'ipc', plugin, location })
34
- throw error
35
- }
36
-
37
- const messagePromise = pEvent(childProcess, 'message', { filter: ([actualCallId]) => actualCallId === callId })
38
- const errorPromise = pEvent(childProcess, 'message', { filter: ([actualCallId]) => actualCallId === 'error' })
39
- const exitPromise = pEvent(childProcess, 'exit', { multiArgs: true })
40
- try {
41
- return await Promise.race([
42
- getMessage(messagePromise),
43
- getError(errorPromise, { plugin, location }),
44
- getExit(exitPromise, { plugin, location }),
45
- ])
46
- } finally {
47
- messagePromise.cancel()
48
- errorPromise.cancel()
49
- exitPromise.cancel()
50
- }
51
- }
52
-
53
- const getMessage = async function(messagePromise) {
54
- const [, response] = await messagePromise
55
- return response
56
- }
57
-
58
- const getError = async function(errorPromise, { plugin, location }) {
59
- const [, { errorProps, ...values }] = await errorPromise
60
- throw buildError({ ...values, ...errorProps, plugin, location })
61
- }
62
-
63
- const getExit = async function(exitPromise, { plugin, location }) {
64
- const [exitCode, signal] = await exitPromise
65
- const error = new Error(`Plugin exited with exit code ${exitCode} and signal ${signal}.
66
- ${EXIT_WARNING}`)
67
- addErrorInfo(error, { type: 'ipc', plugin, location })
68
- throw error
69
- }
70
-
71
- // Plugins should not terminate processes explicitly:
72
- // - It prevents specifying error messages to the end users
73
- // - It makes it impossible to distinguish between bugs (such as infinite loops) and user errors
74
- // - It complicates child process orchestration. For example if an async operation
75
- // of a previous event handler is still running, it would be aborted if another
76
- // is terminating the process.
77
- const EXIT_WARNING = `The plugin might have exited due to a bug terminating the process, such as an infinite loop.
78
- The plugin might also have explicitly terminated the process, for example with process.exit().
79
- Plugin methods should instead:
80
- - on success: return
81
- - on failure: call utils.build.failPlugin() or utils.build.failBuild()`
82
-
83
- // Send event from parent to child process
84
- const sendEventToChild = async function(childProcess, callId, eventName, payload) {
85
- const payloadA = serializePayload(payload)
86
- await promisify(childProcess.send.bind(childProcess))([callId, eventName, payloadA])
87
- }
88
-
89
- // Respond to events from parent to child process.
90
- // This runs forever until `childProcess.kill()` is called.
91
- const getEventsFromParent = async function(callback) {
92
- return new Promise((resolve, reject) => {
93
- process.on('message', async message => {
94
- try {
95
- const [callId, eventName, payload] = message
96
- const payloadA = parsePayload(payload)
97
- await callback(callId, eventName, payloadA)
98
- } catch (error) {
99
- reject(error)
100
- }
101
- })
102
- })
103
- }
104
-
105
- // Send event from child to parent process
106
- const sendEventToParent = async function(callId, payload) {
107
- await promisify(process.send.bind(process))([callId, payload])
108
- }
109
-
110
- // Errors are not serializable through `child_process` `ipc` so we need to
111
- // convert from/to plain objects.
112
- // TODO: use `child_process.spawn()` `serialization: 'advanced'` option after
113
- // dropping support for Node.js <=13.2.0
114
- const serializePayload = function({ error: { name, message, stack, ...errorProps } = {}, ...payload }) {
115
- if (name === undefined) {
116
- return payload
117
- }
118
-
119
- return { ...payload, error: { ...errorProps, name, message, stack } }
120
- }
121
-
122
- const parsePayload = function({ error = {}, ...payload }) {
123
- if (error.name === undefined) {
124
- return payload
125
- }
126
-
127
- const errorA = buildError(error)
128
- return { ...payload, error: errorA }
129
- }
130
-
131
- module.exports = {
132
- callChild,
133
- getEventFromChild,
134
- getEventsFromParent,
135
- sendEventToParent,
136
- }
@@ -1,66 +0,0 @@
1
- const { reportPluginLoadError } = require('../status/report')
2
-
3
- const { callChild } = require('./ipc')
4
-
5
- // Retrieve all plugins commands
6
- // Can use either a module name or a file path to the plugin.
7
- const loadPlugins = async function({
8
- pluginsOptions,
9
- childProcesses,
10
- netlifyConfig,
11
- utilsData,
12
- token,
13
- constants,
14
- mode,
15
- api,
16
- }) {
17
- const pluginsCommands = await Promise.all(
18
- pluginsOptions.map((pluginOptions, index) =>
19
- loadPlugin(pluginOptions, {
20
- childProcesses,
21
- index,
22
- netlifyConfig,
23
- utilsData,
24
- token,
25
- constants,
26
- mode,
27
- api,
28
- }),
29
- ),
30
- )
31
- const pluginsCommandsA = pluginsCommands.flat()
32
- return pluginsCommandsA
33
- }
34
-
35
- // Retrieve plugin commands for one plugin.
36
- // Do it by executing the plugin `load` event handler.
37
- const loadPlugin = async function(
38
- { package, packageJson, packageJson: { version } = {}, pluginPath, manifest, inputs, loadedFrom, origin },
39
- { childProcesses, index, netlifyConfig, utilsData, token, constants, mode, api },
40
- ) {
41
- const { childProcess } = childProcesses[index]
42
- const event = 'load'
43
-
44
- try {
45
- const { pluginCommands } = await callChild(
46
- childProcess,
47
- 'load',
48
- { pluginPath, manifest, inputs, netlifyConfig, utilsData, token, constants },
49
- { plugin: { package, packageJson }, location: { event, package, loadedFrom, origin } },
50
- )
51
- const pluginCommandsA = pluginCommands.map(({ event }) => ({
52
- event,
53
- package,
54
- loadedFrom,
55
- origin,
56
- packageJson,
57
- childProcess,
58
- }))
59
- return pluginCommandsA
60
- } catch (error) {
61
- await reportPluginLoadError({ error, api, mode, event, package, version })
62
- throw error
63
- }
64
- }
65
-
66
- module.exports = { loadPlugins }
@@ -1,80 +0,0 @@
1
- const { addErrorInfo } = require('../../error/info')
2
- const { serializeObject } = require('../../log/serialize')
3
- const { THEME } = require('../../log/theme')
4
-
5
- // Check that plugin inputs match the validation specified in "manifest.yml"
6
- // Also assign default values
7
- const checkInputs = function({ inputs, manifest: { inputs: rules = [] }, package, packageJson, loadedFrom, origin }) {
8
- try {
9
- const inputsA = addDefaults(inputs, rules)
10
- checkRequiredInputs({ inputs: inputsA, rules, package, packageJson, loadedFrom, origin })
11
- Object.keys(inputsA).map(name => checkInput({ name, rules, package, packageJson, loadedFrom, origin }))
12
- return inputsA
13
- } catch (error) {
14
- error.message = `${error.message}
15
-
16
- ${THEME.errorSubHeader('Plugin inputs')}
17
- ${serializeObject(inputs)}`
18
- throw error
19
- }
20
- }
21
-
22
- // Add "inputs[*].default"
23
- const addDefaults = function(inputs, rules) {
24
- const defaults = rules.filter(hasDefault).map(getDefault)
25
- return Object.assign({}, ...defaults, inputs)
26
- }
27
-
28
- const hasDefault = function(rule) {
29
- return rule.default !== undefined
30
- }
31
-
32
- const getDefault = function({ name, default: defaultValue }) {
33
- return { [name]: defaultValue }
34
- }
35
-
36
- // Check "inputs[*].required"
37
- const checkRequiredInputs = function({ inputs, rules, package, packageJson, loadedFrom, origin }) {
38
- const missingInputs = rules.filter(rule => isMissingRequired(inputs, rule))
39
- if (missingInputs.length === 0) {
40
- return
41
- }
42
-
43
- const names = missingInputs.map(getName)
44
- const error = new Error(`Required inputs for plugin "${package}": ${names.join(', ')}`)
45
- addInputError({ error, name: names[0], package, packageJson, loadedFrom, origin })
46
- throw error
47
- }
48
-
49
- const isMissingRequired = function(inputs, { name, required }) {
50
- return required && inputs[name] === undefined
51
- }
52
-
53
- const getName = function({ name }) {
54
- return name
55
- }
56
-
57
- // Check each "inputs[*].*" property for a specific input
58
- const checkInput = function({ name, rules, package, packageJson, loadedFrom, origin }) {
59
- const ruleA = rules.find(rule => rule.name === name)
60
- if (ruleA === undefined) {
61
- const error = new Error(`Invalid input "${name}" for plugin "${package}".
62
- Check your plugin configuration to be sure that:
63
- - the input name is spelled correctly
64
- - the input is included in the plugin's available configuration options
65
- - the plugin's input requirements have not changed`)
66
- addInputError({ error, name, package, packageJson, loadedFrom, origin })
67
- throw error
68
- }
69
- }
70
-
71
- // Add error information
72
- const addInputError = function({ error, name, package, packageJson, loadedFrom, origin }) {
73
- addErrorInfo(error, {
74
- type: 'pluginInput',
75
- plugin: { package, packageJson },
76
- location: { event: 'load', package, input: name, loadedFrom, origin },
77
- })
78
- }
79
-
80
- module.exports = { checkInputs }