Skip to content

Commit

Permalink
fix: update docs for v3
Browse files Browse the repository at this point in the history
  • Loading branch information
shazron committed Jan 8, 2024
1 parent 9afdc73 commit 12c1364
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 215 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
Copyright 2019 Adobe. All rights reserved.
Copyright 2024 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Expand All @@ -10,20 +10,18 @@ OF ANY KIND, either express or implied. See the License for the specific languag
governing permissions and limitations under the License.
-->

# Adobe I/O Lib State

[![Version](https://img.shields.io/npm/v/@adobe/aio-lib-state.svg)](https://npmjs.org/package/@adobe/aio-lib-state)
[![Downloads/week](https://img.shields.io/npm/dw/@adobe/aio-lib-state.svg)](https://npmjs.org/package/@adobe/aio-lib-state)
![Node.js CI](https://github.com/adobe/aio-lib-state/workflows/Node.js%20CI/badge.svg)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Codecov Coverage](https://img.shields.io/codecov/c/github/adobe/aio-lib-state/master.svg?style=flat-square)](https://codecov.io/gh/adobe/aio-lib-state/)

# Adobe I/O Lib State

A Node JavaScript abstraction on top of distributed/cloud DBs that exposes a simple state persistence API.

You can initialize the lib with your Adobe I/O Runtime (a.k.a OpenWhisk) credentials.

Alternatively, you can bring your own cloud db keys. As of now we only support Azure Cosmos.

Please note that currently you must be a customer of [Adobe Developer App Builder](https://www.adobe.io/apis/experienceplatform/project-firefly.html) to use this library. App Builder is a complete framework that enables enterprise developers to build and deploy custom web applications that extend Adobe Experience Cloud solutions and run on Adobe infrastructure.

## Install
Expand All @@ -39,19 +37,23 @@ npm install @adobe/aio-lib-state

// init when running in an Adobe I/O Runtime action (OpenWhisk) (uses env vars __OW_API_KEY and __OW_NAMESPACE automatically)
const state = await stateLib.init()
// or if you want to use your own cloud DB account (make sure your partition key path is /partitionKey)
const state = await stateLib.init({ cosmos: { endpoint, masterKey, databaseId, containerId, partitionKey } })

// get
const res = await state.get('key') // res = { value, expiration }
const value = res.value

// put
await state.put('key', 'value')
await state.put('key', { anObject: 'value' }, { ttl: -1 }) // -1 for no expiry, defaults to 86400 (24 hours)
await state.put('another key', 'another value', { ttl: -1 }) // -1 for no expiry, defaults to 86400 (24 hours)

// delete
await state.delete('key')

// delete all keys and values
await state.deleteAll()

// returns true if you have at least one key and value
await state.any()
```

## Explore
Expand Down
209 changes: 88 additions & 121 deletions doc/api.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions lib/AdobeState.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class AdobeState {
* Deletes all key-values
*
* @returns {Promise<boolean>} true if deleted, false if not
* @memberof StateStore
* @memberof AdobeState
*/
async deleteAll () {
const requestOptions = {
Expand All @@ -350,7 +350,7 @@ class AdobeState {
* There exists key-values.
*
* @returns {Promise<boolean>} true if exists, false if not
* @memberof StateStore
* @memberof AdobeState
*/
async any () {
const requestOptions = {
Expand Down
5 changes: 1 addition & 4 deletions lib/StateError.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ const logger = require('@adobe/aio-lib-core-logging')('@adobe/aio-lib-state', {
* Adobe State lib custom errors.
* `e.sdkDetails` provides additional context for each error (e.g. function parameter)
*
* @typedef StateLibErrors
* @typedef AdobeStateLibErrors
* @type {object}
* @property {AdobeStateLibError} ERROR_BAD_ARGUMENT this error is thrown when an argument is missing, has invalid type, or includes invalid characters.
* @property {AdobeStateLibError} ERROR_BAD_REQUEST this error is thrown when an argument has an illegal value.
* @property {AdobeStateLibError} ERROR_NOT_IMPLEMENTED this error is thrown when a method is not implemented or when calling
* methods directly on the abstract class (StateStore).
* @property {AdobeStateLibError} ERROR_PAYLOAD_TOO_LARGE this error is thrown when the state key, state value or underlying request payload size
* exceeds the specified limitations.
* @property {AdobeStateLibError} ERROR_BAD_CREDENTIALS this error is thrown when the supplied init credentials are invalid.
Expand Down Expand Up @@ -58,7 +56,6 @@ E('ERROR_INTERNAL', '%s')
E('ERROR_BAD_REQUEST', '%s')
E('ERROR_BAD_ARGUMENT', '%s')
E('ERROR_UNKNOWN_PROVIDER', '%s')
E('ERROR_NOT_IMPLEMENTED', 'method `%s` not implemented')
E('ERROR_UNAUTHORIZED', 'you are not authorized to access %s')
E('ERROR_BAD_CREDENTIALS', 'cannot access %s, make sure your credentials are valid')
E('ERROR_PAYLOAD_TOO_LARGE', 'key, value or request payload is too large')
Expand Down
3 changes: 1 addition & 2 deletions lib/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ const { AdobeState } = require('./AdobeState')
* To use the SDK you must either provide your
* [OpenWhisk credentials]{@link OpenWhiskCredentials} in
* `config.ow` or your own
* [Azure Cosmos credentials]{@link AzureCosmosMasterCredentials} in `config.cosmos`.
*
* OpenWhisk credentials can also be read from environment variables `__OW_NAMESPACE` and `__OW_API_KEY`.
*
Expand All @@ -43,7 +42,7 @@ const { AdobeState } = require('./AdobeState')
* to use ootb credentials to access the state management service. OpenWhisk
* namespace and auth can also be passed through environment variables:
* `__OW_NAMESPACE` and `__OW_API_KEY`
* @returns {Promise<AdobeState>} An AdobeStateStore instance
* @returns {Promise<AdobeState>} An AdobeState instance
*/
async function init (config = {}) {
const logConfig = utils.withHiddenFields(config, ['ow.auth'])
Expand Down
1 change: 1 addition & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const cloneDeep = require('lodash.clonedeep')
/**
* Replaces any hidden field values with the string '<hidden>'
*
* @private
* @param {object} sourceObj the object to needs fields hidden
* @param {Array<string>} fieldsToHide the fields that need the value hidden
* @returns {object} the source object but with the specified fields hidden
Expand Down
1 change: 0 additions & 1 deletion test/jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,5 @@ global.expectToThrowForbidden = async (received, expectedErrorDetails) => global
global.expectToThrowFirewall = async (received, expectedErrorDetails) => global.expectToThrowCustomError(received, 'ERROR_FIREWALL', ['your', 'IP', 'blocked', 'firewall'], expectedErrorDetails)
global.expectToThrowInternalWithStatus = async (received, status, expectedErrorDetails) => global.expectToThrowCustomError(received, 'ERROR_INTERNAL', ['' + status], expectedErrorDetails)
global.expectToThrowInternal = async (received, expectedErrorDetails) => global.expectToThrowCustomError(received, 'ERROR_INTERNAL', ['unknown'], expectedErrorDetails)
global.expectToThrowNotImplemented = async (received, methodName) => global.expectToThrowCustomError(received, 'ERROR_NOT_IMPLEMENTED', ['not', 'implemented', methodName], {})
global.expectToThrowTooLarge = async (received, expectedErrorDetails) => global.expectToThrowCustomError(received, 'ERROR_PAYLOAD_TOO_LARGE', ['payload', 'is', 'too', 'large'], expectedErrorDetails)
global.expectToThrowRequestRateTooHigh = async (received, expectedErrorDetails) => global.expectToThrowCustomError(received, 'ERROR_REQUEST_RATE_TOO_HIGH', ['Request', 'rate', 'too', 'high'], expectedErrorDetails)
123 changes: 46 additions & 77 deletions types.d.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,76 @@
/**
* StateStore put options
* AdobeStateCredentials
* @property namespace - the state store namespace
* @property apikey - the state store api key
*/
export type AdobeStateCredentials = {
namespace: string;
apikey: string;
};

/**
* AdobeState put options
* @property ttl - time-to-live for key-value pair in seconds, defaults to 24 hours (86400s). Set to < 0 for no expiry. A
* value of 0 sets default.
*/
export type StateStorePutOptions = {
export type AdobeStatePutOptions = {
ttl: number;
};

/**
* StateStore get return object
* AdobeState get return object
* @property expiration - ISO date string of expiration time for the key-value pair, if the ttl is infinite
* expiration=null
* @property value - the value set by put
*/
export type StateStoreGetReturnValue = {
export type AdobeStateGetReturnValue = {
expiration: string | null;
value: any;
};

/**
* Validates json according to a schema.
* @param schema - the AJV schema
* @param data - the json data to test
* @returns the result
*/
export function validate(schema: any, data: any): any;

/**
* Cloud State Management
*/
export class StateStore {
export class AdobeState {
/**
* Retrieves the state value for given key.
* If the key doesn't exist returns undefined.
* @param key - state key identifier
* @returns get response holding value and additional info
*/
get(key: string): Promise<StateStoreGetReturnValue>;
get(key: string): Promise<AdobeStateGetReturnValue>;
/**
* Creates or updates a state key-value pair
* @param key - state key identifier
* @param value - state value
* @param [options = {}] - put options
* @returns key
*/
put(key: string, value: any, options?: StateStorePutOptions): Promise<string>;
put(key: string, value: string, options?: AdobeStatePutOptions): Promise<string>;
/**
* Deletes a state key-value pair
* @param key - state key identifier
* @returns key of deleted state or `null` if state does not exists
*/
delete(key: string): Promise<string>;
/**
* @param key - state key identifier
* @returns get response holding value and additional info
* Deletes all key-values
* @returns true if deleted, false if not
*/
protected _get(key: string): Promise<StateStoreGetReturnValue>;
deleteAll(): Promise<boolean>;
/**
* @param key - state key identifier
* @param value - state value
* @param options - state put options
* @returns key
* There exists key-values.
* @returns true if exists, false if not
*/
protected _put(key: string, value: any, options: any): Promise<string>;
/**
* @param key - state key identifier
* @returns key of deleted state or `null` if state does not exists
*/
protected _delete(key: string): Promise<string>;
any(): Promise<boolean>;
}

/**
Expand All @@ -68,33 +79,34 @@ export class StateStore {
* @property sdk - The SDK associated with the Error
* @property sdkDetails - The SDK details associated with the Error
*/
export type StateLibError = {
export type AdobeStateLibError = {
message: string;
code: string;
sdk: string;
sdkDetails: any;
};

/**
* State lib custom errors.
* Adobe State lib custom errors.
* `e.sdkDetails` provides additional context for each error (e.g. function parameter)
* @property ERROR_BAD_ARGUMENT - this error is thrown when an argument is missing or has invalid type
* @property ERROR_BAD_ARGUMENT - this error is thrown when an argument is missing, has invalid type, or includes invalid characters.
* @property ERROR_BAD_REQUEST - this error is thrown when an argument has an illegal value.
* @property ERROR_NOT_IMPLEMENTED - this error is thrown when a method is not implemented or when calling
* methods directly on the abstract class (StateStore).
* @property ERROR_PAYLOAD_TOO_LARGE - this error is thrown when the state key, state value or underlying request payload size
* exceeds the specified limitations.
* @property ERROR_BAD_CREDENTIALS - this error is thrown when the supplied init credentials are invalid.
* @property ERROR_UNAUTHORIZED - this error is thrown when the credentials are unauthorized to access the resource
* @property ERROR_INTERNAL - this error is thrown when an unknown error is thrown by the underlying
* DB provider or TVM server for credential exchange. More details can be found in `e.sdkDetails._internal`.
* @property ERROR_REQUEST_RATE_TOO_HIGH - this error is thrown when the request rate for accessing state is too high.
*/
export type StateLibErrors = {
ERROR_BAD_ARGUMENT: StateLibError;
ERROR_BAD_REQUEST: StateLibError;
ERROR_NOT_IMPLEMENTED: StateLibError;
ERROR_PAYLOAD_TOO_LARGE: StateLibError;
ERROR_BAD_CREDENTIALS: StateLibError;
ERROR_INTERNAL: StateLibError;
export type AdobeStateLibErrors = {
ERROR_BAD_ARGUMENT: AdobeStateLibError;
ERROR_BAD_REQUEST: AdobeStateLibError;
ERROR_PAYLOAD_TOO_LARGE: AdobeStateLibError;
ERROR_BAD_CREDENTIALS: AdobeStateLibError;
ERROR_UNAUTHORIZED: AdobeStateLibError;
ERROR_INTERNAL: AdobeStateLibError;
ERROR_REQUEST_RATE_TOO_HIGH: AdobeStateLibError;
};

/**
Expand All @@ -107,65 +119,22 @@ export type OpenWhiskCredentials = {
auth: string;
};

/**
* An object holding the Azure Cosmos resource credentials with permissions on a single partition and container
* @property endpoint - cosmosdb resource endpoint
* @property resourceToken - cosmosdb resource token restricted to the partitionKey
* @property databaseId - id for cosmosdb database
* @property containerId - id for cosmosdb container within database
* @property partitionKey - key for cosmosdb partition within container authorized by resource token
*/
export type AzureCosmosPartitionResourceCredentials = {
endpoint: string;
resourceToken: string;
databaseId: string;
containerId: string;
partitionKey: string;
};

/**
* An object holding the Azure Cosmos account master key
* @property endpoint - cosmosdb resource endpoint
* @property masterKey - cosmosdb account masterKey
* @property databaseId - id for cosmosdb database
* @property containerId - id for cosmosdb container within database
* @property partitionKey - key for cosmosdb partition where data will be stored
*/
export type AzureCosmosMasterCredentials = {
endpoint: string;
masterKey: string;
databaseId: string;
containerId: string;
partitionKey: string;
};

/**
* Initializes and returns the key-value-store SDK.
*
* To use the SDK you must either provide your
* [OpenWhisk credentials]{@link OpenWhiskCredentials} in
* `config.ow` or your own
* [Azure Cosmos credentials]{@link AzureCosmosMasterCredentials} in `config.cosmos`.
*
* OpenWhisk credentials can also be read from environment variables `__OW_NAMESPACE` and `__OW_API_KEY`.
* @param [config = {}] - used to init the sdk
* @param [config.ow] - {@link OpenWhiskCredentials}. Set those if you want
* to use ootb credentials to access the state management service. OpenWhisk
* namespace and auth can also be passed through environment variables:
* `__OW_NAMESPACE` and `__OW_API_KEY`
* @param [config.cosmos] - [Azure Cosmos resource credentials]{@link AzureCosmosPartitionResourceCredentials} or
* [Azure Cosmos account credentials]{@link AzureCosmosMasterCredentials}
* @param [config.tvm] - tvm configuration, applies only when passing OpenWhisk credentials
* @param [config.tvm.apiUrl] - alternative tvm api url.
* @param [config.tvm.cacheFile] - alternative tvm cache file, set to `false` to disable caching of temporary credentials.
* @returns A StateStore instance
* @returns An AdobeState instance
*/
export function init(config?: {
ow?: OpenWhiskCredentials;
cosmos?: AzureCosmosMasterCredentials | AzureCosmosPartitionResourceCredentials;
tvm?: {
apiUrl?: string;
cacheFile?: string;
};
}): Promise<StateStore>;
}): Promise<AdobeState>;

0 comments on commit 12c1364

Please sign in to comment.