Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@unifig/core

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@unifig/core - npm Package Compare versions

Comparing version 0.6.0 to 0.7.0

dist/adapters/adapter.d.ts

4

dist/adapters/index.d.ts

@@ -1,2 +0,2 @@

export * from './config-adapter.interface';
export * from './plain.adapter';
export * from './adapter';
export * from './plain';

@@ -17,3 +17,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./config-adapter.interface"), exports);
__exportStar(require("./plain.adapter"), exports);
__exportStar(require("./adapter"), exports);
__exportStar(require("./plain"), exports);

@@ -5,6 +5,10 @@ export * from './adapters';

export * from './validator';
import { ConfigManager } from './manager';
import { ConfigContainer } from './manager';
/**
* @deprecated Will be removed in v1.0.0. Renamed to `ConfigContainer`.
*/
export type IConfigContainer<TTemplate extends Record<string, any>> = ConfigContainer<TTemplate>;
/**
* Global ConfigManager instance.
*/
export declare const Config: ConfigManager;
export declare const Config: import("./manager").ConfigManager;

@@ -22,6 +22,6 @@ "use strict";

__exportStar(require("./validator"), exports);
const manager_1 = require("./manager");
const manager_factory_1 = require("./manager/manager.factory");
/**
* Global ConfigManager instance.
*/
exports.Config = new manager_1.ConfigManager();
exports.Config = manager_factory_1.ConfigManagerFactory.create();
export declare const mappedPropertyKey: (key: string) => string;
export declare const PROPERTIES_MAPPING_METADATA = "__unifigPropertiesMapping__";
export declare const PROPERTIES_NESTING_METADATA = "__unifigPropertiesNesting___";
export declare const PROPERTIES_MAPPING_METADATA: unique symbol;
export declare const PROPERTIES_NESTING_METADATA: unique symbol;

@@ -6,3 +6,3 @@ "use strict";

exports.mappedPropertyKey = mappedPropertyKey;
exports.PROPERTIES_MAPPING_METADATA = '__unifigPropertiesMapping__';
exports.PROPERTIES_NESTING_METADATA = '__unifigPropertiesNesting___';
exports.PROPERTIES_MAPPING_METADATA = Symbol('unifigPropertiesMapping');
exports.PROPERTIES_NESTING_METADATA = Symbol('unifigPropertiesNesting');

@@ -1,2 +0,2 @@

import { Type } from '../../utils/type.interface';
import { ClassConstructor } from '../../utils/class-constructor.interface';
/**

@@ -6,3 +6,6 @@ * @deprecated Support for passing subtemplate class directly will be removed in v1.0.0. Instead, pass a factory function: `@Nested(() => SubClass)`. This is because of `SubClass` reference being undefined when parent and child templates reference each other in a circular way.

*/
export declare function Nested<T>(type: Type<T>): PropertyDecorator;
export declare function Nested<T>(type: () => Type<T>): PropertyDecorator;
export declare function Nested<T>(type: ClassConstructor<T>): PropertyDecorator;
/**
* Defines subtemplate to use.
*/
export declare function Nested<T>(type: () => ClassConstructor<T>): PropertyDecorator;

@@ -1,5 +0,5 @@

import { Type } from '../utils/type.interface';
export declare type PropertySource = string;
export declare type PropertyTarget = string;
export declare type PropertiesMapping = Map<PropertyTarget, PropertySource>;
export declare type PropertiesNesting = Map<PropertyTarget, () => Type>;
import { ClassConstructor } from '../utils/class-constructor.interface';
export type PropertySource = string;
export type PropertyTarget = string;
export type PropertiesMapping = Map<PropertyTarget, PropertySource>;
export type PropertiesNesting = Map<PropertyTarget, () => ClassConstructor>;

@@ -1,1 +0,1 @@

export * from './config.container.interface';
export * from './container';

@@ -17,2 +17,2 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./config.container.interface"), exports);
__exportStar(require("./container"), exports);

@@ -1,5 +0,5 @@

import { Type } from '../../utils/type.interface';
import { UnifigException } from '../../exceptions/unifig.exception';
import { ClassConstructor } from '../../utils/class-constructor.interface';
export declare class ConfigNotInitializedException extends UnifigException {
constructor(template: Type);
constructor(template: ClassConstructor);
}
export * from './container';
export * from './exceptions';
export * from './config.manager';
export * from './config.manager.options';
export * from './manager.factory';
export * from './manager.options';
export * from './manager';

@@ -19,3 +19,4 @@ "use strict";

__exportStar(require("./exceptions"), exports);
__exportStar(require("./config.manager"), exports);
__exportStar(require("./config.manager.options"), exports);
__exportStar(require("./manager.factory"), exports);
__exportStar(require("./manager.options"), exports);
__exportStar(require("./manager"), exports);

@@ -1,5 +0,5 @@

export declare type DeepReadonly<T> = T extends (infer R)[] ? DeepReadonlyArray<R> : T extends Function ? T : T extends object ? DeepReadonlyObject<T> : T;
export type DeepReadonly<T> = T extends (infer R)[] ? DeepReadonlyArray<R> : T extends Function ? T : T extends object ? DeepReadonlyObject<T> : T;
interface DeepReadonlyArray<T> extends ReadonlyArray<DeepReadonly<T>> {
}
declare type DeepReadonlyObject<T> = {
type DeepReadonlyObject<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>;

@@ -6,0 +6,0 @@ };

@@ -1,1 +0,1 @@

export * from './config.validation.exception';
export * from './errors';

@@ -17,2 +17,2 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./config.validation.exception"), exports);
__exportStar(require("./errors"), exports);
{
"name": "@unifig/core",
"version": "0.6.0",
"version": "0.7.0",
"description": "Universal, typed and validated configuration manager",

@@ -32,5 +32,5 @@ "keywords": [

"devDependencies": {
"@types/validator": "^13.7.7",
"@types/validator": "^13.7.10",
"class-transformer": "^0.5.1",
"class-validator": "^0.13.2",
"class-validator": "^0.14.0",
"reflect-metadata": "^0.1.13"

@@ -44,6 +44,3 @@ },

},
"dependencies": {
"table": "^6.8.0"
},
"gitHead": "8924e03fc9ce192bf4746e84b5334f16ab2553f5"
"gitHead": "8bc3b487a11a717e789734f973255dbf896fa188"
}

@@ -17,6 +17,9 @@ <h1 align="center">Unifig</h1>

- [Goal](#goal)
- [Installation](#installation)
- [Quick Start](#quick_start)
- [Multiple Configurations](#multiple_configurations)
- [Setting up Templates](#templates)
- [Subtemplates](#templates_subtemplates)
- [Loading](#loading)
- [Values Adapters](#loading_adapters)
- [Multiple Configurations](#loading_multiple_configurations)
- [Inline Validation Rejection](#loading_inline_rejection)
- [Stale Data](#stale_data)

@@ -44,6 +47,8 @@ - [Todo Before 1.0.0](#100todo)

## Quick Start
## Setting up Templates
<a name="quick_start"></a>
<a name="templates"></a>
Unifig centralizes configuration management in classes called templates. They are resposible for deserializing config values from sources into rich js / ts objects and validating them afterwards.
```ts

@@ -55,20 +60,29 @@ import { From, Nested } from '@unifig/core';

class DbSettings {
@From('global.dbUrl')
@From({ key: 'DB_URL', default: 'localhost' })
@IsString()
url: string;
@From('global.dbPassword')
@From('DB_PASSWORD')
@IsString()
password: string;
@From('DB_RECONNECT_DELAYS')
@Transform(({ value }) => value.split(',').map((n) => Number(n)))
@IsArray()
reconnectDelays: number[];
}
```
export class Settings {
@From('local.port')
### Subtemplates
<a name="templates_subtemplates"></a>
They allow to keep config structure organized by grouping inseparable properties and allowing reusing of them. The subtemplate itself is declared just as regular template, including option to nest further subtemplates in it.
```ts
export class AppSettings {
@From('PORT')
@IsInt()
port: number;
@Transform(({ value }) => value.split(',').map((n) => Number(n)))
@IsArray()
intervals: number[];
@Nested(() => DbSettings)

@@ -79,2 +93,8 @@ db: DbSettings;

## Loading configuration
<a name="loading"></a>
After defining template they should be loaded before any other action in the application takes place.
```ts

@@ -84,12 +104,18 @@ import { Config, PlainConfigAdapter } from '@unifig/core';

async function bootstrap() {
await Config.register({
template: Settings,
const validationError = await Config.register({
template: AppSettings,
adapter: new PlainConfigAdapter({
local: { port: 3000 },
global: { dbUrl: 'localhost:5467', dbPassword: 'password' },
intervals: '56,98,34,72',
PORT: 3000,
DB_URL: 'localhost:5467',
DB_PASSWORD: 'password',
DB_RECONNECT_DELAYS: '56,98,34,72',
}),
});
console.log(Config.getValues(Settings).port); // output: 3000
if (validationError) {
console.error(validationError.message);
process.exit(1);
}
console.log(Config.getValues(AppSettings).port); // output: 3000
}

@@ -102,23 +128,55 @@

## Multiple Configurations
### Values adapters
<a name="multiple_configurations"></a>
<a name="loading_adapters"></a>
Unifig allows to easily swap config values sources or introduce new ones.
Implementation of the adapter consist of class which exposes `load` method, which is called upon config initialization. The method should return dictionary with keys used in `@From` decorators in templates and underlying values.
```ts
async function bootstrap() {
await Config.register(
{ template: Settings, adapter: ... },
{ template: AnotherSettings, adapter: ... },
{ templates: [MoreAnotherSettings, YetMoreAnotherSettings], adapter: ... },
);
import { ConfigAdapter, ConfigSource } from '@unifig/core';
config.log(Config.getValues(Settings).someProperty)
config.log(Config.getValues(AnotherSettings).someProperty)
config.log(Config.getValues(MoreAnotherSettings).someProperty)
config.log(Config.getValues(YetMoreAnotherSettings).someProperty)
export class CustomAdapter implements ConfigAdapter {
async load(): Promise<ConfigSource> {
return {
PORT: '3000', // will be parsed to number as declared in template
DB_URL: 'localhost:5467',
DB_PASSWORD: 'password',
DB_RECONNECT_DELAYS: '56,98,34,72',
};
}
}
```
Additional configs may be registered with separate `.register()` calls.
```ts
await Config.register({
template: AppSettings,
adapter: new CustomAdapter(),
});
```
### Multiple Configurations
<a name="loading_multiple_configurations"></a>
In case no single configuration root (`AppSettings` in above example), templates need to be registered separately.
```ts
await Config.register(
{ template: DbSettings, adapter: ... },
{ template: AuthSettings, adapter: ... },
{ templates: [FilesStorageSettings, CacheSettings], adapter: ... },
);
```
### Inline validation rejection
<a name="loading_inline_rejection"></a>
To throw validation exception right away after encountering errors instead of returning it use
```ts
await Config.registerOrReject({ template: DbSettings, adapter: ... });
```
## Stale Data

@@ -125,0 +183,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc