Skip to content

Commit e5aa4aa

Browse files
authored
Version 1.0.5 (#22) (#24)
1 parent 7f9fb68 commit e5aa4aa

11 files changed

Lines changed: 238 additions & 33 deletions

File tree

README.md

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,137 @@
1-
# conev sync
1+
# conev-sync
2+
Conev-sync is a synchronous version of [conev](#reference). You can save, manage and use configuration through it.
3+
4+
## Contents
5+
6+
- [Install](#install)
7+
- [Usage](#usage)
8+
- [ConfigBuilder](#configbuilder)
9+
- [Config](#config)
10+
- [Source](#source)
11+
- [Sources](#sources)
12+
- [JsonSource](#jsonsource)
13+
- [Example](#example)
14+
- [Reference](#reference)
15+
## Install
16+
```shell
17+
npm install conev-sync
18+
```
19+
20+
## Usage
21+
22+
Get ConfigBuilder from conev-sync and one or more Sources to use. In this example, the built-in JsonSource is used.
23+
24+
```typescript
25+
import { ConfigBuilder, JsonSource } from 'conev-sync';
26+
```
27+
28+
29+
Then, create Sources and set up.
30+
31+
```typescript
32+
const jsonSource = new JsonSource();
33+
34+
jsonSource
35+
.set('basic', basic) //basic is JSON
36+
.set('dev', dev) //dev is JSON
37+
.set('prd', prd); //prd is JSON
38+
```
39+
40+
41+
Create ConfigBuilder and add Environment, Source.
42+
43+
```typescript
44+
const builder = new ConfigBuilder();
45+
46+
builder
47+
.addEnv('dev', 'basic')
48+
.addSource(jsonSource);
49+
```
50+
51+
52+
Build configuration.
53+
54+
```typescript
55+
const config = builder.build(); // This is the result of combining dev and basic.
56+
```
57+
58+
59+
Use configuration.
60+
61+
```typescript
62+
config.get(); // The whole configuration created comes out
63+
config.get('a.b.c'); // Is same as config.get().a.b.c
64+
```
65+
66+
67+
68+
*Each of Environments and Sources are merged by [deepmerge](#reference).(What is added first has high priority)*
69+
You can set deepmerge options as follow :
70+
71+
```typescript
72+
builder.setOptions(options);
73+
```
74+
75+
### ConfigBuilder
76+
77+
```typescript
78+
class ConfigBuilder {
79+
addSource(...sources: Source[]): ConfigBuilder;
80+
addEnv(...envs: string[]): ConfigBuilder;
81+
setOptions(options?: Options): ConfigBuilder;
82+
build(): Config;
83+
}
84+
```
85+
`ConfigBuilder` takes a configuration from the source and creates a new configuration according to the environment. `Env` and `Source` have priority. If priority is not defined, highest priority is added first.
86+
87+
### Config
88+
89+
```typescript
90+
class Config {
91+
constructor(sources: Source[], envs: string[], options?: Options);
92+
sync(): Config;
93+
get(key = ''): unknown | undefined;
94+
}
95+
```
96+
`config` is a container for configuration. `config` is provided by creating a new configuration from the configuration and environment obtained from `source`.
97+
98+
### Source
99+
100+
```typescript
101+
interface Source {
102+
export(): Map<string, Record<string, unknown>>;
103+
}
104+
```
105+
`Source` defines the source from which to get the configuration. Map is returned as the result value of `export`. The key of this map is environment and the value is the configuration when environment.
106+
107+
You can make custom `Source` and use that.
108+
109+
### Sources
110+
111+
```typescript
112+
class Sources implements Source {
113+
constructor(sources: Source[], options?: Options);
114+
add(source: Source, priority = -1): Sources;
115+
export(): Map<string, Record<string, unknown>>;
116+
}
117+
```
118+
`Sources` defines the source by merging several sources. Use `add` to add source for new source. Map is returned as the result value of `export`. The key of this map is environment and the value is the configuration when environment.
119+
120+
121+
### JsonSource
122+
123+
```typescript
124+
export default class JsonSource {
125+
constructor();
126+
set(env: string, json: Record<string, unknown>): JsonSource;
127+
export(): Map<string, Record<string, unknown>>;
128+
}
129+
```
130+
`JsonSource` defines the source from JSON. Use `set` to add a configuration for a new environment. Map is returned as the result value of `export`. The key of this map is environment and the value is the configuration when environment.
131+
132+
## Example
133+
134+
## Reference
135+
136+
- [conev](https://github.com/CourseDesign/conev)
137+
- [deepmerge](https://github.com/TehShrike/deepmerge)

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "conev-sync",
3-
"version": "1.0.2",
3+
"version": "1.0.5",
44
"description": "",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -24,14 +24,14 @@
2424
},
2525
"repository": {
2626
"type": "git",
27-
"url": "git+https://github.com/CourseDesign/design-system.git"
27+
"url": "git+https://github.com/CourseDesign/conev-sync.git"
2828
},
2929
"author": "",
3030
"license": "ISC",
3131
"bugs": {
32-
"url": "https://github.com/CourseDesign/design-system/issues"
32+
"url": "https://github.com/CourseDesign/conev-sync/issues"
3333
},
34-
"homepage": "https://github.com/CourseDesign/design-system#readme",
34+
"homepage": "https://github.com/CourseDesign/conev-sync#readme",
3535
"husky": {
3636
"hooks": {
3737
"pre-push": "npm run test",
@@ -83,7 +83,7 @@
8383
"typescript": "^4.0.2"
8484
},
8585
"dependencies": {
86-
"conev-sync-core": "^1.0.4",
86+
"conev-sync-core": "^1.0.5",
8787
"conev-sync-json-source": "^1.0.4"
8888
}
8989
}

package/conev-sync-core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "conev-sync-core",
3-
"version": "1.0.4",
3+
"version": "1.0.5",
44
"description": "",
55
"main": "dist/index.js",
66
"types" : "dist/index.d.ts",
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export default class Cache<K, V> {
2+
private readonly provider: (key: K) => V | undefined;
3+
4+
private readonly values: Map<K, V>;
5+
6+
constructor(provider: (key: K) => V | undefined) {
7+
this.provider = provider;
8+
this.values = new Map<K, V>();
9+
}
10+
11+
refresh(): Cache<K, V> {
12+
this.values.clear();
13+
return this;
14+
}
15+
16+
get(key: K): V | undefined {
17+
if (!this.values.has(key)) {
18+
const value = this.provider(key);
19+
if (value !== undefined) {
20+
this.values.set(key, value);
21+
}
22+
}
23+
return this.values.get(key);
24+
}
25+
}

package/conev-sync-core/src/config/config.spec.ts

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,24 @@ import Config from './config';
22
import SourceMock from '../source/source.mock';
33

44
describe('config', () => {
5-
const source1 = new SourceMock(
6-
new Map<string, Record<string, unknown>>([
7-
['default', { source: '1', port: 3000, db: { type: 'postgres' } }],
8-
['develop', { env: 'develop', port: 3001 }],
9-
])
10-
);
11-
12-
const source2 = new SourceMock(
13-
new Map<string, Record<string, unknown>>([
14-
[
15-
'default',
16-
{
17-
source: '2',
18-
port: 3000,
19-
db: { port: 7070, username: 'test', type: 'mysql' },
20-
},
21-
],
22-
['production', { env: 'production', port: 3002 }],
23-
])
24-
);
5+
const values1 = new Map<string, Record<string, unknown>>([
6+
['default', { source: '1', port: 3000, db: { type: 'postgres' } }],
7+
['develop', { env: 'develop', port: 3001 }],
8+
]);
9+
const source1 = new SourceMock(values1);
10+
11+
const values2 = new Map<string, Record<string, unknown>>([
12+
[
13+
'default',
14+
{
15+
source: '2',
16+
port: 3000,
17+
db: { port: 7070, username: 'test', type: 'mysql' },
18+
},
19+
],
20+
['production', { env: 'production', port: 3002 }],
21+
]);
22+
const source2 = new SourceMock(values2);
2523

2624
test('get', () => {
2725
const config = new Config([source1, source2], ['default', 'develop']);
@@ -33,6 +31,34 @@ describe('config', () => {
3331
db: { port: 7070, username: 'test', type: 'mysql' },
3432
});
3533
expect(config.get('source')).toEqual('2');
34+
expect(config.get('port')).toEqual(3001);
35+
expect(config.get('db.port')).toEqual(7070);
36+
});
37+
38+
test('sync', () => {
39+
const config = new Config([source1, source2], ['default', 'develop']);
40+
41+
expect(config.get()).toEqual({
42+
source: '2',
43+
env: 'develop',
44+
port: 3001,
45+
db: { port: 7070, username: 'test', type: 'mysql' },
46+
});
47+
expect(config.get('source')).toEqual('2');
48+
expect(config.get('port')).toEqual(3001);
49+
expect(config.get('db.port')).toEqual(7070);
50+
51+
values2.set('develop', { port: 3002 });
52+
config.sync();
53+
54+
expect(config.get()).toEqual({
55+
source: '2',
56+
env: 'develop',
57+
port: 3002,
58+
db: { port: 7070, username: 'test', type: 'mysql' },
59+
});
60+
expect(config.get('source')).toEqual('2');
61+
expect(config.get('port')).toEqual(3002);
3662
expect(config.get('db.port')).toEqual(7070);
3763
});
3864
});

package/conev-sync-core/src/config/config.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import merge, { Options } from 'deepmerge';
22
import Sources from '../source/sources';
33
import Source from '../source/source';
4+
import Cache from '../cache/cache';
45

56
export default class Config {
67
private readonly sources: Sources;
@@ -11,16 +12,21 @@ export default class Config {
1112

1213
private values: Record<string, unknown> | null;
1314

15+
private cache: Cache<string, unknown>;
16+
1417
constructor(sources: Source[], envs: string[], options?: Options) {
1518
this.sources = new Sources(sources, options);
1619
this.envs = envs;
1720
this.options = options;
1821
this.values = null;
22+
this.cache = new Cache((key: string) => this.getValue(key));
1923

2024
this.sync();
2125
}
2226

2327
sync(): Config {
28+
this.cache.refresh();
29+
2430
const source = this.sources.export();
2531
const configs = this.envs
2632
.map((env) => source.get(env))
@@ -31,7 +37,11 @@ export default class Config {
3137
return this;
3238
}
3339

34-
get(key = ''): unknown | null {
40+
get(key = ''): unknown | undefined {
41+
return this.cache.get(key);
42+
}
43+
44+
private getValue(key = ''): unknown | undefined {
3545
const tokens: string[] = key.split('.').reverse();
3646

3747
let current: any = this.values;

package/conev-sync-core/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
/* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
1111
"lib": [
1212
"es2017",
13+
"es2015",
1314
"dom"
1415
],
1516
/* Specify library files to be included in the compilation. */
@@ -48,7 +49,7 @@
4849
/* Additional Checks */
4950
// "noUnusedLocals": true, /* Report errors on unused locals. */
5051
// "noUnusedParameters": true, /* Report errors on unused parameters. */
51-
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
52+
// "noImplicitReturns": true, /* Report error when not all code paths in function return a proxy. */
5253
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
5354

5455
/* Module Resolution Options */

package/conev-sync-json-source/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
/* Additional Checks */
4949
// "noUnusedLocals": true, /* Report errors on unused locals. */
5050
// "noUnusedParameters": true, /* Report errors on unused parameters. */
51-
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
51+
// "noImplicitReturns": true, /* Report error when not all code paths in function return a proxy. */
5252
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
5353

5454
/* Module Resolution Options */

script/change-package.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ if (key == null) {
1616

1717
const value = process.argv[4];
1818
if (value == null) {
19-
console.error('Value is undefined!');
19+
console.error('Proxy is undefined!');
2020
process.exit(1);
2121
}
2222

src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
1-
export * from 'conev-sync-core';
1+
export {
2+
default,
3+
ConfigBuilder,
4+
Config,
5+
Source,
6+
Sources,
7+
} from 'conev-sync-core';
28
export { default as JsonSource } from 'conev-sync-json-source';

0 commit comments

Comments
 (0)