diff --git a/.changeset/mrt-data-store-env-prefix.md b/.changeset/mrt-data-store-env-prefix.md new file mode 100644 index 00000000..136819cc --- /dev/null +++ b/.changeset/mrt-data-store-env-prefix.md @@ -0,0 +1,5 @@ +--- +'@salesforce/mrt-utilities': patch +--- + +Rename development data-store environment variables from `SFNEXT_DATA_STORE_DEFAULTS`/`SFNEXT_DATA_STORE_WARN_ON_MISSING` to `MRT_DATA_STORE_DEFAULTS`/`MRT_DATA_STORE_WARN_ON_MISSING` and update docs/examples accordingly. diff --git a/docs/guide/mrt-utilities.md b/docs/guide/mrt-utilities.md index 9d4540b3..8bd197ec 100644 --- a/docs/guide/mrt-utilities.md +++ b/docs/guide/mrt-utilities.md @@ -168,14 +168,14 @@ const entry = await store.getEntry('custom-global-preferences'); Provide local data-store values through environment variables: -- `SFNEXT_DATA_STORE_DEFAULTS`: JSON map of data-store keys to object values -- `SFNEXT_DATA_STORE_WARN_ON_MISSING`: set to `false` to suppress missing-key warnings +- `MRT_DATA_STORE_DEFAULTS`: JSON map of data-store keys to object values +- `MRT_DATA_STORE_WARN_ON_MISSING`: set to `false` to suppress missing-key warnings Example: ```bash -export SFNEXT_DATA_STORE_DEFAULTS='{"custom-global-preferences":{"featureFlag":true}}' -export SFNEXT_DATA_STORE_WARN_ON_MISSING=true +export MRT_DATA_STORE_DEFAULTS='{"custom-global-preferences":{"featureFlag":true}}' +export MRT_DATA_STORE_WARN_ON_MISSING=true ``` The development pseudo store keeps production parity for missing keys and throws `DataStoreNotFoundError` when a key is not found. diff --git a/packages/mrt-utilities/DEV-DATA-STORE-PLAN.md b/packages/mrt-utilities/DEV-DATA-STORE-PLAN.md index 6ab4107b..8df2eb7e 100644 --- a/packages/mrt-utilities/DEV-DATA-STORE-PLAN.md +++ b/packages/mrt-utilities/DEV-DATA-STORE-PLAN.md @@ -12,8 +12,8 @@ This behavior should be activated through the existing package export condition: The pseudo local implementation must read default entry values from environment variables (as implied by the provided prototype): -- `SFNEXT_DATA_STORE_DEFAULTS` (JSON object map of key -> value object) -- `SFNEXT_DATA_STORE_WARN_ON_MISSING` (`"false"` disables warnings; default is warning enabled) +- `MRT_DATA_STORE_DEFAULTS` (JSON object map of key -> value object) +- `MRT_DATA_STORE_WARN_ON_MISSING` (`"false"` disables warnings; default is warning enabled) ## Current State @@ -61,7 +61,7 @@ Use conditional exports to load the development implementation for local dev fro ## 4) Environment variable behavior in dev store -### `SFNEXT_DATA_STORE_DEFAULTS` +### `MRT_DATA_STORE_DEFAULTS` - Parse as JSON object. - Expected shape: @@ -70,7 +70,7 @@ Use conditional exports to load the development implementation for local dev fro - fall back to empty defaults - warn once with clear message -### `SFNEXT_DATA_STORE_WARN_ON_MISSING` +### `MRT_DATA_STORE_WARN_ON_MISSING` - If unset: warnings enabled - If set to `"false"` (case-insensitive): disable missing-key warnings @@ -91,10 +91,10 @@ Add/adjust tests to cover both modes: - **Production tests** - Keep current behavior assertions unchanged. - **Development tests** - - Reads defaults from `SFNEXT_DATA_STORE_DEFAULTS` + - Reads defaults from `MRT_DATA_STORE_DEFAULTS` - Throws `DataStoreNotFoundError` when key is absent (default behavior) - Warns once per missing key when warnings enabled - - Does not warn when `SFNEXT_DATA_STORE_WARN_ON_MISSING=false` + - Does not warn when `MRT_DATA_STORE_WARN_ON_MISSING=false` - Handles invalid JSON safely - (If lenient mode is added) returns `{}` only when explicitly enabled @@ -128,8 +128,8 @@ Update `packages/mrt-utilities/README.md` (or docs page if preferred) with: ## Acceptance Criteria - Local development using `--conditions development` no longer fails due to missing DynamoDB/MRT runtime vars. -- Dev data-store entries are sourced from `SFNEXT_DATA_STORE_DEFAULTS`. -- Missing-key behavior is predictable and configurable via `SFNEXT_DATA_STORE_WARN_ON_MISSING`. +- Dev data-store entries are sourced from `MRT_DATA_STORE_DEFAULTS`. +- Missing-key behavior is predictable and configurable via `MRT_DATA_STORE_WARN_ON_MISSING`. - Production behavior and API remain backward-compatible. - No breaking public interface changes: existing import paths, exported symbols, and type surface for `@salesforce/mrt-utilities` and `@salesforce/mrt-utilities/data-store` remain intact (except correcting the `development` export target to built `dist` output). - Default dev missing-key semantics match production (`DataStoreNotFoundError`), with no implicit `{}` fallback. diff --git a/packages/mrt-utilities/README.md b/packages/mrt-utilities/README.md index d03356a6..d927da7f 100644 --- a/packages/mrt-utilities/README.md +++ b/packages/mrt-utilities/README.md @@ -65,14 +65,14 @@ const entry = await store.getEntry('custom-global-preferences'); Configure local values with environment variables: -- `SFNEXT_DATA_STORE_DEFAULTS`: JSON map of key to object value -- `SFNEXT_DATA_STORE_WARN_ON_MISSING`: set to `false` to suppress missing-key warnings +- `MRT_DATA_STORE_DEFAULTS`: JSON map of key to object value +- `MRT_DATA_STORE_WARN_ON_MISSING`: set to `false` to suppress missing-key warnings Example: ```bash -export SFNEXT_DATA_STORE_DEFAULTS='{"custom-global-preferences":{"featureFlag":true}}' -export SFNEXT_DATA_STORE_WARN_ON_MISSING=true +export MRT_DATA_STORE_DEFAULTS='{"custom-global-preferences":{"featureFlag":true}}' +export MRT_DATA_STORE_WARN_ON_MISSING=true ``` By default, missing keys still throw `DataStoreNotFoundError` in development (matching production semantics). diff --git a/packages/mrt-utilities/src/data-store/development.ts b/packages/mrt-utilities/src/data-store/development.ts index 0d8032e3..50f0061e 100644 --- a/packages/mrt-utilities/src/data-store/development.ts +++ b/packages/mrt-utilities/src/data-store/development.ts @@ -75,7 +75,7 @@ export class DataStore { } function readDefaultsFromEnv(): Record> { - const raw = process.env.SFNEXT_DATA_STORE_DEFAULTS; + const raw = process.env.MRT_DATA_STORE_DEFAULTS ?? process.env.SFNEXT_DATA_STORE_DEFAULTS; if (!raw) { return {}; } @@ -86,14 +86,14 @@ function readDefaultsFromEnv(): Record> { return parsed as Record>; } } catch (error) { - console.warn('Failed to parse SFNEXT_DATA_STORE_DEFAULTS JSON.', error); + console.warn('Failed to parse MRT_DATA_STORE_DEFAULTS JSON.', error); } return {}; } function readWarnOnMissingFromEnv(): boolean { - const raw = process.env.SFNEXT_DATA_STORE_WARN_ON_MISSING; + const raw = process.env.MRT_DATA_STORE_WARN_ON_MISSING ?? process.env.SFNEXT_DATA_STORE_WARN_ON_MISSING; if (!raw) { return true; } diff --git a/packages/mrt-utilities/test/data-store-development.test.ts b/packages/mrt-utilities/test/data-store-development.test.ts index a7e87543..dfd59942 100644 --- a/packages/mrt-utilities/test/data-store-development.test.ts +++ b/packages/mrt-utilities/test/data-store-development.test.ts @@ -28,8 +28,8 @@ describe('DataStore (development)', () => { expect(store.isDataStoreAvailable()).to.equal(true); }); - it('returns entries from SFNEXT_DATA_STORE_DEFAULTS', async () => { - process.env.SFNEXT_DATA_STORE_DEFAULTS = JSON.stringify({ + it('returns entries from MRT_DATA_STORE_DEFAULTS', async () => { + process.env.MRT_DATA_STORE_DEFAULTS = JSON.stringify({ 'my-key': {theme: 'dark'}, }); @@ -42,8 +42,22 @@ describe('DataStore (development)', () => { }); }); - it('throws DataStoreNotFoundError for missing keys by default', async () => { + it('falls back to SFNEXT_DATA_STORE_DEFAULTS for backward compatibility', async () => { process.env.SFNEXT_DATA_STORE_DEFAULTS = JSON.stringify({ + 'my-key': {theme: 'legacy'}, + }); + + const store = DataStore.getDataStore(); + const result = await store.getEntry('my-key'); + + expect(result).to.deep.equal({ + key: 'my-key', + value: {theme: 'legacy'}, + }); + }); + + it('throws DataStoreNotFoundError for missing keys by default', async () => { + process.env.MRT_DATA_STORE_DEFAULTS = JSON.stringify({ 'other-key': {theme: 'dark'}, }); @@ -59,7 +73,7 @@ describe('DataStore (development)', () => { }); it('warns once per missing key when warnings are enabled', async () => { - process.env.SFNEXT_DATA_STORE_DEFAULTS = '{}'; + process.env.MRT_DATA_STORE_DEFAULTS = '{}'; const warnStub = sinon.stub(console, 'warn'); const store = DataStore.getDataStore(); @@ -75,9 +89,9 @@ describe('DataStore (development)', () => { expect(warnStub.firstCall.firstArg).to.include("Local data-store provider did not find 'my-key'"); }); - it('does not warn for missing keys when SFNEXT_DATA_STORE_WARN_ON_MISSING=false', async () => { - process.env.SFNEXT_DATA_STORE_DEFAULTS = '{}'; - process.env.SFNEXT_DATA_STORE_WARN_ON_MISSING = 'false'; + it('does not warn for missing keys when MRT_DATA_STORE_WARN_ON_MISSING=false', async () => { + process.env.MRT_DATA_STORE_DEFAULTS = '{}'; + process.env.MRT_DATA_STORE_WARN_ON_MISSING = 'false'; const warnStub = sinon.stub(console, 'warn'); const store = DataStore.getDataStore(); @@ -92,8 +106,8 @@ describe('DataStore (development)', () => { expect(warnStub.called).to.equal(false); }); - it('warns when SFNEXT_DATA_STORE_DEFAULTS is invalid JSON', async () => { - process.env.SFNEXT_DATA_STORE_DEFAULTS = '{"my-key": '; + it('falls back to SFNEXT_DATA_STORE_WARN_ON_MISSING for backward compatibility', async () => { + process.env.MRT_DATA_STORE_DEFAULTS = '{}'; process.env.SFNEXT_DATA_STORE_WARN_ON_MISSING = 'false'; const warnStub = sinon.stub(console, 'warn'); @@ -106,7 +120,24 @@ describe('DataStore (development)', () => { expect(error).to.be.an.instanceOf(DataStoreNotFoundError); } + expect(warnStub.called).to.equal(false); + }); + + it('warns when MRT_DATA_STORE_DEFAULTS is invalid JSON', async () => { + process.env.MRT_DATA_STORE_DEFAULTS = '{"my-key": '; + process.env.MRT_DATA_STORE_WARN_ON_MISSING = 'false'; + + const warnStub = sinon.stub(console, 'warn'); + const store = DataStore.getDataStore(); + + try { + await store.getEntry('my-key'); + expect.fail('should have thrown'); + } catch (error) { + expect(error).to.be.an.instanceOf(DataStoreNotFoundError); + } + expect(warnStub.calledOnce).to.equal(true); - expect(warnStub.firstCall.firstArg).to.equal('Failed to parse SFNEXT_DATA_STORE_DEFAULTS JSON.'); + expect(warnStub.firstCall.firstArg).to.equal('Failed to parse MRT_DATA_STORE_DEFAULTS JSON.'); }); });