Skip to content

Commit

Permalink
Improve prefixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Feb 13, 2022
1 parent a2e571f commit 799399a
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 58 deletions.
2 changes: 1 addition & 1 deletion src/config/normalize/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { cleanObject } from '../../../utils/clean.js'

import { applyDefinition } from './definition.js'
import { addCwd } from './path.js'
import { DEFAULT_PREFIX } from './prefix.js'
import { list } from './prop_path/get.js'
import { parse } from './prop_path/parse.js'
import { set, remove } from './prop_path/set.js'
import { DEFAULT_PREFIX } from './validate.js'

// Normalize configuration shape and do custom validation.
// An array of definition objects is passed.
Expand Down
60 changes: 60 additions & 0 deletions src/config/normalize/lib/prefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { normalizeError } from '../../../error/utils.js'
import { wrapError } from '../../../error/wrap.js'
import { maybeFunction } from '../../../utils/function.js'

// Append `prefix` option to error message.
// The space at the end of `prefix` is optional.
// If `prefix` ends with `.`:
// - The default prefix is prepended.
// - No space is appended.
// Also surround property name with quotes.
export const addPropPrefix = async function (error, opts) {
const prefix = await getPrefix(opts)
const propName = `${prefix}${opts.name}`
const propNameA = quotePropName(propName)
return wrapError(error, propNameA)
}

// Default value for the `prefix` option
export const DEFAULT_PREFIX = 'Configuration property'

const getPrefix = async function (opts) {
const prefix = await callPrefix(opts)

if (prefix === undefined) {
return `${DEFAULT_PREFIX} `
}

const prefixA = String(prefix)

if (prefixA.endsWith('.')) {
return `${DEFAULT_PREFIX} ${prefixA}`
}

return shouldAppendSpace(prefixA) ? `${prefixA} ` : prefixA
}

const callPrefix = async function ({ prefix, ...opts }) {
try {
return await maybeFunction(prefix, opts)
} catch (error) {
const { message } = normalizeError(error)
return `${message}\n`
}
}

const shouldAppendSpace = function (prefix) {
return prefix !== '' && !prefix.endsWith(' ')
}

const quotePropName = function (propName) {
const lastSpaceIndex = propName.lastIndexOf(' ')
const [firstWords, lastWord] =
lastSpaceIndex === -1
? ['', propName]
: [
propName.slice(0, lastSpaceIndex + 1),
propName.slice(lastSpaceIndex + 1),
]
return `${firstWords}"${lastWord}"`
}
41 changes: 1 addition & 40 deletions src/config/normalize/lib/validate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { normalizeError } from '../../../error/utils.js'
import { wrapError } from '../../../error/wrap.js'
import { maybeFunction } from '../../../utils/function.js'
import { addPropPrefix } from './prefix.js'

// Consumers can distinguish users errors from system bugs by checking
// the `error.validation` boolean property.
Expand Down Expand Up @@ -34,40 +32,3 @@ export const throwValidateError = async function (message, opts) {
const setValidationProp = function (error) {
error.validation = true
}

const addPropPrefix = async function (error, opts) {
const propName = await getPropName(opts)
const propNameA = quotePropName(propName)
return wrapError(error, propNameA)
}

export const DEFAULT_PREFIX = 'Configuration property'

const getPropName = async function (opts) {
const prefix = await callPrefix(opts)
const space =
prefix === '' || prefix.endsWith(' ') || prefix.endsWith('.') ? '' : ' '
return `${prefix}${space}${opts.name}`
}

const quotePropName = function (propName) {
const lastSpaceIndex = propName.lastIndexOf(' ')
const [firstWords, lastWord] =
lastSpaceIndex === -1
? ['', propName]
: [
propName.slice(0, lastSpaceIndex + 1),
propName.slice(lastSpaceIndex + 1),
]
return `${firstWords}"${lastWord}"`
}

const callPrefix = async function ({ prefix, ...opts }) {
try {
const prefixA = await maybeFunction(prefix, opts)
return String(prefixA)
} catch (error) {
const { message } = normalizeError(error)
return `${message}\n`
}
}
3 changes: 1 addition & 2 deletions src/config/plugin/lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ export const normalizePluginConfig = async function ({
}

const getPrefix = function (unmergedConfig, propName, { path }) {
const prefix = has(unmergedConfig, path) ? `${propName}.` : ''
return `Configuration property ${prefix}`
return has(unmergedConfig, path) ? `${propName}.` : undefined
}

const normalizeSharedConfig = async function ({
Expand Down
28 changes: 13 additions & 15 deletions src/config/plugin/lib/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ export const normalizeList = async function ({
context,
cwd,
}) {
const definitions = getListDefinitions(name, list, pluginProp)
const { [name]: pluginConfigsA } = await normalizeConfig(
{ [name]: pluginConfigs },
definitions,
{ context: { ...context, builtins, pluginProp, modulePrefix }, cwd },
)
const definitions = getListDefinitions(list, pluginProp)
const pluginConfigsA = await normalizeConfig(pluginConfigs, definitions, {
context: { ...context, builtins, pluginProp, modulePrefix },
cwd,
prefix: `${name}.`,
})
return pluginConfigsA
}

const getListDefinitions = function (name, list, pluginProp) {
const getListDefinitions = function (list, pluginProp) {
return [
{ ...list, name, ...normalizeListProp },
{ name: `${name}.*`, ...normalizeItem },
{ name: `${name}.*.moduleId`, ...normalizeItemModuleId },
{ name: `${name}.*.${pluginProp}`, ...normalizeItemId },
{ ...list, name: '', ...normalizeListProp },
{ name: '*', ...normalizeItem },
{ name: '*.moduleId', ...normalizeItemModuleId },
{ name: `*.${pluginProp}`, ...normalizeItemId },
]
}

Expand All @@ -57,11 +57,9 @@ const normalizeItem = {
const normalizeItemModuleId = {
compute({
context: { builtins, modulePrefix },
path: [name, index],
path: [index],
config: {
[name]: {
[index]: { id },
},
[index]: { id },
},
}) {
return isModuleId(id, modulePrefix, builtins) ? id : undefined
Expand Down

0 comments on commit 799399a

Please sign in to comment.