Skip to content

Commit 241c386

Browse files
committed
fix: Added dangerouslyAllowBrowser
1 parent 336ed4c commit 241c386

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

src/AI21.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
import * as Types from './types';
22
import { AI21EnvConfig } from './EnvConfig';
3-
import { MissingAPIKeyError } from './errors';
3+
import { AI21Error, MissingAPIKeyError } from './errors';
44
import { Chat } from './resources/chat';
55
import { APIClient } from './APIClient';
66
import { Headers } from './types';
7+
import * as Runtime from './runtime';
78
import { ConversationalRag } from './resources/rag/conversationalRag';
89

9-
export type ClientOptions = {
10+
export interface ClientOptions {
1011
baseURL?: string;
1112
apiKey?: string;
1213
maxRetries?: number;
1314
timeout?: number;
1415
via?: string | null;
1516
defaultHeaders?: Headers;
17+
/**
18+
* By default, using this library on the client side is prohibited to prevent exposing your secret API credentials to potential attackers.
19+
* Only enable this option by setting it to `true` if you fully understand the risks and have implemented appropriate security measures.
20+
*/
1621
dangerouslyAllowBrowser?: boolean;
17-
};
22+
}
1823

1924
export class AI21 extends APIClient {
2025
protected options: ClientOptions;
@@ -28,7 +33,7 @@ export class AI21 extends APIClient {
2833
maxRetries,
2934
via,
3035
...opts
31-
}: ClientOptions) {
36+
}: ClientOptions = {}) {
3237
const options: ClientOptions = {
3338
apiKey,
3439
baseURL,
@@ -38,6 +43,12 @@ export class AI21 extends APIClient {
3843
...opts,
3944
};
4045

46+
if (!options.dangerouslyAllowBrowser && Runtime.isBrowser) {
47+
throw new AI21Error(
48+
'AI21 client is not supported in the browser by default due to potential API key exposure. Use `dangerouslyAllowBrowser` option to `true` to override it.',
49+
);
50+
}
51+
4152
super({
4253
baseURL,
4354
timeout,

tests/AI21.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { AI21, ClientOptions } from '../src/AI21';
2-
import { MissingAPIKeyError } from '../src/errors';
2+
import { AI21Error, MissingAPIKeyError } from '../src/errors';
33
import { Chat } from '../src/resources/chat';
44

55
describe('AI21', () => {
@@ -8,11 +8,12 @@ describe('AI21', () => {
88
apiKey: mockApiKey,
99
baseURL: 'https://some-url/v1',
1010
timeout: 600,
11+
dangerouslyAllowBrowser: true, // Test env is in the browser and we need to allow it
1112
};
1213

1314
describe('constructor', () => {
1415
it('should initialize with default options', () => {
15-
const client = new AI21({ apiKey: mockApiKey });
16+
const client = new AI21({ apiKey: mockApiKey, dangerouslyAllowBrowser: true });
1617
expect(client).toBeInstanceOf(AI21);
1718
expect(client.chat).toBeInstanceOf(Chat);
1819
});
@@ -21,6 +22,10 @@ describe('AI21', () => {
2122
expect(() => new AI21({apiKey: undefined} as ClientOptions)).toThrow(MissingAPIKeyError);
2223
});
2324

25+
it('should throw AI21Error when browser is detected without dangerouslyAllowBrowser option', () => {
26+
expect(() => new AI21({...defaultOptions, dangerouslyAllowBrowser: false})).toThrow(AI21Error);
27+
});
28+
2429
it('should initialize with custom options', () => {
2530
const customOptions: ClientOptions = {
2631
...defaultOptions,

0 commit comments

Comments
 (0)