@netlify/config 20.7.0 → 20.8.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/lib/base.js CHANGED
@@ -1,26 +1,34 @@
1
1
  import { resolvePath } from './files.js';
2
- // Retrieve the first `base` directory used to load the first config file.
3
- export const getInitialBase = function ({ repositoryRoot, defaultConfig: { build: { base: defaultBase } = {} }, inlineConfig: { build: { base: initialBase = defaultBase } = {} }, }) {
2
+ /**
3
+ * Retrieve the first `base` directory used to load the first config file.
4
+ */
5
+ export const getInitialBase = function ({ repositoryRoot,
6
+ // @ts-expect-error TODO: enhance the types later on, just moved the file to .ts
7
+ defaultConfig: { build: { base: defaultBase } = {} }, inlineConfig: { build: { base: initialBase = defaultBase } = {} }, }) {
4
8
  return resolveBase(repositoryRoot, initialBase);
5
9
  };
6
- // Two config files can be used:
7
- // - The first one, using the `config` property or doing a default lookup
8
- // of `netlify.toml`
9
- // - If the first one has a `base` property pointing to a directory with
10
- // another `netlify.toml`, that second config file is used instead.
11
- // This retrieves the final `base` directory used:
12
- // - To load the second config file
13
- // - As the `buildDir`
14
- // - To resolve file paths
15
- // If the second file has a `base` property, it is ignored, i.e. it is not
16
- // recursive.
10
+ /**
11
+ * Two config files can be used:
12
+ * - The first one, using the `config` property or doing a default lookup
13
+ * of `netlify.toml`
14
+ * - If the first one has a `base` property pointing to a directory with
15
+ * another `netlify.toml`, that second config file is used instead.
16
+ * This retrieves the final `base` directory used:
17
+ * - To load the second config file
18
+ * - As the `buildDir`
19
+ * - To resolve file paths
20
+ * If the second file has a `base` property, it is ignored, i.e. it is not
21
+ * recursive.
22
+ */
17
23
  export const getBase = function (base, repositoryRoot, config) {
18
24
  return base === undefined ? resolveBase(repositoryRoot, config.build.base) : base;
19
25
  };
20
26
  const resolveBase = function (repositoryRoot, base) {
21
27
  return resolvePath(repositoryRoot, repositoryRoot, base, 'build.base');
22
28
  };
23
- // Also `config.build.base`.
29
+ /**
30
+ * Also `config.build.base`.
31
+ */
24
32
  export const addBase = function (config, base) {
25
33
  return { ...config, build: { ...config.build, base } };
26
34
  };
package/lib/bin/flags.js CHANGED
@@ -72,6 +72,10 @@ Default: empty array.`,
72
72
  describe: `Current directory. Used to retrieve the configuration file.
73
73
  Default: current directory`,
74
74
  },
75
+ packagePath: {
76
+ string: true,
77
+ describe: `A relative path from the repository root to the package. Used inside monorepos to specify a package`,
78
+ },
75
79
  repositoryRoot: {
76
80
  string: true,
77
81
  describe: `Git repository root directory. Used to retrieve the configuration file.
package/lib/build_dir.js CHANGED
@@ -1,19 +1,23 @@
1
1
  import { isDirectory } from 'path-type';
2
2
  import { throwUserError } from './error.js';
3
- // Retrieve the build directory used to resolve most paths.
4
- // This is (in priority order):
5
- // - `build.base`
6
- // - `--repositoryRoot`
7
- // - the current directory (default value of `--repositoryRoot`)
3
+ /**
4
+ * Retrieve the build directory used to resolve most paths.
5
+ * This is (in priority order):
6
+ * - `build.base`
7
+ * - `--repositoryRoot`
8
+ * - the current directory (default value of `--repositoryRoot`)
9
+ */
8
10
  export const getBuildDir = async function (repositoryRoot, base) {
9
11
  const buildDir = base === undefined ? repositoryRoot : base;
10
12
  await checkBuildDir(buildDir, repositoryRoot);
11
13
  return buildDir;
12
14
  };
13
- // The build directory is used as the current directory of build commands and
14
- // build plugins. Therefore, it must exist.
15
- // We already check `repositoryRoot` earlier in the code, so only need to check
16
- // `buildDir` when it is the base directory instead.
15
+ /**
16
+ * The build directory is used as the current directory of build commands and
17
+ * build plugins. Therefore, it must exist.
18
+ * We already check `repositoryRoot` earlier in the code, so only need to check
19
+ * `buildDir` when it is the base directory instead.
20
+ */
17
21
  const checkBuildDir = async function (buildDir, repositoryRoot) {
18
22
  if (buildDir === repositoryRoot || (await isDirectory(buildDir))) {
19
23
  return;
package/lib/files.js CHANGED
@@ -1,26 +1,44 @@
1
1
  import { existsSync } from 'fs';
2
- import { resolve, relative, parse } from 'path';
2
+ import { resolve, relative, parse, join } from 'path';
3
3
  import { getProperty, setProperty, deleteProperty } from 'dot-prop';
4
4
  import { throwUserError } from './error.js';
5
5
  import { mergeConfigs } from './merge.js';
6
6
  import { isTruthy } from './utils/remove_falsy.js';
7
- // Make configuration paths relative to `buildDir` and converts them to
8
- // absolute paths
9
- export const resolveConfigPaths = function ({ config, repositoryRoot, buildDir, baseRelDir }) {
10
- const baseRel = baseRelDir ? buildDir : repositoryRoot;
11
- const configA = resolvePaths(config, FILE_PATH_CONFIG_PROPS, baseRel, repositoryRoot);
12
- const configB = addDefaultPaths(configA, repositoryRoot, baseRel);
13
- return configB;
14
- };
15
- // All file paths in the configuration file are relative to `buildDir`
16
- // (if `baseRelDir` is `true`).
7
+ /**
8
+ * We allow paths in configuration file to start with /
9
+ * In that case, those are actually relative paths not absolute.
10
+ */
11
+ const LEADING_SLASH_REGEXP = /^\/+/;
12
+ /**
13
+ * All file paths in the configuration file are relative to `buildDir`
14
+ * (if `baseRelDir` is `true`).
15
+ */
17
16
  const FILE_PATH_CONFIG_PROPS = [
18
17
  'functionsDirectory',
19
18
  'functions.*.deno_import_map',
20
19
  'build.publish',
21
20
  'build.edge_functions',
22
21
  ];
23
- const resolvePaths = function (config, propNames, baseRel, repositoryRoot) {
22
+ /**
23
+ * Make configuration paths relative to `buildDir` and converts them to
24
+ * absolute paths
25
+ */
26
+ export const resolveConfigPaths = function (options) {
27
+ const baseRel = options.baseRelDir ? options.buildDir : options.repositoryRoot;
28
+ const config = resolvePaths({
29
+ config: options.config,
30
+ propNames: FILE_PATH_CONFIG_PROPS,
31
+ baseRel,
32
+ repositoryRoot: options.repositoryRoot,
33
+ });
34
+ return addDefaultPaths({
35
+ config,
36
+ repositoryRoot: options.repositoryRoot,
37
+ baseRel,
38
+ packagePath: options.packagePath,
39
+ });
40
+ };
41
+ const resolvePaths = function ({ config, propNames, baseRel, repositoryRoot, }) {
24
42
  return propNames.reduce((configA, propName) => resolvePathProp(configA, propName, baseRel, repositoryRoot), config);
25
43
  };
26
44
  const resolvePathProp = function (config, propName, baseRel, repositoryRoot) {
@@ -31,7 +49,7 @@ const resolvePathProp = function (config, propName, baseRel, repositoryRoot) {
31
49
  }
32
50
  return setProperty(config, propName, resolvePath(repositoryRoot, baseRel, path, propName));
33
51
  };
34
- export const resolvePath = function (repositoryRoot, baseRel, originalPath, propName) {
52
+ export const resolvePath = (repositoryRoot, baseRel, originalPath, propName) => {
35
53
  if (!isTruthy(originalPath)) {
36
54
  return;
37
55
  }
@@ -40,24 +58,23 @@ export const resolvePath = function (repositoryRoot, baseRel, originalPath, prop
40
58
  validateInsideRoot(originalPath, pathA, repositoryRoot, propName);
41
59
  return pathA;
42
60
  };
43
- // We allow paths in configuration file to start with /
44
- // In that case, those are actually relative paths not absolute.
45
- const LEADING_SLASH_REGEXP = /^\/+/;
46
- // We ensure all file paths are within the repository root directory.
47
- // However, we allow file paths to be outside the build directory, since this
48
- // can be convenient in monorepo setups.
49
- const validateInsideRoot = function (originalPath, path, repositoryRoot, propName) {
61
+ /**
62
+ * We ensure all file paths are within the repository root directory.
63
+ * However, we allow file paths to be outside the build directory, since this
64
+ * can be convenient in monorepo setups.
65
+ */
66
+ const validateInsideRoot = (originalPath, path, repositoryRoot, propName) => {
50
67
  if (relative(repositoryRoot, path).startsWith('..') || getWindowsDrive(repositoryRoot) !== getWindowsDrive(path)) {
51
68
  throwUserError(`Configuration property "${propName}" "${originalPath}" must be inside the repository root directory.`);
52
69
  }
53
70
  };
54
- const getWindowsDrive = function (path) {
55
- return parse(path).root;
56
- };
57
- // Some configuration properties have default values that are only set if a
58
- // specific directory/file exists in the build directory
59
- const addDefaultPaths = function (config, repositoryRoot, baseRel) {
60
- const defaultPathsConfigs = DEFAULT_PATHS.map(({ defaultPath, getConfig, propName }) => addDefaultPath({ repositoryRoot, baseRel, defaultPath, getConfig, propName })).filter(Boolean);
71
+ const getWindowsDrive = (path) => parse(path).root;
72
+ /**
73
+ * Some configuration properties have default values that are only set if a
74
+ * specific directory/file exists in the build directory
75
+ */
76
+ const addDefaultPaths = ({ config, repositoryRoot, baseRel, packagePath, }) => {
77
+ const defaultPathsConfigs = DEFAULT_PATHS.map(({ defaultPath, getConfig, propName }) => addDefaultPath({ repositoryRoot, packagePath, baseRel, defaultPath, getConfig, propName })).filter(Boolean);
61
78
  return mergeConfigs([...defaultPathsConfigs, config]);
62
79
  };
63
80
  const DEFAULT_PATHS = [
@@ -78,9 +95,9 @@ const DEFAULT_PATHS = [
78
95
  propName: 'build.edge_functions',
79
96
  },
80
97
  ];
81
- const addDefaultPath = function ({ repositoryRoot, baseRel, defaultPath, getConfig, propName }) {
82
- const absolutePath = resolvePath(repositoryRoot, baseRel, defaultPath, propName);
83
- if (!existsSync(absolutePath)) {
98
+ const addDefaultPath = ({ repositoryRoot, packagePath, baseRel, defaultPath, getConfig, propName, }) => {
99
+ const absolutePath = resolvePath(repositoryRoot, join(baseRel, packagePath || ''), defaultPath, propName);
100
+ if (!absolutePath || !existsSync(absolutePath)) {
84
101
  return;
85
102
  }
86
103
  return getConfig(absolutePath);
package/lib/main.js CHANGED
@@ -17,11 +17,13 @@ import { UI_ORIGIN, CONFIG_ORIGIN, INLINE_ORIGIN } from './origin.js';
17
17
  import { parseConfig } from './parse.js';
18
18
  import { getConfigPath } from './path.js';
19
19
  import { getRedirectsPath, addRedirects } from './redirects.js';
20
- // Load the configuration file.
21
- // Takes an optional configuration file path as input and return the resolved
22
- // `config` together with related properties such as the `configPath`.
20
+ /**
21
+ * Load the configuration file.
22
+ * Takes an optional configuration file path as input and return the resolved
23
+ * `config` together with related properties such as the `configPath`.
24
+ */
23
25
  export const resolveConfig = async function (opts) {
24
- const { cachedConfig, cachedConfigPath, host, scheme, pathPrefix, testOpts, token, offline, siteFeatureFlagPrefix, ...optsA } = addDefaultOpts(opts);
26
+ const { cachedConfig, cachedConfigPath, host, scheme, packagePath, pathPrefix, testOpts, token, offline, siteFeatureFlagPrefix, ...optsA } = addDefaultOpts(opts);
25
27
  // `api` is not JSON-serializable, so we cannot cache it inside `cachedConfig`
26
28
  const api = getApiClient({ token, offline, host, scheme, pathPrefix, testOpts });
27
29
  const parsedCachedConfig = await getCachedConfig({ cachedConfig, cachedConfigPath, token, api });
@@ -52,6 +54,7 @@ export const resolveConfig = async function (opts) {
52
54
  cwd,
53
55
  context,
54
56
  repositoryRoot,
57
+ packagePath,
55
58
  branch,
56
59
  defaultConfig: defaultConfigA,
57
60
  inlineConfig: inlineConfigA,
@@ -95,8 +98,10 @@ export const resolveConfig = async function (opts) {
95
98
  logResult(result, { logs, debug });
96
99
  return result;
97
100
  };
98
- // Adds a `build.functions` property that mirrors `functionsDirectory`, for
99
- // backward compatibility.
101
+ /**
102
+ * Adds a `build.functions` property that mirrors `functionsDirectory`, for
103
+ * backward compatibility.
104
+ */
100
105
  const addLegacyFunctionsDirectory = (config) => {
101
106
  if (!config.functionsDirectory) {
102
107
  return config;
@@ -109,10 +114,12 @@ const addLegacyFunctionsDirectory = (config) => {
109
114
  },
110
115
  };
111
116
  };
112
- // Try to load the configuration file in two passes.
113
- // The first pass uses the `defaultConfig`'s `build.base` (if defined).
114
- // The second pass uses the `build.base` from the first pass (if defined).
115
- const loadConfig = async function ({ configOpt, cwd, context, repositoryRoot, branch, defaultConfig, inlineConfig, baseRelDir, logs, featureFlags, }) {
117
+ /**
118
+ * Try to load the configuration file in two passes.
119
+ * The first pass uses the `defaultConfig`'s `build.base` (if defined).
120
+ * The second pass uses the `build.base` from the first pass (if defined).
121
+ */
122
+ const loadConfig = async function ({ configOpt, cwd, context, repositoryRoot, packagePath, branch, defaultConfig, inlineConfig, baseRelDir, logs, featureFlags, }) {
116
123
  const initialBase = getInitialBase({ repositoryRoot, defaultConfig, inlineConfig });
117
124
  const { configPath, config, buildDir, base, redirectsPath, headersPath } = await getFullConfig({
118
125
  configOpt,
@@ -123,6 +130,7 @@ const loadConfig = async function ({ configOpt, cwd, context, repositoryRoot, br
123
130
  defaultConfig,
124
131
  inlineConfig,
125
132
  baseRelDir,
133
+ packagePath,
126
134
  configBase: initialBase,
127
135
  logs,
128
136
  featureFlags,
@@ -158,9 +166,17 @@ const loadConfig = async function ({ configOpt, cwd, context, repositoryRoot, br
158
166
  headersPath: headersPathA,
159
167
  };
160
168
  };
161
- // Load configuration file and normalize it, merge contexts, etc.
162
- const getFullConfig = async function ({ configOpt, cwd, context, repositoryRoot, branch, defaultConfig, inlineConfig, baseRelDir, configBase, base, logs, featureFlags, }) {
163
- const configPath = await getConfigPath({ configOpt, cwd, repositoryRoot, configBase });
169
+ /**
170
+ * Load configuration file and normalize it, merge contexts, etc.
171
+ */
172
+ const getFullConfig = async function ({ configOpt, cwd, context, repositoryRoot, packagePath, branch, defaultConfig, inlineConfig, baseRelDir, configBase, base, logs, featureFlags, }) {
173
+ const configPath = await getConfigPath({
174
+ configOpt,
175
+ cwd,
176
+ repositoryRoot,
177
+ packagePath,
178
+ configBase,
179
+ });
164
180
  try {
165
181
  const config = await parseConfig(configPath);
166
182
  const configA = mergeAndNormalizeConfig({
@@ -170,8 +186,9 @@ const getFullConfig = async function ({ configOpt, cwd, context, repositoryRoot,
170
186
  context,
171
187
  branch,
172
188
  logs,
189
+ packagePath,
173
190
  });
174
- const { config: configB, buildDir, base: baseA, } = await resolveFiles({ config: configA, repositoryRoot, base, baseRelDir });
191
+ const { config: configB, buildDir, base: baseA, } = await resolveFiles({ packagePath, config: configA, repositoryRoot, base, baseRelDir });
175
192
  const headersPath = getHeadersPath(configB);
176
193
  const configC = await addHeaders({ config: configB, headersPath, logs, featureFlags });
177
194
  const redirectsPath = getRedirectsPath(configC);
@@ -184,33 +201,36 @@ const getFullConfig = async function ({ configOpt, cwd, context, repositoryRoot,
184
201
  throw error;
185
202
  }
186
203
  };
187
- // Merge:
188
- // - `--defaultConfig`: UI build settings and UI-installed plugins
189
- // - `inlineConfig`: Netlify CLI flags
190
- // Then merge context-specific configuration.
191
- // Before and after those steps, also performs validation and normalization.
192
- // Those need to be done at different stages depending on whether they should
193
- // happen before/after the merges mentioned above.
194
- const mergeAndNormalizeConfig = function ({ config, defaultConfig, inlineConfig, context, branch, logs }) {
204
+ /**
205
+ * Merge:
206
+ * - `--defaultConfig`: UI build settings and UI-installed plugins
207
+ * - `inlineConfig`: Netlify CLI flags
208
+ * Then merge context-specific configuration.
209
+ * Before and after those steps, also performs validation and normalization.
210
+ * Those need to be done at different stages depending on whether they should
211
+ * happen before/after the merges mentioned above.
212
+ */
213
+ const mergeAndNormalizeConfig = function ({ config, defaultConfig, inlineConfig, context, branch, logs, packagePath }) {
195
214
  const configA = normalizeConfigAndContext(config, CONFIG_ORIGIN);
196
215
  const defaultConfigA = normalizeConfigAndContext(defaultConfig, UI_ORIGIN);
197
216
  const inlineConfigA = normalizeConfigAndContext(inlineConfig, INLINE_ORIGIN);
198
217
  const configB = mergeConfigs([defaultConfigA, configA]);
199
218
  const configC = mergeContext({ config: configB, context, branch, logs });
200
219
  const configD = mergeConfigs([configC, inlineConfigA]);
201
- const configE = normalizeAfterConfigMerge(configD);
202
- return configE;
220
+ return normalizeAfterConfigMerge(configD, packagePath);
203
221
  };
204
222
  const normalizeConfigAndContext = function (config, origin) {
205
223
  const configA = normalizeBeforeConfigMerge(config, origin);
206
224
  const configB = normalizeContextProps({ config: configA, origin });
207
225
  return configB;
208
226
  };
209
- // Find base directory, build directory and resolve all paths to absolute paths
210
- const resolveFiles = async function ({ config, repositoryRoot, base, baseRelDir }) {
227
+ /**
228
+ * Find base directory, build directory and resolve all paths to absolute paths
229
+ */
230
+ const resolveFiles = async function ({ config, repositoryRoot, base, packagePath, baseRelDir, }) {
211
231
  const baseA = getBase(base, repositoryRoot, config);
212
232
  const buildDir = await getBuildDir(repositoryRoot, baseA);
213
- const configA = resolveConfigPaths({ config, repositoryRoot, buildDir, baseRelDir });
233
+ const configA = resolveConfigPaths({ config, packagePath, repositoryRoot, buildDir, baseRelDir });
214
234
  const configB = addBase(configA, baseA);
215
235
  return { config: configB, buildDir, base: baseA };
216
236
  };
@@ -3,10 +3,12 @@ import { normalizeConfig } from './normalize.js';
3
3
  import { addOrigins } from './origin.js';
4
4
  import { validateIdenticalPlugins } from './validate/identical.js';
5
5
  import { validatePreCaseNormalize, validatePreMergeConfig, validatePreNormalizeConfig, validatePostNormalizeConfig, } from './validate/main.js';
6
- // Perform validation and normalization logic to apply to all of:
7
- // - config, defaultConfig, inlineConfig
8
- // - context-specific configs
9
- // Therefore, this is performing before merging those together.
6
+ /**
7
+ * Perform validation and normalization logic to apply to all of:
8
+ * - config, defaultConfig, inlineConfig
9
+ * - context-specific configs
10
+ * Therefore, this is performing before merging those together.
11
+ */
10
12
  export const normalizeBeforeConfigMerge = function (config, origin) {
11
13
  validatePreCaseNormalize(config);
12
14
  const configA = normalizeConfigCase(config);
@@ -15,10 +17,12 @@ export const normalizeBeforeConfigMerge = function (config, origin) {
15
17
  validateIdenticalPlugins(configB);
16
18
  return configB;
17
19
  };
18
- // Validation and normalization logic performed after merging
19
- export const normalizeAfterConfigMerge = function (config) {
20
+ /**
21
+ * Validation and normalization logic performed after merging
22
+ */
23
+ export const normalizeAfterConfigMerge = function (config, packagePath) {
20
24
  validatePreNormalizeConfig(config);
21
- const configA = normalizeConfig(config);
25
+ const configA = normalizeConfig(config, packagePath);
22
26
  validatePostNormalizeConfig(configA);
23
27
  return configA;
24
28
  };
package/lib/normalize.js CHANGED
@@ -2,31 +2,35 @@ import { normalizeFunctionsProps, WILDCARD_ALL } from './functions_config.js';
2
2
  import { mergeConfigs } from './merge.js';
3
3
  import { DEFAULT_ORIGIN } from './origin.js';
4
4
  import { removeFalsy } from './utils/remove_falsy.js';
5
- // Normalize configuration object
6
- export const normalizeConfig = function (config) {
5
+ /**
6
+ * Normalize configuration object
7
+ */
8
+ export const normalizeConfig = function (config, packagePath) {
7
9
  const configA = removeEmpty(config);
8
- const { build, functions, plugins, ...configB } = mergeConfigs([DEFAULT_CONFIG, configA]);
10
+ const { build, functions, plugins, ...configB } = mergeConfigs([DEFAULT_CONFIG(packagePath), configA]);
9
11
  const { build: buildA, functions: functionsA, functionsDirectoryProps } = normalizeFunctionsProps(build, functions);
10
12
  const pluginsA = plugins.map(normalizePlugin);
11
13
  return { ...configB, build: buildA, functions: functionsA, plugins: pluginsA, ...functionsDirectoryProps };
12
14
  };
13
- // Remove empty strings.
14
- // This notably ensures that empty strings in the build command are removed.
15
- // Otherwise, those would be run during builds, making the build fail.
15
+ /**
16
+ * Remove empty strings.
17
+ * This notably ensures that empty strings in the build command are removed.
18
+ * Otherwise, those would be run during builds, making the build fail.
19
+ */
16
20
  const removeEmpty = function ({ build, ...config }) {
17
21
  return removeFalsy({ ...config, build: removeFalsy(build) });
18
22
  };
19
- const DEFAULT_CONFIG = {
23
+ const DEFAULT_CONFIG = (packagePath) => ({
20
24
  build: {
21
25
  environment: {},
22
- publish: '.',
26
+ publish: packagePath || '.',
23
27
  publishOrigin: DEFAULT_ORIGIN,
24
28
  processing: { css: {}, html: {}, images: {}, js: {} },
25
29
  services: {},
26
30
  },
27
31
  functions: { [WILDCARD_ALL]: {} },
28
32
  plugins: [],
29
- };
33
+ });
30
34
  const normalizePlugin = function ({ inputs = {}, ...plugin }) {
31
35
  return removeFalsy({ ...plugin, inputs });
32
36
  };
package/lib/path.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { existsSync } from 'fs';
2
- import { resolve } from 'path';
2
+ import { join, resolve } from 'path';
3
3
  import { findUp } from 'find-up';
4
4
  import pLocate from 'p-locate';
5
+ const FILENAME = 'netlify.toml';
5
6
  /**
6
7
  * Configuration location can be:
7
8
  * - a local path with the --config CLI flag
@@ -9,10 +10,10 @@ import pLocate from 'p-locate';
9
10
  * - a `netlify.*` file in the `repositoryRoot`
10
11
  * - a `netlify.*` file in the current directory or any parent
11
12
  */
12
- export const getConfigPath = async function ({ configOpt, cwd, repositoryRoot, configBase }) {
13
+ export const getConfigPath = async function ({ configOpt, cwd, repositoryRoot, configBase, packagePath, }) {
13
14
  const configPath = await pLocate([
14
15
  searchConfigOpt(cwd, configOpt),
15
- searchBaseConfigFile(configBase),
16
+ searchBaseConfigFile(repositoryRoot, configBase, packagePath),
16
17
  searchConfigFile(repositoryRoot),
17
18
  findUp(FILENAME, { cwd }),
18
19
  ], Boolean);
@@ -26,13 +27,14 @@ const searchConfigOpt = function (cwd, configOpt) {
26
27
  return resolve(cwd, configOpt);
27
28
  };
28
29
  /**
29
- * Look for `repositoryRoot/{base}/netlify.*`
30
+ * Look for `repositoryRoot/{base}/{packagePath || '}/netlify.*`
30
31
  */
31
- const searchBaseConfigFile = function (configBase) {
32
- if (configBase === undefined) {
32
+ const searchBaseConfigFile = function (repoRoot, base, packagePath) {
33
+ if (base === undefined && packagePath === undefined) {
33
34
  return;
34
35
  }
35
- return searchConfigFile(configBase);
36
+ const cwd = join(base ? base : repoRoot, packagePath || '');
37
+ return searchConfigFile(cwd);
36
38
  };
37
39
  /**
38
40
  * Look for several file extensions for `netlify.*`
@@ -44,4 +46,3 @@ const searchConfigFile = function (cwd) {
44
46
  }
45
47
  return path;
46
48
  };
47
- const FILENAME = 'netlify.toml';
package/lib/redirects.js CHANGED
@@ -6,13 +6,14 @@ export const getRedirectsPath = function ({ build: { publish } }) {
6
6
  return resolve(publish, REDIRECTS_FILENAME);
7
7
  };
8
8
  const REDIRECTS_FILENAME = '_redirects';
9
- // Add `config.redirects`
10
- export const addRedirects = async function ({ config: { redirects: configRedirects, ...config }, redirectsPath, logs, featureFlags, }) {
9
+ /**
10
+ * Add `config.redirects`
11
+ */
12
+ export const addRedirects = async function ({ config: { redirects: configRedirects, ...config }, redirectsPath, logs, }) {
11
13
  const { redirects, errors } = await parseAllRedirects({
12
14
  redirectsFiles: [redirectsPath],
13
15
  configRedirects,
14
16
  minimal: true,
15
- featureFlags,
16
17
  });
17
18
  warnRedirectsParsing(logs, errors);
18
19
  return { ...config, redirects };
@@ -1,14 +1,10 @@
1
1
  import { includeKeys } from 'filter-obj';
2
- // Remove falsy values from object
2
+ /**
3
+ * Remove falsy values from object
4
+ */
3
5
  export const removeFalsy = function (obj) {
4
- return includeKeys(obj, (key, value) => isTruthy(value));
5
- };
6
- export const removeUndefined = function (obj) {
7
- return includeKeys(obj, (key, value) => isDefined(value));
8
- };
9
- export const isTruthy = function (value) {
10
- return isDefined(value) && (typeof value !== 'string' || value.trim() !== '');
11
- };
12
- export const isDefined = function (value) {
13
- return value !== undefined && value !== null;
6
+ return includeKeys(obj, (_key, value) => isTruthy(value));
14
7
  };
8
+ export const removeUndefined = (obj) => includeKeys(obj, (_key, value) => isDefined(value));
9
+ export const isTruthy = (value) => isDefined(value) && (typeof value !== 'string' || value.trim() !== '');
10
+ export const isDefined = (value) => value !== undefined && value !== null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/config",
3
- "version": "20.7.0",
3
+ "version": "20.8.0",
4
4
  "description": "Netlify config module",
5
5
  "type": "module",
6
6
  "exports": "./lib/index.js",
@@ -72,7 +72,7 @@
72
72
  "map-obj": "^5.0.0",
73
73
  "netlify": "^13.1.10",
74
74
  "netlify-headers-parser": "^7.1.2",
75
- "netlify-redirect-parser": "^14.1.3",
75
+ "netlify-redirect-parser": "^14.2.0",
76
76
  "node-fetch": "^3.3.1",
77
77
  "omit.js": "^2.0.2",
78
78
  "p-locate": "^6.0.0",
@@ -94,5 +94,5 @@
94
94
  "engines": {
95
95
  "node": "^14.16.0 || >=16.0.0"
96
96
  },
97
- "gitHead": "a20207ec7cdc1101a875d9411355bd48f12733a3"
97
+ "gitHead": "0c6f5c014958f692559ea720c38415a0e63b7522"
98
98
  }