Skip to content

Commit

Permalink
Add the feature of Custom Parser and add any test unit
Browse files Browse the repository at this point in the history
  • Loading branch information
Arylo committed Jun 22, 2018
1 parent fff6146 commit 7e57814
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 32 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ const config = new Config();
config.addConfigPath('./config', 'yaml');
```

### Use Custom parse

```javascript
const config = new Config();
config.addParser({
format: 'ini',
filter: /\.ini$/,
handler: (filepath) => {
const fs = require('fs');
const ini = require('ini');
return ini.parse(fs.readFileSync('./config.ini', 'utf-8'))
}
});
```

### Add Config Data

```javascript
Expand Down
95 changes: 66 additions & 29 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,70 @@ import * as fs from "fs";
import merge = require("lodash.merge");
import * as path from "path";

type Format = "json" | "yaml";
// tslint:disable-next-line:no-namespace
declare namespace Config {
export type Format = "json" | "yaml" | string;
type TrueFormat = symbol | Format;

type TrueFormat = "object" | Format;
interface IStoreObj {
data: object | string;
format: TrueFormat;
}

interface IStoreObj {
data: object | string;
format: TrueFormat;
export interface IParserrObj<T> {
handler: (p: fs.PathLike) => Partial<T>;
filter: RegExp;
format: string;
}
}

export = class Config<T extends { }> {
class Config<T extends { }> {

private storeObjs: IStoreObj[] = [ ];
private storeObjs: Config.IStoreObj[] = [ ];
private config = { };
private objSymbol = Symbol("object");

private parsers: Array<Config.IParserrObj<T>> = [{
filter: /\.json$/,
format: "yaml",
handler: (filepath) => {
const fileOptions = { encoding: "utf-8" };
const filedata = fs.readFileSync(filepath, fileOptions);
return JSON.parse(filedata);
}
}, {
filter: /\.ya?ml$/,
format: "json",
handler: (filepath) => {
return YAML(filepath);
}
}];

public addConfig(obj: Partial<T>) {
this.storeObjs.push({
data: obj,
format: "object"
format: this.objSymbol
});
return true;
}

public addConfigPath(p: fs.PathLike, format?: Format) {
public addConfigPath(p: fs.PathLike, format?: Config.Format) {
p = p.toString();
if (!path.isAbsolute(p)) {
p = `${process.cwd()}/${p}`;
}
if (fs.existsSync(p)) {
if (!format) {
format = "json";
if (/\.json$/.test(p)) {
format = "json";
} else if (/\.ya?ml$/.test(p)) {
format = "yaml";
if (format === undefined) {
for (const parserObj of this.parsers) {
if (parserObj.filter.test(p)) {
format = parserObj.format;
break;
}
}
}
if (format === undefined) {
return false;
}
this.storeObjs.push({
data: p,
format
Expand All @@ -50,6 +78,11 @@ export = class Config<T extends { }> {
}
}

public addParser(obj: Config.IParserrObj<T>) {
this.parsers.push(obj);
return true;
}

public get(key: keyof T) {
return this.getConfig()[key as any];
}
Expand All @@ -64,20 +97,22 @@ export = class Config<T extends { }> {
.forEach((item) => {
delete this.config[item];
});
for (const info of this.storeObjs) {
for (const storeObj of this.storeObjs) {
let data = { };
if (info.format === "object") {
data = info.data;
} else if (info.format === "json") {
const p = info.data as string;
try {
const fileOptions = { encoding: "utf-8" };
const filedata = fs.readFileSync(p, fileOptions);
data = JSON.parse(filedata);
// tslint:disable-next-line:no-empty
} catch (error) { }
} else if (info.format === "yaml") {
data = YAML(path);
if (storeObj.format === this.objSymbol) {
data = storeObj.data;
} else {
const filepath = storeObj.data as string;
for (const parserObj of this.parsers) {
if (parserObj.format !== storeObj.format) {
continue;
}
try {
data = parserObj.handler(filepath);
// tslint:disable-next-line:no-empty
} catch (error) { }
break;
}
}
config = merge(config, data);
}
Expand All @@ -100,4 +135,6 @@ export = class Config<T extends { }> {
return md5.digest("hex");
}

};
}

export = Config;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "y-config",
"version": "2.0.0",
"version": "2.0.1",
"description": "Create public configuration for the project",
"main": "dist/index.js",
"types": "lib/index.ts",
Expand Down
3 changes: 3 additions & 0 deletions simples/config/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "JSON"
}
1 change: 1 addition & 0 deletions simples/config/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type: "YAML"
18 changes: 16 additions & 2 deletions test/muchConfig.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import test from "ava";
import * as findUp from "find-up";
import * as path from "path";
import Config = require("../lib");

test("Empty Config", (t) => {
const oneConfig = new Config();
const configFolderPath = path.resolve(findUp.sync("simples"), "config");

test("Much Config", (t) => {
const oneConfig = new Config<{ baz: string; }>();
const otherConfig = new Config();
oneConfig.addConfig({
baz: "foo"
});
t.not(oneConfig.toString(), otherConfig.toString());
t.not(oneConfig.toObject(), otherConfig.toObject());
t.not(oneConfig.getConfig(), otherConfig.getConfig());
t.is(oneConfig.get("baz"), "foo");
t.is(otherConfig.get("baz" as never), undefined);
});

test("Much Config File", (t) => {
const config = new Config<{ type: string; comment: string; }>();
config.addConfigPath(path.resolve(configFolderPath, "config.json"));
t.is(config.get("type"), "JSON");
config.addConfigPath(path.resolve(configFolderPath, "config.yaml"));
t.is(config.get("type"), "YAML");
});

0 comments on commit 7e57814

Please sign in to comment.