Skip to content

Commit 6271e7c

Browse files
committed
Clean up LDClient implementation and add eventsUri option
1 parent a422de4 commit 6271e7c

File tree

5 files changed

+62
-39
lines changed

5 files changed

+62
-39
lines changed

packages/sdk/fastly/__tests__/api/LDClient.test.ts

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@ jest.mock('@launchdarkly/js-sdk-common', () => {
1717
};
1818
});
1919

20-
const mockEventProcessor = internal.EventProcessor as jest.Mock;
20+
let mockEventProcessor = internal.EventProcessor as jest.Mock;
21+
beforeEach(() => {
22+
mockEventProcessor = internal.EventProcessor as jest.Mock;
23+
mockEventProcessor.mockClear();
24+
});
25+
2126
describe('Edge LDClient', () => {
2227
it('uses clientSideID endpoints', async () => {
23-
const client = new LDClient(
24-
'client-side-id',
25-
createBasicPlatform().info,
26-
{
27-
sendEvents: true,
28-
},
29-
'launchdarkly',
30-
);
28+
const client = new LDClient('client-side-id', createBasicPlatform().info, {
29+
sendEvents: true,
30+
eventsBackendName: 'launchdarkly',
31+
});
3132
await client.waitForInitialization({ timeout: 10 });
3233
const passedConfig = mockEventProcessor.mock.calls[0][0];
3334

@@ -43,4 +44,25 @@ describe('Edge LDClient', () => {
4344
},
4445
});
4546
});
47+
it('uses custom eventsUri when specified', async () => {
48+
const client = new LDClient('client-side-id', createBasicPlatform().info, {
49+
sendEvents: true,
50+
eventsBackendName: 'launchdarkly',
51+
eventsUri: 'https://custom-base-uri.launchdarkly.com',
52+
});
53+
await client.waitForInitialization({ timeout: 10 });
54+
const passedConfig = mockEventProcessor.mock.calls[0][0];
55+
56+
expect(passedConfig).toMatchObject({
57+
sendEvents: true,
58+
serviceEndpoints: {
59+
includeAuthorizationHeader: false,
60+
analyticsEventPath: '/events/bulk/client-side-id',
61+
diagnosticEventPath: '/events/diagnostic/client-side-id',
62+
events: 'https://custom-base-uri.launchdarkly.com',
63+
polling: 'https://custom-base-uri.launchdarkly.com',
64+
streaming: 'https://stream.launchdarkly.com',
65+
},
66+
});
67+
});
4668
});

packages/sdk/fastly/src/api/LDClient.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
1-
import { Info, internal, LDClientImpl, LDOptions } from '@launchdarkly/js-server-sdk-common';
1+
import { Info, internal, LDClientImpl } from '@launchdarkly/js-server-sdk-common';
22

33
import EdgePlatform from '../platform';
4+
import { FastlySDKOptions } from '../utils/validateOptions';
45
import createCallbacks from './createCallbacks';
56
import createOptions from './createOptions';
67

8+
export const DEFAULT_EVENTS_BACKEND_NAME = 'launchdarkly';
9+
710
/**
811
* The LaunchDarkly SDK edge client object.
912
*/
1013
export default class LDClient extends LDClientImpl {
1114
// clientSideID is only used to query the edge key-value store and send analytics, not to initialize with LD servers
12-
constructor(clientSideID: string, platformInfo: Info, options: LDOptions, eventsBackend: string) {
13-
const platform = new EdgePlatform(platformInfo, eventsBackend);
15+
constructor(clientSideID: string, platformInfo: Info, options: FastlySDKOptions) {
16+
const { eventsBackendName, ...ldOptions } = options;
17+
const platform = new EdgePlatform(
18+
platformInfo,
19+
eventsBackendName || DEFAULT_EVENTS_BACKEND_NAME,
20+
);
1421
const internalOptions: internal.LDInternalOptions = {
1522
analyticsEventPath: `/events/bulk/${clientSideID}`,
1623
diagnosticEventPath: `/events/diagnostic/${clientSideID}`,
1724
includeAuthorizationHeader: false,
1825
};
1926

20-
const finalOptions = createOptions(options);
27+
const finalOptions = createOptions(ldOptions);
2128

2229
super(clientSideID, platform, finalOptions, createCallbacks(), internalOptions);
2330
}

packages/sdk/fastly/src/api/createOptions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ export const defaultOptions: LDOptions = {
1010

1111
const createOptions = (options: LDOptions) => {
1212
const finalOptions = { ...defaultOptions, ...options };
13+
14+
// The Fastly SDK does not poll LaunchDarkly for updates, so a custom baseUri does not make sense. However, we need
15+
// to set it to something when a custom eventsUri is specified in order to pass validation in sdk-server-common.
16+
if (finalOptions.eventsUri) {
17+
finalOptions.baseUri = finalOptions.eventsUri;
18+
}
1319
finalOptions.logger?.debug(`Using LD options: ${JSON.stringify(finalOptions)}`);
1420
return finalOptions;
1521
};

packages/sdk/fastly/src/index.ts

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
/// <reference types="@fastly/js-compute" />
22
import { KVStore } from 'fastly:kv-store';
33

4-
import { BasicLogger, LDOptions } from '@launchdarkly/js-server-sdk-common';
4+
import { BasicLogger } from '@launchdarkly/js-server-sdk-common';
55

66
import { EdgeFeatureStore, EdgeProvider, LDClient } from './api';
7+
import { DEFAULT_EVENTS_BACKEND_NAME } from './api/LDClient';
78
import createPlatformInfo from './createPlatformInfo';
8-
import validateOptions from './utils/validateOptions';
9-
10-
const DEFAULT_EVENTS_BACKEND_NAME = 'launchdarkly';
11-
12-
export type FastlySDKOptions = LDOptions & {
13-
/**
14-
* The Fastly Backend name to send LaunchDarkly events. Backends are configured using the Fastly service backend configuration. This option can be ignored if the `sendEvents` option is set to `false`. See [Fastly's Backend documentation](https://developer.fastly.com/reference/api/services/backend/) for more information. The default value is `launchdarkly`.
15-
*/
16-
eventsBackendName?: string;
17-
};
9+
import validateOptions, { FastlySDKOptions } from './utils/validateOptions';
1810

1911
export const init = (
2012
sdkKey: string,
@@ -30,19 +22,12 @@ export const init = (
3022
},
3123
};
3224

33-
const { eventsBackendName, ...ldOptions } = options;
34-
3525
const finalOptions = {
3626
featureStore: new EdgeFeatureStore(edgeProvider, sdkKey, 'Fastly', logger),
3727
logger,
38-
...ldOptions,
28+
...options,
3929
};
4030

4131
validateOptions(sdkKey, finalOptions);
42-
return new LDClient(
43-
sdkKey,
44-
createPlatformInfo(),
45-
finalOptions,
46-
eventsBackendName || DEFAULT_EVENTS_BACKEND_NAME,
47-
);
32+
return new LDClient(sdkKey, createPlatformInfo(), finalOptions);
4833
};

packages/sdk/fastly/src/utils/validateOptions.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import { LDOptions as LDOptionsCommon } from '@launchdarkly/js-server-sdk-common';
22

33
/**
4-
* The Launchdarkly Edge SDKs configuration options. Only logger is officially
5-
* supported. sendEvents is unsupported and is only included as a beta
6-
* preview.
4+
* The Launchdarkly Fastly Compute SDK configuration options.
75
*/
8-
export type LDOptions = Pick<LDOptionsCommon, 'logger' | 'sendEvents'>;
6+
export type FastlySDKOptions = Pick<LDOptionsCommon, 'logger' | 'sendEvents' | 'eventsUri'> & {
7+
/**
8+
* The Fastly Backend name to send LaunchDarkly events. Backends are configured using the Fastly service backend configuration. This option can be ignored if the `sendEvents` option is set to `false`. See [Fastly's Backend documentation](https://developer.fastly.com/reference/api/services/backend/) for more information. The default value is `launchdarkly`.
9+
*/
10+
eventsBackendName?: string;
11+
};
912

1013
/**
1114
* The internal options include featureStore because that's how the LDClient
1215
* implementation expects it.
1316
*/
14-
export type LDOptionsInternal = LDOptions & Pick<LDOptionsCommon, 'featureStore'>;
17+
export type LDOptionsInternal = FastlySDKOptions & Pick<LDOptionsCommon, 'featureStore'>;
1518

1619
const validateOptions = (sdkKey: string, options: LDOptionsInternal) => {
17-
const { featureStore, logger, sendEvents, ...rest } = options;
20+
const { eventsBackendName, featureStore, logger, sendEvents, ...rest } = options;
1821
if (!sdkKey) {
1922
throw new Error('You must configure the client with a client key');
2023
}

0 commit comments

Comments
 (0)