@konfirm/resolver
v1.0.0
Published
Resolver implementations to traverse into structured information
Downloads
3
Maintainers
Readme
Resolver
Resolver implementations to traverse into structured information
Installation
@konfirm/resolver
is a scoped package, which means the scope must be provided for both installation and usage.
Using npm
$ npm install --save @konfirm/resolver
Using yarn
$ yarn add @konfirm/resolver
Exports
The Resolve module is an object with various exposed classes
| name | purpose |
| ------------------ | -------------------------------------------------------------------------- |
| AbstractResolver
| Abstract implementation of Resolver, providing the base implementation |
| VirtualResolver
| Implementation which matches everything |
| RequireResolver
| Implementation to resolve directories and all files that can be require
d |
Usage
A resolver can be used to determine whether a given key can be used reached through traversal. It is up to the implementation to provide meaning to what it is that is resolved.
A tangible resolver is the RequireResolver
, which is allows for traversal of the filesystem and ultimately the inclusion of files through require
.
const Path = require('path');
const { RequireResolver } = require('@konfirm/resolver');
const root = new RequireResolve(process.cwd());
// for this example, a config/application.js file is assumed
// determine if a directory or (requireable) file exists with the name 'config'
if (root.match('config')) {
// 'config' exists, so we can use it
const config = root.use('config');
// determine if a directory or (requireable) file exists with the name 'application'
if (config.match('application')) {
const application = config.use('application');
// the application variable now contains the required config/application.js
}
}
As the Resolvers are able to test whether the provided key is usable, it opens up to the possibility to easily implement traversal mechanisms.
const Path = require('path');
const { RequireResolver } = require('@konfirm/resolver');
const root = new RequireResolve(process.cwd());
function resolve(resolver, path) {
return path.split(Path.sep).reduce((carry, key) => {
if (carry && carry.match(key)) {
return carry.use(key);
}
return null;
}, resolver);
}
const root = new RequireResolver(process.cwd());
const application = resolve(root, 'config/application');
API
All exported Resolvers provide the same base; AbstractResolver
AbstractResolver
constructor(...path)
Creates an instance of AbstractResolver. The meaning of path
and the validity of the values may differ per implementation.
get path
The path of the Resolver. It reflects the path as it was provided during construction, in order to prevent runtime manipulation the return path is a slice
of what is stored, which means it cannot be compared using the shallow equality operator (===
).
use(key)
Create a new Resolver for the given key. A new instance using the current path + the provided key is created. By default the result is a new instance of the Resolver it was used on.
match(key)
Can the resolver match the key. Verify whether the provided key can be used to create a new Resolver. The default implementation always results in undefined
, meaning use
should not be called.
if (resolver.match('key')) {
// able to invoke resolver.use('key')
}
[Symbol.match](key)
Symbol.match
implementation. This allows for using the Resolver as argument of a string
key using key.match(resolver)
.
NOTE This will only work on keys of type string
, if you cannot be sure of string values, use resolver.match
instead.
if ('key'.match(resolver)) {
// able to invoke resolver.use('key')
}
*[Symbol.iterator]()
Symbol.iterator
generator implementation. Allows the Resolver to be used in a for...of
loop. The default implementation does not yield
any value.
for (const value of resolver) {
// do something with value
}
// or, using destructuring
const values = [...resolver];
NOTE it is important to look at the implementation specifics on what values are yielded (if any).
VirtualResolver
Unless otherwise stated, the VirtualResolver
API does not override the AbstractResolver
implementation.
match(key)
All keys given to a VirtualResolver
will be returned as is, therefor allowing everything thrown at it.
console.log(resolver.match('key')); // key
[Symbol.match](key)
As the default [Symbol.match]
implementation uses the match
method under the hood, all string
keys will be matched in full.
console.log('key'.match(resolver)); // key
RequireResolver
Unless otherwise stated, the RequireResolver
API does not override the AbstractResolver
implementation.
use(key)
If the key refers to a directory and no file with precedence (according to require
) exists, calling use
will create a new RequireResolver
pointing to that directory. If a file takes precedence the return value of use
will return the required file.
match(key)
Try to match the provided key to the path associated with the RequireResolver
, if a file takes precedence (according to require
), the name of that file is returned. If there's no matched, undefined
is returned.
[Symbol.match](key)
As the default [Symbol.match]
implementation uses the match
method under the hood, all string
keys will provide the full file name that can be used.
*[Symbol.iterator]()
As any RequireResolver
instance basically reflects a directory, the iterator implementation can (and will) list all directory entry names as string
value
License
MIT License Copyright (c) 2019 Rogier Spieker (Konfirm)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.