From 33d64e8bf943fba406c858d3ba95a1f7e493e83d Mon Sep 17 00:00:00 2001 From: moritzraho Date: Tue, 21 Nov 2023 11:10:52 +0100 Subject: [PATCH 1/3] feat: allow no validation --- package.json | 24 ----------------------- src/index.js | 15 ++++++++++++-- test/index.test.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 868d5d3..de9c97e 100644 --- a/package.json +++ b/package.json @@ -50,29 +50,5 @@ }, "engines": { "node": "^14.18 || ^16.13 || >=18" - }, - "jest": { - "collectCoverage": true, - "collectCoverageFrom": [ - "src/**/*.js" - ], - "coverageThreshold": { - "global": { - "branches": 100, - "lines": 100, - "statements": 100 - } - }, - "testPathIgnorePatterns": [ - "/jest.setup.js" - ], - "reporters": [ - "default", - "jest-junit" - ], - "testEnvironment": "node", - "setupFilesAfterEnv": [ - "./test/jest.setup.js" - ] } } diff --git a/src/index.js b/src/index.js index f157660..78bdf51 100644 --- a/src/index.js +++ b/src/index.js @@ -139,11 +139,14 @@ const cloneDeep = require('lodash.clonedeep') * @param {object} options options to load Config * @param {boolean} options.allowNoImpl do not throw if there is no implementation * @param {boolean} options.ignoreAioConfig do not load .aio config via aio-lib-core-config, which is loaded synchronously and blocks the main thread. + * @param {boolean} [options.validateAppConfig=true] set to false to not validate * @returns {object} the config */ async function load (options = {}) { const allowNoImpl = options.allowNoImpl === undefined ? false : options.allowNoImpl const ignoreAioConfig = options.ignoreAioConfig === undefined ? false : options.ignoreAioConfig + const validateAppConfig = options.validateAppConfig === undefined ? true : options.validateAppConfig + // *NOTE* it would be nice to support an appFolder option to load config from a different folder. // However, this requires to update aio-lib-core-config to support loading // from a different folder aswell (or enforcing ignore). @@ -164,7 +167,9 @@ async function load (options = {}) { // this will resolve $include directives and output the app config into a single object // paths config values in $included files will be rewritten const appConfigWithIndex = await coalesce(defaults.USER_CONFIG_FILE, { absolutePaths: true }) - await validate(appConfigWithIndex.config, { throws: true }) + if (validateAppConfig) { + await validate(appConfigWithIndex.config, { throws: true }) + } const mergedAppConfig = await mergeLegacyAppConfig(appConfigWithIndex, legacyAppConfigWithIndex) appConfig = mergedAppConfig.config @@ -589,7 +594,13 @@ async function buildSingleConfig (configName, singleUserConfig, commonConfig, in // Let's search the config path that defines a key in the same config object level as 'web' or // 'action' const otherKeyInObject = Object.keys(singleUserConfig)[0] - const configFilePath = includeIndex[`${fullKeyPrefix}.${otherKeyInObject}`].file + let configFilePath + if (otherKeyInObject === undefined) { + // corner case if config is empty e.g. application: {} + configFilePath = includeIndex[`${fullKeyPrefix}`].file + } else { + configFilePath = includeIndex[`${fullKeyPrefix}.${otherKeyInObject}`].file + } const defaultActionPath = resolveToRoot('actions/', configFilePath) const defaultWebPath = resolveToRoot('web-src/', configFilePath) diff --git a/test/index.test.js b/test/index.test.js index 0a09e4f..1162860 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -273,6 +273,20 @@ extensions: await expect(appConfig.load({})).rejects.toThrow('must have required property \'packages\'') }) + test('app config with empty application implementation', async () => { + global.loadFixtureApp('app') + global.fakeFileSystem.addJson({ + '/package.json': '{}', + 'app.config.yaml': +` + application: {} +` + }) + config = await appConfig.load() + expect(config.all.application).toBeDefined() + expect(config.implements).toEqual(['application']) + }) + // options test('standalone app config - ignoreAioConfig=true', async () => { global.loadFixtureApp('app') @@ -281,6 +295,41 @@ extensions: expect(config).toEqual(mockConfig) }) + test('invalid app config with validateAppConfig=true', async () => { + global.loadFixtureApp('app') + global.fakeFileSystem.addJson({ + '/package.json': '{}', + 'app.config.yaml': +` + application: { + web: { notallowed: true } + } +` + }) + await expect(appConfig.load({ validateAppConfig: true })).rejects.toThrow('Missing or invalid keys in app.config.yaml') + }) + + test('invalid app config with validateAppConfig=false', async () => { + global.loadFixtureApp('app') + global.fakeFileSystem.addJson({ + '/package.json': '{}', + 'app.config.yaml': +` + application: { + web: { notallowed: true } + } +` + }) + config = await appConfig.load({ validateAppConfig: false }) + // the notallowed config is not picked up + expect(config.all.application.web).toEqual({ + distDev: '/dist/application/web-dev', + distProd: '/dist/application/web-prod', + injectedConfig: '/web-src/src/config.json', + src: '/web-src' + }) + }) + test('no implementation - allowNoImpl=false', async () => { global.fakeFileSystem.addJson({ '/package.json': '{}' }) await expect(appConfig.load({})).rejects.toThrow('Couldn\'t find configuration') From 1178c0652efcde2d9ccaba015482976d48962268 Mon Sep 17 00:00:00 2001 From: moritzraho Date: Tue, 21 Nov 2023 11:18:55 +0100 Subject: [PATCH 2/3] fix windows tests --- test/index.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/index.test.js b/test/index.test.js index 1162860..6a10fc1 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -323,10 +323,10 @@ extensions: config = await appConfig.load({ validateAppConfig: false }) // the notallowed config is not picked up expect(config.all.application.web).toEqual({ - distDev: '/dist/application/web-dev', - distProd: '/dist/application/web-prod', - injectedConfig: '/web-src/src/config.json', - src: '/web-src' + distDev: winCompat('/dist/application/web-dev'), + distProd: winCompat('/dist/application/web-prod'), + injectedConfig: winCompat('/web-src/src/config.json'), + src: winCompat('/web-src') }) }) From 9711ed1ca3e59b98c421f694d78812aca9690c3c Mon Sep 17 00:00:00 2001 From: moritzraho Date: Mon, 4 Dec 2023 16:54:30 +0100 Subject: [PATCH 3/3] review comment --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 78bdf51..942882a 100644 --- a/src/index.js +++ b/src/index.js @@ -137,8 +137,8 @@ const cloneDeep = require('lodash.clonedeep') * } * * @param {object} options options to load Config - * @param {boolean} options.allowNoImpl do not throw if there is no implementation - * @param {boolean} options.ignoreAioConfig do not load .aio config via aio-lib-core-config, which is loaded synchronously and blocks the main thread. + * @param {boolean} [options.allowNoImpl=false] do not throw if there is no implementation + * @param {boolean} [options.ignoreAioConfig=false] do not load .aio config via aio-lib-core-config, which is loaded synchronously and blocks the main thread. * @param {boolean} [options.validateAppConfig=true] set to false to not validate * @returns {object} the config */