Skip to content

Commit 936308d

Browse files
committed
Prepared deep merge improvement
1 parent abbb91a commit 936308d

File tree

4 files changed

+44
-33
lines changed

4 files changed

+44
-33
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Removed support for Node.js below 12
66
- Added support for asynchronous creators (#54)
77
- Added optional `direction` parameter to middlewares (#53)
8+
- Added a deep merge of injector settings (#52)
89
- Updated dependencies
910

1011
## 0.14.3

src/server/core/config.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,25 @@ export function readConfiguration(path: string): ConfigurationFile {
8989
return {};
9090
}
9191

92+
function deepMerge(obj: any, value: any) {
93+
Object.keys(value).forEach((key) => {
94+
const oldItem = obj[key];
95+
const newItem = value[key];
96+
97+
if (newItem === undefined) {
98+
delete obj[key];
99+
} else if (Array.isArray(oldItem) && Array.isArray(newItem)) {
100+
obj[key] = [...oldItem, ...newItem] as any;
101+
} else if (typeof oldItem === 'object') {
102+
obj[key] = deepMerge({ ...oldItem }, newItem);
103+
} else {
104+
obj[key] = newItem;
105+
}
106+
});
107+
108+
return obj;
109+
}
110+
92111
function mergeObjects<T>(
93112
sources: Array<Partial<KrasConfiguration>>,
94113
select: (config: Partial<KrasConfiguration>) => Dict<T>,
@@ -99,21 +118,7 @@ function mergeObjects<T>(
99118
const value = select(source);
100119

101120
if (value && typeof value === 'object') {
102-
Object.keys(value).forEach((key) => {
103-
const oldItem = obj[key];
104-
const newItem = value[key];
105-
106-
if (newItem === undefined) {
107-
delete obj[key];
108-
} else if (typeof oldItem === 'object') {
109-
obj[key] = {
110-
...oldItem,
111-
...newItem,
112-
};
113-
} else {
114-
obj[key] = newItem;
115-
}
116-
});
121+
deepMerge(obj, value);
117122
}
118123
}
119124

src/server/core/webserver.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,11 @@ export class WebServer extends EventEmitter implements BaseKrasServer {
222222
return api;
223223
}
224224

225-
start() {
225+
async setup() {}
226+
227+
async start() {
228+
await this.setup();
229+
226230
this.app.all('*', (req: Request, res: Response) => {
227231
if (req.method !== 'OPTIONS') {
228232
const hook = findHook(this.hooks, req);
@@ -239,7 +243,7 @@ export class WebServer extends EventEmitter implements BaseKrasServer {
239243
return corsHandler(req, res);
240244
});
241245

242-
return new Promise<void>((resolve) => {
246+
return await new Promise<void>((resolve) => {
243247
this.server.listen(this.port, () => {
244248
this.emit('open', {
245249
port: this.port,

src/server/server.ts

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class MockServer extends MockServerCore implements KrasServer {
5555
readonly logs: Array<LogEntry> = [];
5656
readonly logLevel: LogLevel;
5757

58-
constructor(config: KrasConfiguration) {
58+
constructor(private config: KrasConfiguration) {
5959
super(config);
6060

6161
this.logLevel = config.logLevel || 'error';
@@ -66,15 +66,18 @@ export class MockServer extends MockServerCore implements KrasServer {
6666
}
6767
}
6868

69-
async setup(config: KrasConfiguration) {
69+
async setup() {
70+
const config = this.config;
71+
await super.setup();
7072
await withManagement(this, config);
7173
await withInjectors(this, config);
7274
await withMiddlewares(this, config);
7375
await withFiles(this, config);
7476
}
7577

76-
stop() {
77-
return super.stop().then(() => this.injectors.forEach(disposeInjector));
78+
async stop() {
79+
await super.stop();
80+
this.injectors.forEach(disposeInjector);
7881
}
7982

8083
private log(type: LogEntryType, data: any) {
@@ -98,30 +101,28 @@ export function readKrasConfig(options?: ConfigurationOptions, ...files: Array<s
98101
return mergeConfiguration(options, ...configurations);
99102
}
100103

101-
export async function buildKras(config?: Partial<KrasConfiguration>) {
104+
export function buildKras(config?: Partial<KrasConfiguration>) {
102105
const options = buildConfiguration(config);
103-
const server = new MockServer(options);
104-
await server.setup(options);
105-
return server;
106+
return new MockServer(options);
106107
}
107108

108-
export async function buildKrasWithCli(config: KrasConfiguration) {
109-
const server = await buildKras(config);
109+
export function buildKrasWithCli(config: KrasConfiguration) {
110+
const server = buildKras(config);
110111
connectToCli(server, config.api !== false);
111112
return server;
112113
}
113114

114115
export async function runKras(config?: Partial<KrasConfiguration>) {
115-
const server = await buildKras(config);
116-
server.start();
116+
const server = buildKras(config);
117+
await server.start();
117118
return server;
118119
}
119120

120121
export type KrasRuntimeConfiguration = Partial<KrasConfiguration> & KrasHandlerConfiguration;
121122

122123
export function withKras(config?: KrasRuntimeConfiguration) {
123-
return async (callback: KrasRunner) => {
124-
const server = await buildKras(config);
124+
return (callback: KrasRunner) => {
125+
const server = buildKras(config);
125126
configureHandler(server, config);
126127
return runWith(server, callback);
127128
};
@@ -205,8 +206,8 @@ export function connectToCli(server: MockServer, canManage = true) {
205206

206207
export async function runFromCli(options: ConfigurationOptions, rcfile: string) {
207208
const config = readKrasConfig(options, resolve(homedir(), krasrc), resolve(currentDir, krasrc), rcfile);
208-
const server = await buildKrasWithCli(config);
209+
const server = buildKrasWithCli(config);
209210
console.log(`Starting kras v${version} ...`);
210-
server.start();
211+
await server.start();
211212
return server;
212213
}

0 commit comments

Comments
 (0)