Skip to content
Open
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
15 changes: 15 additions & 0 deletions .github/workflows/javascript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ jobs:
npm install
npm run test-typescript

commonjs_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: '18'
cache-dependency-path: ./package-lock.json
cache: 'npm'
- name: Run CommonJS example
run: |
npm install
npm run test-commonjs

integration_tests:
uses: optimizely/javascript-sdk/.github/workflows/integration_test.yml@master
secrets:
Expand Down
84 changes: 84 additions & 0 deletions examples/node-commonjs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Copyright 2026, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const fs = require('fs');
const path = require('path');

const {
createInstance,
createStaticProjectConfigManager,
createForwardingEventProcessor,
createLogger,
createErrorNotifier,
INFO,
} = require('@optimizely/optimizely-sdk');

const datafilePath = path.join(__dirname, '..', 'shared', 'datafile.json');
const testDatafile = fs.readFileSync(datafilePath, 'utf8');

const TIMEOUT_MS = 10000;

async function testCommonJsRequire() {
let resolveUuid;
const uuidPromise = new Promise((resolve, reject) => {
resolveUuid = resolve;
setTimeout(() => reject(new Error('Timed out waiting for event dispatch')), TIMEOUT_MS);
});

const dispatcher = {
dispatchEvent(logEvent) {
const uuid = logEvent.params.visitors[0].snapshots[0].events[0].uuid;
console.log(`Dispatched event with uuid: ${uuid}`);

if (typeof uuid === 'string' && uuid.length > 0) {
resolveUuid(uuid);
}

return Promise.resolve({});
},
};

const configManager = createStaticProjectConfigManager({
datafile: testDatafile,
});

const eventProcessor = createForwardingEventProcessor(dispatcher);

const client = createInstance({
projectConfigManager: configManager,
eventProcessor: eventProcessor,
});

await client.onReady();

const userContext = client.createUserContext('test_user', { age: 22 });
userContext.decide('flag_1');

const uuid = await uuidPromise;
console.log(`Test passed: event contained valid uuid "${uuid}"`);

client.close();
}

testCommonJsRequire()
.then(() => {
console.log('\n=== CommonJS example completed successfully! ===\n');
process.exit(0);
})
.catch((error) => {
console.error('Test failed:', error);
process.exit(1);
});
9 changes: 9 additions & 0 deletions examples/node-commonjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "optimizely-sdk-commonjs-example",
"version": "1.0.0",
"private": true,
"description": "CommonJS example for Optimizely SDK - verifies CJS compatibility",
"scripts": {
"start": "node index.js"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,9 @@
* Runs at http://localhost:PORT
*/

import http from 'http';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const http = require('http');
const fs = require('fs');
const path = require('path');

const PORT = 8910;
const datafilePath = path.join(__dirname, 'datafile.json');
Expand Down
File renamed without changes.
1 change: 0 additions & 1 deletion examples/typescript/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ node_modules/
dist/
*.log
.DS_Store
package-lock.json
2 changes: 0 additions & 2 deletions examples/typescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ This example demonstrates all factory functions from the Optimizely SDK, includi
## Files

- `src/index.ts` - Main example demonstrating all SDK factory functions
- `datafile.json` - Test datafile with Optimizely configuration
- `datafile-server.js` - Simple HTTP server for testing polling datafile manager

## Running the Example

Expand Down
41 changes: 41 additions & 0 deletions examples/typescript/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/typescript/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import { fileURLToPath } from 'url';
const __filename: string = fileURLToPath(import.meta.url);
const __dirname: string = dirname(__filename);

const datafilePath: string = path.join(__dirname, '..', 'datafile.json');
const datafilePath: string = path.join(__dirname, '..', '..', 'shared', 'datafile.json');
const testDatafile: string = fs.readFileSync(datafilePath, 'utf8');

async function testStaticConfigSetup(): Promise<void> {
Expand Down
22 changes: 22 additions & 0 deletions lib/tests/uuid_cjs_shim.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* CJS require hook that intercepts `require('uuid')` to provide a CJS-compatible
* shim. Needed because uuid v13+ is ESM-only and cannot be loaded via require().
* Uses Node's built-in crypto.randomUUID() which produces identical RFC 4122 v4 UUIDs.
*/
const Module = require('module'); // eslint-disable-line @typescript-eslint/no-var-requires
const crypto = require('crypto'); // eslint-disable-line @typescript-eslint/no-var-requires

const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;

const uuidShim = {
v4: () => crypto.randomUUID(),
validate: (str) => typeof str === 'string' && UUID_REGEX.test(str),
};

const originalLoad = Module._load;
Module._load = function (request, parent, isMain) {
if (request === 'uuid') {
return uuidShim;
}
return originalLoad.call(this, request, parent, isMain);
};
Loading
Loading