Skip to content

Commit

Permalink
Improve any token
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Mar 6, 2022
1 parent 55a76ba commit 0908357
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/config/normalize/lib/star_dot_path/entries.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import isPlainObj from 'is-plain-obj'

import { isAnyToken } from './parsing/any.js'
import {
convertIndexInteger,
convertIndexString,
getArrayIndex,
isIndexToken,
} from './parsing/array.js'
import { serialize } from './parsing/serialize.js'
import { ANY_TOKEN } from './parsing/special.js'

// List all values (and their associated path) matching a specific query for
// on specific target value.
Expand All @@ -28,7 +28,7 @@ const listTokenEntries = function (entries, token) {
}

const getTokenEntries = function ({ value, path }, token) {
return token === ANY_TOKEN
return isAnyToken(token)
? getAnyEntries(value, path)
: getKeyEntries(value, path, token)
}
Expand Down
13 changes: 13 additions & 0 deletions src/config/normalize/lib/star_dot_path/parsing/any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import isPlainObj from 'is-plain-obj'

// Create a new token for *
export const createAnyToken = function () {
return { type: ANY_TYPE }
}

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

const ANY_TYPE = 'any'
18 changes: 6 additions & 12 deletions src/config/normalize/lib/star_dot_path/parsing/parse.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { createAnyToken } from './any.js'
import { convertIndexInteger } from './array.js'
import { normalizePath } from './normalize.js'
import {
ESCAPE,
SEPARATOR,
ANY,
MINUS,
SPECIAL_CHARS,
ANY_TOKEN,
} from './special.js'
import { ESCAPE, SEPARATOR, ANY, MINUS, SPECIAL_CHARS } from './special.js'
import { isQueryString } from './validate.js'

// Parse a query string into an array of tokens.
Expand All @@ -29,9 +23,9 @@ import { isQueryString } from './validate.js'
// Tokens are an array of one of:
// - Object property as a string or symbol
// - Array index as a positive|negative integer|string
// - `Symbol.for('*')` for wildcards
// - We use symbols as it allows using dynamic strings without injection
// risk
// - Wildcards: { type: "any" }
// - We use objects instead of strings or symbols as both are valid as
// object properties which creates a risk for injections
// We allow passing an array of tokens instead of a query string which:
// - Removes the need for escaping
// - Is sometimes more convenient
Expand Down Expand Up @@ -123,5 +117,5 @@ Regular expressions can be used instead.`,
)
}

return ANY_TOKEN
return createAnyToken()
}
5 changes: 3 additions & 2 deletions src/config/normalize/lib/star_dot_path/parsing/serialize.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { isAnyToken } from './any.js'
import { isIndexToken } from './array.js'
import { parse } from './parse.js'
import { SEPARATOR, ANY, ANY_TOKEN, SPECIAL_CHARS_REGEXP } from './special.js'
import { SEPARATOR, ANY, SPECIAL_CHARS_REGEXP } from './special.js'

// Inverse of `parse()`
// When passing a query string, it is parsed and re-serialized to validate and
Expand All @@ -15,7 +16,7 @@ const serializePath = function (path) {
}

const serializeToken = function (token, index) {
if (token === ANY_TOKEN) {
if (isAnyToken(token)) {
return ANY
}

Expand Down
2 changes: 0 additions & 2 deletions src/config/normalize/lib/star_dot_path/parsing/special.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@ export const SEPARATOR = '.'
export const ANY = '*'
export const MINUS = '-'
export const SPECIAL_CHARS = new Set([ESCAPE, SEPARATOR, ANY, MINUS])
// Tokens for special characters
export const ANY_TOKEN = Symbol.for('*')
// Special characters which should always be escaped
export const SPECIAL_CHARS_REGEXP = /[\\.*]|^-/gu
6 changes: 3 additions & 3 deletions src/config/normalize/lib/star_dot_path/parsing/validate.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { inspect } from 'util'

import { isAnyToken } from './any.js'
import { isIndexToken } from './array.js'
import { ANY_TOKEN } from './special.js'

// Most methods accept both query and path syntaxes.
// This checks which one is used.
Expand Down Expand Up @@ -31,13 +31,13 @@ const validateToken = function (token, path) {
throwTokenError(
path,
token,
'It must be a string, integer or Symbol.for("*").',
'It must be a string, an integer or { type: "any" }',
)
}
}

const isValidToken = function (token) {
return typeof token === 'string' || isIndexToken(token) || token === ANY_TOKEN
return typeof token === 'string' || isIndexToken(token) || isAnyToken(token)
}

const throwPathError = function (path, message) {
Expand Down

0 comments on commit 0908357

Please sign in to comment.