References

This is a special type which is used in another form.

1. Usage

1.1. Within schema

It can be set in schema settings on the normal types to read the setting from the reference instead of using a fixed setting value.

const schema = new ObjectSchema()
// as value
.key('a', new Reference(...))
// as setting value
.key('b', new BooleanSchema().default(new Reference(...)))
// as flag setting
.key('c', new BooleanSchema().optional(new Reference(...)))

If references are used within a schema it will resolve before using the value. If not specifically defined as raw the reference will check for values within the validating structure only after the value pointed to is checked itself.

This may lead to circular references which will freeze the check. If so change the reference or use the raw value in one place at least.

1.2. Within data structure

A reference may also be used within the data structure:

const data = {
  // as value
  a: new Reference(...)
}

Within the data structure the references will be resolved also before using them. Here the raw() value will always be used ignoring the setting in the reference itself. So no problems with circular references will be there.

It is only replaced in parts which are specified with any type of Schema. Parts which are deeper and are not specified in Schema will not be replaced.

2. Sources

The references allows to point to

  • other parts of the validating structure
  • any other data structure
  • a function returning data directly or by promise
  • an environment value
  • a command output
  • a local file content
  • a web resource

And each source may return results pointing to other sources, too. But this is only possible in the above list top-down. So the given function may return a command to call, which returns a file URI which contains a we URI there the real data is loaded.

2.1. Schema Data

This allows you to reference other values within the same schema. This will get the validated value of the referenced element:

const ref = new Reference() // will use the current schema data element as start

2.2. Object Structure

Also a value can be retrieved from any other data structure:

const ref = new Reference(data)

2.3. Function

For every not as simple things you can also give a function which returns a promise or the base value:

function source() { ... }
const ref = new Reference(source)

2.4. Environment Setting

Use a value from the environment.

const ref = new Reference('env://TEST')

2.5. Command

An local command may be also called by giving a command line:

const ref = new Reference('exec://date')
const ref = new Reference('exec:///bin/date +%Y') // with full path and options

This can also be used on remote commands (not implemented yet!):

const ref = new Reference('ssh://server#date') // server defined for alinex-exec
const ref = new Reference('ssh://root:password@server#date')
const ref = new Reference('ssh://root@server/home/alex/.ssh/id#date')

2.6. Local file

The local file is read in as complete text.

const ref = new Reference('file:///etc/myconf')

2.7. Web resource

The page code or file contents is used as one text element.

const ref = new Reference('http://example.com/data')
const ref = new Reference('https://example.com/data')

3. Accessors

The different accessor methods are used to work on the reference value and get the final value out. They are added to a queue and are done in the order they are defined.

3.1. path()

Allows to access specific parts of an object structure:

const data = {
  a: { b: '11' },
  c: '2',
}
const ref1 = new Reference(data).path('/c') // '2'
const ref2 = new Reference(data).path('/a/b') // '11'

Backreferences are only possible in schema data:

const ref = new Reference().path('../a') // neighbor element

You can search by using asterisk as directory placeholder or a double asterisk to go multiple level deep:

const ref = new Reference().path('/name/*/min')   // within any subelement
const ref = new Reference().path('/name/*/*/min') // two level deep
const ref = new Reference().path('/name/**/min')  // in any depth

You may also use regexp notation to find the correct element:

const ref = new Reference().path('/name/test[AB]/min') // one missing character
const ref = new Reference().path('/name/test\d+/min')  // multiple missing characters

See the Mozilla Developer Network for the possible syntax but without modifier.

3.2. keys()

Get only the list of keys from an object.

const data = { one: 1, two: 2 }
const ref = new Reference(data).keys()
// value will be ['one', 'two']

3.3. values()

Get only the list of values from an object.

const data = { one: 1, two: 2 }
const ref = new Reference(data).values()
// value will be [1, 2]

3.4. trim()

Starting and ending whitespace which may come from file read or command input will be removed.

const data = 'Test\n'
const ref = new Reference(data).trim()
// value will be 'Test'

This method may also called on arrays or objects which will trim all of their string values.

