Repository: artusjs/core
Pull request #274 (2024-03-21 12:57:43)

fix: deep merge config


Patch:
diff --git a/src/application.ts b/src/application.ts
index c8246d4..4ab38e6 100644
--- a/src/application.ts
+++ b/src/application.ts
@@ -4,6 +4,7 @@ import { ArtusInjectEnum } from './constant';
 import { ArtusStdError } from './exception';
 import { HookFunction, LifecycleManager } from './lifecycle';
 import { LoaderFactory, Manifest } from './loader';
+import { mergeConfig } from './loader/utils/merge';
 import { Application, ApplicationInitOptions } from './types';
 import ConfigurationHandler from './configuration';
 import { Logger, LoggerType } from './logger';
@@ -114,7 +115,7 @@ export class ArtusApplication implements Application {
     const newConfig = this.configurationHandler.getMergedConfig() ?? {};
     this.container.set({
       id: ArtusInjectEnum.Config,
-      value: Object.assign(oldConfig, newConfig),
+      value: mergeConfig(oldConfig, newConfig),
     });
   }
 }


Test patch:
diff --git a/test/config.test.ts b/test/config.test.ts
index e4150a9..5653423 100644
--- a/test/config.test.ts
+++ b/test/config.test.ts
@@ -16,4 +16,13 @@ describe("test/config.test.ts", () => {
       process.env[ARTUS_SERVER_ENV] = undefined;
     });
   });
+
+
+  describe("app with manifest should load config ok", () => {
+    it("should load config ok", async () => {
+      const { main } = require("./fixtures/app_with_manifest/bootstrap");
+      const app = await main();
+      expect(app.config).toEqual({ httpConfig: { key1: 'value1', port: 3000 }, plugin: {} });
+    });
+  });
 });
diff --git a/test/fixtures/app_with_manifest/bootstrap.ts b/test/fixtures/app_with_manifest/bootstrap.ts
new file mode 100644
index 0000000..dd4e7c3
--- /dev/null
+++ b/test/fixtures/app_with_manifest/bootstrap.ts
@@ -0,0 +1,29 @@
+import path from "path";
+// import fs from 'fs';
+import 'reflect-metadata';
+import { ArtusApplication } from "../../../src";
+
+const rootDir = path.resolve(__dirname, "./");
+
+async function main() {
+  const app = new ArtusApplication();
+  const metaFilePath = path.resolve(rootDir, 'manifest.json');
+  //   let manifest;
+  // if (fs.existsSync(metaFilePath)) {
+  const manifest = require((metaFilePath));
+  // } else {
+  // const scanner = new ArtusScanner({
+  //     configDir: 'config',
+  //     needWriteFile: true,
+  //     useRelativePath: true,
+  //     extensions: ['.ts', '.js', '.json'],
+  //     app,
+  // });
+  // manifest = await scanner.scan(rootDir);
+  // }
+  await app.load(manifest, rootDir);
+  await app.run();
+  return app;
+
+}
+export { main };
diff --git a/test/fixtures/app_with_manifest/config/config.default.ts b/test/fixtures/app_with_manifest/config/config.default.ts
new file mode 100644
index 0000000..377ca83
--- /dev/null
+++ b/test/fixtures/app_with_manifest/config/config.default.ts
@@ -0,0 +1,6 @@
+
+export default {
+  httpConfig: {
+    port: 3000,
+  },
+};
\ No newline at end of file
diff --git a/test/fixtures/app_with_manifest/controller/home.ts b/test/fixtures/app_with_manifest/controller/home.ts
new file mode 100644
index 0000000..cc5bc25
--- /dev/null
+++ b/test/fixtures/app_with_manifest/controller/home.ts
@@ -0,0 +1,8 @@
+import { Injectable } from '../../../../src/';
+
+@Injectable()
+export default class DemoController {
+  public async index() {
+    return { code: 0, message: 'ok', data: {} };
+  }
+}
diff --git a/test/fixtures/app_with_manifest/lifecycle.ts b/test/fixtures/app_with_manifest/lifecycle.ts
new file mode 100644
index 0000000..13739bb
--- /dev/null
+++ b/test/fixtures/app_with_manifest/lifecycle.ts
@@ -0,0 +1,13 @@
+import { LifecycleHookUnit, ApplicationLifecycle, LifecycleHook, Inject, ArtusApplication, ArtusInjectEnum } from '../../../src';
+
+@LifecycleHookUnit()
+export default class MyLifecycle implements ApplicationLifecycle {
+  @Inject(ArtusInjectEnum.Application)
+  private app: ArtusApplication;
+
+  @LifecycleHook()
+  public async configWillLoad() {
+    this.app.config.httpConfig = this.app.config.httpConfig ?? {};
+    this.app.config.httpConfig.key1 = 'value1';
+  }
+}
diff --git a/test/fixtures/app_with_manifest/manifest.json b/test/fixtures/app_with_manifest/manifest.json
new file mode 100644
index 0000000..d844113
--- /dev/null
+++ b/test/fixtures/app_with_manifest/manifest.json
@@ -0,0 +1,49 @@
+{
+  "version": "2",
+  "refMap": {
+    "_app": {
+      "relativedPath": "",
+      "pluginConfig": {},
+      "items": [
+        {
+          "path": "config/config.default",
+          "extname": ".ts",
+          "filename": "config.default.ts",
+          "loader": "config",
+          "source": "app",
+          "unitName": "_app",
+          "loaderState": {
+            "exportNames": []
+          }
+        },
+        {
+          "path": "controller/home",
+          "extname": ".ts",
+          "filename": "home.ts",
+          "loader": "module",
+          "source": "app",
+          "unitName": "_app",
+          "loaderState": {
+            "exportNames": [
+              "default"
+            ]
+          }
+        },
+        {
+          "path": "lifecycle",
+          "extname": ".ts",
+          "filename": "lifecycle.ts",
+          "loader": "lifecycle-hook-unit",
+          "source": "app",
+          "unitName": "_app",
+          "loaderState": {
+            "exportNames": [
+              "default"
+            ]
+          }
+        }
+      ]
+    }
+  },
+  "extraPluginConfig": {}
+}
\ No newline at end of file