You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Consider renaming this repo generically to @elite-libs/config, and seamlessly combine the 2 use case/interfaces.
Look into combining the usage patterns of easyConfig & autoConfig (where each option is either defined using an object, or Array<string | Function> w/ optional last-position validation function.)
Alternatively, maintain 2 awkwardly differing modules for a bit longer - closer to v2.
autoConfig rename to cliConfig, configMap, appConfig, (should this be default export anyway?)
easyConfig, keep name? Might change to: appConfig?
Make sure the JSDoc content shows up where it's needed. (Not primarily on types, internals.)
Current easyConfig doesn't support the optional formatter function in tail position.
Current EasyConfig
Minimalist way to centralize your app configuration, handling both Argument & Environment key-value mapping.
Limits: Everything is a string. No built-in Zod validation like auto-config. No nesting, no arrays, no booleans, no numbers.
This snippet takes a url string and returns a new URL() instance.
If an error is encountered, the app will prevent invalid runtime states by exiting & re-throwing the original error message!
// Example used anonymous arrow function, but you can use a named function too.constparseUrl=(url: string)=>newURL(url);
ProTip 3: Parse JSON input strings
Note: Advanced example. Feel free to skip & revisit later.
The following example is a fair bit more complex.
The goal is showing a 'real-world' JSON parsing pattern evolves with this library.
Since arguments and environment variables can support long strings, it can sometimes be a convenient strategy to use stringified JSON. For example adding/removing features is easier if you know that theres only 1 place it's configured. A related issue: most enterprise apps eventually have to manage dozens to 100+'s of environment & configuration variables. The sprawl can quickly be a drag to manage and difficult to trace when things go wrong.
Let's visualize combining 2 keys into PRODUCT_PAGE={json}.
Given
PRODUCT_PAGE_SCROLL=infinite
PRODUCT_PAGE_LIMIT=10
We want to combine them into a single JSON key:
PRODUCT_PAGE={"scroll": "infinite", "limit": 10}
Future product additions can be added to the JSON with relative ease:
Let's say, your legal team has requested a new disclaimer be added to the product page.
We might have named this DISCLAIMER_PRODUCT, which could easily be overlooked when sorting and looking for PRODUCT_* in a sea of keys.
// Throws on invalid JSON.conststrictJsonParser=(json: string)=>JSON.parse(json);// Invalid JSON will get logged, and the app will return false.constsafeJsonParser=(json: string,sourceKey: string)=>{try{if(!json||json.length<2)returnfalse;returnJSON.parse(json);}catch(error){console.error('Invalid JSON supplied',error,{json, sourceKey});// NOTE: Change your default fall-back json value: instead of `false`, maybe `null` or an empty object or array might make more sense.returnfalse;}};
4. ProTip: Configurable Port number validator
// Using the curried `portRangeChecker()` helper (see below)constisHttpIsh=portRangeChecker({min: 80,max: 443});// The func `isHttpIsh(port)` accepts a number, and if outside the range provided it'll fail, and if inside the.isHttpIsh(79)//-> falseisHttpIsh(80)//-> trueisHttpIsh(444)//-> falseisHttpIsh(79)//-> false
constportRangeChecker=({min =1_000, max =60_000}: PortRange)=>(port: number|string)=>{port=parseInt(`${port}`);if(port>65_535)throwError(`Port number ${port} can't exceed 65535`);if(port<1)throwError(`Port number ${port} must be at least 1`);if(port>=min&&port<=max)returnport;thrownewError(`Unexpected Port ${port} value detected.`);}typePortRange={min: number,max: number};
5. ProTip: Zod-based type validation
// Use a Zod schema to validate, type check any config values.constparseAcctId=input=>zod.any(input).refine(Number).safeParse(input)?.data;exportconstconfig=easyConfig({"accountId": ['--accountId','ACCOUNT_ID',parseAcctId],});
The text was updated successfully, but these errors were encountered:
Extend easyConfig API
@elite-libs/config
, and seamlessly combine the 2 use case/interfaces.Array<string | Function>
w/ optional last-position validation function.)autoConfig
rename tocliConfig
,configMap
,appConfig
, (should this be default export anyway?)easyConfig
, keep name? Might change to:appConfig
?easyConfig
doesn't support the optional formatter function in tail position.Current EasyConfig
Limits: Everything is a string. No built-in Zod validation like auto-config. No nesting, no arrays, no booleans, no numbers.
Proposed API Changes
Validator function interface:
Example Validators
To support custom logic while getting types for free we'll support a trailing function pattern.
After the list of input args & env keys, include a
ValidatorFunction
as the last array element.Tip 1: Auto-type keys using JS' built-in methods
Boolean()
,Number()
,String()
, etcA quick way to add type hints: use the language's primitive constructors.
ProTip 2: Convert inputs into advanced types
This snippet takes a
url
string and returns anew URL()
instance.If an error is encountered, the app will prevent invalid runtime states by exiting & re-throwing the original error message!
ProTip 3: Parse JSON input strings
The following example is a fair bit more complex.
The goal is showing a 'real-world' JSON parsing pattern evolves with this library.
Since
arguments
andenvironment variables
can support long strings, it can sometimes be a convenient strategy to use stringified JSON. For example adding/removing features is easier if you know that theres only 1 place it's configured. A related issue: most enterprise apps eventually have to manage dozens to 100+'s of environment & configuration variables. The sprawl can quickly be a drag to manage and difficult to trace when things go wrong.Let's visualize combining 2 keys into
PRODUCT_PAGE={json}
.Given
PRODUCT_PAGE_SCROLL=infinite
PRODUCT_PAGE_LIMIT=10
We want to combine them into a single JSON key:
PRODUCT_PAGE={"scroll": "infinite", "limit": 10}
Future
product
additions can be added to the JSON with relative ease:Let's say, your legal team has requested a new disclaimer be added to the product page.
We might have named this
DISCLAIMER_PRODUCT
, which could easily be overlooked when sorting and looking forPRODUCT_*
in a sea of keys.PRODUCT_PAGE={"scroll": "infinite", "limit": 10, "disclaimer": "..."}
SUGGESTIONS_PAGE={"scroll": "none", "limit": 10, "disclaimer": "(items other shoppers purchased)"}
When adding legal text to a website, it may be more important to see the disclaimers co-located in one key.
DISCLAIMERS={"product": "...", "home": "all rights reversed", "partner_content": "rights owned by their respective owners"}
Let's look at more examples of JSON embedded keys.
The following example shows how to tie this all together:
Example Strict & Safe JSON Parsers
4. ProTip: Configurable Port number validator
5. ProTip: Zod-based type validation
The text was updated successfully, but these errors were encountered: