Skip to content

Instantly share code, notes, and snippets.

@Lakitna
Created June 18, 2019 16:20
Show Gist options
  • Save Lakitna/8d1b8c13ec92454e207169f12b48c5ab to your computer and use it in GitHub Desktop.
Save Lakitna/8d1b8c13ec92454e207169f12b48c5ab to your computer and use it in GitHub Desktop.
interface LawConfig {
[config: string]: any;
/**
* Define the severity of the law.
* note: `omit` will always result in the law not being enforced
* @default must
*/
severity?: 'must' | 'should' | 'may' | 'optional' | 'omit';
/**
* Define the behaviour of a failure.
* @private
*/
_throw?: 'error' | 'warn' | 'log' | null;
/**
* @private
*/
_name?: string;
/**
* Specificity level used to cascase configurations
* @private
*/
_specificity?: number;
}
declare type severityLevel = 'error' | 'warn' | 'log' | null;
interface LawbookConfig {
/**
* Define what log level you want to output
* @default log
*/
verboseness: 'error' | 'warn' | 'log' | 'debug';
/**
* Describe the effect a failure has in a given severity category
*/
severity: {
/**
* @default error
*/
must: severityLevel;
/**
* @default warn
*/
should: severityLevel;
/**
* @default log
*/
may: severityLevel;
/**
* @default log
*/
optional: severityLevel;
};
/**
* List of law configurations
*/
laws: {
[lawName: string]: LawConfig;
};
/**
* @private
* List of laws and their parsed configurations.
*/
_laws: any[];
}
/**
* Configuration handling
*/
declare class ConfigManager {
config: LawbookConfig;
constructor(config?: LawbookConfig);
readonly full: LawbookConfig;
readonly laws: any[];
readonly generic: Pick<LawbookConfig, "verboseness" | "severity">;
set(config: LawbookConfig): void;
/**
* Find the most specific config for a law
*/
get(lawName: string): LawConfig;
/**
* Apply config cascading based on law name specificity
*/
parse(config: LawbookConfig): LawbookConfig;
/**
* Sort a list of objects by the specificity of the provided key
* @private
*/
private _sortBySpecificity;
}
/**
* Collection to manage laws
*/
declare class Lawbook {
config: ConfigManager;
laws: Law[];
constructor(config?: LawbookConfig);
readonly length: number;
/**
* Loop over the laws in the set
*/
forEach(fn: (value: Law, index: number, array: Law[]) => void, thisArg?: any): void;
/**
* Add a law or create a new empty one
* Sets configuration
*/
add(law: string | Law, defaultConfig?: LawConfig): Law;
/**
* Returns true if the set contains the given Law name pattern
*/
has(globPattern: string): boolean;
/**
* Return laws matching filter in a new law book
* Opposite of omit()
* @return new Lawbook
*/
filter(globPattern: string): Lawbook;
/**
* Return laws not matching filter in a new law book
* Opposite of filter()
* @return new Lawbook
*/
omit(globPattern: string): Lawbook;
/**
* Enforce all laws in the set
*/
enforce(globPattern: string, ...input: any[]): Promise<this>;
}
/**
* A testing rule
*
* @example
* new Law('foo')
* .describe(`
* An example law
* `)
* .define(function(val) {
* return val <= 5;
* })
* .punishment(function(val) {
* throw new Error(`${val} is above 5`);
* })
* .reward(function(val) {
* console.log(`${val} is below or equal to 5`);
* })
* .enforce(1);
*/
declare class Law {
name: string;
description: string | undefined;
specificity: number;
lawbook: Lawbook;
private _config;
private on;
constructor(name: string, lawbook: Lawbook);
/**
* Get config, omitting keys that start with `_`
*/
/**
* Set config while treating existing config as defaults
*/
config: LawConfig;
/**
* Define the law logic.
* Return `true` to reward, return anything else or throw an error
* to punish. The returned value is passed to the punishment as the
* final argument.
*
* @example
* Law.define(function(val) {
* return val > 5;
* });
*/
define(fn: (...input: any) => boolean | any): this;
/**
* Define what will happen if the law fails
*
* @example
* Law.punishment(function(input) {
* throw new Error(`Law failed. Input: ${input}`)
* });
*
* @example The final argument is the result of the definition
* Law.punishment(function(input, result) {
* this.throw(`Enforcing resulted in ${result}`);
* });
*/
punishment(fn: (input: any, err: any) => void): this;
/**
* Define what will happen if the law passes.
*
* @example
* Law.reward(function(val) {
* console.log('Yay! The law is uphold. Let\'s party!');
* });
*/
reward(fn: (input: any[]) => void): this;
/**
* Provide a human readable description of the law.
*
* @example
* Law.describe(`
* Look at this amazing description!
* `);
*/
describe(description: string): this;
/**
* Enforce a law.
*
* @example
* Law.enforce('foo');
*
* @example
* Law.enforce('foo', 'bar', 1, 86, 9302);
*/
enforce(...input: any): Promise<this>;
/**
* Throw an error or log a warning for this law.
* Severity decides if it'll throw or log at witch level.
*
* @example
* Law.throw('An error has occured');
*/
throw(...message: string[]): void;
}
/**
* Collection to manage laws
*/
declare class Lawbook$1 {
config: ConfigManager;
laws: Law[];
constructor(config?: LawbookConfig);
readonly length: number;
/**
* Loop over the laws in the set
*/
forEach(fn: (value: Law, index: number, array: Law[]) => void, thisArg?: any): void;
/**
* Add a law or create a new empty one
* Sets configuration
*/
add(law: string | Law, defaultConfig?: LawConfig): Law;
/**
* Returns true if the set contains the given Law name pattern
*/
has(globPattern: string): boolean;
/**
* Return laws matching filter in a new law book
* Opposite of omit()
* @return new Lawbook
*/
filter(globPattern: string): Lawbook$1;
/**
* Return laws not matching filter in a new law book
* Opposite of filter()
* @return new Lawbook
*/
omit(globPattern: string): Lawbook$1;
/**
* Enforce all laws in the set
*/
enforce(globPattern: string, ...input: any[]): Promise<this>;
}
export default Lawbook$1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment