@dtavern/options v1.1.2
JS Options Parser (!!!deprecated!!!)
This version is outdated, use @dmitrytavern/object-parser.
- Added nested objects support.
- Added powerful documentation.
- v2.0.0 version.
- Fixed bugs.
A very light-weight options parser for node or web. How props in vue.js. Includes:
- Checking for options existence
- Checking for options types
- Default value setter
- Custom validator
- No dependencies
Usage
npm i @dtavern/options
const { defineOptions } = require('@dtavern/options')
function someFunction(options) {
defineOptions(options, {
name: String,
age: [String, Number],
colors: {
type: Array,
required: false,
default: () => ['red', 'blue'],
validator: (value) => value.length > 0,
},
})
console.log(options)
}
someFunction({
name: 'Rocket',
age: '17',
})
/* Output:
{
name: 'Rocket',
age: '17',
colors: ['red', 'blue']
}
*/
How you can see, defineOptions
overwrite original object.
If you need clone object, use spread operator or set clone option
in config.
Documentation
Table of Contents
- Set plugin settings as array
- Set plugin settings as object
- Set options settings as object
- Config API
- Nested objects
- Using typescript
Settings as array
If you need to use only existing checkers, you can use settings as an array.
Example:
const { defineOptions } = require('@dtavern/options')
// throw error
defineOptions({}, ['name'])
// throw error
defineOptions({ name: 'any type' }, [])
// Returns { name: 'any type' }
defineOptions({ name: 'any type' }, ['name'])
Settings as object
If you need to use checkers of existing and typing, you can use settings as an object.
Example:
const { defineOptions } = require('@dtavern/options')
// Returns { name: 'only string type' }
defineOptions({ name: 'only string type' }, { name: String })
// Returns { age: 17 }
defineOptions({ age: 17 }, { age: [String, Number] })
// Returns { _null: 17 } - skip type checker
defineOptions({ _null: 17 }, { _null: null })
You need to use classes as the value of settings.
Options settings as object
if you need more fine tuning you can use option settings as object.
Example:
const { defineOptions } = require('@dtavern/options')
// Returns { name: 'hello' }
defineOptions(
{},
{
name: {
type: String,
required: false,
default: 'hello',
validator: (value) => value.length > 0,
},
}
)
Option setting API
type
Type: class
| array
of Classes | null
\
Default: null
Use for checking property value on the class constructor.
Note: If the type is null
- this property will skip only
type checking. But if your options have no this property -
this will result in an error. To prevent it use the required
option.
name: {} // skip type checker
name: {
type: String,
}
age: {
type: [String, Number],
}
someAsyncFunction: {
type: AsyncFunction
}
You can use any classes. If you use the async function, import constructor form lib:
const { AsyncFunction } = require('@dtavern/options')
Note for async: babel converting your async function to the simple function which returns Promise. If you use babel on your project, use Function, AsyncFunction for type option. For dev - AsyncFunction, for bundle - Function.
required
Type: boolean
\
Default: true
If required is false and properties have no needs key, throw error will not happen
root: {
required: false
}
default
Type: function
| any
\
Arguments: null
\
Returns: any
\
Default: null
If required is false and properties have no needs key, you can set a default value. It can be both primitives and objects.
Note: for objects, I recommend using the function. Also, if the default value will not be the correct type or if the validator doesn't miss it, this will result in an error.
color: {
required: false,
default: 'red'
}
colors: {
required: false,
default: () => ['red', 'blue']
}
validator
Type: function
\
Arguments: (value: any)
\
Returns: boolean
\
Default: null
If you need to check property value to allowable values, you can use a custom validator.
colors: {
required: false,
default: () => 'red',
validator: (value) => ['red', 'blue'].includes(value)
}
Checkers execution order
If you use settings as object, script complicates option checking.
1. Exists checker
The script checks if a property does exist in options and is it necessary.
If the property does not exist but the setting required
is false
verification will be completed successfully.
Otherwise, it will result in an error.
2. Default setter
The script checks if a property does not exist in options and has its default value.
If the property does not exist, the script set the default value if it exists.
3. Type option checker
Before the type checker, the script checks if the type input
is correct in the setting. If the type is null
- skip,
if another type - check.
4. Type checker
The script checks the property value on the correct type if
the type does not equal to null
and the property does exist
in options.
5. Validator
If the validator does exist in options, the script calls it.
If the validator returns true
- the script moves to the
next property or ends work. But if returns false
- this
will result in an error
Config API
mode
Type: strict
, log
, disabled
\
Default: strict
Mode option needs for changes the way errors are output.
- strict - error will be throw script
- log - error will be output to console
- disabled - error will be ignored
Example:
// Error without throw script
defineOptions({}, ['name'], { mode: 'log' })
clone
Type: boolean
\
Default: false
Clone option needed if you don't want to change the original options object.
const originalObject = {}
const newObject = defineOptions(
originalObject,
{ name: { required: false, default: 'Dmitry' } },
{ clone: true }
)
console.log(originalObject) // Returns: {}
console.log(newObject) // Returns: { name: 'Dmitry' }
Nested objects
When you have a difficult object, use:
const difficultObjects = {
user: {
name: 'Dmitry',
age: 20,
tags: {
public: ['developer'],
private: []
}
},
some: {
function: () => {},
}
}
defineOptions(difficultObjects, {
user: Object,
some: Object,
})
defineOptions(difficultObjects.user, {
name: String,
age: [Number, String],
tags: Object
})
defineOptions(difficultObjects.user.tags, {
public: Array,
private: Array,
})
defineOptions(difficultObjects.some, {
function: Function,
test: {
type: String,
required: false,
default: 'hello_world'
}
})
// Returns:
// {
// user: {
// name: 'Dmitry',
// age: 20,
// tags: {
// public: [Array],
// private: []
// }
// },
// some: {
// function: [Function: function],
// test: 'hello_world'
// }
// }
Using typescript
If you using typescript, you can use generic type in plugin:
defineOptions<Options, Return>(options: Options, settings): Return;
Example:
import { defineOptions } from '@dtavern/options'
interface Options {
name?: string
}
function someFunction(options: Options = {}) {
// Returns { name: 'hello' }
const newOptions = defineOptions<Options>(options, {
name: {
type: String,
required: false,
default: 'Dmitry',
},
})
// Valid
console.log(newOptions.name)
}
someFunction()
License
MIT - check repo files
Copyright (c) 2022-present, Dmitry Tavern