Skip to content

Commit

Permalink
Improve undefined values
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Mar 6, 2022
1 parent ea94b02 commit d932f84
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 35 deletions.
8 changes: 0 additions & 8 deletions src/config/normalize/lib/star_dot_path/entries.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@ import { getObjectTokenType } from './tokens/main.js'

// List all values (and their associated path) matching a specific query for
// on specific target value.
export const listExistingEntries = function (target, path) {
return listEntries(target, path).filter(isDefined)
}

const isDefined = function ({ defined }) {
return defined
}

export const listEntries = function (target, path) {
return path.reduce(listTokenEntries, [
{ value: target, path: [], defined: true },
Expand Down
23 changes: 18 additions & 5 deletions src/config/normalize/lib/star_dot_path/get.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
import { listExistingEntries, normalizeEntry } from './entries.js'
import { listEntries, normalizeEntry } from './entries.js'
import { parse } from './parsing/parse.js'

// Retrieve all properties in `target` matching a query string.
export const list = function (target, queryOrPath) {
const path = parse(queryOrPath)
const entries = listExistingEntries(target, path)
const entries = listExistingEntries(target, queryOrPath)
return entries.map(normalizeEntry)
}

// Retrieve a single property's value in `target` matching a query string.
// Wildcards can be used, but only the first value is returned.
export const get = function (target, queryOrPath) {
const entries = listExistingEntries(target, queryOrPath)
return entries.length === 0 ? undefined : entries[0].value
}

// Check if a property is defined according to a query
export const has = function (target, queryOrPath) {
const entries = listExistingEntries(target, queryOrPath)
return entries.length !== 0
}

const listExistingEntries = function (target, queryOrPath) {
const path = parse(queryOrPath)
const [entry] = listExistingEntries(target, path)
return entry === undefined ? undefined : entry.value
return listEntries(target, path).filter(isDefined)
}

const isDefined = function ({ defined }) {
return defined
}
16 changes: 0 additions & 16 deletions src/config/normalize/lib/star_dot_path/has.js

This file was deleted.

3 changes: 1 addition & 2 deletions src/config/normalize/lib/star_dot_path/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export { list, get } from './get.js'
export { has } from './has.js'
export { list, get, has } from './get.js'
export { equals, parent } from './parsing/compare.js'
export { serialize } from './parsing/serialize.js'
export { parse } from './parsing/parse.js'
Expand Down
9 changes: 6 additions & 3 deletions src/config/normalize/lib/star_dot_path/tokens/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,14 @@ const getEntries = function (value, path, token) {
}

// Retrieve an array using a positive or negative index.
// Indices that are out-of-bound return no entries but do not error.
const getArrayIndex = function (array, token) {
// Indices that are out-of-bound:
// - Do not error
// - Return an entry with an `undefined` value
// - This allows appending to arrays, e.g. with -0
const getArrayIndex = function (value, token) {
return token > 0 || Object.is(token, +0)
? token
: Math.max(array.length + token, 0)
: Math.max(value.length + token, 0)
}

// Check if two tokens are the same
Expand Down
5 changes: 4 additions & 1 deletion src/config/normalize/lib/star_dot_path/tokens/prop.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ const isDefined = function (value) {
const defaultValue = {}

// Use the token to list entries against a target value.
// We distinguish between:
// - Missing property name: return no entries
// - Property exists but has `undefined` value: return an entry
const getEntries = function (value, path, token) {
return [{ value: value[token], path: [...path, token] }]
return token in value ? [{ value: value[token], path: [...path, token] }] : []
}

// Check if two tokens are the same
Expand Down

0 comments on commit d932f84

Please sign in to comment.