javascript-value-locator
v1.4.7
Published
Load javascript values from multiples sources and using multiple protocols
Downloads
35
Maintainers
Readme
Javascript Value Locator
Load javascript values from multiples sources and using multiple protocols
Introduction
This module provide a minimalist api to load (asynchronously only) javascript values from different sources, using javascript value locators - JVL. A JVL is an object or a string (matching a specific format), which represent a way to load a javascript value. It's composed both of a protocol and a target.
// this is a jvl object
{
protocol: 'protocol-name',
target: 'full/path/to/module/exporting/the/targeted/value'
}
// this is the equivalent jvl string
'protocol-name:full/path/to/module/exporting/the/targeted/value'
You can see this module as a kind of webpack at the run time, where protocols are loaders, and where instead of doing this :
require.ensure([], require => {
const value = require('module/path');
// do something with the value
})
You do this :
const jvl = require('javascript-value-locator');
jvl.load('require:module/path').then(value => {
// do something with the value
})
And for example, if you want to load a yaml, you could use a specific protocol, as you would have used a yaml-loader in webpack
const jvl = require('javascript-value-locator');
/**
* Assuming that a "require-yaml" protocol was defined in the first place
* (which is currently not the case)
*/
jvl.load('require-yaml:module/path.yaml').then(value => {
// do something with the value
})
Note that the comparison with webpack is only here for explanatory purpose, this module doesn't aim the same use cases.
Purpose and use cases
The previous examples are here only for the sake of explaining the module basic usage. If you want to require a module in node.js, you should more than probably just do a require (unless you want to load it asynchronously). The following use case is the one for what the module was created in the first place.
- Use the JVL string format to "require" a module in a cli command option
Assuming you want to provide a command with an option which can be a javascript value. If the option is a number, it's ok to do that :
cli command input --javascript-value-option=5
But if the option is a complex/dynamic object, using JVL allow you to do that :
cli command input --javascript-value-option=require:full/path/to/module
The cli users have in that way a more fine control over the module he wants use to do some task. A logger module is a good example. Imagine you implement a cli command which only log the input, you could have something like :
// ./load-override.js
// create a custom load function
const path = require('path');
const {load, setLocatorDefaultProtocol, defaultProtocols} = require('javascript-value-locator');
module.exports = function customLoad(locator, options){
// if the locator is an object and doesn't have protocol property,
// or if it's a string without protocol ahead, the 'custom-protocol' will be used
return load(setLocatorDefaultProtocol(locator, 'custom-protocol'), options, {
protocols: Object.assign({}, defaultProtocols, {
['custom-protocol'](resolve, reject, target){
// define a way to "require" the javascript value targeted
// for instance, require the path from a custom directory
// It will allow to provide some built-in log functions
defaultProtocols.require(resolve, reject,
path.join(__dirname, '../custom/directory/path', target)
);
}
})
})
}
// ./log-command.js
// then use the custom load function in your log command implementation
const load = require('./load-override');
module.exports = async function logCommand(
input,
log = (...logs) => console.log(...logs) // provide a default logger
){
// enable silent mode
if(log === false){
log = ()=>{};
}
// enable the user to directly use a function as log option
if(typeof log !== 'function'){
log = await load(log);
}
assert(typeof log === 'function');
return log(input);
}
Make the cli implementation which will call this async function, then your users can do :
this will use a simple console.log
cli log "hello world"
this will not log anything
cli log "hello world" --log=false
this will use a built-in logger defined in custom/directory/path
cli log "hello world" --log=custom-protocol:log-one
this will use an other built-in logger defined in custom/directory/path
cli log "hello world" --log=log-two
this will use a logger defined by the user
cli log "hello world" --log=require:path/to/a/custom/logger
Speculative use cases
The module wasn't thinked in order to do that, but it may could be used to accomplish some of these things :
Create and use some custom protocols able to load javascript from the cloud
Use in the browser to load assets (still with custom protocols)
And probably more...
Get started
Install
using npm
npm install --save javascript-value-locator
or using yarn
yarn add javascript-value-locator
Load one or more values from JVL
TO DO - see the load function documentation for now
Available protocols
Currently, the only implemented protocol is the require. If needed, add others and eventually open a issue or event better, a PR.
Use custom protocols
You can use the inject.protocols option of the load function. Look here for concrete example.
Load a value synchronously
JVL is not aimed to do that.
About the documentation
The following documentation was generated using documentation.js.
Naming conventions
CapitalizedCamelCasedNames are used for types
dashified-case-names are used for filenames
camelCasedNames are used for methods and properties
Documentation
Table of Contents
- JavascriptValueLocator
- JavascriptValueLocatorString
- JavascriptValueLocatorObject
- JavascriptValueLocatorProtocol
- javascript-value-locator
- load
- setLocatorDefaultProtocol
- parse
- stringify
- defaultProtocols
- require
JavascriptValueLocator
A JavascriptValueLocator (JVL) is a string or an object which describe a way to access to a javascript value. It must provide at least:
Type: (JavascriptValueLocatorString | JavascriptValueLocatorObject)
JavascriptValueLocatorString
A JavascriptValueLocatorString (JVL string) is a string which describe a way to access to a javascript value. It must matches the following format:
- protocol-name:target-name see JavascriptValueLocator
Type: string
Examples
// Those are valid JVL strings
"require:/path/to/file"
"any-defined-protocol-name:any-target-name_case is-NotImportant"
// Those are unvalid JVL strings
":target-name" // Missing protocol
"protocol-name" // Missing target
JavascriptValueLocatorObject
A JavascriptValueLocatorObject is an object which describe a way to access to a javascript value.
Type: object
Properties
protocol
(string | JavascriptValueLocatorProtocol) The name of the protocol or the protocol himself (as a function which respect the JavascriptValueLocatorProtocol definition)target
string The javascript value targeted.
JavascriptValueLocatorProtocol
A JavascriptValueLocatorProtocol is a function which take the following arguments (resolve, reject, target, options) and resolve the targeted javascript value or reject an error
Type: function
Parameters
resolve
function A resolve function which will be called with the targeted javascript value as single argumentreject
function A reject function which will be called with a error as single argument if the javascript value load failedtarget
string The target to load and resolve. A target must be a unique identifier/path (or maybe other things depending on the used protocol) to the requested javascript value. You must use it to know which value is requestedoptions
object The options passed to the protocol.
javascript-value-locator
The JVL API is an object providing the following properties:
Examples
// require the public API
const JVL = require('javascript-value-locator')
// then use a method of the API
JVL.load('npm:[email protected]').then(_ => console.log(_('hello-world'))) // Hello world
load
This function loads a javascript value in a async way
Parameters
locator
(JavascriptValueLocator | Array<JavascriptValueLocator>) A javascript value locator as an object or a string which follow the JVL format. Can also be an Array of locators.options
object? The javascript options object which will be passed to the locator protocol function. If locator is an object, it can provide directly an options object which will be merged with the options parameter. (optional, default{}
)inject
object? A javascript object containing the load function dependencies. (optional, default{}
)inject.protocols
object A Dictionnary where keys are the names of the protocols and value are the protocols functions. If locator is an object, it can provide directly a protocols key which will be merged with the inject.protocols parameter. (optional, defaultdefaultProtocols
)
Returns Promise A promise resolving the javascript value targeted by the locator. If locator was an Array, the promise resolve an Array containing all the targeted values in the same order as defined.
setLocatorDefaultProtocol
This function returns a locator with the specified default protocol if the input locator doesn't provide one.
Parameters
locator
((string | object) | Array<(string | object)>) A potential JVL which must at least provide a target. It will be transformed in a valid JVL. If it's an Array, the function will return an Array of valid JVL. The output JVl will keep the type of the original input locator.defaultProtocol
string If no protocol is found in the locator, then the default protocol will be setted as the current locator protocol. Note that you can't provide a protocol as a function using the setLocatorDefaultProtocol function.
Returns (JavascriptValueLocator | Array<JavascriptValueLocator>) The corresponding locator as an object.
parse
This function returns a locator object from a JVL string.
Parameters
JVL
JavascriptValueLocatorString The locator as string to parse.
Returns JavascriptValueLocatorObject The corresponding locator as an object.
stringify
This function transforms a locator object to a JVL string.
Parameters
locator
JavascriptValueLocatorObject The locator object to stringify.
Returns JavascriptValueLocatorString The corresponding JVL string.
defaultProtocols
This object contains the defaults protocols defined by the javascript-value-locator package :
You can use it, for example, in order to create a new load functions with new custom protocols.
Examples
//import the load function and the default-protocols
const {load, defaultProtocols} = require('javascript-value-locator')
//define some custom protocols
const customProtocols = {
newProtocol: function(resolve, reject, target, options){
resolve(getTheValueUsingTheTargetAndOptions)
//or
reject()
}
}
//create and export a function which call the original function,
//but passing to it a new protocols object dependency
module.exports = function customLoad(locator, options){
return load(locator, options, {
protocols: Object.assign({}, defaultProtocols, customProtocols)
})
}
require
This function is a JavascriptValueLocatorProtocol that use the node require function to load the target.
Parameters
resolve
function A resolve function which will be called with the targeted javascript value as single argument.reject
function A reject function which will be called with a error as single argument if the javascript value load failed.target
string The target to load and resolve. It must be a path to a valid node module.options
object? A javascript object containing the require protocol options. (optional, default{}
)options.cwd
string The current working directory to use if the target path is not absolute. (optional, defaultprocess.cwd()
)
Returns undefined
License
javascript-value-locator is released under MIT. Copyright (c) 2017-present Alexis Tessier