From e8b6cd664faa853b741bcd03f7ba85ca9d34d9f9 Mon Sep 17 00:00:00 2001 From: ajaz Date: Mon, 3 Nov 2025 18:39:23 +0530 Subject: [PATCH 1/4] feat: update schema to add db config --- schema/app.config.yaml.schema.json | 12 +- src/index.js | 7 + .../app-with-database/app.config.yaml | 20 +++ .../app-with-database/myactions/action.js | 10 ++ .../app-with-database/package.json | 7 + .../app-with-database/web-src/index.html | 9 ++ test/data-mocks/config-loader.js | 79 +++++++++ test/index.test.js | 150 ++++++++++++++++++ 8 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 test/__fixtures__/app-with-database/app.config.yaml create mode 100644 test/__fixtures__/app-with-database/myactions/action.js create mode 100644 test/__fixtures__/app-with-database/package.json create mode 100644 test/__fixtures__/app-with-database/web-src/index.html diff --git a/schema/app.config.yaml.schema.json b/schema/app.config.yaml.schema.json index 4b764b5..7e8501f 100644 --- a/schema/app.config.yaml.schema.json +++ b/schema/app.config.yaml.schema.json @@ -96,7 +96,8 @@ "runtimeManifest": { "type": "object", "properties": { - "packages": { "$ref": "#/definitions/packages" } + "packages": { "$ref": "#/definitions/packages" }, + "database": { "$ref": "#/definitions/database" } }, "required": ["packages"] }, @@ -109,6 +110,15 @@ }, "additionalProperties": false }, + "database": { + "type": "object", + "properties": { + "auto-provision": { "type": "boolean"}, + "region": { "type": "string", "enum": ["amer", "emea", "apac"]} + }, + "required": ["auto-provision"], + "additionalProperties": false + }, "package": { "type": "object", "properties": { diff --git a/src/index.js b/src/index.js index 40b98cd..5cdae1a 100644 --- a/src/index.js +++ b/src/index.js @@ -637,6 +637,13 @@ async function buildSingleConfig (configName, singleUserConfig, commonConfig, in if (singleUserConfig.events) { config.events = { ...singleUserConfig.events } } + if (manifest && manifest.database) { + config.database = { ...manifest.database } + // set default region if auto-provision is true and no region is set + if (config.database['auto-provision'] === true && !config.database.region) { + config.database.region = 'amer' + } + } if (commonConfig?.aio?.project) { config.project = commonConfig.aio.project } diff --git a/test/__fixtures__/app-with-database/app.config.yaml b/test/__fixtures__/app-with-database/app.config.yaml new file mode 100644 index 0000000..f5277ef --- /dev/null +++ b/test/__fixtures__/app-with-database/app.config.yaml @@ -0,0 +1,20 @@ +application: + actions: 'myactions' + runtimeManifest: + database: + auto-provision: true + region: 'emea' + packages: + my-app-package: + license: 'Apache-2.0' + actions: + action: + function: 'myactions/action.js' + web: 'yes' + runtime: 'nodejs:14' + inputs: + LOG_LEVEL: 'debug' + annotations: + final: true + require-adobe-auth: true + web: 'web-src' diff --git a/test/__fixtures__/app-with-database/myactions/action.js b/test/__fixtures__/app-with-database/myactions/action.js new file mode 100644 index 0000000..38a6e5a --- /dev/null +++ b/test/__fixtures__/app-with-database/myactions/action.js @@ -0,0 +1,10 @@ +/** + * Main action function + * @param {object} params - Action parameters + * @returns {object} Response object + */ +function main (params) { + return { msg: 'Hello world with database!' } +} + +module.exports.main = main diff --git a/test/__fixtures__/app-with-database/package.json b/test/__fixtures__/app-with-database/package.json new file mode 100644 index 0000000..fb948e8 --- /dev/null +++ b/test/__fixtures__/app-with-database/package.json @@ -0,0 +1,7 @@ +{ + "name": "app-with-database", + "version": "1.0.0", + "scripts": { + "test": "echo test" + } +} \ No newline at end of file diff --git a/test/__fixtures__/app-with-database/web-src/index.html b/test/__fixtures__/app-with-database/web-src/index.html new file mode 100644 index 0000000..2c8966e --- /dev/null +++ b/test/__fixtures__/app-with-database/web-src/index.html @@ -0,0 +1,9 @@ + + + + App with Database + + +

Hello from App with Database!

+ + \ No newline at end of file diff --git a/test/data-mocks/config-loader.js b/test/data-mocks/config-loader.js index 6eb135c..1dd2623 100644 --- a/test/data-mocks/config-loader.js +++ b/test/data-mocks/config-loader.js @@ -284,6 +284,73 @@ const applicationSingleConfig = { } } +const appWithDatabaseActionsFolder = winCompat(`${root}myactions`) +const applicationWithDatabaseSingleConfig = { + application: { + app: { + hasBackend: true, + hasFrontend: true, + dist: winCompat(`${root}dist/application`), + defaultHostname: 'adobeio-static.net', + hostname: 'mydomain.test', + htmlCacheDuration: '60', + jsCacheDuration: '60', + cssCacheDuration: '60', + imageCacheDuration: '60' + }, + ow, + s3: { + credsCacheFile: winCompat(`${root}.aws.tmp.creds.json`) + }, + web: { + src: winCompat(`${root}web-src`), + injectedConfig: winCompat(`${root}web-src/src/config.json`), + distDev: winCompat(`${root}dist/application/web-dev`), + distProd: winCompat(`${root}dist/application/web-prod`) + }, + manifest: { + src: 'manifest.yml', + full: { + packages: { + 'my-app-package': { + license: 'Apache-2.0', + actions: { + action: { + function: winCompat(`${appWithDatabaseActionsFolder}/action.js`), + web: 'yes', + runtime: 'nodejs:14', + inputs: { + LOG_LEVEL: 'debug' + }, + annotations: { + final: true, + 'require-adobe-auth': true + } + } + } + } + }, + database: { + 'auto-provision': true, + region: 'emea' + } + }, + packagePlaceholder: '__APP_PACKAGE__', + package: undefined + }, + actions: { + src: appWithDatabaseActionsFolder, + dist: winCompat(`${root}dist/application/actions`) + }, + tests: { + e2e: winCompat(`${root}e2e`), + unit: winCompat(`${root}test`) + }, + root: `${root}`, + name: 'application' + } +} + const legacyManifest = fullFakeRuntimeManifest(appActionsFolder, '__APP_PACKAGE__') const applicationLegacyConfig = { application: { @@ -362,6 +429,18 @@ const expectedConfigs = { }, root }, + 'app-with-database': { + all: { ...applicationWithDatabaseSingleConfig }, + implements: [ + 'application' + ], + includeIndex: appIncludeIndex, + packagejson: { + version: '1.0.0', + name: 'app-with-database' + }, + root + }, 'app-exc-nui': { all: { ...excSingleConfig, ...nuiSingleConfig, ...applicationSingleConfig }, implements: [ diff --git a/test/index.test.js b/test/index.test.js index 116ca01..98adfe4 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -46,6 +46,17 @@ describe('load config', () => { expect(config).toEqual(mockConfig) }) + test('standalone app config with database', async () => { + global.loadFixtureApp('app-with-database') + config = await appConfig.load() + expect(config.all.application.database).toEqual({ + 'auto-provision': true, + region: 'emea' + }) + expect(config.all.application.app.hasBackend).toBe(true) + expect(config.all.application.app.hasFrontend).toBe(true) + }) + test('not in an app', async () => { global.loadFixtureApp('not-in-app') await expect(appConfig.load()).rejects.toThrow(new Error('ENOENT: no such file or directory, open \'package.json\'')) @@ -1064,3 +1075,142 @@ describe('coalesce config', () => { expect(coalesced.includeIndex['application.runtimeManifest.packages.my-app-package.actions.action.function']).toEqual({ file: 'app/myactions/action.config.yaml', key: 'function' }) }) }) + +describe('database config', () => { + beforeEach(async () => { + mockAIOConfig.get.mockImplementation(k => global.fakeConfig.tvm) + process.chdir('/') + global.fakeFileSystem.clear() + libEnv.getCliEnv.mockReturnValue('prod') + }) + + test('valid database configuration', async () => { + global.fakeFileSystem.addJson({ + '/package.json': '{"name": "test-app", "version": "1.0.0"}', + '/app.config.yaml': ` +application: + runtimeManifest: + database: + auto-provision: true + region: 'emea' + packages: + my-app-package: + actions: + action: + function: 'actions/hello.js' + web: true +` + }) + const config = await appConfig.load() + expect(config.all.application.database).toEqual({ + 'auto-provision': true, + region: 'emea' + }) + }) + + test('database configuration with auto-provision true', async () => { + global.fakeFileSystem.addJson({ + '/package.json': '{"name": "test-app", "version": "1.0.0"}', + '/app.config.yaml': ` +application: + runtimeManifest: + database: + auto-provision: true + packages: + my-app-package: + actions: + action: + function: 'actions/hello.js' + web: true +` + }) + const config = await appConfig.load() + expect(config.all.application.database).toEqual({ + 'auto-provision': true, + region: 'amer' + }) + }) + + test('database configuration with empty fields', async () => { + global.fakeFileSystem.addJson({ + '/package.json': '{"name": "test-app", "version": "1.0.0"}', + '/app.config.yaml': ` +application: + runtimeManifest: + database: {} + packages: + my-app-package: + actions: + action: + function: 'actions/hello.js' + web: true +` + }) + await expect(appConfig.load()).rejects.toThrow('Missing or invalid keys in app.config.yaml:') + }) + + test('database configuration validation - valid', async () => { + const validConfig = { + application: { + runtimeManifest: { + database: { + 'auto-provision': true, + region: 'apac' + }, + packages: { + 'my-app': { + actions: { + hello: { + function: 'hello.js' + } + } + } + } + } + } + } + const validation = await appConfig.validate(validConfig) + expect(validation.valid).toBe(true) + expect(validation.errors).toBe(null) + }) + + test('invalid database configuration - invalid auto-provision type', async () => { + global.fakeFileSystem.addJson({ + '/package.json': '{"name": "test-app", "version": "1.0.0"}', + '/app.config.yaml': ` +application: + runtimeManifest: + database: + auto-provision: 'invalid' + region: 'amer' + packages: + my-app-package: + actions: + action: + function: 'actions/hello.js' + web: true +` + }) + await expect(appConfig.load({})).rejects.toThrow('must be boolean') + }) + + test('invalid database configuration - invalid region', async () => { + global.fakeFileSystem.addJson({ + '/package.json': '{"name": "test-app", "version": "1.0.0"}', + '/app.config.yaml': ` +application: + runtimeManifest: + database: + auto-provision: true + region: 'invalid-region' + packages: + my-app-package: + actions: + action: + function: 'actions/hello.js' + web: true +` + }) + await expect(appConfig.load({})).rejects.toThrow('must be equal to one of the allowed values') + }) +}) From 126514d98caa422ad76fc040dfc1b1ac4f4f3ae1 Mon Sep 17 00:00:00 2001 From: ajaz Date: Mon, 3 Nov 2025 18:42:04 +0530 Subject: [PATCH 2/4] fix: add newline at eof --- test/__fixtures__/app-with-database/package.json | 2 +- test/__fixtures__/app-with-database/web-src/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/__fixtures__/app-with-database/package.json b/test/__fixtures__/app-with-database/package.json index fb948e8..8ec31ee 100644 --- a/test/__fixtures__/app-with-database/package.json +++ b/test/__fixtures__/app-with-database/package.json @@ -4,4 +4,4 @@ "scripts": { "test": "echo test" } -} \ No newline at end of file +} diff --git a/test/__fixtures__/app-with-database/web-src/index.html b/test/__fixtures__/app-with-database/web-src/index.html index 2c8966e..41631a1 100644 --- a/test/__fixtures__/app-with-database/web-src/index.html +++ b/test/__fixtures__/app-with-database/web-src/index.html @@ -6,4 +6,4 @@

Hello from App with Database!

- \ No newline at end of file + From 4fc6654ea8a618690fe47aa708ecd706649b8d6b Mon Sep 17 00:00:00 2001 From: ajaz Date: Thu, 6 Nov 2025 17:50:25 +0530 Subject: [PATCH 3/4] remove default region --- src/index.js | 4 ---- test/index.test.js | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/index.js b/src/index.js index 5cdae1a..6a02cf4 100644 --- a/src/index.js +++ b/src/index.js @@ -639,10 +639,6 @@ async function buildSingleConfig (configName, singleUserConfig, commonConfig, in } if (manifest && manifest.database) { config.database = { ...manifest.database } - // set default region if auto-provision is true and no region is set - if (config.database['auto-provision'] === true && !config.database.region) { - config.database.region = 'amer' - } } if (commonConfig?.aio?.project) { config.project = commonConfig.aio.project diff --git a/test/index.test.js b/test/index.test.js index 98adfe4..0a13c3d 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1126,8 +1126,7 @@ application: }) const config = await appConfig.load() expect(config.all.application.database).toEqual({ - 'auto-provision': true, - region: 'amer' + 'auto-provision': true }) }) From 473df98d93af07dac8b5a30473f46007cbec0cb6 Mon Sep 17 00:00:00 2001 From: ajaz Date: Fri, 7 Nov 2025 21:10:30 +0530 Subject: [PATCH 4/4] remove allowed region enum --- schema/app.config.yaml.schema.json | 2 +- test/index.test.js | 20 -------------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/schema/app.config.yaml.schema.json b/schema/app.config.yaml.schema.json index 7e8501f..6738c2a 100644 --- a/schema/app.config.yaml.schema.json +++ b/schema/app.config.yaml.schema.json @@ -114,7 +114,7 @@ "type": "object", "properties": { "auto-provision": { "type": "boolean"}, - "region": { "type": "string", "enum": ["amer", "emea", "apac"]} + "region": { "type": "string"} }, "required": ["auto-provision"], "additionalProperties": false diff --git a/test/index.test.js b/test/index.test.js index 0a13c3d..040e8d9 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1192,24 +1192,4 @@ application: }) await expect(appConfig.load({})).rejects.toThrow('must be boolean') }) - - test('invalid database configuration - invalid region', async () => { - global.fakeFileSystem.addJson({ - '/package.json': '{"name": "test-app", "version": "1.0.0"}', - '/app.config.yaml': ` -application: - runtimeManifest: - database: - auto-provision: true - region: 'invalid-region' - packages: - my-app-package: - actions: - action: - function: 'actions/hello.js' - web: true -` - }) - await expect(appConfig.load({})).rejects.toThrow('must be equal to one of the allowed values') - }) })