librechat-data-provider 0.8.402 → 0.8.403

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/dist/types/accessPermissions.d.ts +744 -0
  2. package/dist/types/actions.d.ts +118 -0
  3. package/dist/types/api-endpoints.d.ts +149 -0
  4. package/dist/types/artifacts.d.ts +97 -0
  5. package/dist/types/azure.d.ts +22 -0
  6. package/dist/types/bedrock.d.ts +1220 -0
  7. package/dist/types/config.d.ts +13916 -0
  8. package/dist/types/config.spec.d.ts +1 -0
  9. package/dist/types/createPayload.d.ts +5 -0
  10. package/dist/types/data-service.d.ts +284 -0
  11. package/dist/types/feedback.d.ts +36 -0
  12. package/dist/types/file-config.d.ts +263 -0
  13. package/dist/types/file-config.spec.d.ts +1 -0
  14. package/dist/types/generate.d.ts +597 -0
  15. package/dist/types/headers-helpers.d.ts +2 -0
  16. package/{src/index.ts → dist/types/index.d.ts} +0 -15
  17. package/dist/types/keys.d.ts +92 -0
  18. package/dist/types/mcp.d.ts +2760 -0
  19. package/dist/types/messages.d.ts +10 -0
  20. package/dist/types/models.d.ts +1677 -0
  21. package/dist/types/parameterSettings.d.ts +69 -0
  22. package/dist/types/parsers.d.ts +110 -0
  23. package/dist/types/permissions.d.ts +522 -0
  24. package/dist/types/react-query/react-query-service.d.ts +85 -0
  25. package/dist/types/request.d.ts +25 -0
  26. package/dist/types/roles.d.ts +554 -0
  27. package/dist/types/roles.spec.d.ts +1 -0
  28. package/dist/types/schemas.d.ts +4815 -0
  29. package/dist/types/schemas.spec.d.ts +1 -0
  30. package/dist/types/types/agents.d.ts +433 -0
  31. package/dist/types/types/assistants.d.ts +547 -0
  32. package/dist/types/types/files.d.ts +172 -0
  33. package/dist/types/types/graph.d.ts +135 -0
  34. package/{src/types/mcpServers.ts → dist/types/types/mcpServers.d.ts} +12 -18
  35. package/dist/types/types/mutations.d.ts +209 -0
  36. package/dist/types/types/queries.d.ts +169 -0
  37. package/dist/types/types/runs.d.ts +36 -0
  38. package/dist/types/types/web.d.ts +520 -0
  39. package/dist/types/types.d.ts +503 -0
  40. package/dist/types/utils.d.ts +12 -0
  41. package/package.json +4 -1
  42. package/babel.config.js +0 -4
  43. package/check_updates.sh +0 -52
  44. package/jest.config.js +0 -19
  45. package/react-query/package-lock.json +0 -292
  46. package/react-query/package.json +0 -10
  47. package/rollup.config.js +0 -74
  48. package/server-rollup.config.js +0 -40
  49. package/specs/actions.spec.ts +0 -2533
  50. package/specs/api-endpoints-subdir.spec.ts +0 -140
  51. package/specs/api-endpoints.spec.ts +0 -74
  52. package/specs/azure.spec.ts +0 -844
  53. package/specs/bedrock.spec.ts +0 -862
  54. package/specs/filetypes.spec.ts +0 -175
  55. package/specs/generate.spec.ts +0 -770
  56. package/specs/headers-helpers.spec.ts +0 -24
  57. package/specs/mcp.spec.ts +0 -147
  58. package/specs/openapiSpecs.ts +0 -524
  59. package/specs/parsers.spec.ts +0 -601
  60. package/specs/request-interceptor.spec.ts +0 -304
  61. package/specs/utils.spec.ts +0 -196
  62. package/src/accessPermissions.ts +0 -346
  63. package/src/actions.ts +0 -813
  64. package/src/api-endpoints.ts +0 -440
  65. package/src/artifacts.ts +0 -3104
  66. package/src/azure.ts +0 -328
  67. package/src/bedrock.ts +0 -425
  68. package/src/config.spec.ts +0 -315
  69. package/src/config.ts +0 -2006
  70. package/src/createPayload.ts +0 -46
  71. package/src/data-service.ts +0 -1087
  72. package/src/feedback.ts +0 -141
  73. package/src/file-config.spec.ts +0 -1248
  74. package/src/file-config.ts +0 -764
  75. package/src/generate.ts +0 -634
  76. package/src/headers-helpers.ts +0 -13
  77. package/src/keys.ts +0 -99
  78. package/src/mcp.ts +0 -271
  79. package/src/messages.ts +0 -50
  80. package/src/models.ts +0 -69
  81. package/src/parameterSettings.ts +0 -1111
  82. package/src/parsers.ts +0 -563
  83. package/src/permissions.ts +0 -188
  84. package/src/react-query/react-query-service.ts +0 -566
  85. package/src/request.ts +0 -171
  86. package/src/roles.spec.ts +0 -132
  87. package/src/roles.ts +0 -225
  88. package/src/schemas.spec.ts +0 -355
  89. package/src/schemas.ts +0 -1234
  90. package/src/types/agents.ts +0 -470
  91. package/src/types/assistants.ts +0 -654
  92. package/src/types/files.ts +0 -191
  93. package/src/types/graph.ts +0 -145
  94. package/src/types/mutations.ts +0 -422
  95. package/src/types/queries.ts +0 -208
  96. package/src/types/runs.ts +0 -40
  97. package/src/types/web.ts +0 -588
  98. package/src/types.ts +0 -676
  99. package/src/utils.ts +0 -85
  100. package/tsconfig.json +0 -28
  101. package/tsconfig.spec.json +0 -10
  102. /package/{src/react-query/index.ts → dist/types/react-query/index.d.ts} +0 -0
  103. /package/{src/types/index.ts → dist/types/types/index.d.ts} +0 -0
