@adobe/aio-lib-db 0.1.0-beta.2 → 0.1.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -39,7 +39,12 @@ __OW_API_KEY=user:password
39
39
 
40
40
  ### Basic Usage
41
41
 
42
- > When calling `libDb.init()`, you can pass `{ region: '<region>>' }` to specify the region where your database is provisioned.
42
+ > When calling `libDb.init()`, you can pass `{ region: '<region>>' }` to specify the region where your database is provisioned, or if region is defined in `app.config.yaml` of aio app, then `libDb.init()` will initialize in specified region.
43
+ >
44
+ > **Note:** region defined in `app.config.yaml` holds preference over passed in config param.
45
+ >
46
+ > If region is not specified in any of the above ways, it falls back to default.
47
+ >
43
48
  > Valid regions are `amer` (default), `emea`, and `apac`.
44
49
 
45
50
  ```javascript
package/lib/DbBase.js CHANGED
@@ -14,6 +14,7 @@ const { pingApi, provisionStatusApi, provisionRequestApi, deleteDatabaseApi } =
14
14
  const DbClient = require('./DbClient')
15
15
  const DbError = require("./DbError")
16
16
  const { getAxiosClient } = require("../utils/axiosUtils")
17
+ const { getRegionFromAppConfig } = require("../utils/manifestUtils")
17
18
  const {
18
19
  ALLOWED_REGIONS, STAGE_ENV, STAGE_ENDPOINT, PROD_ENDPOINT_RUNTIME, PROD_ENDPOINT_EXTERNAL
19
20
  } = require("./constants")
@@ -86,7 +87,15 @@ class DbBase {
86
87
  static async init(config = {}) {
87
88
  const namespace = config.namespace || process.env.__OW_NAMESPACE
88
89
  const apikey = config.apikey || process.env.__OW_API_KEY
89
- const region = config.region || ALLOWED_REGIONS[getCliEnv()].at(0)
90
+ let aioAppRegion = null
91
+
92
+ try {
93
+ aioAppRegion = getRegionFromAppConfig(process.cwd())
94
+ } catch (e) {
95
+ throw new DbError(`Error reading region from app config: ${e.message}`)
96
+ }
97
+
98
+ const region = aioAppRegion || config.region || ALLOWED_REGIONS[getCliEnv()].at(0)
90
99
  return new DbBase(region, namespace, apikey)
91
100
  }
92
101
 
package/lib/api/db.js CHANGED
@@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag
10
10
  governing permissions and limitations under the License.
11
11
  */
12
12
  const { apiPost, apiGet } = require("../../utils/apiRequest")
13
+ const { writeRegionToAppConfig } = require("../../utils/manifestUtils")
14
+ const logger = require('@adobe/aio-lib-core-logging')('@adobe/aio-lib-db', { provider: 'debug' })
13
15
 
14
16
  /**
15
17
  * Make a post request to the App Builder Database Service db API and return the result
@@ -46,7 +48,17 @@ async function getDbApi(db, endpoint) {
46
48
  * @throws {DbError}
47
49
  */
48
50
  async function provisionRequest(db) {
49
- return await postDbApi(db, db.axiosClient, 'provision/request')
51
+ const response = await postDbApi(db, db.axiosClient, 'provision/request')
52
+
53
+ // Update app.config.yaml with the region after successful provision request
54
+ try {
55
+ writeRegionToAppConfig(process.cwd(), db.region)
56
+ logger.info(`Updated app.config.yaml with region: ${db.region}`)
57
+ } catch (error) {
58
+ logger.warn(`Failed to update app.config.yaml: ${error.message}`)
59
+ }
60
+
61
+ return response
50
62
  }
51
63
 
52
64
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/aio-lib-db",
3
- "version": "0.1.0-beta.2",
3
+ "version": "0.1.0-beta.3",
4
4
  "description": "An abstraction on top of Document DB storage",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,11 +16,13 @@
16
16
  ],
17
17
  "contributors": [],
18
18
  "dependencies": {
19
+ "@adobe/aio-lib-core-logging": "^3.0.2",
19
20
  "@adobe/aio-lib-env": "^3.0.1",
20
21
  "axios": "^1.8.4",
21
22
  "bson": "^6.10.3",
22
23
  "dotenv": "^17.0.0",
23
24
  "http-cookie-agent": "^6.0.8",
25
+ "js-yaml": "^4.1.0",
24
26
  "tough-cookie": "^5.1.2"
25
27
  },
26
28
  "devDependencies": {
@@ -0,0 +1,141 @@
1
+ /*
2
+ Copyright 2025 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ const fs = require('fs')
13
+ const path = require('path')
14
+ const yaml = require('js-yaml')
15
+
16
+
17
+ /**
18
+ * Walk upwards from startDir looking for the filename. Returns the absolute
19
+ * path to the first match or null if none found.
20
+ *
21
+ * @param {string} startDir - Starting directory for search
22
+ * @param {string} filename - Filename to search for
23
+ * @returns {string|null} Absolute path to file or null if not found
24
+ */
25
+ function getFilePath(startDir, filename) {
26
+ if (!startDir || typeof startDir !== 'string') return null
27
+ if (!filename || typeof filename !== 'string') return null
28
+
29
+ let dir = path.resolve(startDir)
30
+ const root = path.parse(dir).root
31
+ while (true) {
32
+ const manifestPath = path.join(dir, filename)
33
+ if (fs.existsSync(manifestPath)) return manifestPath
34
+ if (dir === root) break
35
+ dir = path.dirname(dir)
36
+ }
37
+ return null
38
+ }
39
+
40
+ /**
41
+ * Read and parse YAML configuration file
42
+ *
43
+ * @param {string} filePath - Path to YAML file
44
+ * @returns {Object} Parsed YAML content or empty object if file doesn't exist
45
+ */
46
+ function readYamlConfig(filePath) {
47
+ if (!fs.existsSync(filePath)) return {}
48
+ const content = fs.readFileSync(filePath, 'utf8')
49
+ return yaml.load(content)
50
+ }
51
+
52
+ /**
53
+ * Read `app.config.yaml` (if present) and return the `runtimeManifest` object
54
+ * or null if not found.
55
+ *
56
+ * @param {string} startDir - Starting directory to search from
57
+ * @returns {Object|null} Runtime manifest object or null if not found
58
+ */
59
+ function getRuntimeManifestFromAppConfig(startDir) {
60
+ const APP_CONFIG_FILE = 'app.config.yaml'
61
+ const appConfigPath = getFilePath(startDir, APP_CONFIG_FILE)
62
+ if (!appConfigPath) return null
63
+ const parsed = readYamlConfig(appConfigPath)
64
+
65
+ // Return runtimeManifest from application.runtimeManifest
66
+ return parsed?.application?.runtimeManifest || null
67
+ }
68
+
69
+ /**
70
+ * Extract region from app config manifest
71
+ *
72
+ * @param {string} startDir - Starting directory to search from
73
+ * @returns {string|null} Region string or null if not found
74
+ */
75
+ function getRegionFromAppConfig(startDir) {
76
+ const runtimeManifest = getRuntimeManifestFromAppConfig(startDir)
77
+ return runtimeManifest?.database?.region || null
78
+ }
79
+
80
+ /**
81
+ * Write database configuration to existing app.config.yaml
82
+ *
83
+ * @param {string} startDir - Starting directory to search from
84
+ * @param {string} region - Database region
85
+ * @returns {boolean} True if region was written, false if file not found
86
+ * @throws {Error} If file operations fail (read/write/parse errors)
87
+ */
88
+ function writeRegionToAppConfig(startDir, region) {
89
+ const APP_CONFIG_FILE = 'app.config.yaml'
90
+ const appConfigPath = getFilePath(startDir, APP_CONFIG_FILE)
91
+
92
+ // Return false if no app.config.yaml exists
93
+ if (!appConfigPath) {
94
+ return false
95
+ }
96
+
97
+ // Read existing config
98
+ const existingConfig = readYamlConfig(appConfigPath)
99
+
100
+ // Get current auto-provision value from runtimeManifest.database
101
+ const currentAutoProv = existingConfig?.application?.runtimeManifest?.database?.['auto-provision']
102
+
103
+ // Determine auto-provision value:
104
+ // - If true, keep it true
105
+ // - If false or not present, set to false
106
+ const autoProvision = currentAutoProv === true ? true : false
107
+
108
+ // Ensure nested structure exists and add region + auto-provision inside runtimeManifest
109
+ const config = {
110
+ ...existingConfig,
111
+ application: {
112
+ ...existingConfig?.application,
113
+ runtimeManifest: {
114
+ ...existingConfig?.application?.runtimeManifest,
115
+ database: {
116
+ ...existingConfig?.application?.runtimeManifest?.database,
117
+ 'auto-provision': autoProvision,
118
+ region: region
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ // Write updated config back to file
125
+ const yamlContent = yaml.dump(config, {
126
+ defaultFlowStyle: false,
127
+ lineWidth: -1
128
+ })
129
+
130
+ fs.writeFileSync(appConfigPath, yamlContent, 'utf8')
131
+ return true
132
+
133
+ }
134
+
135
+ module.exports = {
136
+ getFilePath,
137
+ readYamlConfig,
138
+ getRuntimeManifestFromAppConfig,
139
+ getRegionFromAppConfig,
140
+ writeRegionToAppConfig
141
+ }