Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/mrt-data-store-env-prefix.md
Original file line number Diff line number Diff line change
@@ -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.
8 changes: 4 additions & 4 deletions docs/guide/mrt-utilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
16 changes: 8 additions & 8 deletions packages/mrt-utilities/DEV-DATA-STORE-PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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.
8 changes: 4 additions & 4 deletions packages/mrt-utilities/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
6 changes: 3 additions & 3 deletions packages/mrt-utilities/src/data-store/development.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class DataStore {
}

function readDefaultsFromEnv(): Record<string, Record<string, unknown>> {
const raw = process.env.SFNEXT_DATA_STORE_DEFAULTS;
const raw = process.env.MRT_DATA_STORE_DEFAULTS ?? process.env.SFNEXT_DATA_STORE_DEFAULTS;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wanna leave a comment here to explain why there is SFNEXT_DATA_STORE_DEFAULTS in the code base?

if (!raw) {
return {};
}
Expand All @@ -86,14 +86,14 @@ function readDefaultsFromEnv(): Record<string, Record<string, unknown>> {
return parsed as Record<string, Record<string, unknown>>;
}
} 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;
}
Expand Down
51 changes: 41 additions & 10 deletions packages/mrt-utilities/test/data-store-development.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'},
});

Expand All @@ -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'},
});

Expand All @@ -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();

Expand All @@ -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();
Expand All @@ -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');
Expand All @@ -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.');
});
});
Loading