Skip to content

Commit bab593c

Browse files
authored
feat: support cjs and esm for cloudflare and edge common (#87)
* chore: add example cloudflare app and skeletal esbuild config * chore: add example app. TODO: fix tests in example app and esbuild config issue. * fix: example app linting and unit tests. Rollback to commonjs output for now * fix: build esm and cjs outputs. TODO: fix package.json imports in cloudfare packageInfo. * feat: added common cjs esm build script. Fixed broken example tests. Cleaned up description and removed esbuild config. * chore: improved example readme. * fix: added prerequisites to readme. include kv_id instructions in readme. removed unused app.js file. --------- Co-authored-by: Yusinto Ngadiman <[email protected]>
1 parent 0578190 commit bab593c

File tree

17 files changed

+429
-11
lines changed

17 files changed

+429
-11
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ coverage/
77
**/tmp_test/
88
docs/
99
.pnp.*
10-
.yarn/*
10+
**/.yarn/*
1111
.dev*
1212
.vscode/launch.json
1313
.idea

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"packages/shared/sdk-server",
66
"packages/shared/sdk-server-edge",
77
"packages/sdk/server-node",
8-
"packages/sdk/cloudflare"
8+
"packages/sdk/cloudflare",
9+
"packages/sdk/cloudflare/example"
910
],
1011
"private": true,
1112
"scripts": {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Example test app for Cloudflare LaunchDarkly SDK
2+
3+
This is an example test app to showcase the usage of the Cloudflare LaunchDarkly
4+
SDK. This app was created with wrangler v2.
5+
6+
## Prerequisites
7+
8+
A node environment of version 16 and yarn are required to develop in this repository.
9+
You will also need the wrangler cli installed and a Cloudflare account to setup
10+
the test data required by this example. See the [wrangler docs](https://developers.cloudflare.com/workers/wrangler/commands/#login)
11+
on how to login to your Cloudflare account. Make sure you are logged in before
12+
attempting to follow the usage instructions below.
13+
14+
## Usage
15+
16+
1. At the root of the js-core repo:
17+
18+
```shell
19+
yarn && yarn build
20+
```
21+
22+
2. Then back in this example, replace `YOUR_KV_ID` and `YOUR_PREVIEW_KV_ID` in [wrangler.toml](https://github.com/launchdarkly/js-core/blob/main/packages/sdk/cloudflare/example/wrangler.toml) with your account values:
23+
24+
```toml
25+
kv_namespaces = [{ binding = "LD_KV", id = "YOUR_KV_ID", preview_id = "YOUR_PREVIEW_KV_ID" }]
26+
```
27+
28+
3. Insert test data to the preview environment:
29+
30+
```shell
31+
# The Cloudflare SDK automatically adds the "LD-Env-" prefix to your sdk key
32+
npx wrangler kv:key put --binding=LD_KV "LD-Env-test-sdk-key" --path ./src/testData.json --preview
33+
```
34+
35+
4. View that test data to ensure it's present:
36+
37+
```shell
38+
npx wrangler kv:key get --binding=LD_KV "LD-Env-test-sdk-key" --preview
39+
```
40+
41+
5. Finally:
42+
43+
```shell
44+
yarn start
45+
```
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import path from 'path';
2+
import { fileURLToPath } from 'url';
3+
import { build } from 'esbuild';
4+
5+
const __filename = fileURLToPath(import.meta.url);
6+
const __dirname = path.dirname(__filename);
7+
8+
try {
9+
await build({
10+
bundle: true,
11+
sourcemap: true,
12+
format: 'esm',
13+
target: 'esnext',
14+
external: ['__STATIC_CONTENT_MANIFEST'],
15+
conditions: ['worker', 'browser'],
16+
entryPoints: [path.join(__dirname, 'src', 'index.ts')],
17+
outdir: path.join(__dirname, 'dist'),
18+
outExtension: { '.js': '.mjs' },
19+
platform: 'node',
20+
});
21+
} catch {
22+
process.exitCode = 1;
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export default {
2+
transform: { '^.+\\.ts?$': 'ts-jest' },
3+
testMatch: ['**/*.test.ts?(x)'],
4+
testPathIgnorePatterns: ['node_modules', 'dist'],
5+
modulePathIgnorePatterns: ['dist'],
6+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
7+
testEnvironment: 'miniflare',
8+
testEnvironmentOptions: {
9+
// Miniflare doesn't yet support the `main` field in `wrangler.toml` so we
10+
// need to explicitly tell it where our built worker is. We also need to
11+
// explicitly mark it as an ES module.
12+
scriptPath: 'dist/index.mjs',
13+
modules: true,
14+
},
15+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "example",
3+
"version": "0.0.0",
4+
"type": "module",
5+
"module": "./dist/index.mjs",
6+
"packageManager": "[email protected]",
7+
"dependencies": {
8+
"@launchdarkly/cloudflare-server-sdk": "0.0.1"
9+
},
10+
"devDependencies": {
11+
"@cloudflare/workers-types": "^4.20230321.0",
12+
"@types/jest": "^27.5.1",
13+
"esbuild": "^0.14.41",
14+
"jest": "^28.1.0",
15+
"jest-environment-miniflare": "^2.5.0",
16+
"miniflare": "^2.5.0",
17+
"prettier": "^2.6.2",
18+
"ts-jest": "^28.0.3",
19+
"typescript": "^5.0.3",
20+
"wrangler": "2.13.0"
21+
},
22+
"scripts": {
23+
"build": "node build.js",
24+
"start": "wrangler dev",
25+
"deploy": "wrangler publish",
26+
"test": "yarn build && node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js"
27+
}
28+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
interface Bindings {
2+
LD_KV: KVNamespace;
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
declare global {
2+
function getMiniflareBindings(): Bindings;
3+
}
4+
5+
export {};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import app from './index';
2+
import testData from './testData.json';
3+
4+
test('variation true', async () => {
5+
// arrange
6+
const env = getMiniflareBindings();
7+
const { LD_KV } = env;
8+
await LD_KV.put('LD-Env-test-sdk-key', JSON.stringify(testData));
9+
10+
// act
11+
const res = await app.fetch(new Request('http://localhost'), env);
12+
13+
// assert
14+
expect(await res.text()).toContain('testFlag1: true');
15+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { init as initLD } from '@launchdarkly/cloudflare-server-sdk';
2+
3+
export default {
4+
async fetch(request: Request, env: Bindings): Promise<Response> {
5+
const sdkKey = 'test-sdk-key';
6+
const flagKey = 'testFlag1';
7+
const context = { kind: 'user', key: 'test-user-key-1' };
8+
9+
// start using ld
10+
const client = initLD(sdkKey, env.LD_KV);
11+
await client.waitForInitialization();
12+
const flag = await client.variation(flagKey, context, false);
13+
const flagDetail = await client.variationDetail(flagKey, context, false);
14+
const allFlags = await client.allFlagsState(context);
15+
16+
const resp = `${flagKey}: ${flag}, detail: ${JSON.stringify(
17+
flagDetail
18+
)}, allFlags: ${JSON.stringify(allFlags)}`;
19+
20+
// eslint-disable-next-line
21+
console.log(`------------- ${resp}`);
22+
return new Response(`${resp}`);
23+
},
24+
};

0 commit comments

Comments
 (0)