Skip to content

Commit

Permalink
Move files
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Feb 27, 2022
1 parent d9b2159 commit 7e281db
Show file tree
Hide file tree
Showing 19 changed files with 170 additions and 134 deletions.
2 changes: 1 addition & 1 deletion src/config/cwd.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import filterObj from 'filter-obj'
import { recurseValues } from '../utils/recurse.js'

import { canRecurse } from './merge.js'
import { get } from './normalize/lib/star_dot_path/get.js'
import { get } from './normalize/lib/star_dot_path/main.js'

// When resolving configuration relative file paths:
// - The CLI and programmatic flags always use the current directory.
Expand Down
9 changes: 6 additions & 3 deletions src/config/load/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import { UserError } from '../../error/main.js'
import { findValues } from '../../utils/recurse.js'
import { addBases, getBasePath } from '../cwd.js'
import { deepMerge, canRecurse } from '../merge.js'
import { get, has } from '../normalize/lib/star_dot_path/get.js'
import { serialize } from '../normalize/lib/star_dot_path/parse.js'
import { set } from '../normalize/lib/star_dot_path/set.js'
import {
get,
has,
serialize,
set,
} from '../normalize/lib/star_dot_path/main.js'

import { loadConfigContents } from './contents.js'
import { normalizeConfigProp } from './normalize.js'
Expand Down
3 changes: 1 addition & 2 deletions src/config/normalize/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import { cleanObject } from '../../../utils/clean.js'
import { applyRule } from './apply.js'
import { addMoves } from './move.js'
import { getOpts } from './opts.js'
import { list } from './star_dot_path/get.js'
import { set, remove } from './star_dot_path/set.js'
import { normalizeRule } from './rule.js'
import { list, set, remove } from './star_dot_path/main.js'
import { addWarnings, logWarnings } from './warn.js'

// Normalize configuration shape and do custom validation.
Expand Down
2 changes: 1 addition & 1 deletion src/config/normalize/lib/modify.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { callValueFunc, callUserFunc, getValidateExampleError } from './call.js'
import { resolvePath } from './path.js'
import { has } from './star_dot_path/get.js'
import { has } from './star_dot_path/main.js'
import { transformValue } from './transform.js'
import { getWarnings } from './warn.js'

Expand Down
2 changes: 1 addition & 1 deletion src/config/normalize/lib/opts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { getCwd } from './cwd.js'
import { applyMoves } from './move.js'
import { appendParentToName } from './parent.js'
import { getPrefix, DEFAULT_PREFIX } from './prefix.js'
import { parse, tokensToPath } from './star_dot_path/parse.js'
import { parse, tokensToPath } from './star_dot_path/main.js'

// Retrieve `opts` passed to most methods.
// `funcOpts` are passed to user-provided functions.
Expand Down
2 changes: 1 addition & 1 deletion src/config/normalize/lib/rule.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get } from './star_dot_path/get.js'
import { get } from './star_dot_path/main.js'

// Validate and normalize rules
export const normalizeRule = function (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,7 @@
import isPlainObj from 'is-plain-obj'

import { isAnyPart } from './parse.js'

// List all values (and their associated path) matching a specific query for
// on specific target value.
export const listEntries = function (target, tokens) {
return tokens.reduce(listTokenEntries, [{ value: target, path: [] }])
}

const listTokenEntries = function (entries, token) {
return entries.flatMap((entry) => getTokenEntries(entry, token))
}

const getTokenEntries = function ({ value, path }, token) {
if (token.length > 1) {
return getComplexEntries(value, path, token)
}

const [part] = token
return isAnyPart(part)
? getAnyEntries(value, path)
: getKeyEntries(value, path, part)
}

// For queries which use * combined with other characters, e.g. `a.b*c`
const getComplexEntries = function (value, path, token) {
export const getComplexEntries = function (value, path, token) {
if (!isPlainObj(value)) {
return []
}
Expand Down Expand Up @@ -83,29 +60,3 @@ const startsWith = function (string, prefix, startIndex) {
}
/* eslint-enable complexity, max-depth, fp/no-loops, fp/no-let, max-params,
fp/no-mutation */

// For queries which use * on its own, e.g. `a.*`
const getAnyEntries = function (value, path) {
if (Array.isArray(value)) {
return value.map((childValue, index) => ({
value: childValue,
path: [...path, index],
}))
}

if (isPlainObj(value)) {
return Object.entries(value).map(([childKey, childValue]) => ({
value: childValue,
path: [...path, childKey],
}))
}

return []
}

// For queries which do not use *, e.g. `a.b` or `a.1`
const getKeyEntries = function (value, path, part) {
return Array.isArray(value) || isPlainObj(value)
? [{ value: value[part], path: [...path, part] }]
: []
}
52 changes: 52 additions & 0 deletions src/config/normalize/lib/star_dot_path/entries/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import isPlainObj from 'is-plain-obj'

import { isAnyPart } from '../parsing/special.js'

import { getComplexEntries } from './complex.js'

// List all values (and their associated path) matching a specific query for
// on specific target value.
export const listEntries = function (target, tokens) {
return tokens.reduce(listTokenEntries, [{ value: target, path: [] }])
}

const listTokenEntries = function (entries, token) {
return entries.flatMap((entry) => getTokenEntries(entry, token))
}

const getTokenEntries = function ({ value, path }, token) {
if (token.length > 1) {
return getComplexEntries(value, path, token)
}

const [part] = token
return isAnyPart(part)
? getAnyEntries(value, path)
: getKeyEntries(value, path, part)
}

// For queries which use * on its own, e.g. `a.*`
const getAnyEntries = function (value, path) {
if (Array.isArray(value)) {
return value.map((childValue, index) => ({
value: childValue,
path: [...path, index],
}))
}

if (isPlainObj(value)) {
return Object.entries(value).map(([childKey, childValue]) => ({
value: childValue,
path: [...path, childKey],
}))
}

return []
}

// For queries which do not use *, e.g. `a.b` or `a.1`
const getKeyEntries = function (value, path, part) {
return Array.isArray(value) || isPlainObj(value)
? [{ value: value[part], path: [...path, part] }]
: []
}
13 changes: 8 additions & 5 deletions src/config/normalize/lib/star_dot_path/get.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { listEntries } from './entries.js'
import { maybeParse, ANY, isAnyPart, serialize, pathToTokens } from './parse.js'
import { listEntries } from './entries/main.js'
import { maybeParse } from './parsing/parse.js'
import { pathToTokens } from './parsing/path.js'
import { serialize } from './parsing/serialize.js'
import { ANY, isAnyTokens } from './parsing/special.js'

// Retrieve all properties in `target` matching a query string.
// The return value is an object where the key is the path to each value.
Expand All @@ -18,13 +21,13 @@ const normalizeEntry = function ({ value, path }) {
// Wildcards cannot be used.
export const get = function (target, queryOrPropNames) {
const tokens = maybeParse(queryOrPropNames)
validateWildcards(tokens)
validateAny(tokens)
const [entry] = listEntries(target, tokens)
return entry === undefined ? undefined : entry.value
}

const validateWildcards = function (tokens) {
if (tokens.some((token) => token.some(isAnyPart))) {
const validateAny = function (tokens) {
if (isAnyTokens(tokens)) {
throw new Error(
`Cannot use wildcard "${ANY}" when using get(): please use list() instead.`,
)
Expand Down
6 changes: 6 additions & 0 deletions src/config/normalize/lib/star_dot_path/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export { set, remove } from './set.js'
export { list, get, has } from './get.js'
export { pathToTokens, tokensToPath } from './parsing/path.js'
export { isParent } from './parsing/parent.js'
export { serialize } from './parsing/serialize.js'
export { parse } from './parsing/parse.js'
6 changes: 6 additions & 0 deletions src/config/normalize/lib/star_dot_path/parsing/parent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { SEPARATOR } from './special.js'

// Check if a query is a parent of another
export const isParent = function (parentQuery, childQuery) {
return childQuery.startsWith(`${parentQuery}${SEPARATOR}`)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import isPlainObj from 'is-plain-obj'
import { pathToTokens } from './path.js'
import { ESCAPE, SEPARATOR, ANY, createAnyPart } from './special.js'

// Parse a query string into an array of tokens.
// This is similar to JSON paths but:
Expand Down Expand Up @@ -75,7 +76,7 @@ export const parse = function (query) {
part = ''
}

token.push({ type: ANY_TYPE })
token.push(createAnyPart())
continue
}

Expand All @@ -101,64 +102,3 @@ const validateEscape = function (escapedCharacter, query, character, index) {
}

const POSITIVE_INTEGER_REGEXP = /^\d+$/u

// Inverse of `parse()`
export const serialize = function (tokens) {
return tokens.map(serializeToken).join(SEPARATOR)
}

const serializeToken = function (token, index) {
if (index === 0 && token[0] === '') {
return SEPARATOR
}

return token.map(serializePart).join('')
}

const serializePart = function (part) {
if (Number.isInteger(part)) {
return String(part)
}

if (isAnyPart(part)) {
return ANY
}

return part.replace(UNESCAPED_CHARS_REGEXP, '\\$&')
}

export const isAnyPart = function (part) {
return isPlainObj(part) && part.type === ANY_TYPE
}

export const isParent = function (parentQuery, childQuery) {
return childQuery.startsWith(`${parentQuery}${SEPARATOR}`)
}

const ESCAPE = '\\'
const SEPARATOR = '.'
export const ANY = '*'
const ANY_TYPE = 'any'
const UNESCAPED_CHARS_REGEXP = /[\\.*]/gu

// From an array of property names to an array to tokens
export const pathToTokens = function (path) {
return path.map(getPropNameToken)
}

const getPropNameToken = function (propName) {
return [propName]
}

// Inverse of `pathToTokens()`
export const tokensToPath = function (tokens) {
return tokens.map(getTokenPropName)
}

const getTokenPropName = function (token) {
if (token.some(isAnyPart)) {
throw new Error(`Cannot use wildcard "${ANY}" when using tokensToPath().`)
}

return token[0]
}
23 changes: 23 additions & 0 deletions src/config/normalize/lib/star_dot_path/parsing/path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ANY, isAnyToken } from './special.js'

// From an array of property names to an array to tokens
export const pathToTokens = function (path) {
return path.map(getPropNameToken)
}

const getPropNameToken = function (propName) {
return [propName]
}

// Inverse of `pathToTokens()`
export const tokensToPath = function (tokens) {
return tokens.map(getTokenPropName)
}

const getTokenPropName = function (token) {
if (isAnyToken(token)) {
throw new Error(`Cannot use wildcard "${ANY}" when using tokensToPath().`)
}

return token[0]
}
26 changes: 26 additions & 0 deletions src/config/normalize/lib/star_dot_path/parsing/serialize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { SEPARATOR, ANY, SPECIAL_CHARS_REGEXP, isAnyPart } from './special.js'

// Inverse of `parse()`
export const serialize = function (tokens) {
return tokens.map(serializeToken).join(SEPARATOR)
}

const serializeToken = function (token, index) {
if (index === 0 && token[0] === '') {
return SEPARATOR
}

return token.map(serializePart).join('')
}

const serializePart = function (part) {
if (Number.isInteger(part)) {
return String(part)
}

if (isAnyPart(part)) {
return ANY
}

return part.replace(SPECIAL_CHARS_REGEXP, '\\$&')
}
29 changes: 29 additions & 0 deletions src/config/normalize/lib/star_dot_path/parsing/special.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import isPlainObj from 'is-plain-obj'

// Check if at least one token has some ANY parts
export const isAnyTokens = function (tokens) {
return tokens.some(isAnyToken)
}

// Check if a token has some ANY parts
export const isAnyToken = function (token) {
return token.some(isAnyPart)
}

// Check if a token part is ANY
export const isAnyPart = function (part) {
return isPlainObj(part) && part.type === ANY_TYPE
}

export const createAnyPart = function () {
return { type: ANY_TYPE }
}

const ANY_TYPE = 'any'

// All special characters
export const ESCAPE = '\\'
export const SEPARATOR = '.'
export const ANY = '*'
// Matches any special characters
export const SPECIAL_CHARS_REGEXP = /[\\.*]/gu
4 changes: 2 additions & 2 deletions src/config/normalize/lib/star_dot_path/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import omit from 'omit.js'

import { setArray } from '../../../../utils/set.js'

import { listEntries } from './entries.js'
import { maybeParse } from './parse.js'
import { listEntries } from './entries/main.js'
import { maybeParse } from './parsing/parse.js'

// Set a value to one or multiple properties in `target` using a query string
export const set = function (target, queryOrPropNames, setValue) {
Expand Down
2 changes: 1 addition & 1 deletion src/config/plugin/lib/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { deepMerge } from '../../merge.js'
import { getDummyRules } from '../../normalize/dummy.js'
import { has } from '../../normalize/lib/star_dot_path/get.js'
import { has } from '../../normalize/lib/star_dot_path/main.js'

import { UserError, PluginError, ConsumerError } from './error.js'
import { safeNormalizeConfig } from './normalize.js'
Expand Down
Loading

0 comments on commit 7e281db

Please sign in to comment.