Skip to content

Commit

Permalink
fix(config): arrays in config couldn't be overwritten
Browse files Browse the repository at this point in the history
  • Loading branch information
jagregory committed Nov 27, 2021
1 parent 1e6cb52 commit 7526a0a
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 11 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@types/express": "^4.17.13",
"@types/jest": "^25.2.1",
"@types/jsonwebtoken": "^8.3.9",
"@types/lodash.mergewith": "^4.6.6",
"@types/supertest": "^2.0.8",
"@types/uuid": "^7.0.2",
"@typescript-eslint/eslint-plugin": "^2.27.0",
Expand All @@ -60,9 +61,9 @@
"boxen": "^4.2.0",
"cors": "^2.8.5",
"debug": "^4.1.1",
"deepmerge": "^4.2.2",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"lodash.mergewith": "^4.6.2",
"short-uuid": "^4.2.0",
"stormdb": "^0.4.1",
"uuid": "^7.0.3"
Expand Down
101 changes: 101 additions & 0 deletions src/server/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { newMockDataStore } from "../__tests__/mockDataStore";
import { DefaultConfig, loadConfig } from "./config";

describe("loadConfig", () => {
it("returns the default config if no config exists", async () => {
const createDataStore = jest.fn().mockResolvedValue(newMockDataStore());

const config = await loadConfig("dir", createDataStore);

expect(config).toEqual(DefaultConfig);
});

it("merges the defaults with any existing config", async () => {
const ds = newMockDataStore();
const createDataStore = jest.fn().mockResolvedValue(ds);

ds.getRoot.mockResolvedValue({
TriggerFunctions: {
CustomMessage: "custom-config",
},
UserPoolDefaults: {
MFAOptions: "OPTIONAL",
},
});

const config = await loadConfig("dir", createDataStore);

expect(config).toEqual({
...DefaultConfig,
TriggerFunctions: {
CustomMessage: "custom-config",
},
UserPoolDefaults: {
// new field
MFAOptions: "OPTIONAL",
// field from defaults
UsernameAttributes: ["email"],
},
});
});

it("can unset a property when merging", async () => {
const ds = newMockDataStore();
const createDataStore = jest.fn().mockResolvedValue(ds);

ds.getRoot.mockResolvedValue({
UserPoolDefaults: {
UsernameAttributes: null,
},
});

const config = await loadConfig("dir", createDataStore);

expect(config).toEqual({
...DefaultConfig,
UserPoolDefaults: {
UsernameAttributes: null,
},
});
});

it("overwrites arrays when merging", async () => {
const ds = newMockDataStore();
const createDataStore = jest.fn().mockResolvedValue(ds);

ds.getRoot.mockResolvedValue({
UserPoolDefaults: {
UsernameAttributes: ["phone_number"],
},
});

const config = await loadConfig("dir", createDataStore);

expect(config).toEqual({
...DefaultConfig,
UserPoolDefaults: {
UsernameAttributes: ["phone_number"],
},
});
});

it("can set an arrays to empty when merging", async () => {
const ds = newMockDataStore();
const createDataStore = jest.fn().mockResolvedValue(ds);

ds.getRoot.mockResolvedValue({
UserPoolDefaults: {
UsernameAttributes: [],
},
});

const config = await loadConfig("dir", createDataStore);

expect(config).toEqual({
...DefaultConfig,
UserPoolDefaults: {
UsernameAttributes: [],
},
});
});
});
24 changes: 15 additions & 9 deletions src/server/config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import deepmerge from "deepmerge";
import { createDataStore } from "../services/dataStore";
import { CreateDataStore } from "../services/dataStore";
import { FunctionConfig } from "../services/lambda";
import { UserPool } from "../services/userPoolService";
import { TokenConfig } from "../services/tokens";
import mergeWith from "lodash.mergewith";

export type UserPoolDefaults = Omit<
UserPool,
Expand Down Expand Up @@ -34,14 +34,20 @@ export const DefaultConfig: Config = {
},
};

export const loadConfig = async (configDirectory: string): Promise<Config> => {
const dataStore = await createDataStore(
"config",
DefaultConfig,
configDirectory
);
export const loadConfig = async (
configDirectory: string,
createDataStore: CreateDataStore
): Promise<Config> => {
const dataStore = await createDataStore("config", {}, configDirectory);

const config = await dataStore.getRoot<Config>();

return deepmerge(DefaultConfig, config ?? {});
return mergeWith({}, DefaultConfig, config ?? {}, function customizer(
objValue,
srcValue
) {
if (Array.isArray(srcValue)) {
return srcValue;
}
});
};
2 changes: 1 addition & 1 deletion src/server/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const createDefaultServer = async (logger: Logger): Promise<Server> => {
const configDirectory = ".cognito";
const dataDirectory = `${configDirectory}/db`;

const config = await loadConfig(configDirectory);
const config = await loadConfig(configDirectory, createDataStore);

logger.debug("Loaded config:", config);

Expand Down
17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,18 @@
dependencies:
"@types/node" "*"

"@types/lodash.mergewith@^4.6.6":
version "4.6.6"
resolved "https://registry.yarnpkg.com/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz#c4698f5b214a433ff35cb2c75ee6ec7f99d79f10"
integrity sha512-RY/8IaVENjG19rxTZu9Nukqh0W2UrYgmBj5sdns4hWRZaV8PqR7wIKHFKzvOTjo4zVRV7sVI+yFhAJql12Kfqg==
dependencies:
"@types/lodash" "*"

"@types/lodash@*":
version "4.14.177"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.177.tgz#f70c0d19c30fab101cad46b52be60363c43c4578"
integrity sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw==

"@types/mime@^1":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
Expand Down Expand Up @@ -6519,6 +6531,11 @@ lodash.isstring@^4.0.1:
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=

lodash.mergewith@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==

lodash.once@^4.0.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
Expand Down

0 comments on commit 7526a0a

Please sign in to comment.