Skip to content

Commit

Permalink
Improve simple paths
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Mar 13, 2022
1 parent 75d08bc commit 1d88d20
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/config/normalize/lib/wild_wild_path/iterate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { groupBy } from '../../../../utils/group.js'

import { equalsSimple, isSameToken } from './parsing/compare.js'
import { fastEqualsSimple, isSameToken } from './parsing/compare.js'
import { parse } from './parsing/parse.js'
import { serialize } from './parsing/serialize.js'
import { getObjectTokenType } from './tokens/main.js'
Expand Down Expand Up @@ -61,7 +61,7 @@ const isDuplicate = function (
{ simplePath: simplePathB, path: pathB },
) {
return (
equalsSimple(simplePathA, simplePathB) &&
fastEqualsSimple(simplePathA, simplePathB) &&
pathA.length === pathB.length &&
pathA.every(
(tokenA, index) =>
Expand Down
8 changes: 8 additions & 0 deletions src/config/normalize/lib/wild_wild_path/parsing/compare.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getObjectTokenType } from '../tokens/main.js'

import { validateSimplePath } from './normalize.js'
import { parse } from './parse.js'

// Check if two queries are equal.
Expand All @@ -19,6 +20,13 @@ export const equals = function (queryOrPathsA, queryOrPathsB) {

// Check if two simple paths are equal
export const equalsSimple = function (simplePathA, simplePathB) {
validateSimplePath(simplePathA)
validateSimplePath(simplePathB)
return fastEqualsSimple(simplePathA, simplePathB)
}

// Same as `equalsSimple()` but without validation
export const fastEqualsSimple = function (simplePathA, simplePathB) {
return (
simplePathA.length === simplePathB.length &&
simplePathA.every((prop, index) => simplePathB[index] === prop)
Expand Down
26 changes: 25 additions & 1 deletion src/config/normalize/lib/wild_wild_path/parsing/normalize.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,37 @@
import { inspect } from 'util'

import { getObjectTokenType } from '../tokens/main.js'
import { getObjectTokenType, getSObjectTokenType } from '../tokens/main.js'

// Most methods accept both query and path syntaxes.
// This checks which one is used.
export const isQueryString = function (queryOrPaths) {
return typeof queryOrPaths === 'string'
}

// Simple paths are a subset of paths which uses no unions and only array|prop
// tokens.
// Those are the ones exposed in output, as opposed to normal paths which are
// exposed in input.
export const validateSimplePath = function (simplePath) {
if (!Array.isArray(simplePath)) {
throwPathError(simplePath, 'It must be an array.')
}

simplePath.forEach((prop) => {
validateProp(prop, simplePath)
})
}

const validateProp = function (prop, simplePath) {
if (getSObjectTokenType(prop) === undefined) {
throwTokenError(
simplePath,
prop,
'It must be a property name (string) or an array index (positive integer).',
)
}
}

// Normalize paths of tokens
export const normalizePaths = function (paths) {
validatePaths(paths)
Expand Down
8 changes: 8 additions & 0 deletions src/config/normalize/lib/wild_wild_path/tokens/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ARRAY_TOKEN } from './array.js'
import { OTHER_TOKEN_TYPES } from './other.js'
import { PROP_TOKEN } from './prop.js'

Expand All @@ -15,3 +16,10 @@ export const getStringTokenType = function (chars, isProp) {

// Order is significant as they are tested serially
const TOKEN_TYPES = [...OTHER_TOKEN_TYPES, PROP_TOKEN]

// Like `getObjectTokenType()` but for simple paths
export const getSObjectTokenType = function (token) {
return SIMPLE_TOKEN_TYPES.find((tokenType) => tokenType.testObject(token))
}

const SIMPLE_TOKEN_TYPES = [ARRAY_TOKEN, PROP_TOKEN]

0 comments on commit 1d88d20

Please sign in to comment.