@adobe/aio-lib-db 0.1.0-beta.6 → 0.2.0-beta.1

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
@@ -22,21 +22,47 @@ npm install @adobe/aio-lib-db
22
22
 
23
23
  **aio-lib-db** must be initialized in the region the workspace database was provisioned. Otherwise, the connection will fail. To explicitly initialize the library in a specific region, pass the `{region: "<region>"}` argument to the `libDb.init()` method. Called with no arguments, `libDb.init()` will initialize the library either in the default `amer` region or in the region defined in the `AIO_DB_REGION` environment variable.
24
24
 
25
+ **aio-lib-db** requires an IMS access token for authentication. Generate the token using `@adobe/aio-sdk` and pass the `{token : "<token>"}` argument to the `libDb.init()` method.
26
+
27
+ ```bash
28
+ npm install @adobe/aio-sdk --save
29
+ ```
30
+
31
+ To Add IMS credentials in your Runtime action parameter, set the action annotation `include-ims-credentials: true` in AIO App `app.config.yaml` file.
32
+
33
+ ```yaml
34
+ actions:
35
+ action:
36
+ function: actions/generic/action.js
37
+ annotations:
38
+ include-ims-credentials: true
39
+ require-adobe-auth: true
40
+ final: true
41
+ ```
42
+
43
+ > [!IMPORTANT]
44
+ > Add **App Builder Data Services** to your project to add the required database scopes (`adobeio.abdata.write`, `adobeio.abdata.read`, `adobeio.abdata.manage`). (See [APIs and Services](https://developer.adobe.com/developer-console/docs/guides/apis-and-services) in the [Getting Started with Database Storage](https://developer.adobe.com/app-builder/docs/guides/app_builder_guides/storage/database) guide for details.)
45
+
25
46
  ### Basic Usage
26
47
 
27
48
  ```javascript
49
+ const { generateAccessToken } = require('@adobe/aio-sdk').Core.AuthClient;
28
50
  const libDb = require('@adobe/aio-lib-db');
29
51
 
30
- async function main() {
52
+ // Runtime action params
53
+ async function main(params) {
31
54
  let client;
32
55
  try {
33
- // initialize library with the default amer region or what is defined in AIO_DB_REGION
34
- const db = await libDb.init();
56
+ // Generate access token
57
+ const token = await generateAccessToken(params);
35
58
 
36
- // initialize library with an explicit region
37
- // const db = await libDb.init({region: "emea"});
59
+ // Initialize library with token
60
+ const db = await libDb.init({ token: token });
38
61
 
39
- // connect to the database
62
+ // or with explicit region, the default being amer or whatever is defined in AIO_DB_REGION
63
+ // const db = await libDb.init({ token: token, region: 'emea' });
64
+
65
+ // Connect to the database
40
66
  client = await db.connect();
41
67
 
42
68
  // Get a collection
@@ -277,21 +303,54 @@ const cursor = collection.aggregate()
277
303
 
278
304
  ### Storage Statics
279
305
 
306
+ #### Individual database statistics:
307
+
280
308
  ```javascript
281
- // Get storage statistics for the database
309
+ // Get storage statistics for the database with the default scale factor (bytes)
282
310
  const dbStats = client.dbStats()
311
+
312
+ // Get storage statistics for the database with a scale factor (e.g. KB)
313
+ const dbStatsKb = client.dbStats({ scale: 1024 })
314
+ ```
315
+ | field returned | description |
316
+ |----------------|-------------------------------------------------------------------------------------------------|
317
+ | collections | the number of collections |
318
+ | objects | the number of objects/documents |
319
+ | views | the number of views (not currently supported) |
320
+ | indexes | the number of indexes |
321
+ | dataSize | the actual amount of storage used (default bytes) |
322
+ | storageSize | space allocated for storage (default bytes) |
323
+ | indexSize | space allocated for indexes (default bytes) |
324
+ | ok | whether the request was successful |
325
+ | scaleFactor | the scale factor used for the size fields, ex: 1024 for kilobyte-scale (default is 1 for bytes) |
326
+ | lastUpdated | when the statistics were last updated |
327
+
328
+ #### Organization storage statistics:
329
+
330
+ ```javascript
331
+ // Get combined storage statistics across databases in the organization with the default scale factor (bytes)
332
+ const orgStats = client.orgStats()
333
+
334
+ // Get combined storage statistics across databases in the organization with a scale factor (e.g. MB)
335
+ const orgStatsMb = client.orgStats({ scale: 1024 * 1024 })
283
336
  ```
284
- | field returned | description |
285
- |----------------|-----------------------------------------------|
286
- | collections | the number of collections |
287
- | objects | the number of objects/documents |
288
- | views | the number of views (not currently supported) |
289
- | indexes | the number of indexes |
290
- | dataSize | the actual amount of storage used in bytes |
291
- | storageSize | space allocated for storage in bytes |
292
- | indexSize | space allocated for indexes in bytes |
293
- | ok | whether the request was successful |
294
- | lastUpdated | when the statistics where last updated |
337
+ | field returned | description |
338
+ |---------------------------|----------------------------------------------------------------------------------------------------------------------------|
339
+ | ok | whether the request was successful |
340
+ | databases | the number of databases in the organization |
341
+ | collections | the total number of collections across databases |
342
+ | dataSize | the total actual amount of storage used across databases (default bytes) |
343
+ | storageSize | space allocated for storage (default bytes) |
344
+ | indexSize | space allocated for indexes (default bytes) |
345
+ | scaleFactor | the scale factor used for the size fields, ex: 1024 for kilobyte-scale (default is 1 for bytes) |
346
+ | databaseStats | an array of statistics for individual databases in the organization |
347
+ | databaseStats.namespace | the runtime namespace the database corresponds to |
348
+ | databaseStats.dataSize | the actual amount of storage used by the database (default bytes) |
349
+ | databaseStats.storageSize | space allocated for storage for the database (default bytes) |
350
+ | databaseStats.indexSize | space allocated for indexes for the database (default bytes) |
351
+ | databaseStats.collections | the number of collections in the database |
352
+ | databaseStats.scaleFactor | the scale factor used for the size fields in the databaseStats array, ex: 1024 for kilobyte-scale (default is 1 for bytes) |
353
+ | databaseStats.lastUpdated | when the database statistics were last updated |
295
354
 
296
355
  ### Indexing
297
356
 
package/lib/DbBase.js CHANGED
@@ -24,23 +24,21 @@ class DbBase {
24
24
  /**
25
25
  * @param {string} region
26
26
  * @param {string} runtimeNamespace
27
- * @param {string} runtimeAuth
27
+ * @param {string} token
28
28
  * @hideconstructor
29
29
  */
30
- constructor(region, runtimeNamespace, runtimeAuth) {
31
- this.runtimeAuth = runtimeAuth
32
- if (!this.runtimeAuth) {
33
- throw new DbError('Runtime auth is required')
34
- }
35
- if (!/.+:.+/.test(this.runtimeAuth)) {
36
- throw new DbError("Invalid format for runtime auth, must be '<user>:<pass>'")
37
- }
30
+ constructor(region, runtimeNamespace, token) {
38
31
 
39
32
  this.runtimeNamespace = runtimeNamespace
40
33
  if (!this.runtimeNamespace) {
41
34
  throw new DbError('Runtime namespace is required')
42
35
  }
43
36
 
37
+ this.accessToken = token
38
+ if (!this.accessToken) {
39
+ throw new DbError('Ims access token is required')
40
+ }
41
+
44
42
  this.region = region.toLowerCase()
45
43
  const env = process.env.AIO_DB_ENVIRONMENT || getCliEnv()
46
44
  const validRegions = ALLOWED_REGIONS[env]
@@ -78,16 +76,15 @@ class DbBase {
78
76
  *
79
77
  * @static
80
78
  * @constructs
81
- * @param {Object=} config
79
+ * @param {Object} config
82
80
  * @param {string=} config.namespace required here or as __OW_API_NAMESPACE in .env
83
- * @param {string=} config.apikey required here or as __OW_API_KEY in .env
84
81
  * @param {string=} config.region optional, default is 'amer'. Allowed prod values are 'amer', 'emea', 'apac', 'aus'
82
+ * @param {string} config.token required to be passed here for Ims authentication
85
83
  * @returns {Promise<DbBase>} a new DbBase instance
86
84
  * @memberof DbBase
87
85
  */
88
- static async init(config = {}) {
86
+ static async init(config) {
89
87
  const namespace = config.namespace || process.env.__OW_NAMESPACE
90
- const apikey = config.apikey || process.env.__OW_API_KEY
91
88
  let aioAppRegion = null
92
89
 
93
90
  try {
@@ -97,7 +94,8 @@ class DbBase {
97
94
  }
98
95
 
99
96
  const region = aioAppRegion || config.region || ALLOWED_REGIONS[getCliEnv()].at(0)
100
- return new DbBase(region, namespace, apikey)
97
+ const token = config.token
98
+ return new DbBase(region, namespace, token)
101
99
  }
102
100
 
103
101
  /**
package/lib/DbClient.js CHANGED
@@ -9,7 +9,7 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
9
9
  OF ANY KIND, either express or implied. See the License for the specific language
10
10
  governing permissions and limitations under the License.
11
11
  */
12
- const { dbStatsApi, listCollectionsApi, createCollectionApi } = require('./api/client')
12
+ const { dbStatsApi, listCollectionsApi, createCollectionApi, orgStatsApi } = require('./api/client')
13
13
  const DbCollection = require('./DbCollection')
14
14
 
15
15
  class DbClient {
@@ -37,11 +37,23 @@ class DbClient {
37
37
  /**
38
38
  * Get the statistics for the scoped database
39
39
  *
40
+ * @param {Object=} options
41
+ * @returns {Promise<Object>}
42
+ * @throws {DbError}
43
+ */
44
+ async dbStats(options = {}) {
45
+ return dbStatsApi(this.db, options)
46
+ }
47
+
48
+ /**
49
+ * Gets the combined statistics for all databases that fall under the same organization as the scoped database
50
+ *
51
+ * @param {Object=} options
40
52
  * @returns {Promise<Object>}
41
53
  * @throws {DbError}
42
54
  */
43
- async dbStats() {
44
- return dbStatsApi(this.db)
55
+ async orgStats(options = {}) {
56
+ return orgStatsApi(this.db, options)
45
57
  }
46
58
 
47
59
  /**
package/lib/api/client.js CHANGED
@@ -43,11 +43,24 @@ async function getClientApi(db, endpoint) {
43
43
  * Gets the statistics for the scoped database
44
44
  *
45
45
  * @param {DbBase} db
46
+ * @param {Object=} options
47
+ * @returns {Promise<Object>}
48
+ * @throws {DbError}
49
+ */
50
+ async function dbStats(db, options = {}) {
51
+ return await postClientApi(db, 'dbStats', undefined, options)
52
+ }
53
+
54
+ /**
55
+ * Gets the combined statistics for all databases that fall under the same organization as the scoped database
56
+ *
57
+ * @param {DbBase} db
58
+ * @param {Object=} options
46
59
  * @returns {Promise<Object>}
47
60
  * @throws {DbError}
48
61
  */
49
- async function dbStats(db) {
50
- return await getClientApi(db, 'dbStats')
62
+ async function orgStats(db, options = {}) {
63
+ return await postClientApi(db, 'orgStats', undefined, options)
51
64
  }
52
65
 
53
66
  /**
@@ -90,6 +103,7 @@ async function close(db, axiosClient) {
90
103
 
91
104
  module.exports = {
92
105
  dbStatsApi: dbStats,
106
+ orgStatsApi: orgStats,
93
107
  closeApi: close,
94
108
  createCollectionApi: createCollection,
95
109
  listCollectionsApi: listCollections
package/lib/constants.js CHANGED
@@ -13,6 +13,8 @@ require('dotenv/config')
13
13
 
14
14
  const RUNTIME_HEADER = 'x-runtime-namespace'
15
15
  const REQUEST_ID_HEADER = 'x-request-id'
16
+ const IMS_AUTHORIZATION_HEADER = 'Authorization'
17
+ const IMS_AUTHORIZATION_HEADER_PREFIX = 'Bearer '
16
18
 
17
19
  const CURSOR_INIT_ERR_MESSAGE = 'Cursor has already been initialized, cannot modify request.'
18
20
 
@@ -34,6 +36,8 @@ const PROD_ENDPOINT_EXTERNAL = 'https://storage-database-<region>.app-builder.ad
34
36
  module.exports = {
35
37
  RUNTIME_HEADER,
36
38
  REQUEST_ID_HEADER,
39
+ IMS_AUTHORIZATION_HEADER,
40
+ IMS_AUTHORIZATION_HEADER_PREFIX,
37
41
  CURSOR_INIT_ERR_MESSAGE,
38
42
  PROD_ENV,
39
43
  STAGE_ENV,
package/lib/init.js CHANGED
@@ -18,18 +18,18 @@ require('dotenv/config')
18
18
  * Initializes and returns the ADP Storage Database SDK.
19
19
  *
20
20
  * To use the SDK you must either provide your OpenWhisk credentials in `config.ow` or in the environment variables
21
- * `__OW_NAMESPACE` and `__OW_API_KEY`.
21
+ * `__OW_NAMESPACE`.
22
22
  *
23
- * @param {Object=} [config] used to init the sdk
23
+ * @param {Object} config used to init the sdk
24
24
  * @param {('amer'|'apac'|'emea'|'aus')=} [config.region] optional region to use, default: `amer`
25
25
  * @param {Object=} [config.ow] Set those if you want to use ootb credentials to access the database service
26
26
  * @param {string=} [config.ow.namespace]
27
- * @param {string=} [config.ow.auth]
27
+ * @param {string} config.token Ims acccess token required here to authenticate
28
28
  * @returns {Promise<DbBase>} A DbBase instance
29
29
  */
30
- async function init (config = {}) {
31
- const { auth: apikey, namespace } = (config.ow ?? {})
32
- return DbBase.init({ apikey, namespace, region: config.region })
30
+ async function init (config) {
31
+ const { namespace } = (config.ow ?? {})
32
+ return DbBase.init({ namespace, region: config.region, token: config.token })
33
33
  }
34
34
 
35
35
  module.exports = { init }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/aio-lib-db",
3
- "version": "0.1.0-beta.6",
3
+ "version": "0.2.0-beta.1",
4
4
  "description": "An abstraction on top of Document DB storage",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -26,7 +26,7 @@
26
26
  "tough-cookie": "^5.1.2"
27
27
  },
28
28
  "devDependencies": {
29
- "jest": "^29.7.0",
29
+ "jest": "^30.2.0",
30
30
  "uuid": "^11.1.0"
31
31
  },
32
32
  "keywords": [
@@ -9,7 +9,7 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
9
9
  OF ANY KIND, either express or implied. See the License for the specific language
10
10
  governing permissions and limitations under the License.
11
11
  */
12
- const { RUNTIME_HEADER, REQUEST_ID_HEADER } = require('../lib/constants')
12
+ const { RUNTIME_HEADER, REQUEST_ID_HEADER, IMS_AUTHORIZATION_HEADER, IMS_AUTHORIZATION_HEADER_PREFIX } = require('../lib/constants')
13
13
  const DbError = require('../lib/DbError')
14
14
  const { EJSON } = require("bson")
15
15
 
@@ -60,15 +60,10 @@ async function apiRequest(db, axiosClient, apiPath, method, body = {}) {
60
60
  const fullUrl = `${db.serviceUrl}/${apiPath}`
61
61
  let res
62
62
  try {
63
- const creds = db.runtimeAuth.split(/:(.*)/,2)
64
63
  /** @type {Object}
65
64
  * @mixes AxiosRequestConfig */
66
65
  const reqConfig = {
67
- headers: { [RUNTIME_HEADER]: db.runtimeNamespace },
68
- auth: {
69
- username: creds[0],
70
- password: creds[1]
71
- }
66
+ headers: { [RUNTIME_HEADER]: db.runtimeNamespace, [IMS_AUTHORIZATION_HEADER]: IMS_AUTHORIZATION_HEADER_PREFIX + db.accessToken }
72
67
  }
73
68
  if (method === 'GET') {
74
69
  res = await axiosClient.get(fullUrl, reqConfig)