Skip to content

Commit e8b6cd6

Browse files
committed
feat: update schema to add db config
1 parent fd1dfac commit e8b6cd6

8 files changed

Lines changed: 293 additions & 1 deletion

File tree

schema/app.config.yaml.schema.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@
9696
"runtimeManifest": {
9797
"type": "object",
9898
"properties": {
99-
"packages": { "$ref": "#/definitions/packages" }
99+
"packages": { "$ref": "#/definitions/packages" },
100+
"database": { "$ref": "#/definitions/database" }
100101
},
101102
"required": ["packages"]
102103
},
@@ -109,6 +110,15 @@
109110
},
110111
"additionalProperties": false
111112
},
113+
"database": {
114+
"type": "object",
115+
"properties": {
116+
"auto-provision": { "type": "boolean"},
117+
"region": { "type": "string", "enum": ["amer", "emea", "apac"]}
118+
},
119+
"required": ["auto-provision"],
120+
"additionalProperties": false
121+
},
112122
"package": {
113123
"type": "object",
114124
"properties": {

src/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,13 @@ async function buildSingleConfig (configName, singleUserConfig, commonConfig, in
637637
if (singleUserConfig.events) {
638638
config.events = { ...singleUserConfig.events }
639639
}
640+
if (manifest && manifest.database) {
641+
config.database = { ...manifest.database }
642+
// set default region if auto-provision is true and no region is set
643+
if (config.database['auto-provision'] === true && !config.database.region) {
644+
config.database.region = 'amer'
645+
}
646+
}
640647
if (commonConfig?.aio?.project) {
641648
config.project = commonConfig.aio.project
642649
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
application:
2+
actions: 'myactions'
3+
runtimeManifest:
4+
database:
5+
auto-provision: true
6+
region: 'emea'
7+
packages:
8+
my-app-package:
9+
license: 'Apache-2.0'
10+
actions:
11+
action:
12+
function: 'myactions/action.js'
13+
web: 'yes'
14+
runtime: 'nodejs:14'
15+
inputs:
16+
LOG_LEVEL: 'debug'
17+
annotations:
18+
final: true
19+
require-adobe-auth: true
20+
web: 'web-src'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Main action function
3+
* @param {object} params - Action parameters
4+
* @returns {object} Response object
5+
*/
6+
function main (params) {
7+
return { msg: 'Hello world with database!' }
8+
}
9+
10+
module.exports.main = main
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "app-with-database",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"test": "echo test"
6+
}
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>App with Database</title>
5+
</head>
6+
<body>
7+
<h1>Hello from App with Database!</h1>
8+
</body>
9+
</html>

test/data-mocks/config-loader.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,73 @@ const applicationSingleConfig = {
284284
}
285285
}
286286

287+
const appWithDatabaseActionsFolder = winCompat(`${root}myactions`)
288+
const applicationWithDatabaseSingleConfig = {
289+
application: {
290+
app: {
291+
hasBackend: true,
292+
hasFrontend: true,
293+
dist: winCompat(`${root}dist/application`),
294+
defaultHostname: 'adobeio-static.net',
295+
hostname: 'mydomain.test',
296+
htmlCacheDuration: '60',
297+
jsCacheDuration: '60',
298+
cssCacheDuration: '60',
299+
imageCacheDuration: '60'
300+
},
301+
ow,
302+
s3: {
303+
credsCacheFile: winCompat(`${root}.aws.tmp.creds.json`)
304+
},
305+
web: {
306+
src: winCompat(`${root}web-src`),
307+
injectedConfig: winCompat(`${root}web-src/src/config.json`),
308+
distDev: winCompat(`${root}dist/application/web-dev`),
309+
distProd: winCompat(`${root}dist/application/web-prod`)
310+
},
311+
manifest: {
312+
src: 'manifest.yml',
313+
full: {
314+
packages: {
315+
'my-app-package': {
316+
license: 'Apache-2.0',
317+
actions: {
318+
action: {
319+
function: winCompat(`${appWithDatabaseActionsFolder}/action.js`),
320+
web: 'yes',
321+
runtime: 'nodejs:14',
322+
inputs: {
323+
LOG_LEVEL: 'debug'
324+
},
325+
annotations: {
326+
final: true,
327+
'require-adobe-auth': true
328+
}
329+
}
330+
}
331+
}
332+
},
333+
database: {
334+
'auto-provision': true,
335+
region: 'emea'
336+
}
337+
},
338+
packagePlaceholder: '__APP_PACKAGE__',
339+
package: undefined
340+
},
341+
actions: {
342+
src: appWithDatabaseActionsFolder,
343+
dist: winCompat(`${root}dist/application/actions`)
344+
},
345+
tests: {
346+
e2e: winCompat(`${root}e2e`),
347+
unit: winCompat(`${root}test`)
348+
},
349+
root: `${root}`,
350+
name: 'application'
351+
}
352+
}
353+
287354
const legacyManifest = fullFakeRuntimeManifest(appActionsFolder, '__APP_PACKAGE__')
288355
const applicationLegacyConfig = {
289356
application: {
@@ -362,6 +429,18 @@ const expectedConfigs = {
362429
},
363430
root
364431
},
432+
'app-with-database': {
433+
all: { ...applicationWithDatabaseSingleConfig },
434+
implements: [
435+
'application'
436+
],
437+
includeIndex: appIncludeIndex,
438+
packagejson: {
439+
version: '1.0.0',
440+
name: 'app-with-database'
441+
},
442+
root
443+
},
365444
'app-exc-nui': {
366445
all: { ...excSingleConfig, ...nuiSingleConfig, ...applicationSingleConfig },
367446
implements: [

test/index.test.js

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ describe('load config', () => {
4646
expect(config).toEqual(mockConfig)
4747
})
4848

49+
test('standalone app config with database', async () => {
50+
global.loadFixtureApp('app-with-database')
51+
config = await appConfig.load()
52+
expect(config.all.application.database).toEqual({
53+
'auto-provision': true,
54+
region: 'emea'
55+
})
56+
expect(config.all.application.app.hasBackend).toBe(true)
57+
expect(config.all.application.app.hasFrontend).toBe(true)
58+
})
59+
4960
test('not in an app', async () => {
5061
global.loadFixtureApp('not-in-app')
5162
await expect(appConfig.load()).rejects.toThrow(new Error('ENOENT: no such file or directory, open \'package.json\''))
@@ -1064,3 +1075,142 @@ describe('coalesce config', () => {
10641075
expect(coalesced.includeIndex['application.runtimeManifest.packages.my-app-package.actions.action.function']).toEqual({ file: 'app/myactions/action.config.yaml', key: 'function' })
10651076
})
10661077
})
1078+
1079+
describe('database config', () => {
1080+
beforeEach(async () => {
1081+
mockAIOConfig.get.mockImplementation(k => global.fakeConfig.tvm)
1082+
process.chdir('/')
1083+
global.fakeFileSystem.clear()
1084+
libEnv.getCliEnv.mockReturnValue('prod')
1085+
})
1086+
1087+
test('valid database configuration', async () => {
1088+
global.fakeFileSystem.addJson({
1089+
'/package.json': '{"name": "test-app", "version": "1.0.0"}',
1090+
'/app.config.yaml': `
1091+
application:
1092+
runtimeManifest:
1093+
database:
1094+
auto-provision: true
1095+
region: 'emea'
1096+
packages:
1097+
my-app-package:
1098+
actions:
1099+
action:
1100+
function: 'actions/hello.js'
1101+
web: true
1102+
`
1103+
})
1104+
const config = await appConfig.load()
1105+
expect(config.all.application.database).toEqual({
1106+
'auto-provision': true,
1107+
region: 'emea'
1108+
})
1109+
})
1110+
1111+
test('database configuration with auto-provision true', async () => {
1112+
global.fakeFileSystem.addJson({
1113+
'/package.json': '{"name": "test-app", "version": "1.0.0"}',
1114+
'/app.config.yaml': `
1115+
application:
1116+
runtimeManifest:
1117+
database:
1118+
auto-provision: true
1119+
packages:
1120+
my-app-package:
1121+
actions:
1122+
action:
1123+
function: 'actions/hello.js'
1124+
web: true
1125+
`
1126+
})
1127+
const config = await appConfig.load()
1128+
expect(config.all.application.database).toEqual({
1129+
'auto-provision': true,
1130+
region: 'amer'
1131+
})
1132+
})
1133+
1134+
test('database configuration with empty fields', async () => {
1135+
global.fakeFileSystem.addJson({
1136+
'/package.json': '{"name": "test-app", "version": "1.0.0"}',
1137+
'/app.config.yaml': `
1138+
application:
1139+
runtimeManifest:
1140+
database: {}
1141+
packages:
1142+
my-app-package:
1143+
actions:
1144+
action:
1145+
function: 'actions/hello.js'
1146+
web: true
1147+
`
1148+
})
1149+
await expect(appConfig.load()).rejects.toThrow('Missing or invalid keys in app.config.yaml:')
1150+
})
1151+
1152+
test('database configuration validation - valid', async () => {
1153+
const validConfig = {
1154+
application: {
1155+
runtimeManifest: {
1156+
database: {
1157+
'auto-provision': true,
1158+
region: 'apac'
1159+
},
1160+
packages: {
1161+
'my-app': {
1162+
actions: {
1163+
hello: {
1164+
function: 'hello.js'
1165+
}
1166+
}
1167+
}
1168+
}
1169+
}
1170+
}
1171+
}
1172+
const validation = await appConfig.validate(validConfig)
1173+
expect(validation.valid).toBe(true)
1174+
expect(validation.errors).toBe(null)
1175+
})
1176+
1177+
test('invalid database configuration - invalid auto-provision type', async () => {
1178+
global.fakeFileSystem.addJson({
1179+
'/package.json': '{"name": "test-app", "version": "1.0.0"}',
1180+
'/app.config.yaml': `
1181+
application:
1182+
runtimeManifest:
1183+
database:
1184+
auto-provision: 'invalid'
1185+
region: 'amer'
1186+
packages:
1187+
my-app-package:
1188+
actions:
1189+
action:
1190+
function: 'actions/hello.js'
1191+
web: true
1192+
`
1193+
})
1194+
await expect(appConfig.load({})).rejects.toThrow('must be boolean')
1195+
})
1196+
1197+
test('invalid database configuration - invalid region', async () => {
1198+
global.fakeFileSystem.addJson({
1199+
'/package.json': '{"name": "test-app", "version": "1.0.0"}',
1200+
'/app.config.yaml': `
1201+
application:
1202+
runtimeManifest:
1203+
database:
1204+
auto-provision: true
1205+
region: 'invalid-region'
1206+
packages:
1207+
my-app-package:
1208+
actions:
1209+
action:
1210+
function: 'actions/hello.js'
1211+
web: true
1212+
`
1213+
})
1214+
await expect(appConfig.load({})).rejects.toThrow('must be equal to one of the allowed values')
1215+
})
1216+
})

0 commit comments

Comments
 (0)