@netlify/build 24.0.1 → 25.0.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/build",
3
- "version": "24.0.1",
3
+ "version": "25.0.3",
4
4
  "description": "Netlify build module",
5
5
  "main": "src/core/main.js",
6
6
  "types": "types/index.d.ts",
@@ -55,13 +55,13 @@
55
55
  "dependencies": {
56
56
  "@bugsnag/js": "^7.0.0",
57
57
  "@netlify/cache-utils": "^4.0.0",
58
- "@netlify/config": "^16.0.0",
58
+ "@netlify/config": "^17.0.0",
59
59
  "@netlify/functions-utils": "^4.0.0",
60
60
  "@netlify/git-utils": "^4.0.0",
61
61
  "@netlify/plugin-edge-handlers": "^3.0.0",
62
62
  "@netlify/plugins-list": "^6.2.0",
63
63
  "@netlify/run-utils": "^4.0.0",
64
- "@netlify/zip-it-and-ship-it": "^5.2.0",
64
+ "@netlify/zip-it-and-ship-it": "^5.3.0",
65
65
  "@sindresorhus/slugify": "^1.1.0",
66
66
  "ansi-escapes": "^4.3.2",
67
67
  "chalk": "^4.1.2",
@@ -112,6 +112,7 @@
112
112
  "ava": "^3.15.0",
113
113
  "cpy": "^8.1.0",
114
114
  "del": "^6.0.0",
115
+ "fast-safe-stringify": "^2.0.7",
115
116
  "get-bin-path": "^5.1.0",
116
117
  "get-node": "^11.0.2",
117
118
  "get-port": "^5.1.1",
@@ -1,8 +1,6 @@
1
1
  /* eslint-disable max-lines */
2
2
  'use strict'
3
3
 
4
- const resolveConfig = require('@netlify/config')
5
- const { updateConfig, restoreConfig } = require('@netlify/config')
6
4
  const mapObj = require('map-obj')
7
5
 
8
6
  const { getChildEnv } = require('../env/main')
@@ -15,6 +13,8 @@ const { getPackageJson } = require('../utils/package')
15
13
 
16
14
  const { getUserNodeVersion } = require('./user_node_version')
17
15
 
16
+ const netlifyConfigPromise = import('@netlify/config')
17
+
18
18
  // Retrieve immutable options passed to `@netlify/config`.
19
19
  // This does not include options which might change during the course of the
20
20
  // build:
@@ -78,7 +78,7 @@ const tLoadConfig = async function ({ configOpts, cachedConfig, cachedConfigPath
78
78
  siteInfo,
79
79
  env,
80
80
  } = await resolveInitialConfig(configOpts, cachedConfig, cachedConfigPath)
81
- logConfigInfo({ logs, configPath, buildDir, netlifyConfig, context: contextA, debug })
81
+ await logConfigInfo({ logs, configPath, buildDir, netlifyConfig, context: contextA, debug })
82
82
 
83
83
  const apiA = addApiErrorHandlers(api)
84
84
  const envValues = mapObj(env, (key, { value }) => [key, value])
@@ -108,13 +108,14 @@ const loadConfig = measureDuration(tLoadConfig, 'resolve_config')
108
108
  // In the buildbot and CLI, we re-use the already parsed `@netlify/config`
109
109
  // return value which is passed as `cachedConfig`/`cachedConfigPath`.
110
110
  const resolveInitialConfig = async function (configOpts, cachedConfig, cachedConfigPath) {
111
+ const { resolveConfig } = await netlifyConfigPromise
111
112
  return await resolveConfig({ ...configOpts, cachedConfig, cachedConfigPath })
112
113
  }
113
114
 
114
- const logConfigInfo = function ({ logs, configPath, buildDir, netlifyConfig, context, debug }) {
115
+ const logConfigInfo = async function ({ logs, configPath, buildDir, netlifyConfig, context, debug }) {
115
116
  logBuildDir(logs, buildDir)
116
117
  logConfigPath(logs, configPath)
117
- logConfig({ logs, netlifyConfig, debug })
118
+ await logConfig({ logs, netlifyConfig, debug })
118
119
  logContext(logs, context)
119
120
  }
120
121
 
@@ -126,6 +127,7 @@ const logConfigInfo = function ({ logs, configPath, buildDir, netlifyConfig, con
126
127
  // Errors are propagated and assigned to the specific plugin or core step
127
128
  // which changed the configuration.
128
129
  const resolveUpdatedConfig = async function (configOpts, configMutations) {
130
+ const { resolveConfig } = await netlifyConfigPromise
129
131
  try {
130
132
  return await resolveConfig({ ...configOpts, configMutations, debug: false })
131
133
  } catch (error) {
@@ -156,6 +158,7 @@ const saveUpdatedConfig = async function ({
156
158
  return
157
159
  }
158
160
 
161
+ const { updateConfig } = await netlifyConfigPromise
159
162
  await updateConfig(configMutations, {
160
163
  buildDir,
161
164
  configPath,
@@ -184,6 +187,7 @@ const restoreUpdatedConfig = async function ({
184
187
  return
185
188
  }
186
189
 
190
+ const { restoreConfig } = await netlifyConfigPromise
187
191
  await restoreConfig(configMutations, { buildDir, configPath, headersPath, redirectsPath })
188
192
  }
189
193
 
@@ -5,7 +5,7 @@ const { relative, normalize } = require('path')
5
5
  const mapObj = require('map-obj')
6
6
  const pathExists = require('path-exists')
7
7
 
8
- const { version } = require('../../package.json')
8
+ const { ROOT_PACKAGE_JSON } = require('../utils/json')
9
9
 
10
10
  const cacheUtilsPromise = import('@netlify/cache-utils')
11
11
 
@@ -35,7 +35,7 @@ const getConstants = async function ({
35
35
  // Boolean indicating whether the build was run locally (Netlify CLI) or in the production CI
36
36
  IS_LOCAL: isLocal,
37
37
  // The version of Netlify Build
38
- NETLIFY_BUILD_VERSION: version,
38
+ NETLIFY_BUILD_VERSION: ROOT_PACKAGE_JSON.version,
39
39
  // The Netlify Site ID
40
40
  SITE_ID: siteId,
41
41
  // The Netlify API access token
package/src/core/main.js CHANGED
@@ -595,7 +595,7 @@ const runBuild = async function ({
595
595
  verbose,
596
596
  })
597
597
 
598
- const { steps, events } = getSteps(pluginsSteps)
598
+ const { steps, events } = await getSteps(pluginsSteps)
599
599
 
600
600
  if (dry) {
601
601
  await doDryRun({ buildDir, steps, netlifyConfig, constants, buildbotServerSocket, logs })
@@ -26,7 +26,7 @@ const handleBuildError = async function (
26
26
  removeErrorColors(error)
27
27
  // Some errors, such as telemetry ones, should not be logged
28
28
  if (basicErrorInfo.showInBuildLog) {
29
- logBuildError({ error, netlifyConfig, mode, logs, debug, testOpts })
29
+ await logBuildError({ error, netlifyConfig, mode, logs, debug, testOpts })
30
30
  }
31
31
  logOldCliVersionError({ mode, testOpts })
32
32
  await reportBuildError({ error, errorMonitor, childEnv, logs, testOpts })
@@ -3,8 +3,8 @@
3
3
  const Bugsnag = require('@bugsnag/js')
4
4
  const memoizeOne = require('memoize-one')
5
5
 
6
- const { name, version } = require('../../../package.json')
7
6
  const { log } = require('../../log/logger')
7
+ const { ROOT_PACKAGE_JSON } = require('../../utils/json')
8
8
 
9
9
  const projectRoot = `${__dirname}/../../..`
10
10
 
@@ -20,8 +20,8 @@ const startErrorMonitor = function ({ flags: { mode }, logs, bugsnagKey }) {
20
20
  try {
21
21
  const errorMonitor = startBugsnag({
22
22
  apiKey: bugsnagKey,
23
- appVersion: `${name} ${version}`,
24
- appType: name,
23
+ appVersion: `${ROOT_PACKAGE_JSON.name} ${ROOT_PACKAGE_JSON.version}`,
24
+ appType: ROOT_PACKAGE_JSON.name,
25
25
  releaseStage,
26
26
  logger,
27
27
  projectRoot,
@@ -1,12 +1,12 @@
1
1
  'use strict'
2
2
 
3
- const { cleanupConfig } = require('@netlify/config')
4
-
5
3
  const { DEFAULT_FEATURE_FLAGS } = require('../../core/feature_flags')
6
4
  const { omit } = require('../../utils/omit')
7
5
  const { logMessage, logObject, logSubHeader } = require('../logger')
8
6
  const { THEME } = require('../theme')
9
7
 
8
+ const netlifyConfigPromise = import('@netlify/config')
9
+
10
10
  const logFlags = function (logs, flags, { debug }) {
11
11
  const flagsA = cleanFeatureFlags(flags)
12
12
  const hiddenFlags = debug ? HIDDEN_DEBUG_FLAGS : HIDDEN_FLAGS
@@ -69,29 +69,32 @@ const logConfigPath = function (logs, configPath = NO_CONFIG_MESSAGE) {
69
69
 
70
70
  const NO_CONFIG_MESSAGE = 'No config file was defined: using default values.'
71
71
 
72
- const logConfig = function ({ logs, netlifyConfig, debug }) {
72
+ const logConfig = async function ({ logs, netlifyConfig, debug }) {
73
73
  if (!debug) {
74
74
  return
75
75
  }
76
76
 
77
+ const { cleanupConfig } = await netlifyConfigPromise
77
78
  logSubHeader(logs, 'Resolved config')
78
79
  logObject(logs, cleanupConfig(netlifyConfig))
79
80
  }
80
81
 
81
- const logConfigOnUpdate = function ({ logs, netlifyConfig, debug }) {
82
+ const logConfigOnUpdate = async function ({ logs, netlifyConfig, debug }) {
82
83
  if (!debug) {
83
84
  return
84
85
  }
85
86
 
87
+ const { cleanupConfig } = await netlifyConfigPromise
86
88
  logSubHeader(logs, 'Updated config')
87
89
  logObject(logs, cleanupConfig(netlifyConfig))
88
90
  }
89
91
 
90
- const logConfigOnError = function ({ logs, netlifyConfig, severity }) {
92
+ const logConfigOnError = async function ({ logs, netlifyConfig, severity }) {
91
93
  if (netlifyConfig === undefined || severity === 'none') {
92
94
  return
93
95
  }
94
96
 
97
+ const { cleanupConfig } = await netlifyConfigPromise
95
98
  logMessage(logs, THEME.errorSubHeader('Resolved config'))
96
99
  logObject(logs, cleanupConfig(netlifyConfig))
97
100
  }
@@ -3,10 +3,10 @@
3
3
  const { link } = require('ansi-escapes')
4
4
  const prettyMs = require('pretty-ms')
5
5
 
6
- const { name, version } = require('../../../package.json')
7
6
  const { getFullErrorInfo } = require('../../error/parse/parse')
8
7
  const { serializeLogError } = require('../../error/parse/serialize_log')
9
8
  const { roundTimerToMillisecs } = require('../../time/measure')
9
+ const { ROOT_PACKAGE_JSON } = require('../../utils/json')
10
10
  const { getLogHeaderFunc } = require('../header_func')
11
11
  const { log, logMessage, logWarning, logHeader, logSubHeader, logWarningArray } = require('../logger')
12
12
  const { logOldCliVersionError } = require('../old_version')
@@ -17,17 +17,17 @@ const { logConfigOnError } = require('./config')
17
17
  const logBuildStart = function (logs) {
18
18
  logHeader(logs, 'Netlify Build')
19
19
  logSubHeader(logs, 'Version')
20
- logMessage(logs, `${name} ${version}`)
20
+ logMessage(logs, `${ROOT_PACKAGE_JSON.name} ${ROOT_PACKAGE_JSON.version}`)
21
21
  }
22
22
 
23
- const logBuildError = function ({ error, netlifyConfig, mode, logs, debug, testOpts }) {
23
+ const logBuildError = async function ({ error, netlifyConfig, mode, logs, debug, testOpts }) {
24
24
  const fullErrorInfo = getFullErrorInfo({ error, colors: true, debug })
25
25
  const { severity } = fullErrorInfo
26
26
  const { title, body } = serializeLogError({ fullErrorInfo })
27
27
  const logHeaderFunc = getLogHeaderFunc(error)
28
28
  logHeaderFunc(logs, title)
29
29
  logMessage(logs, `\n${body}\n`)
30
- logConfigOnError({ logs, netlifyConfig, severity })
30
+ await logConfigOnError({ logs, netlifyConfig, severity })
31
31
  logOldCliVersionError({ mode, testOpts })
32
32
  }
33
33
 
@@ -4,7 +4,7 @@ const { stdout } = require('process')
4
4
 
5
5
  const UpdateNotifier = require('update-notifier')
6
6
 
7
- const CORE_PACKAGE_JSON = require('../../package.json')
7
+ const { ROOT_PACKAGE_JSON } = require('../utils/json')
8
8
 
9
9
  // Many build errors happen in local builds that do not use the latest version
10
10
  // of `@netlify/build`. We print a warning message on those.
@@ -32,10 +32,10 @@ const getCorePackageJson = function (testOpts) {
32
32
  // eslint-disable-next-line fp/no-mutation
33
33
  stdout.isTTY = true
34
34
 
35
- return { ...CORE_PACKAGE_JSON, version: '0.0.1' }
35
+ return { ...ROOT_PACKAGE_JSON, version: '0.0.1' }
36
36
  }
37
37
 
38
- return CORE_PACKAGE_JSON
38
+ return ROOT_PACKAGE_JSON
39
39
  }
40
40
 
41
41
  const OLD_VERSION_MESSAGE = `Please update netlify-cli to its latest version.
@@ -15,7 +15,7 @@ const load = async function ({ pluginPath, inputs, packageJson, verbose }) {
15
15
  const tsNodeService = registerTypeScript(pluginPath)
16
16
  const logic = await getLogic({ pluginPath, inputs, tsNodeService })
17
17
 
18
- validatePlugin(logic)
18
+ await validatePlugin(logic)
19
19
 
20
20
  const methods = filterObj(logic, isEventHandler)
21
21
  const events = Object.keys(methods)
@@ -2,10 +2,10 @@
2
2
 
3
3
  const { addErrorInfo } = require('../../error/info')
4
4
  const { serializeArray } = require('../../log/serialize')
5
- const { EVENTS } = require('../events')
5
+ const { listEvents } = require('../events')
6
6
 
7
7
  // Validate the shape of a plugin return value
8
- const validatePlugin = function (logic) {
8
+ const validatePlugin = async function (logic) {
9
9
  try {
10
10
  // This validation must work with the return value of `import()` which has
11
11
  // a `Module` prototype, not `Object`
@@ -13,8 +13,9 @@ const validatePlugin = function (logic) {
13
13
  throw new Error('Plugin must be an object or a function')
14
14
  }
15
15
 
16
+ const EVENTS = await listEvents()
16
17
  Object.entries(logic).forEach(([propName, value]) => {
17
- validateEventHandler(value, propName)
18
+ validateEventHandler(value, propName, EVENTS)
18
19
  })
19
20
  } catch (error) {
20
21
  addErrorInfo(error, { type: 'pluginValidation' })
@@ -23,7 +24,7 @@ const validatePlugin = function (logic) {
23
24
  }
24
25
 
25
26
  // All other properties are event handlers
26
- const validateEventHandler = function (value, propName) {
27
+ const validateEventHandler = function (value, propName, EVENTS) {
27
28
  if (!EVENTS.includes(propName)) {
28
29
  throw new Error(`Invalid event '${propName}'.
29
30
  Please use a valid event name. One of:
@@ -3,6 +3,7 @@ const pEvery = require('p-every')
3
3
  const pLocate = require('p-locate')
4
4
  const { satisfies, clean: cleanVersion } = require('semver')
5
5
 
6
+ const { importJsonFile } = require('../utils/json')
6
7
  const { resolvePath } = require('../utils/resolve')
7
8
 
8
9
  // Retrieve the `expectedVersion` of a plugin:
@@ -107,8 +108,7 @@ const siteDependencyTest = async function ({ dependencyName, allowedVersion, sit
107
108
  try {
108
109
  // if this is a range we need to get the exact version
109
110
  const packageJsonPath = await resolvePath(`${dependencyName}/package.json`, buildDir)
110
- // eslint-disable-next-line node/global-require, import/no-dynamic-require
111
- const { version } = require(packageJsonPath)
111
+ const { version } = await importJsonFile(packageJsonPath)
112
112
  return satisfies(version, allowedVersion)
113
113
  } catch (error) {
114
114
  return false
@@ -1,6 +1,11 @@
1
1
  'use strict'
2
2
 
3
- const { EVENTS } = require('@netlify/config')
3
+ const netlifyConfigPromise = import('@netlify/config')
4
+
5
+ const listEvents = async function () {
6
+ const { EVENTS } = await netlifyConfigPromise
7
+ return EVENTS
8
+ }
4
9
 
5
10
  const isAmongEvents = function (events, event) {
6
11
  return events.includes(event)
@@ -19,7 +24,7 @@ const runsOnlyOnBuildFailure = isAmongEvents.bind(null, ['onError'])
19
24
  const runsAfterDeploy = isAmongEvents.bind(null, ['onSuccess', 'onEnd'])
20
25
 
21
26
  module.exports = {
22
- EVENTS,
27
+ listEvents,
23
28
  isSoftFailEvent,
24
29
  runsAlsoOnBuildFailure,
25
30
  runsOnlyOnBuildFailure,
@@ -3,6 +3,7 @@
3
3
  const { satisfies } = require('semver')
4
4
 
5
5
  const { addErrorInfo } = require('../error/info')
6
+ const { importJsonFile } = require('../utils/json')
6
7
  const { resolvePath } = require('../utils/resolve')
7
8
 
8
9
  const { getExpectedVersion } = require('./compatibility')
@@ -95,8 +96,7 @@ const isMissingVersion = async function ({ autoPluginsDir, packageName, pluginPa
95
96
 
96
97
  const getAutoPluginVersion = async function (packageName, autoPluginsDir) {
97
98
  const packageJsonPath = await resolvePath(`${packageName}/package.json`, autoPluginsDir)
98
- // eslint-disable-next-line node/global-require, import/no-dynamic-require
99
- const { version } = require(packageJsonPath)
99
+ const { version } = await importJsonFile(packageJsonPath)
100
100
  return version
101
101
  }
102
102
 
@@ -4,10 +4,8 @@ const { version: currentVersion, execPath } = require('process')
4
4
 
5
5
  const { satisfies, clean: cleanVersion } = require('semver')
6
6
 
7
- const {
8
- engines: { node: nodeVersionSupportedRange },
9
- } = require('../../package.json')
10
7
  const { addErrorInfo } = require('../error/info')
8
+ const { ROOT_PACKAGE_JSON } = require('../utils/json')
11
9
 
12
10
  // Local plugins and `package.json`-installed plugins use user's preferred Node.js version if higher than our minimum
13
11
  // supported version. Else default to the system Node version.
@@ -29,7 +27,7 @@ const addPluginNodeVersion = function ({
29
27
  nodePath,
30
28
  }) {
31
29
  return (loadedFrom === 'local' || loadedFrom === 'package.json') &&
32
- satisfies(userNodeVersion, nodeVersionSupportedRange)
30
+ satisfies(userNodeVersion, ROOT_PACKAGE_JSON.engines.node)
33
31
  ? { ...pluginOptions, nodePath, nodeVersion: userNodeVersion }
34
32
  : { ...pluginOptions, nodePath: execPath, nodeVersion: currentNodeVersion }
35
33
  }
@@ -2,9 +2,9 @@
2
2
 
3
3
  const { dirname } = require('path')
4
4
 
5
- const corePackageJson = require('../../package.json')
6
5
  const { installLocalPluginsDependencies } = require('../install/local')
7
6
  const { measureDuration } = require('../time/main')
7
+ const { ROOT_PACKAGE_JSON } = require('../utils/json')
8
8
  const { getPackageJson } = require('../utils/package')
9
9
 
10
10
  const { useManifest } = require('./manifest/main')
@@ -83,10 +83,9 @@ const isNotRedundantCorePlugin = function (pluginOptionsA, index, pluginsOptions
83
83
  // Retrieve information about @netlify/build when an error happens there and not
84
84
  // in a plugin
85
85
  const getSpawnInfo = function () {
86
- const { name } = corePackageJson
87
86
  return {
88
- plugin: { packageName: name, pluginPackageJson: corePackageJson },
89
- location: { event: 'load', packageName: name, loadedFrom: 'core', origin: 'core' },
87
+ plugin: { packageName: ROOT_PACKAGE_JSON.name, pluginPackageJson: ROOT_PACKAGE_JSON },
88
+ location: { event: 'load', packageName: ROOT_PACKAGE_JSON.name, loadedFrom: 'core', origin: 'core' },
90
89
  }
91
90
  }
92
91
 
package/src/steps/get.js CHANGED
@@ -1,14 +1,14 @@
1
1
  'use strict'
2
2
 
3
- const { EVENTS } = require('../plugins/events')
3
+ const { listEvents } = require('../plugins/events')
4
4
  const { buildCommandCore } = require('../plugins_core/build_command')
5
5
  const { deploySite } = require('../plugins_core/deploy')
6
6
  const { bundleFunctions } = require('../plugins_core/functions')
7
7
 
8
8
  // Get all build steps
9
- const getSteps = function (steps) {
9
+ const getSteps = async function (steps) {
10
10
  const stepsA = addCoreSteps(steps)
11
- const stepsB = sortSteps(stepsA)
11
+ const stepsB = await sortSteps(stepsA)
12
12
  const events = getEvents(stepsB)
13
13
  return { steps: stepsB, events }
14
14
  }
@@ -18,7 +18,8 @@ const addCoreSteps = function (steps) {
18
18
  }
19
19
 
20
20
  // Sort plugin steps by event order.
21
- const sortSteps = function (steps) {
21
+ const sortSteps = async function (steps) {
22
+ const EVENTS = await listEvents()
22
23
  return EVENTS.flatMap((event) => steps.filter((step) => step.event === event))
23
24
  }
24
25
 
@@ -36,7 +36,7 @@ const updateNetlifyConfig = async function ({
36
36
  headersPath: headersPathA,
37
37
  redirectsPath: redirectsPathA,
38
38
  } = await resolveUpdatedConfig(configOpts, configMutationsA)
39
- logConfigOnUpdate({ logs, netlifyConfig: netlifyConfigA, debug })
39
+ await logConfigOnUpdate({ logs, netlifyConfig: netlifyConfigA, debug })
40
40
  // eslint-disable-next-line fp/no-mutation,no-param-reassign
41
41
  errorParams.netlifyConfig = netlifyConfigA
42
42
  return {
@@ -5,9 +5,9 @@ const { platform } = require('process')
5
5
  const got = require('got')
6
6
  const osName = require('os-name')
7
7
 
8
- const { version: buildVersion } = require('../../package.json')
9
8
  const { addErrorInfo } = require('../error/info')
10
9
  const { roundTimerToMillisecs } = require('../time/measure')
10
+ const { ROOT_PACKAGE_JSON } = require('../utils/json')
11
11
 
12
12
  const DEFAULT_TELEMETRY_TIMEOUT = 1200
13
13
  const DEFAULT_TELEMETRY_CONFIG = {
@@ -89,7 +89,7 @@ const getPayload = function ({
89
89
  buildId,
90
90
  status,
91
91
  steps: stepsCount,
92
- buildVersion,
92
+ buildVersion: ROOT_PACKAGE_JSON.version,
93
93
  // We're passing the node version set by the buildbot/user which will run the `build.command` and
94
94
  // the `package.json`/locally defined plugins
95
95
  nodeVersion: userNodeVersion,
@@ -0,0 +1,22 @@
1
+ 'use strict'
2
+
3
+ const { promises: fs, readFileSync } = require('fs')
4
+
5
+ const ROOT_PACKAGE_JSON_PATH = `${__dirname}/../../package.json`
6
+
7
+ // TODO: Replace with dynamic `import()` once it is supported without
8
+ // experimental flags
9
+ const importJsonFile = async function (filePath) {
10
+ const fileContents = await fs.readFile(filePath, 'utf8')
11
+ return JSON.parse(fileContents)
12
+ }
13
+
14
+ const importJsonFileSync = function (filePath) {
15
+ // Use sync I/O so it is easier to migrate to `import()` later on
16
+ const fileContents = readFileSync(filePath, 'utf8')
17
+ return JSON.parse(fileContents)
18
+ }
19
+
20
+ const ROOT_PACKAGE_JSON = importJsonFileSync(ROOT_PACKAGE_JSON_PATH)
21
+
22
+ module.exports = { importJsonFile, ROOT_PACKAGE_JSON }