@salesforce/mrt-utilities 0.1.4 → 0.1.5
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 +29 -0
- package/dist/cjs/data-store/development.d.ts +35 -0
- package/dist/cjs/data-store/development.js +93 -0
- package/dist/cjs/data-store/development.js.map +1 -0
- package/dist/cjs/data-store/errors.d.ts +9 -0
- package/dist/cjs/data-store/errors.js +33 -0
- package/dist/cjs/data-store/errors.js.map +1 -0
- package/dist/cjs/data-store/index.d.ts +1 -56
- package/dist/cjs/data-store/index.js +15 -123
- package/dist/cjs/data-store/index.js.map +1 -1
- package/dist/cjs/data-store/production.d.ts +48 -0
- package/dist/cjs/data-store/production.js +112 -0
- package/dist/cjs/data-store/production.js.map +1 -0
- package/dist/esm/data-store/development.d.ts +35 -0
- package/dist/esm/data-store/development.js +86 -0
- package/dist/esm/data-store/development.js.map +1 -0
- package/dist/esm/data-store/errors.d.ts +9 -0
- package/dist/esm/data-store/errors.js +27 -0
- package/dist/esm/data-store/errors.js.map +1 -0
- package/dist/esm/data-store/index.d.ts +1 -56
- package/dist/esm/data-store/index.js +1 -118
- package/dist/esm/data-store/index.js.map +1 -1
- package/dist/esm/data-store/production.d.ts +48 -0
- package/dist/esm/data-store/production.js +105 -0
- package/dist/esm/data-store/production.js.map +1 -0
- package/package.json +11 -1
package/README.md
CHANGED
|
@@ -47,3 +47,32 @@ export const createApp = (): Express => {
|
|
|
47
47
|
// Cleans up any remaining headers and sets any remaining values
|
|
48
48
|
app.use(createMRTCleanUpMiddleware());
|
|
49
49
|
```
|
|
50
|
+
|
|
51
|
+
## Development data-store usage
|
|
52
|
+
|
|
53
|
+
Use the `data-store` subpath with Node's `dev-data-store` condition to load the pseudo local data-store implementation:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
node --conditions dev-data-store your-app.js
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import {DataStore} from '@salesforce/mrt-utilities/data-store';
|
|
61
|
+
|
|
62
|
+
const store = DataStore.getDataStore();
|
|
63
|
+
const entry = await store.getEntry('custom-global-preferences');
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Configure local values with environment variables:
|
|
67
|
+
|
|
68
|
+
- `SFNEXT_DATA_STORE_DEFAULTS`: JSON map of key to object value
|
|
69
|
+
- `SFNEXT_DATA_STORE_WARN_ON_MISSING`: set to `false` to suppress missing-key warnings
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
export SFNEXT_DATA_STORE_DEFAULTS='{"custom-global-preferences":{"featureFlag":true}}'
|
|
75
|
+
export SFNEXT_DATA_STORE_WARN_ON_MISSING=true
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
By default, missing keys still throw `DataStoreNotFoundError` in development (matching production semantics).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export { DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError } from './errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Development-only pseudo data store backed by environment variables.
|
|
4
|
+
*
|
|
5
|
+
* This class mirrors the public DataStore API while avoiding DynamoDB access.
|
|
6
|
+
*/
|
|
7
|
+
export declare class DataStore {
|
|
8
|
+
private defaults;
|
|
9
|
+
private warnOnMissing;
|
|
10
|
+
private warnedKeys;
|
|
11
|
+
private static _instance;
|
|
12
|
+
private constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Get or create the singleton DataStore instance.
|
|
15
|
+
*
|
|
16
|
+
* @returns The singleton DataStore instance
|
|
17
|
+
*/
|
|
18
|
+
static getDataStore(): DataStore;
|
|
19
|
+
/**
|
|
20
|
+
* Whether the data store can be used in the current environment.
|
|
21
|
+
*
|
|
22
|
+
* The development pseudo store is always available when loaded.
|
|
23
|
+
*
|
|
24
|
+
* @returns true
|
|
25
|
+
*/
|
|
26
|
+
isDataStoreAvailable(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Fetch an entry from the pseudo data store.
|
|
29
|
+
*
|
|
30
|
+
* @param key The data store entry's key
|
|
31
|
+
* @returns An object containing the entry's key and value
|
|
32
|
+
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
33
|
+
*/
|
|
34
|
+
getEntry(key: string): Promise<Record<string, unknown> | undefined>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
4
|
+
* SPDX-License-Identifier: Apache-2
|
|
5
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.DataStore = exports.DataStoreUnavailableError = exports.DataStoreServiceError = exports.DataStoreNotFoundError = void 0;
|
|
9
|
+
const errors_js_1 = require("./errors.js");
|
|
10
|
+
var errors_js_2 = require("./errors.js");
|
|
11
|
+
Object.defineProperty(exports, "DataStoreNotFoundError", { enumerable: true, get: function () { return errors_js_2.DataStoreNotFoundError; } });
|
|
12
|
+
Object.defineProperty(exports, "DataStoreServiceError", { enumerable: true, get: function () { return errors_js_2.DataStoreServiceError; } });
|
|
13
|
+
Object.defineProperty(exports, "DataStoreUnavailableError", { enumerable: true, get: function () { return errors_js_2.DataStoreUnavailableError; } });
|
|
14
|
+
/**
|
|
15
|
+
* Development-only pseudo data store backed by environment variables.
|
|
16
|
+
*
|
|
17
|
+
* This class mirrors the public DataStore API while avoiding DynamoDB access.
|
|
18
|
+
*/
|
|
19
|
+
class DataStore {
|
|
20
|
+
defaults;
|
|
21
|
+
warnOnMissing;
|
|
22
|
+
warnedKeys;
|
|
23
|
+
static _instance = null;
|
|
24
|
+
constructor() {
|
|
25
|
+
this.defaults = readDefaultsFromEnv();
|
|
26
|
+
this.warnOnMissing = readWarnOnMissingFromEnv();
|
|
27
|
+
this.warnedKeys = new Set();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get or create the singleton DataStore instance.
|
|
31
|
+
*
|
|
32
|
+
* @returns The singleton DataStore instance
|
|
33
|
+
*/
|
|
34
|
+
static getDataStore() {
|
|
35
|
+
if (!DataStore._instance) {
|
|
36
|
+
DataStore._instance = new DataStore();
|
|
37
|
+
}
|
|
38
|
+
return DataStore._instance;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Whether the data store can be used in the current environment.
|
|
42
|
+
*
|
|
43
|
+
* The development pseudo store is always available when loaded.
|
|
44
|
+
*
|
|
45
|
+
* @returns true
|
|
46
|
+
*/
|
|
47
|
+
isDataStoreAvailable() {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Fetch an entry from the pseudo data store.
|
|
52
|
+
*
|
|
53
|
+
* @param key The data store entry's key
|
|
54
|
+
* @returns An object containing the entry's key and value
|
|
55
|
+
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
56
|
+
*/
|
|
57
|
+
async getEntry(key) {
|
|
58
|
+
const value = this.defaults[key];
|
|
59
|
+
if (value && typeof value === 'object') {
|
|
60
|
+
return { key, value };
|
|
61
|
+
}
|
|
62
|
+
if (this.warnOnMissing && !this.warnedKeys.has(key)) {
|
|
63
|
+
this.warnedKeys.add(key);
|
|
64
|
+
console.warn(`Local data-store provider did not find '${key}'.`);
|
|
65
|
+
}
|
|
66
|
+
throw new errors_js_1.DataStoreNotFoundError(`Data store entry '${key}' not found.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.DataStore = DataStore;
|
|
70
|
+
function readDefaultsFromEnv() {
|
|
71
|
+
const raw = process.env.SFNEXT_DATA_STORE_DEFAULTS;
|
|
72
|
+
if (!raw) {
|
|
73
|
+
return {};
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(raw);
|
|
77
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
78
|
+
return parsed;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.warn('Failed to parse SFNEXT_DATA_STORE_DEFAULTS JSON.', error);
|
|
83
|
+
}
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
function readWarnOnMissingFromEnv() {
|
|
87
|
+
const raw = process.env.SFNEXT_DATA_STORE_WARN_ON_MISSING;
|
|
88
|
+
if (!raw) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
return raw.toLowerCase() !== 'false';
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=development.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"development.js","sourceRoot":"","sources":["../../../src/data-store/development.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,2CAAmD;AAEnD,yCAAqG;AAA7F,mHAAA,sBAAsB,OAAA;AAAE,kHAAA,qBAAqB,OAAA;AAAE,sHAAA,yBAAyB,OAAA;AAEhF;;;;GAIG;AACH,MAAa,SAAS;IACZ,QAAQ,CAA0C;IAElD,aAAa,CAAU;IAEvB,UAAU,CAAc;IAExB,MAAM,CAAC,SAAS,GAAqB,IAAI,CAAC;IAElD;QACE,IAAI,CAAC,QAAQ,GAAG,mBAAmB,EAAE,CAAC;QACtC,IAAI,CAAC,aAAa,GAAG,wBAAwB,EAAE,CAAC;QAChD,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,YAAY;QACjB,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;YACzB,SAAS,CAAC,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;QACxC,CAAC;QAED,OAAO,SAAS,CAAC,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,oBAAoB;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ,CAAC,GAAW;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvC,OAAO,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC;QACtB,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,2CAA2C,GAAG,IAAI,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,IAAI,kCAAsB,CAAC,qBAAqB,GAAG,cAAc,CAAC,CAAC;IAC3E,CAAC;;AA1DH,8BA2DC;AAED,SAAS,mBAAmB;IAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;IACnD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,OAAO,MAAiD,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,kDAAkD,EAAE,KAAK,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,wBAAwB;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC;IAC1D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,GAAG,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class DataStoreNotFoundError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class DataStoreServiceError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class DataStoreUnavailableError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
4
|
+
* SPDX-License-Identifier: Apache-2
|
|
5
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.DataStoreUnavailableError = exports.DataStoreServiceError = exports.DataStoreNotFoundError = void 0;
|
|
9
|
+
class DataStoreNotFoundError extends Error {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'DataStoreNotFoundError';
|
|
13
|
+
Object.setPrototypeOf(this, DataStoreNotFoundError.prototype);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.DataStoreNotFoundError = DataStoreNotFoundError;
|
|
17
|
+
class DataStoreServiceError extends Error {
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = 'DataStoreServiceError';
|
|
21
|
+
Object.setPrototypeOf(this, DataStoreServiceError.prototype);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.DataStoreServiceError = DataStoreServiceError;
|
|
25
|
+
class DataStoreUnavailableError extends Error {
|
|
26
|
+
constructor(message) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'DataStoreUnavailableError';
|
|
29
|
+
Object.setPrototypeOf(this, DataStoreUnavailableError.prototype);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.DataStoreUnavailableError = DataStoreUnavailableError;
|
|
33
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/data-store/errors.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,MAAa,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;CACF;AAND,wDAMC;AAED,MAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC;CACF;AAND,sDAMC;AAED,MAAa,yBAA0B,SAAQ,KAAK;IAClD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACnE,CAAC;CACF;AAND,8DAMC"}
|
|
@@ -1,56 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare class DataStoreNotFoundError extends Error {
|
|
3
|
-
constructor(message: string);
|
|
4
|
-
}
|
|
5
|
-
export declare class DataStoreServiceError extends Error {
|
|
6
|
-
constructor(message: string);
|
|
7
|
-
}
|
|
8
|
-
export declare class DataStoreUnavailableError extends Error {
|
|
9
|
-
constructor(message: string);
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* A class for reading entries from the data store.
|
|
13
|
-
*
|
|
14
|
-
* This class uses a singleton pattern.
|
|
15
|
-
* Use DataStore.getDataStore() to get the singleton instance.
|
|
16
|
-
*/
|
|
17
|
-
export declare class DataStore {
|
|
18
|
-
private _tableName;
|
|
19
|
-
private _ddb;
|
|
20
|
-
private static _instance;
|
|
21
|
-
/** @internal Test hook: inject a document client for unit tests */
|
|
22
|
-
static _testDocumentClient: DynamoDBDocumentClient | null;
|
|
23
|
-
/** @internal Test hook: inject logMRTError for unit tests */
|
|
24
|
-
static _testLogMRTError: ((namespace: string, err: unknown, context?: Record<string, unknown>) => void) | null;
|
|
25
|
-
private constructor();
|
|
26
|
-
/**
|
|
27
|
-
* Get or create a DynamoDB document client (for abstraction of attribute values).
|
|
28
|
-
*
|
|
29
|
-
* @private
|
|
30
|
-
* @returns The DynamoDB document client
|
|
31
|
-
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
32
|
-
*/
|
|
33
|
-
private getClient;
|
|
34
|
-
/**
|
|
35
|
-
* Get or create the singleton DataStore instance.
|
|
36
|
-
*
|
|
37
|
-
* @returns The singleton DataStore instance
|
|
38
|
-
*/
|
|
39
|
-
static getDataStore(): DataStore;
|
|
40
|
-
/**
|
|
41
|
-
* Whether the data store can be used in the current environment.
|
|
42
|
-
*
|
|
43
|
-
* @returns true if the data store is available, false otherwise
|
|
44
|
-
*/
|
|
45
|
-
isDataStoreAvailable(): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Fetch an entry from the data store.
|
|
48
|
-
*
|
|
49
|
-
* @param key The data store entry's key
|
|
50
|
-
* @returns An object containing the entry's key and value
|
|
51
|
-
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
52
|
-
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
53
|
-
* @throws {DataStoreServiceError} An internal error occurred
|
|
54
|
-
*/
|
|
55
|
-
getEntry(key: string): Promise<Record<string, unknown> | undefined>;
|
|
56
|
-
}
|
|
1
|
+
export * from './production.js';
|
|
@@ -4,128 +4,20 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2
|
|
5
5
|
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
6
6
|
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
7
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
|
|
9
|
-
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
10
|
-
const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
|
|
11
|
-
const utils_js_1 = require("../utils/utils.js");
|
|
12
|
-
class DataStoreNotFoundError extends Error {
|
|
13
|
-
constructor(message) {
|
|
14
|
-
super(message);
|
|
15
|
-
this.name = 'DataStoreNotFoundError';
|
|
16
|
-
Object.setPrototypeOf(this, DataStoreNotFoundError.prototype);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
exports.DataStoreNotFoundError = DataStoreNotFoundError;
|
|
20
|
-
class DataStoreServiceError extends Error {
|
|
21
|
-
constructor(message) {
|
|
22
|
-
super(message);
|
|
23
|
-
this.name = 'DataStoreServiceError';
|
|
24
|
-
Object.setPrototypeOf(this, DataStoreServiceError.prototype);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
exports.DataStoreServiceError = DataStoreServiceError;
|
|
28
|
-
class DataStoreUnavailableError extends Error {
|
|
29
|
-
constructor(message) {
|
|
30
|
-
super(message);
|
|
31
|
-
this.name = 'DataStoreUnavailableError';
|
|
32
|
-
Object.setPrototypeOf(this, DataStoreUnavailableError.prototype);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
exports.DataStoreUnavailableError = DataStoreUnavailableError;
|
|
36
|
-
/**
|
|
37
|
-
* A class for reading entries from the data store.
|
|
38
|
-
*
|
|
39
|
-
* This class uses a singleton pattern.
|
|
40
|
-
* Use DataStore.getDataStore() to get the singleton instance.
|
|
41
|
-
*/
|
|
42
|
-
class DataStore {
|
|
43
|
-
_tableName = '';
|
|
44
|
-
_ddb = null;
|
|
45
|
-
static _instance = null;
|
|
46
|
-
/** @internal Test hook: inject a document client for unit tests */
|
|
47
|
-
static _testDocumentClient = null;
|
|
48
|
-
/** @internal Test hook: inject logMRTError for unit tests */
|
|
49
|
-
static _testLogMRTError = null;
|
|
50
|
-
constructor() {
|
|
51
|
-
// Private constructor for singleton; use DataStore.getDataStore() instead.
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Get or create a DynamoDB document client (for abstraction of attribute values).
|
|
55
|
-
*
|
|
56
|
-
* @private
|
|
57
|
-
* @returns The DynamoDB document client
|
|
58
|
-
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
59
|
-
*/
|
|
60
|
-
getClient() {
|
|
61
|
-
if (!this.isDataStoreAvailable()) {
|
|
62
|
-
throw new DataStoreUnavailableError('The data store is unavailable.');
|
|
63
|
-
}
|
|
64
|
-
if (DataStore._testDocumentClient) {
|
|
65
|
-
this._tableName = `DataAccessLayer-${process.env.AWS_REGION}`;
|
|
66
|
-
return DataStore._testDocumentClient;
|
|
67
|
-
}
|
|
68
|
-
if (!this._ddb) {
|
|
69
|
-
this._tableName = `DataAccessLayer-${process.env.AWS_REGION}`;
|
|
70
|
-
this._ddb = lib_dynamodb_1.DynamoDBDocumentClient.from(new client_dynamodb_1.DynamoDBClient({
|
|
71
|
-
region: process.env.AWS_REGION,
|
|
72
|
-
}));
|
|
73
|
-
}
|
|
74
|
-
return this._ddb;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Get or create the singleton DataStore instance.
|
|
78
|
-
*
|
|
79
|
-
* @returns The singleton DataStore instance
|
|
80
|
-
*/
|
|
81
|
-
static getDataStore() {
|
|
82
|
-
if (!DataStore._instance) {
|
|
83
|
-
DataStore._instance = new DataStore();
|
|
84
|
-
}
|
|
85
|
-
return DataStore._instance;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Whether the data store can be used in the current environment.
|
|
89
|
-
*
|
|
90
|
-
* @returns true if the data store is available, false otherwise
|
|
91
|
-
*/
|
|
92
|
-
isDataStoreAvailable() {
|
|
93
|
-
return Boolean(process.env.AWS_REGION && process.env.MOBIFY_PROPERTY_ID && process.env.DEPLOY_TARGET);
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Fetch an entry from the data store.
|
|
97
|
-
*
|
|
98
|
-
* @param key The data store entry's key
|
|
99
|
-
* @returns An object containing the entry's key and value
|
|
100
|
-
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
101
|
-
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
102
|
-
* @throws {DataStoreServiceError} An internal error occurred
|
|
103
|
-
*/
|
|
104
|
-
async getEntry(key) {
|
|
105
|
-
if (!this.isDataStoreAvailable()) {
|
|
106
|
-
throw new DataStoreUnavailableError('The data store is unavailable.');
|
|
107
|
-
}
|
|
108
|
-
const ddb = this.getClient();
|
|
109
|
-
let response;
|
|
110
|
-
try {
|
|
111
|
-
response = await ddb.send(new lib_dynamodb_1.GetCommand({
|
|
112
|
-
TableName: this._tableName,
|
|
113
|
-
Key: {
|
|
114
|
-
projectEnvironment: `${process.env.MOBIFY_PROPERTY_ID} ${process.env.DEPLOY_TARGET}`,
|
|
115
|
-
key,
|
|
116
|
-
},
|
|
117
|
-
}));
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
const logFn = DataStore._testLogMRTError ?? utils_js_1.logMRTError;
|
|
121
|
-
logFn('data_store', error, { key, tableName: this._tableName });
|
|
122
|
-
throw new DataStoreServiceError('Data store request failed.');
|
|
123
|
-
}
|
|
124
|
-
if (!response.Item?.value) {
|
|
125
|
-
throw new DataStoreNotFoundError(`Data store entry '${key}' not found.`);
|
|
126
|
-
}
|
|
127
|
-
return { key, value: response.Item.value };
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
exports.DataStore = DataStore;
|
|
22
|
+
__exportStar(require("./production.js"), exports);
|
|
131
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data-store/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data-store/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;AAEH,kDAAgC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
|
|
2
|
+
export { DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError } from './errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* A class for reading entries from the data store.
|
|
5
|
+
*
|
|
6
|
+
* This class uses a singleton pattern.
|
|
7
|
+
* Use DataStore.getDataStore() to get the singleton instance.
|
|
8
|
+
*/
|
|
9
|
+
export declare class DataStore {
|
|
10
|
+
private _tableName;
|
|
11
|
+
private _ddb;
|
|
12
|
+
private static _instance;
|
|
13
|
+
/** @internal Test hook: inject a document client for unit tests */
|
|
14
|
+
static _testDocumentClient: DynamoDBDocumentClient | null;
|
|
15
|
+
/** @internal Test hook: inject logMRTError for unit tests */
|
|
16
|
+
static _testLogMRTError: ((namespace: string, err: unknown, context?: Record<string, unknown>) => void) | null;
|
|
17
|
+
private constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Get or create a DynamoDB document client (for abstraction of attribute values).
|
|
20
|
+
*
|
|
21
|
+
* @private
|
|
22
|
+
* @returns The DynamoDB document client
|
|
23
|
+
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
24
|
+
*/
|
|
25
|
+
private getClient;
|
|
26
|
+
/**
|
|
27
|
+
* Get or create the singleton DataStore instance.
|
|
28
|
+
*
|
|
29
|
+
* @returns The singleton DataStore instance
|
|
30
|
+
*/
|
|
31
|
+
static getDataStore(): DataStore;
|
|
32
|
+
/**
|
|
33
|
+
* Whether the data store can be used in the current environment.
|
|
34
|
+
*
|
|
35
|
+
* @returns true if the data store is available, false otherwise
|
|
36
|
+
*/
|
|
37
|
+
isDataStoreAvailable(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Fetch an entry from the data store.
|
|
40
|
+
*
|
|
41
|
+
* @param key The data store entry's key
|
|
42
|
+
* @returns An object containing the entry's key and value
|
|
43
|
+
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
44
|
+
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
45
|
+
* @throws {DataStoreServiceError} An internal error occurred
|
|
46
|
+
*/
|
|
47
|
+
getEntry(key: string): Promise<Record<string, unknown> | undefined>;
|
|
48
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
4
|
+
* SPDX-License-Identifier: Apache-2
|
|
5
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.DataStore = exports.DataStoreUnavailableError = exports.DataStoreServiceError = exports.DataStoreNotFoundError = void 0;
|
|
9
|
+
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
10
|
+
const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
|
|
11
|
+
const errors_js_1 = require("./errors.js");
|
|
12
|
+
const utils_js_1 = require("../utils/utils.js");
|
|
13
|
+
var errors_js_2 = require("./errors.js");
|
|
14
|
+
Object.defineProperty(exports, "DataStoreNotFoundError", { enumerable: true, get: function () { return errors_js_2.DataStoreNotFoundError; } });
|
|
15
|
+
Object.defineProperty(exports, "DataStoreServiceError", { enumerable: true, get: function () { return errors_js_2.DataStoreServiceError; } });
|
|
16
|
+
Object.defineProperty(exports, "DataStoreUnavailableError", { enumerable: true, get: function () { return errors_js_2.DataStoreUnavailableError; } });
|
|
17
|
+
/**
|
|
18
|
+
* A class for reading entries from the data store.
|
|
19
|
+
*
|
|
20
|
+
* This class uses a singleton pattern.
|
|
21
|
+
* Use DataStore.getDataStore() to get the singleton instance.
|
|
22
|
+
*/
|
|
23
|
+
class DataStore {
|
|
24
|
+
_tableName = '';
|
|
25
|
+
_ddb = null;
|
|
26
|
+
static _instance = null;
|
|
27
|
+
/** @internal Test hook: inject a document client for unit tests */
|
|
28
|
+
static _testDocumentClient = null;
|
|
29
|
+
/** @internal Test hook: inject logMRTError for unit tests */
|
|
30
|
+
static _testLogMRTError = null;
|
|
31
|
+
constructor() {
|
|
32
|
+
// Private constructor for singleton; use DataStore.getDataStore() instead.
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get or create a DynamoDB document client (for abstraction of attribute values).
|
|
36
|
+
*
|
|
37
|
+
* @private
|
|
38
|
+
* @returns The DynamoDB document client
|
|
39
|
+
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
40
|
+
*/
|
|
41
|
+
getClient() {
|
|
42
|
+
if (!this.isDataStoreAvailable()) {
|
|
43
|
+
throw new errors_js_1.DataStoreUnavailableError('The data store is unavailable.');
|
|
44
|
+
}
|
|
45
|
+
if (DataStore._testDocumentClient) {
|
|
46
|
+
this._tableName = `DataAccessLayer-${process.env.AWS_REGION}`;
|
|
47
|
+
return DataStore._testDocumentClient;
|
|
48
|
+
}
|
|
49
|
+
if (!this._ddb) {
|
|
50
|
+
this._tableName = `DataAccessLayer-${process.env.AWS_REGION}`;
|
|
51
|
+
this._ddb = lib_dynamodb_1.DynamoDBDocumentClient.from(new client_dynamodb_1.DynamoDBClient({
|
|
52
|
+
region: process.env.AWS_REGION,
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
return this._ddb;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get or create the singleton DataStore instance.
|
|
59
|
+
*
|
|
60
|
+
* @returns The singleton DataStore instance
|
|
61
|
+
*/
|
|
62
|
+
static getDataStore() {
|
|
63
|
+
if (!DataStore._instance) {
|
|
64
|
+
DataStore._instance = new DataStore();
|
|
65
|
+
}
|
|
66
|
+
return DataStore._instance;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Whether the data store can be used in the current environment.
|
|
70
|
+
*
|
|
71
|
+
* @returns true if the data store is available, false otherwise
|
|
72
|
+
*/
|
|
73
|
+
isDataStoreAvailable() {
|
|
74
|
+
return Boolean(process.env.AWS_REGION && process.env.MOBIFY_PROPERTY_ID && process.env.DEPLOY_TARGET);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Fetch an entry from the data store.
|
|
78
|
+
*
|
|
79
|
+
* @param key The data store entry's key
|
|
80
|
+
* @returns An object containing the entry's key and value
|
|
81
|
+
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
82
|
+
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
83
|
+
* @throws {DataStoreServiceError} An internal error occurred
|
|
84
|
+
*/
|
|
85
|
+
async getEntry(key) {
|
|
86
|
+
if (!this.isDataStoreAvailable()) {
|
|
87
|
+
throw new errors_js_1.DataStoreUnavailableError('The data store is unavailable.');
|
|
88
|
+
}
|
|
89
|
+
const ddb = this.getClient();
|
|
90
|
+
let response;
|
|
91
|
+
try {
|
|
92
|
+
response = await ddb.send(new lib_dynamodb_1.GetCommand({
|
|
93
|
+
TableName: this._tableName,
|
|
94
|
+
Key: {
|
|
95
|
+
projectEnvironment: `${process.env.MOBIFY_PROPERTY_ID} ${process.env.DEPLOY_TARGET}`,
|
|
96
|
+
key,
|
|
97
|
+
},
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const logFn = DataStore._testLogMRTError ?? utils_js_1.logMRTError;
|
|
102
|
+
logFn('data_store', error, { key, tableName: this._tableName });
|
|
103
|
+
throw new errors_js_1.DataStoreServiceError('Data store request failed.');
|
|
104
|
+
}
|
|
105
|
+
if (!response.Item?.value) {
|
|
106
|
+
throw new errors_js_1.DataStoreNotFoundError(`Data store entry '${key}' not found.`);
|
|
107
|
+
}
|
|
108
|
+
return { key, value: response.Item.value };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.DataStore = DataStore;
|
|
112
|
+
//# sourceMappingURL=production.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"production.js","sourceRoot":"","sources":["../../../src/data-store/production.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,8DAAwD;AACxD,wDAAgG;AAEhG,2CAAqG;AACrG,gDAA8C;AAE9C,yCAAqG;AAA7F,mHAAA,sBAAsB,OAAA;AAAE,kHAAA,qBAAqB,OAAA;AAAE,sHAAA,yBAAyB,OAAA;AAEhF;;;;;GAKG;AACH,MAAa,SAAS;IACZ,UAAU,GAAW,EAAE,CAAC;IACxB,IAAI,GAAkC,IAAI,CAAC;IAC3C,MAAM,CAAC,SAAS,GAAqB,IAAI,CAAC;IAElD,mEAAmE;IACnE,MAAM,CAAC,mBAAmB,GAAkC,IAAI,CAAC;IACjE,6DAA6D;IAC7D,MAAM,CAAC,gBAAgB,GAA0F,IAAI,CAAC;IAEtH;QACE,2EAA2E;IAC7E,CAAC;IAED;;;;;;OAMG;IACK,SAAS;QACf,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,qCAAyB,CAAC,gCAAgC,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,SAAS,CAAC,mBAAmB,EAAE,CAAC;YAClC,IAAI,CAAC,UAAU,GAAG,mBAAmB,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;YAC9D,OAAO,SAAS,CAAC,mBAAmB,CAAC;QACvC,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,GAAG,mBAAmB,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;YAC9D,IAAI,CAAC,IAAI,GAAG,qCAAsB,CAAC,IAAI,CACrC,IAAI,gCAAc,CAAC;gBACjB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;aAC/B,CAAC,CACH,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,YAAY;QACjB,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;YACzB,SAAS,CAAC,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;QACxC,CAAC;QACD,OAAO,SAAS,CAAC,SAAS,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,oBAAoB;QAClB,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACxG,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,QAAQ,CAAC,GAAW;QACxB,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,qCAAyB,CAAC,gCAAgC,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAC7B,IAAI,QAA0B,CAAC;QAC/B,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,CACvB,IAAI,yBAAU,CAAC;gBACb,SAAS,EAAE,IAAI,CAAC,UAAU;gBAC1B,GAAG,EAAE;oBACH,kBAAkB,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE;oBACpF,GAAG;iBACJ;aACF,CAAC,CACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,SAAS,CAAC,gBAAgB,IAAI,sBAAW,CAAC;YACxD,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,EAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,UAAU,EAAC,CAAC,CAAC;YAC9D,MAAM,IAAI,iCAAqB,CAAC,4BAA4B,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;YAC1B,MAAM,IAAI,kCAAsB,CAAC,qBAAqB,GAAG,cAAc,CAAC,CAAC;QAC3E,CAAC;QAED,OAAO,EAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAC,CAAC;IAC3C,CAAC;;AArGH,8BAsGC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export { DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError } from './errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Development-only pseudo data store backed by environment variables.
|
|
4
|
+
*
|
|
5
|
+
* This class mirrors the public DataStore API while avoiding DynamoDB access.
|
|
6
|
+
*/
|
|
7
|
+
export declare class DataStore {
|
|
8
|
+
private defaults;
|
|
9
|
+
private warnOnMissing;
|
|
10
|
+
private warnedKeys;
|
|
11
|
+
private static _instance;
|
|
12
|
+
private constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Get or create the singleton DataStore instance.
|
|
15
|
+
*
|
|
16
|
+
* @returns The singleton DataStore instance
|
|
17
|
+
*/
|
|
18
|
+
static getDataStore(): DataStore;
|
|
19
|
+
/**
|
|
20
|
+
* Whether the data store can be used in the current environment.
|
|
21
|
+
*
|
|
22
|
+
* The development pseudo store is always available when loaded.
|
|
23
|
+
*
|
|
24
|
+
* @returns true
|
|
25
|
+
*/
|
|
26
|
+
isDataStoreAvailable(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Fetch an entry from the pseudo data store.
|
|
29
|
+
*
|
|
30
|
+
* @param key The data store entry's key
|
|
31
|
+
* @returns An object containing the entry's key and value
|
|
32
|
+
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
33
|
+
*/
|
|
34
|
+
getEntry(key: string): Promise<Record<string, unknown> | undefined>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2
|
|
4
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { DataStoreNotFoundError } from './errors.js';
|
|
7
|
+
export { DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError } from './errors.js';
|
|
8
|
+
/**
|
|
9
|
+
* Development-only pseudo data store backed by environment variables.
|
|
10
|
+
*
|
|
11
|
+
* This class mirrors the public DataStore API while avoiding DynamoDB access.
|
|
12
|
+
*/
|
|
13
|
+
export class DataStore {
|
|
14
|
+
defaults;
|
|
15
|
+
warnOnMissing;
|
|
16
|
+
warnedKeys;
|
|
17
|
+
static _instance = null;
|
|
18
|
+
constructor() {
|
|
19
|
+
this.defaults = readDefaultsFromEnv();
|
|
20
|
+
this.warnOnMissing = readWarnOnMissingFromEnv();
|
|
21
|
+
this.warnedKeys = new Set();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get or create the singleton DataStore instance.
|
|
25
|
+
*
|
|
26
|
+
* @returns The singleton DataStore instance
|
|
27
|
+
*/
|
|
28
|
+
static getDataStore() {
|
|
29
|
+
if (!DataStore._instance) {
|
|
30
|
+
DataStore._instance = new DataStore();
|
|
31
|
+
}
|
|
32
|
+
return DataStore._instance;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Whether the data store can be used in the current environment.
|
|
36
|
+
*
|
|
37
|
+
* The development pseudo store is always available when loaded.
|
|
38
|
+
*
|
|
39
|
+
* @returns true
|
|
40
|
+
*/
|
|
41
|
+
isDataStoreAvailable() {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Fetch an entry from the pseudo data store.
|
|
46
|
+
*
|
|
47
|
+
* @param key The data store entry's key
|
|
48
|
+
* @returns An object containing the entry's key and value
|
|
49
|
+
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
50
|
+
*/
|
|
51
|
+
async getEntry(key) {
|
|
52
|
+
const value = this.defaults[key];
|
|
53
|
+
if (value && typeof value === 'object') {
|
|
54
|
+
return { key, value };
|
|
55
|
+
}
|
|
56
|
+
if (this.warnOnMissing && !this.warnedKeys.has(key)) {
|
|
57
|
+
this.warnedKeys.add(key);
|
|
58
|
+
console.warn(`Local data-store provider did not find '${key}'.`);
|
|
59
|
+
}
|
|
60
|
+
throw new DataStoreNotFoundError(`Data store entry '${key}' not found.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function readDefaultsFromEnv() {
|
|
64
|
+
const raw = process.env.SFNEXT_DATA_STORE_DEFAULTS;
|
|
65
|
+
if (!raw) {
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(raw);
|
|
70
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
71
|
+
return parsed;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.warn('Failed to parse SFNEXT_DATA_STORE_DEFAULTS JSON.', error);
|
|
76
|
+
}
|
|
77
|
+
return {};
|
|
78
|
+
}
|
|
79
|
+
function readWarnOnMissingFromEnv() {
|
|
80
|
+
const raw = process.env.SFNEXT_DATA_STORE_WARN_ON_MISSING;
|
|
81
|
+
if (!raw) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return raw.toLowerCase() !== 'false';
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=development.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"development.js","sourceRoot":"","sources":["../../../src/data-store/development.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,sBAAsB,EAAC,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAC,sBAAsB,EAAE,qBAAqB,EAAE,yBAAyB,EAAC,MAAM,aAAa,CAAC;AAErG;;;;GAIG;AACH,MAAM,OAAO,SAAS;IACZ,QAAQ,CAA0C;IAElD,aAAa,CAAU;IAEvB,UAAU,CAAc;IAExB,MAAM,CAAC,SAAS,GAAqB,IAAI,CAAC;IAElD;QACE,IAAI,CAAC,QAAQ,GAAG,mBAAmB,EAAE,CAAC;QACtC,IAAI,CAAC,aAAa,GAAG,wBAAwB,EAAE,CAAC;QAChD,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,YAAY;QACjB,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;YACzB,SAAS,CAAC,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;QACxC,CAAC;QAED,OAAO,SAAS,CAAC,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,oBAAoB;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ,CAAC,GAAW;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvC,OAAO,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC;QACtB,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,2CAA2C,GAAG,IAAI,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,IAAI,sBAAsB,CAAC,qBAAqB,GAAG,cAAc,CAAC,CAAC;IAC3E,CAAC;;AAGH,SAAS,mBAAmB;IAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;IACnD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,OAAO,MAAiD,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,kDAAkD,EAAE,KAAK,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,wBAAwB;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC;IAC1D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,GAAG,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class DataStoreNotFoundError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class DataStoreServiceError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class DataStoreUnavailableError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2
|
|
4
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
export class DataStoreNotFoundError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'DataStoreNotFoundError';
|
|
10
|
+
Object.setPrototypeOf(this, DataStoreNotFoundError.prototype);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class DataStoreServiceError extends Error {
|
|
14
|
+
constructor(message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = 'DataStoreServiceError';
|
|
17
|
+
Object.setPrototypeOf(this, DataStoreServiceError.prototype);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class DataStoreUnavailableError extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = 'DataStoreUnavailableError';
|
|
24
|
+
Object.setPrototypeOf(this, DataStoreUnavailableError.prototype);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/data-store/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC;CACF;AAED,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACnE,CAAC;CACF"}
|
|
@@ -1,56 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare class DataStoreNotFoundError extends Error {
|
|
3
|
-
constructor(message: string);
|
|
4
|
-
}
|
|
5
|
-
export declare class DataStoreServiceError extends Error {
|
|
6
|
-
constructor(message: string);
|
|
7
|
-
}
|
|
8
|
-
export declare class DataStoreUnavailableError extends Error {
|
|
9
|
-
constructor(message: string);
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* A class for reading entries from the data store.
|
|
13
|
-
*
|
|
14
|
-
* This class uses a singleton pattern.
|
|
15
|
-
* Use DataStore.getDataStore() to get the singleton instance.
|
|
16
|
-
*/
|
|
17
|
-
export declare class DataStore {
|
|
18
|
-
private _tableName;
|
|
19
|
-
private _ddb;
|
|
20
|
-
private static _instance;
|
|
21
|
-
/** @internal Test hook: inject a document client for unit tests */
|
|
22
|
-
static _testDocumentClient: DynamoDBDocumentClient | null;
|
|
23
|
-
/** @internal Test hook: inject logMRTError for unit tests */
|
|
24
|
-
static _testLogMRTError: ((namespace: string, err: unknown, context?: Record<string, unknown>) => void) | null;
|
|
25
|
-
private constructor();
|
|
26
|
-
/**
|
|
27
|
-
* Get or create a DynamoDB document client (for abstraction of attribute values).
|
|
28
|
-
*
|
|
29
|
-
* @private
|
|
30
|
-
* @returns The DynamoDB document client
|
|
31
|
-
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
32
|
-
*/
|
|
33
|
-
private getClient;
|
|
34
|
-
/**
|
|
35
|
-
* Get or create the singleton DataStore instance.
|
|
36
|
-
*
|
|
37
|
-
* @returns The singleton DataStore instance
|
|
38
|
-
*/
|
|
39
|
-
static getDataStore(): DataStore;
|
|
40
|
-
/**
|
|
41
|
-
* Whether the data store can be used in the current environment.
|
|
42
|
-
*
|
|
43
|
-
* @returns true if the data store is available, false otherwise
|
|
44
|
-
*/
|
|
45
|
-
isDataStoreAvailable(): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Fetch an entry from the data store.
|
|
48
|
-
*
|
|
49
|
-
* @param key The data store entry's key
|
|
50
|
-
* @returns An object containing the entry's key and value
|
|
51
|
-
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
52
|
-
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
53
|
-
* @throws {DataStoreServiceError} An internal error occurred
|
|
54
|
-
*/
|
|
55
|
-
getEntry(key: string): Promise<Record<string, unknown> | undefined>;
|
|
56
|
-
}
|
|
1
|
+
export * from './production.js';
|
|
@@ -3,122 +3,5 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2
|
|
4
4
|
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
import { DynamoDBDocumentClient, GetCommand } from '@aws-sdk/lib-dynamodb';
|
|
8
|
-
import { logMRTError } from '../utils/utils.js';
|
|
9
|
-
export class DataStoreNotFoundError extends Error {
|
|
10
|
-
constructor(message) {
|
|
11
|
-
super(message);
|
|
12
|
-
this.name = 'DataStoreNotFoundError';
|
|
13
|
-
Object.setPrototypeOf(this, DataStoreNotFoundError.prototype);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
export class DataStoreServiceError extends Error {
|
|
17
|
-
constructor(message) {
|
|
18
|
-
super(message);
|
|
19
|
-
this.name = 'DataStoreServiceError';
|
|
20
|
-
Object.setPrototypeOf(this, DataStoreServiceError.prototype);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export class DataStoreUnavailableError extends Error {
|
|
24
|
-
constructor(message) {
|
|
25
|
-
super(message);
|
|
26
|
-
this.name = 'DataStoreUnavailableError';
|
|
27
|
-
Object.setPrototypeOf(this, DataStoreUnavailableError.prototype);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* A class for reading entries from the data store.
|
|
32
|
-
*
|
|
33
|
-
* This class uses a singleton pattern.
|
|
34
|
-
* Use DataStore.getDataStore() to get the singleton instance.
|
|
35
|
-
*/
|
|
36
|
-
export class DataStore {
|
|
37
|
-
_tableName = '';
|
|
38
|
-
_ddb = null;
|
|
39
|
-
static _instance = null;
|
|
40
|
-
/** @internal Test hook: inject a document client for unit tests */
|
|
41
|
-
static _testDocumentClient = null;
|
|
42
|
-
/** @internal Test hook: inject logMRTError for unit tests */
|
|
43
|
-
static _testLogMRTError = null;
|
|
44
|
-
constructor() {
|
|
45
|
-
// Private constructor for singleton; use DataStore.getDataStore() instead.
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Get or create a DynamoDB document client (for abstraction of attribute values).
|
|
49
|
-
*
|
|
50
|
-
* @private
|
|
51
|
-
* @returns The DynamoDB document client
|
|
52
|
-
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
53
|
-
*/
|
|
54
|
-
getClient() {
|
|
55
|
-
if (!this.isDataStoreAvailable()) {
|
|
56
|
-
throw new DataStoreUnavailableError('The data store is unavailable.');
|
|
57
|
-
}
|
|
58
|
-
if (DataStore._testDocumentClient) {
|
|
59
|
-
this._tableName = `DataAccessLayer-${process.env.AWS_REGION}`;
|
|
60
|
-
return DataStore._testDocumentClient;
|
|
61
|
-
}
|
|
62
|
-
if (!this._ddb) {
|
|
63
|
-
this._tableName = `DataAccessLayer-${process.env.AWS_REGION}`;
|
|
64
|
-
this._ddb = DynamoDBDocumentClient.from(new DynamoDBClient({
|
|
65
|
-
region: process.env.AWS_REGION,
|
|
66
|
-
}));
|
|
67
|
-
}
|
|
68
|
-
return this._ddb;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Get or create the singleton DataStore instance.
|
|
72
|
-
*
|
|
73
|
-
* @returns The singleton DataStore instance
|
|
74
|
-
*/
|
|
75
|
-
static getDataStore() {
|
|
76
|
-
if (!DataStore._instance) {
|
|
77
|
-
DataStore._instance = new DataStore();
|
|
78
|
-
}
|
|
79
|
-
return DataStore._instance;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Whether the data store can be used in the current environment.
|
|
83
|
-
*
|
|
84
|
-
* @returns true if the data store is available, false otherwise
|
|
85
|
-
*/
|
|
86
|
-
isDataStoreAvailable() {
|
|
87
|
-
return Boolean(process.env.AWS_REGION && process.env.MOBIFY_PROPERTY_ID && process.env.DEPLOY_TARGET);
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Fetch an entry from the data store.
|
|
91
|
-
*
|
|
92
|
-
* @param key The data store entry's key
|
|
93
|
-
* @returns An object containing the entry's key and value
|
|
94
|
-
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
95
|
-
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
96
|
-
* @throws {DataStoreServiceError} An internal error occurred
|
|
97
|
-
*/
|
|
98
|
-
async getEntry(key) {
|
|
99
|
-
if (!this.isDataStoreAvailable()) {
|
|
100
|
-
throw new DataStoreUnavailableError('The data store is unavailable.');
|
|
101
|
-
}
|
|
102
|
-
const ddb = this.getClient();
|
|
103
|
-
let response;
|
|
104
|
-
try {
|
|
105
|
-
response = await ddb.send(new GetCommand({
|
|
106
|
-
TableName: this._tableName,
|
|
107
|
-
Key: {
|
|
108
|
-
projectEnvironment: `${process.env.MOBIFY_PROPERTY_ID} ${process.env.DEPLOY_TARGET}`,
|
|
109
|
-
key,
|
|
110
|
-
},
|
|
111
|
-
}));
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
const logFn = DataStore._testLogMRTError ?? logMRTError;
|
|
115
|
-
logFn('data_store', error, { key, tableName: this._tableName });
|
|
116
|
-
throw new DataStoreServiceError('Data store request failed.');
|
|
117
|
-
}
|
|
118
|
-
if (!response.Item?.value) {
|
|
119
|
-
throw new DataStoreNotFoundError(`Data store entry '${key}' not found.`);
|
|
120
|
-
}
|
|
121
|
-
return { key, value: response.Item.value };
|
|
122
|
-
}
|
|
123
|
-
}
|
|
6
|
+
export * from './production.js';
|
|
124
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data-store/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data-store/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
|
|
2
|
+
export { DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError } from './errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* A class for reading entries from the data store.
|
|
5
|
+
*
|
|
6
|
+
* This class uses a singleton pattern.
|
|
7
|
+
* Use DataStore.getDataStore() to get the singleton instance.
|
|
8
|
+
*/
|
|
9
|
+
export declare class DataStore {
|
|
10
|
+
private _tableName;
|
|
11
|
+
private _ddb;
|
|
12
|
+
private static _instance;
|
|
13
|
+
/** @internal Test hook: inject a document client for unit tests */
|
|
14
|
+
static _testDocumentClient: DynamoDBDocumentClient | null;
|
|
15
|
+
/** @internal Test hook: inject logMRTError for unit tests */
|
|
16
|
+
static _testLogMRTError: ((namespace: string, err: unknown, context?: Record<string, unknown>) => void) | null;
|
|
17
|
+
private constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Get or create a DynamoDB document client (for abstraction of attribute values).
|
|
20
|
+
*
|
|
21
|
+
* @private
|
|
22
|
+
* @returns The DynamoDB document client
|
|
23
|
+
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
24
|
+
*/
|
|
25
|
+
private getClient;
|
|
26
|
+
/**
|
|
27
|
+
* Get or create the singleton DataStore instance.
|
|
28
|
+
*
|
|
29
|
+
* @returns The singleton DataStore instance
|
|
30
|
+
*/
|
|
31
|
+
static getDataStore(): DataStore;
|
|
32
|
+
/**
|
|
33
|
+
* Whether the data store can be used in the current environment.
|
|
34
|
+
*
|
|
35
|
+
* @returns true if the data store is available, false otherwise
|
|
36
|
+
*/
|
|
37
|
+
isDataStoreAvailable(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Fetch an entry from the data store.
|
|
40
|
+
*
|
|
41
|
+
* @param key The data store entry's key
|
|
42
|
+
* @returns An object containing the entry's key and value
|
|
43
|
+
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
44
|
+
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
45
|
+
* @throws {DataStoreServiceError} An internal error occurred
|
|
46
|
+
*/
|
|
47
|
+
getEntry(key: string): Promise<Record<string, unknown> | undefined>;
|
|
48
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2
|
|
4
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
7
|
+
import { DynamoDBDocumentClient, GetCommand } from '@aws-sdk/lib-dynamodb';
|
|
8
|
+
import { DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError } from './errors.js';
|
|
9
|
+
import { logMRTError } from '../utils/utils.js';
|
|
10
|
+
export { DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError } from './errors.js';
|
|
11
|
+
/**
|
|
12
|
+
* A class for reading entries from the data store.
|
|
13
|
+
*
|
|
14
|
+
* This class uses a singleton pattern.
|
|
15
|
+
* Use DataStore.getDataStore() to get the singleton instance.
|
|
16
|
+
*/
|
|
17
|
+
export class DataStore {
|
|
18
|
+
_tableName = '';
|
|
19
|
+
_ddb = null;
|
|
20
|
+
static _instance = null;
|
|
21
|
+
/** @internal Test hook: inject a document client for unit tests */
|
|
22
|
+
static _testDocumentClient = null;
|
|
23
|
+
/** @internal Test hook: inject logMRTError for unit tests */
|
|
24
|
+
static _testLogMRTError = null;
|
|
25
|
+
constructor() {
|
|
26
|
+
// Private constructor for singleton; use DataStore.getDataStore() instead.
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get or create a DynamoDB document client (for abstraction of attribute values).
|
|
30
|
+
*
|
|
31
|
+
* @private
|
|
32
|
+
* @returns The DynamoDB document client
|
|
33
|
+
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
34
|
+
*/
|
|
35
|
+
getClient() {
|
|
36
|
+
if (!this.isDataStoreAvailable()) {
|
|
37
|
+
throw new DataStoreUnavailableError('The data store is unavailable.');
|
|
38
|
+
}
|
|
39
|
+
if (DataStore._testDocumentClient) {
|
|
40
|
+
this._tableName = `DataAccessLayer-${process.env.AWS_REGION}`;
|
|
41
|
+
return DataStore._testDocumentClient;
|
|
42
|
+
}
|
|
43
|
+
if (!this._ddb) {
|
|
44
|
+
this._tableName = `DataAccessLayer-${process.env.AWS_REGION}`;
|
|
45
|
+
this._ddb = DynamoDBDocumentClient.from(new DynamoDBClient({
|
|
46
|
+
region: process.env.AWS_REGION,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
return this._ddb;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get or create the singleton DataStore instance.
|
|
53
|
+
*
|
|
54
|
+
* @returns The singleton DataStore instance
|
|
55
|
+
*/
|
|
56
|
+
static getDataStore() {
|
|
57
|
+
if (!DataStore._instance) {
|
|
58
|
+
DataStore._instance = new DataStore();
|
|
59
|
+
}
|
|
60
|
+
return DataStore._instance;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Whether the data store can be used in the current environment.
|
|
64
|
+
*
|
|
65
|
+
* @returns true if the data store is available, false otherwise
|
|
66
|
+
*/
|
|
67
|
+
isDataStoreAvailable() {
|
|
68
|
+
return Boolean(process.env.AWS_REGION && process.env.MOBIFY_PROPERTY_ID && process.env.DEPLOY_TARGET);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Fetch an entry from the data store.
|
|
72
|
+
*
|
|
73
|
+
* @param key The data store entry's key
|
|
74
|
+
* @returns An object containing the entry's key and value
|
|
75
|
+
* @throws {DataStoreUnavailableError} The data store is unavailable
|
|
76
|
+
* @throws {DataStoreNotFoundError} An entry with the given key cannot be found
|
|
77
|
+
* @throws {DataStoreServiceError} An internal error occurred
|
|
78
|
+
*/
|
|
79
|
+
async getEntry(key) {
|
|
80
|
+
if (!this.isDataStoreAvailable()) {
|
|
81
|
+
throw new DataStoreUnavailableError('The data store is unavailable.');
|
|
82
|
+
}
|
|
83
|
+
const ddb = this.getClient();
|
|
84
|
+
let response;
|
|
85
|
+
try {
|
|
86
|
+
response = await ddb.send(new GetCommand({
|
|
87
|
+
TableName: this._tableName,
|
|
88
|
+
Key: {
|
|
89
|
+
projectEnvironment: `${process.env.MOBIFY_PROPERTY_ID} ${process.env.DEPLOY_TARGET}`,
|
|
90
|
+
key,
|
|
91
|
+
},
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
const logFn = DataStore._testLogMRTError ?? logMRTError;
|
|
96
|
+
logFn('data_store', error, { key, tableName: this._tableName });
|
|
97
|
+
throw new DataStoreServiceError('Data store request failed.');
|
|
98
|
+
}
|
|
99
|
+
if (!response.Item?.value) {
|
|
100
|
+
throw new DataStoreNotFoundError(`Data store entry '${key}' not found.`);
|
|
101
|
+
}
|
|
102
|
+
return { key, value: response.Item.value };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=production.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"production.js","sourceRoot":"","sources":["../../../src/data-store/production.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/mrt-utilities",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Middleware and utilities to simulate a deployed Managed Runtime environment",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Salesforce",
|
|
@@ -49,6 +49,16 @@
|
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
51
|
"./data-store": {
|
|
52
|
+
"dev-data-store": {
|
|
53
|
+
"import": {
|
|
54
|
+
"types": "./dist/esm/data-store/development.d.ts",
|
|
55
|
+
"default": "./dist/esm/data-store/development.js"
|
|
56
|
+
},
|
|
57
|
+
"require": {
|
|
58
|
+
"types": "./dist/cjs/data-store/development.d.ts",
|
|
59
|
+
"default": "./dist/cjs/data-store/development.js"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
52
62
|
"import": {
|
|
53
63
|
"types": "./dist/esm/data-store/index.d.ts",
|
|
54
64
|
"default": "./dist/esm/data-store/index.js"
|