3.5. split(separator, separator, separator)

This allows to split the string element or the array/objects string values by the defined separators. Up to three splits may be defined here.

const data = 'One;Eins\nTwo;Zwei\nThree;Drei'
const ref = new Reference(data).trim('\n', ';')
// value will be [['One', 'Eins'], ['Two', 'Zwei'], ['Three', 'Drei']]

If nothing given the newline character is assumed as only separator. You may also use regular expressions to separate the string.

3.6. join(separator, separator, separator)

This is the opposite of split and will join array maybe with sub arrays together into a single string. The first separator is used for the outermost join.

const data = [['One', 'Eins'], ['Two', 'Zwei'], ['Three', 'Drei']]
const ref = new Reference(data).join('\n', ';')
// value will be 'One;Eins\nTwo;Zwei\nThree;Drei'

If no separator given it will join one level deep with newline as separator.

3.7. match(regexp)

Run a regular expression on the string and get the found matches back or the match and it's groups for single matches.

const data = 'The house number one is just beside house number three.'
const ref = new Reference(data).match(/number (\w+)/g)
// value will be ['number one', 'number three']
const ref = new Reference(data).match(/number (\w+)/)
// value will be ['number one', 'one']

For single matches element 0 will be the full match, the groups will follow. If used on object or list each element of them will be replaced with the match result.

3.8. range(list...)

The range allows to filter specific elements of an array or object. All other elements will be removed.

const data = [10, 11, 12, 13, 14, 15]
const ref = new Reference(data).range([1], [3, 5])
// value will be [11, 13, 14]
const ref = new Reference(data).range([0, 2], [3, -1])
// value will be [10, 11, 13, 14]

The lists contain one or two integers defining the element to extract or the range of elements to extract. The number 0 defines the start or end of the list. Also negative numbers can be used to define the element from the end. If an end number is given all elements till the defined but excluding the end number are included.

3.9. filter(list|RegExp)

The filter allows to select only some elements of an array or object. Therefor you give a list of allowed elements or an expression which must be matched.

const data = ['number one', 'number two', 'number three', 'number four']
const ref = new Reference(data).filter('number three', 'number four', 'number five')
// value will be ['number three', 'number four']
const ref = new Reference(data).filter(/ t/)
// value will be ['number two', 'number three']

Use exclude() for negated selection.

3.10. exclude(list|RegExp)

The exclude allows to select all elements without the defined ones from an array or object. Therefor you give a list of disallowed elements or an expression which should not be matched.

const data = ['number one', 'number two', 'number three', 'number four']
const ref = new Reference(data).exclude('number three', 'number four', 'number five')
// value will be ['number one', 'number two']
const ref = new Reference(data).exclude(/ t/)
// value will be ['number one', 'number four']

Use filter() for positive selection.

3.11. parse(format)

The parse method allows to convert a string from a defined format into a data structure. All formats from alinex-format are allowed like:

  • yaml
  • json
  • xml
  • csv
const data = 'name: Albert\nage: 21'
const ref = new Reference(data).parse() // autodetect
// value will be {name: 'Albert', age: 21}
const ref = new Reference(data).parse('yaml')
// value will be {name: 'Albert', age: 21}

3.12. fn(function)

An additional method may be called to work on reference value before it is used:

const crop = function (data) {
  if (typeof data !== 'string') return data
  return data.substring(0, 8) // crop to 8 characters
}
const ref = new Reference(data).fn(crop)

3.13. or(Reference)

The or accessor allows to define another referenced value which is used if the first one so far is not there. The value returned from the second reference will be processed further on in the accessor queue of the first one.

const data = undefined
const ref = new Reference(data).or(new Reference('default'))
// value will be 'default'

3.14. concat(Reference)

If the outer reference contains an Array or Object like the sub reference both will be concatenated. In case of objects the keys of the inner one will overwrite the others.

const data = [1, 2, 3]
const ref = new Reference(data).concat(new Reference([6, 7, 8]))
// value will be [1, 2, 3, 6, 7, 8]

results matching ""

    No results matching ""