@optify/config
v1.11.0
Published
Simplifies **configuration driven development**: getting the right configuration options for a process or request using pre-loaded configurations from files (JSON, YAML, etc.) to manage options for feature flags, experiments, or flights.
Readme
Optify Bindings for Node.js
See the homepage for details about how feature files are combined to build the options to process at runtime.
Usage
import { z } from 'zod'
import { OptionsProvider } from '@optify/config'
const MyConfigSchema = z.object({
rootString: z.string(),
myArray: z.array(z.string()),
myObject: z.object({
key: z.string(),
deeper: z.object({
new: z.string(),
num: z.number(),
}),
}),
}).readonly()
const provider = OptionsProvider.build('<configs folder path>')
const config = provider.getOptions('myConfig', ['feature_A', 'feature_B'], MyConfigSchema)
// config is typed and validated at runtime
console.log(config.rootString)
console.log(config.myObject.deeper.num)The getOptions method accepts any object with a parse(data: unknown): T method, making it compatible with Zod and other schema validation libraries.
This package does not depend on Zod; it only requires the schema to have a parse method.
If desired, install Zod (or your preferred validation library) separately in your project:
npm install zodUsing getOptionsJson
If you don't need schema validation, you can use getOptionsJson to get the raw JSON string:
import { OptionsProvider } from '@optify/config'
const provider = OptionsProvider.build('<configs folder path>')
const options = JSON.parse(provider.getOptionsJson('myConfig', ['feature_A', 'feature_B']))
console.log(JSON.stringify(options, null, 2))Outputs:
{
"myArray": [
"item 1",
"item 2"
],
"myObject": {
"deeper": {
"new": "new value",
"num": 3333
},
"key": "val"
},
"rootString": "root string same"
}Multiple directories
import { OptionsProvider } from '@optify/config'
const provider = OptionsProvider.buildFromDirectories(['<configs folder path>', '<another folder path>'])Analyzing where a value comes from
To explain which feature (and import chain) set a value, enable analysis and pass a JSON pointer to the value. Analysis retains more data, so it is meant for local development and debugging tools.
import { BuilderOptions, OptionsProvider } from '@optify/config'
const builderOptions = new BuilderOptions()
builderOptions.setAnalysisEnabled(true)
const provider = OptionsProvider.build('<configs folder path>', builderOptions)
const analysis = provider.analyze('/myConfig/key2', ['grandparent'])
// {
// origins: [{
// path: '/myConfig/key2',
// source: { lineage: ['grandparent', 'parent2', 'base2'], kind: 'feature' },
// overridden: [{ lineage: ['grandparent', 'parent1'], kind: 'feature' }],
// }],
// }See Analysis.md for details about the result.
Development
Use Node >= 22.
corepack enable
yarn install
yarn build:debug
yarn build:ts
yarn testTesting
Run:
yarn build:debug
yarn build:ts
yarn testFormatting
JavaScript and TypeScript files use tabs as configured in .editorconfig.
Run oxfmt before committing:
yarn fmtTo check for formatting issues, run:
yarn fmt:checkLinting
Run linting before committing:
yarn lint:fixTo check for issues, run:
yarn lintRust Formatting
To automatically format the Rust code, run:
cargo fmtBenchmarking
Run:
rm -rf target config.*.node
yarn build
yarn build:ts
node benchmarks/get_all_options.mjsPublishing
Use CI.
Some notes:
See https://napi.rs/docs/introduction/getting-started#deep-dive
See https://napi.rs/docs/introduction/simple-package