@@ -1,304 +0,0 @@
1
- /**
2
- * @jest-environment @happy-dom/jest-environment
3
- */
4
- import axios from 'axios';
5
- import { setTokenHeader } from '../src/headers-helpers';
6
-
7
- /**
8
- * The response interceptor in request.ts registers at import time when
9
- * `typeof window !== 'undefined'` (happy-dom provides window).
10
- *
11
- * We use axios's built-in request adapter mock to avoid real HTTP calls,
12
- * and verify the interceptor's behavior by observing whether a 401 triggers
13
- * a refresh POST or is immediately rejected.
14
- *
15
- * happy-dom is used instead of jsdom because it allows overriding
16
- * window.location via Object.defineProperty, which jsdom 26+ blocks.
17
- */
18
-
19
- const mockAdapter = jest.fn();
20
- let originalAdapter: typeof axios.defaults.adapter;
21
- let savedLocation: Location;
22
-
23
- beforeAll(async () => {
24
- originalAdapter = axios.defaults.adapter;
25
- axios.defaults.adapter = mockAdapter;
26
-
27
- await import('../src/request');
28
- });
29
-
30
- beforeEach(() => {
31
- mockAdapter.mockReset();
32
- savedLocation = window.location;
33
- });
34
-
35
- afterAll(() => {
36
- axios.defaults.adapter = originalAdapter;
37
- });
38
-
39
- afterEach(() => {
40
- delete axios.defaults.headers.common['Authorization'];
41
- Object.defineProperty(window, 'location', {
42
- value: savedLocation,
43
- writable: true,
44
- configurable: true,
45
- });
46
- });
47
-
48
- function setWindowLocation(overrides: Partial<Location>) {
49
- Object.defineProperty(window, 'location', {
50
- value: { ...window.location, ...overrides },
51
- writable: true,
52
- configurable: true,
53
- });
54
- }
55
-
56
- describe('axios 401 interceptor — Authorization header guard', () => {
57
- it('skips refresh and rejects when Authorization header is cleared', async () => {
58
- expect.assertions(1);
59
- setTokenHeader(undefined);
60
-
61
- mockAdapter.mockRejectedValueOnce({
62
- response: { status: 401 },
63
- config: { url: '/api/messages', headers: {} },
64
- });
65
-
66
- try {
67
- await axios.get('/api/messages');
68
- } catch {
69
- // expected rejection
70
- }
71
-
72
- expect(mockAdapter).toHaveBeenCalledTimes(1);
73
- });
74
-
75
- it('attempts refresh on shared link page even without Authorization header', async () => {
76
- expect.assertions(2);
77
- setTokenHeader(undefined);
78
-
79
- setWindowLocation({
80
- href: 'http://localhost/share/abc123',
81
- pathname: '/share/abc123',
82
- search: '',
83
- hash: '',
84
- } as Partial<Location>);
85
-
86
- mockAdapter.mockRejectedValueOnce({
87
- response: { status: 401 },
88
- config: { url: '/api/share/abc123', headers: {} },
89
- });
90
-
91
- mockAdapter.mockResolvedValueOnce({
92
- data: { token: 'new-token' },
93
- status: 200,
94
- headers: {},
95
- config: {},
96
- });
97
-
98
- mockAdapter.mockResolvedValueOnce({
99
- data: { sharedLink: {} },
100
- status: 200,
101
- headers: {},
102
- config: {},
103
- });
104
-
105
- try {
106
- await axios.get('/api/share/abc123');
107
- } catch {
108
- // may reject depending on exact flow
109
- }
110
-
111
- expect(mockAdapter.mock.calls.length).toBe(3);
112
-
113
- const refreshCall = mockAdapter.mock.calls[1];
114
- expect(refreshCall[0].url).toContain('api/auth/refresh');
115
- });
116
-
117
- it('does not bypass guard when share/ appears only in query params', async () => {
118
- expect.assertions(1);
119
- setTokenHeader(undefined);
120
-
121
- setWindowLocation({
122
- href: 'http://localhost/c/chat?ref=share/token',
123
- pathname: '/c/chat',
124
- search: '?ref=share/token',
125
- hash: '',
126
- } as Partial<Location>);
127
-
128
- mockAdapter.mockRejectedValueOnce({
129
- response: { status: 401 },
130
- config: { url: '/api/messages', headers: {} },
131
- });
132
-
133
- try {
134
- await axios.get('/api/messages');
135
- } catch {
136
- // expected rejection
137
- }
138
-
139
- expect(mockAdapter).toHaveBeenCalledTimes(1);
140
- });
141
-
142
- it('redirects to login with redirect_to when unauthenticated on share page and refresh fails', async () => {
143
- expect.assertions(1);
144
- setTokenHeader(undefined);
145
-
146
- setWindowLocation({
147
- href: 'http://localhost/share/abc123',
148
- pathname: '/share/abc123',
149
- search: '',
150
- hash: '',
151
- } as Partial<Location>);
152
-
153
- mockAdapter.mockRejectedValueOnce({
154
- response: { status: 401 },
155
- config: { url: '/api/share/abc123', headers: {} },
156
- });
157
-
158
- mockAdapter.mockResolvedValueOnce({
159
- data: { token: '' },
160
- status: 200,
161
- headers: {},
162
- config: {},
163
- });
164
-
165
- try {
166
- await axios.get('/api/share/abc123');
167
- } catch {
168
- // expected rejection
169
- }
170
-
171
- expect(window.location.href).toBe('/login?redirect_to=%2Fshare%2Fabc123');
172
- });
173
-
174
- it('redirects to login with redirect_to when authenticated and refresh returns no token on share page', async () => {
175
- expect.assertions(1);
176
- setTokenHeader('some-token');
177
-
178
- setWindowLocation({
179
- href: 'http://localhost/share/abc123',
180
- pathname: '/share/abc123',
181
- search: '',
182
- hash: '',
183
- } as Partial<Location>);
184
-
185
- mockAdapter.mockRejectedValueOnce({
186
- response: { status: 401 },
187
- config: { url: '/api/share/abc123', headers: {} },
188
- });
189
-
190
- mockAdapter.mockResolvedValueOnce({
191
- data: { token: '' },
192
- status: 200,
193
- headers: {},
194
- config: {},
195
- });
196
-
197
- try {
198
- await axios.get('/api/share/abc123');
199
- } catch {
200
- // expected rejection
201
- }
202
-
203
- expect(window.location.href).toBe('/login?redirect_to=%2Fshare%2Fabc123');
204
- });
205
-
206
- it('redirects to login with redirect_to when refresh returns no token on regular page', async () => {
207
- expect.assertions(1);
208
- setTokenHeader('some-token');
209
-
210
- setWindowLocation({
211
- href: 'http://localhost/c/some-conversation',
212
- pathname: '/c/some-conversation',
213
- search: '',
214
- hash: '',
215
- } as Partial<Location>);
216
-
217
- mockAdapter.mockRejectedValueOnce({
218
- response: { status: 401 },
219
- config: { url: '/api/messages', headers: {} },
220
- });
221
-
222
- mockAdapter.mockResolvedValueOnce({
223
- data: { token: '' },
224
- status: 200,
225
- headers: {},
226
- config: {},
227
- });
228
-
229
- try {
230
- await axios.get('/api/messages');
231
- } catch {
232
- // expected rejection
233
- }
234
-
235
- expect(window.location.href).toBe('/login?redirect_to=%2Fc%2Fsome-conversation');
236
- });
237
-
238
- it('redirects to plain /login without redirect_to when already on a login path', async () => {
239
- expect.assertions(1);
240
- setTokenHeader('some-token');
241
-
242
- setWindowLocation({
243
- href: 'http://localhost/login/2fa',
244
- pathname: '/login/2fa',
245
- search: '',
246
- hash: '',
247
- } as Partial<Location>);
248
-
249
- mockAdapter.mockRejectedValueOnce({
250
- response: { status: 401 },
251
- config: { url: '/api/messages', headers: {} },
252
- });
253
-
254
- mockAdapter.mockResolvedValueOnce({
255
- data: { token: '' },
256
- status: 200,
257
- headers: {},
258
- config: {},
259
- });
260
-
261
- try {
262
- await axios.get('/api/messages');
263
- } catch {
264
- // expected rejection
265
- }
266
-
267
- expect(window.location.href).toBe('/login');
268
- });
269
-
270
- it('attempts refresh when Authorization header is present', async () => {
271
- expect.assertions(2);
272
- setTokenHeader('valid-token');
273
-
274
- mockAdapter.mockRejectedValueOnce({
275
- response: { status: 401 },
276
- config: { url: '/api/messages', headers: {}, _retry: false },
277
- });
278
-
279
- mockAdapter.mockResolvedValueOnce({
280
- data: { token: 'new-token' },
281
- status: 200,
282
- headers: {},
283
- config: {},
284
- });
285
-
286
- mockAdapter.mockResolvedValueOnce({
287
- data: { messages: [] },
288
- status: 200,
289
- headers: {},
290
- config: {},
291
- });
292
-
293
- try {
294
- await axios.get('/api/messages');
295
- } catch {
296
- // may reject depending on exact flow
297
- }
298
-
299
- expect(mockAdapter.mock.calls.length).toBe(3);
300
-
301
- const refreshCall = mockAdapter.mock.calls[1];
302
- expect(refreshCall[0].url).toContain('api/auth/refresh');
303
- });
304
- });
@@ -1,196 +0,0 @@
1
- import { extractEnvVariable, isSensitiveEnvVar } from '../src/utils';
2
-
3
- describe('Environment Variable Extraction', () => {
4
- const originalEnv = process.env;
5
-
6
- beforeEach(() => {
7
- process.env = {
8
- ...originalEnv,
9
- TEST_API_KEY: 'test-api-key-value',
10
- ANOTHER_VALUE: 'another-value',
11
- };
12
- });
13
-
14
- afterEach(() => {
15
- process.env = originalEnv;
16
- });
17
-
18
- describe('extractEnvVariable (original tests)', () => {
19
- test('should return the value of the environment variable', () => {
20
- process.env.TEST_VAR = 'test_value';
21
- expect(extractEnvVariable('${TEST_VAR}')).toBe('test_value');
22
- });
23
-
24
- test('should return the original string if the envrionment variable is not defined correctly', () => {
25
- process.env.TEST_VAR = 'test_value';
26
- expect(extractEnvVariable('${ TEST_VAR }')).toBe('${ TEST_VAR }');
27
- });
28
-
29
- test('should return the original string if environment variable is not set', () => {
30
- expect(extractEnvVariable('${NON_EXISTENT_VAR}')).toBe('${NON_EXISTENT_VAR}');
31
- });
32
-
33
- test('should return the original string if it does not contain an environment variable', () => {
34
- expect(extractEnvVariable('some_string')).toBe('some_string');
35
- });
36
-
37
- test('should handle empty strings', () => {
38
- expect(extractEnvVariable('')).toBe('');
39
- });
40
-
41
- test('should handle strings without variable format', () => {
42
- expect(extractEnvVariable('no_var_here')).toBe('no_var_here');
43
- });
44
-
45
- /** No longer the expected behavior; keeping for reference */
46
- test.skip('should not process multiple variable formats', () => {
47
- process.env.FIRST_VAR = 'first';
48
- process.env.SECOND_VAR = 'second';
49
- expect(extractEnvVariable('${FIRST_VAR} and ${SECOND_VAR}')).toBe(
50
- '${FIRST_VAR} and ${SECOND_VAR}',
51
- );
52
- });
53
- });
54
-
55
- describe('extractEnvVariable function', () => {
56
- it('should extract environment variables from exact matches', () => {
57
- expect(extractEnvVariable('${TEST_API_KEY}')).toBe('test-api-key-value');
58
- expect(extractEnvVariable('${ANOTHER_VALUE}')).toBe('another-value');
59
- });
60
-
61
- it('should extract environment variables from strings with prefixes', () => {
62
- expect(extractEnvVariable('prefix-${TEST_API_KEY}')).toBe('prefix-test-api-key-value');
63
- });
64
-
65
- it('should extract environment variables from strings with suffixes', () => {
66
- expect(extractEnvVariable('${TEST_API_KEY}-suffix')).toBe('test-api-key-value-suffix');
67
- });
68
-
69
- it('should extract environment variables from strings with both prefixes and suffixes', () => {
70
- expect(extractEnvVariable('prefix-${TEST_API_KEY}-suffix')).toBe(
71
- 'prefix-test-api-key-value-suffix',
72
- );
73
- });
74
-
75
- it('should not match invalid patterns', () => {
76
- expect(extractEnvVariable('$TEST_API_KEY')).toBe('$TEST_API_KEY');
77
- expect(extractEnvVariable('{TEST_API_KEY}')).toBe('{TEST_API_KEY}');
78
- expect(extractEnvVariable('TEST_API_KEY')).toBe('TEST_API_KEY');
79
- });
80
- });
81
-
82
- describe('extractEnvVariable', () => {
83
- it('should extract environment variable values', () => {
84
- expect(extractEnvVariable('${TEST_API_KEY}')).toBe('test-api-key-value');
85
- expect(extractEnvVariable('${ANOTHER_VALUE}')).toBe('another-value');
86
- });
87
-
88
- it('should return the original string if environment variable is not found', () => {
89
- expect(extractEnvVariable('${NON_EXISTENT_VAR}')).toBe('${NON_EXISTENT_VAR}');
90
- });
91
-
92
- it('should return the original string if no environment variable pattern is found', () => {
93
- expect(extractEnvVariable('plain-string')).toBe('plain-string');
94
- });
95
- });
96
-
97
- describe('extractEnvVariable space trimming', () => {
98
- beforeEach(() => {
99
- process.env.HELLO = 'world';
100
- process.env.USER = 'testuser';
101
- });
102
-
103
- it('should extract the value when string contains only an environment variable with surrounding whitespace', () => {
104
- expect(extractEnvVariable(' ${HELLO} ')).toBe('world');
105
- expect(extractEnvVariable(' ${HELLO} ')).toBe('world');
106
- expect(extractEnvVariable('\t${HELLO}\n')).toBe('world');
107
- });
108
-
109
- it('should preserve content when variable is part of a larger string', () => {
110
- expect(extractEnvVariable('Hello ${USER}!')).toBe('Hello testuser!');
111
- expect(extractEnvVariable(' Hello ${USER}! ')).toBe('Hello testuser!');
112
- });
113
-
114
- it('should not handle multiple variables', () => {
115
- expect(extractEnvVariable('${HELLO} ${USER}')).toBe('${HELLO} ${USER}');
116
- expect(extractEnvVariable(' ${HELLO} ${USER} ')).toBe('${HELLO} ${USER}');
117
- });
118
-
119
- it('should handle undefined variables', () => {
120
- expect(extractEnvVariable(' ${UNDEFINED_VAR} ')).toBe('${UNDEFINED_VAR}');
121
- });
122
-
123
- it('should handle mixed content correctly', () => {
124
- expect(extractEnvVariable('Welcome, ${USER}!\nYour message: ${HELLO}')).toBe(
125
- 'Welcome, testuser!\nYour message: world',
126
- );
127
- });
128
- });
129
-
130
- describe('isSensitiveEnvVar', () => {
131
- it('should flag infrastructure secrets', () => {
132
- expect(isSensitiveEnvVar('JWT_SECRET')).toBe(true);
133
- expect(isSensitiveEnvVar('JWT_REFRESH_SECRET')).toBe(true);
134
- expect(isSensitiveEnvVar('CREDS_KEY')).toBe(true);
135
- expect(isSensitiveEnvVar('CREDS_IV')).toBe(true);
136
- expect(isSensitiveEnvVar('MEILI_MASTER_KEY')).toBe(true);
137
- expect(isSensitiveEnvVar('MONGO_URI')).toBe(true);
138
- expect(isSensitiveEnvVar('REDIS_URI')).toBe(true);
139
- expect(isSensitiveEnvVar('REDIS_PASSWORD')).toBe(true);
140
- });
141
-
142
- it('should allow non-infrastructure vars through (including operator-configured secrets)', () => {
143
- expect(isSensitiveEnvVar('OPENAI_API_KEY')).toBe(false);
144
- expect(isSensitiveEnvVar('ANTHROPIC_API_KEY')).toBe(false);
145
- expect(isSensitiveEnvVar('GOOGLE_KEY')).toBe(false);
146
- expect(isSensitiveEnvVar('PROXY')).toBe(false);
147
- expect(isSensitiveEnvVar('DEBUG_LOGGING')).toBe(false);
148
- expect(isSensitiveEnvVar('DOMAIN_CLIENT')).toBe(false);
149
- expect(isSensitiveEnvVar('APP_TITLE')).toBe(false);
150
- expect(isSensitiveEnvVar('OPENID_CLIENT_SECRET')).toBe(false);
151
- expect(isSensitiveEnvVar('DISCORD_CLIENT_SECRET')).toBe(false);
152
- expect(isSensitiveEnvVar('MY_CUSTOM_SECRET')).toBe(false);
153
- });
154
- });
155
-
156
- describe('extractEnvVariable sensitive var blocklist', () => {
157
- beforeEach(() => {
158
- process.env.JWT_SECRET = 'super-secret-jwt';
159
- process.env.JWT_REFRESH_SECRET = 'super-secret-refresh';
160
- process.env.CREDS_KEY = 'encryption-key';
161
- process.env.CREDS_IV = 'encryption-iv';
162
- process.env.MEILI_MASTER_KEY = 'meili-key';
163
- process.env.MONGO_URI = 'mongodb://user:pass@host/db';
164
- process.env.REDIS_URI = 'redis://:pass@host:6379';
165
- process.env.REDIS_PASSWORD = 'redis-pass';
166
- process.env.OPENAI_API_KEY = 'sk-legit-key';
167
- });
168
-
169
- it('should refuse to resolve sensitive vars (single-match path)', () => {
170
- expect(extractEnvVariable('${JWT_SECRET}')).toBe('${JWT_SECRET}');
171
- expect(extractEnvVariable('${JWT_REFRESH_SECRET}')).toBe('${JWT_REFRESH_SECRET}');
172
- expect(extractEnvVariable('${CREDS_KEY}')).toBe('${CREDS_KEY}');
173
- expect(extractEnvVariable('${CREDS_IV}')).toBe('${CREDS_IV}');
174
- expect(extractEnvVariable('${MEILI_MASTER_KEY}')).toBe('${MEILI_MASTER_KEY}');
175
- expect(extractEnvVariable('${MONGO_URI}')).toBe('${MONGO_URI}');
176
- expect(extractEnvVariable('${REDIS_URI}')).toBe('${REDIS_URI}');
177
- expect(extractEnvVariable('${REDIS_PASSWORD}')).toBe('${REDIS_PASSWORD}');
178
- });
179
-
180
- it('should refuse to resolve sensitive vars in composite strings (multi-match path)', () => {
181
- expect(extractEnvVariable('key=${JWT_SECRET}&more')).toBe('key=${JWT_SECRET}&more');
182
- expect(extractEnvVariable('db=${MONGO_URI}/extra')).toBe('db=${MONGO_URI}/extra');
183
- });
184
-
185
- it('should still resolve non-sensitive vars normally', () => {
186
- expect(extractEnvVariable('${OPENAI_API_KEY}')).toBe('sk-legit-key');
187
- expect(extractEnvVariable('Bearer ${OPENAI_API_KEY}')).toBe('Bearer sk-legit-key');
188
- });
189
-
190
- it('should resolve non-sensitive vars while blocking sensitive ones in the same string', () => {
191
- expect(extractEnvVariable('key=${OPENAI_API_KEY}&secret=${JWT_SECRET}')).toBe(
192
- 'key=sk-legit-key&secret=${JWT_SECRET}',
193
- );
194
- });
195
- });
196
- });