galileo-generated 0.2.10 → 0.2.12
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.
- package/README.md +1 -1
- package/dist/commonjs/hooks/sdk-identifier.js +3 -3
- package/dist/commonjs/hooks/sdk-identifier.js.map +1 -1
- package/dist/commonjs/lib/config.d.ts.map +1 -1
- package/dist/commonjs/lib/config.js +5 -3
- package/dist/commonjs/lib/config.js.map +1 -1
- package/dist/commonjs/lib/galileo-config.d.ts +11 -2
- package/dist/commonjs/lib/galileo-config.d.ts.map +1 -1
- package/dist/commonjs/lib/galileo-config.js +24 -5
- package/dist/commonjs/lib/galileo-config.js.map +1 -1
- package/dist/commonjs/models/errors/responsevalidationerror.d.ts +2 -2
- package/dist/commonjs/models/errors/responsevalidationerror.d.ts.map +1 -1
- package/dist/commonjs/models/errors/responsevalidationerror.js +9 -9
- package/dist/commonjs/models/errors/responsevalidationerror.js.map +1 -1
- package/dist/commonjs/models/errors/sdkvalidationerror.d.ts +2 -2
- package/dist/commonjs/models/errors/sdkvalidationerror.d.ts.map +1 -1
- package/dist/commonjs/models/errors/sdkvalidationerror.js +18 -10
- package/dist/commonjs/models/errors/sdkvalidationerror.js.map +1 -1
- package/dist/commonjs/tests/integration/env-auth-ingestion.test.d.ts +2 -0
- package/dist/commonjs/tests/integration/env-auth-ingestion.test.d.ts.map +1 -0
- package/dist/commonjs/tests/integration/env-auth-ingestion.test.js +185 -0
- package/dist/commonjs/tests/integration/env-auth-ingestion.test.js.map +1 -0
- package/dist/esm/hooks/sdk-identifier.js +3 -3
- package/dist/esm/hooks/sdk-identifier.js.map +1 -1
- package/dist/esm/lib/config.d.ts.map +1 -1
- package/dist/esm/lib/config.js +5 -3
- package/dist/esm/lib/config.js.map +1 -1
- package/dist/esm/lib/galileo-config.d.ts +11 -2
- package/dist/esm/lib/galileo-config.d.ts.map +1 -1
- package/dist/esm/lib/galileo-config.js +24 -5
- package/dist/esm/lib/galileo-config.js.map +1 -1
- package/dist/esm/models/errors/responsevalidationerror.d.ts +2 -2
- package/dist/esm/models/errors/responsevalidationerror.d.ts.map +1 -1
- package/dist/esm/models/errors/responsevalidationerror.js +9 -9
- package/dist/esm/models/errors/responsevalidationerror.js.map +1 -1
- package/dist/esm/models/errors/sdkvalidationerror.d.ts +2 -2
- package/dist/esm/models/errors/sdkvalidationerror.d.ts.map +1 -1
- package/dist/esm/models/errors/sdkvalidationerror.js +18 -10
- package/dist/esm/models/errors/sdkvalidationerror.js.map +1 -1
- package/dist/esm/tests/integration/env-auth-ingestion.test.d.ts +2 -0
- package/dist/esm/tests/integration/env-auth-ingestion.test.d.ts.map +1 -0
- package/dist/esm/tests/integration/env-auth-ingestion.test.js +183 -0
- package/dist/esm/tests/integration/env-auth-ingestion.test.js.map +1 -0
- package/package.json +1 -1
- package/src/hooks/sdk-identifier.ts +3 -3
- package/src/lib/config.ts +6 -4
- package/src/lib/galileo-config.ts +26 -5
- package/src/models/errors/responsevalidationerror.ts +14 -10
- package/src/models/errors/sdkvalidationerror.ts +20 -11
- package/src/tests/integration/env-auth-ingestion.test.ts +254 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-auth-ingestion.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/integration/env-auth-ingestion.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { http, HttpResponse } from 'msw';
|
|
2
|
+
import { setupServer } from 'msw/node';
|
|
3
|
+
import { describe, test, expect, beforeAll, afterAll, afterEach, beforeEach } from 'vitest';
|
|
4
|
+
import { GalileoConfig } from '../../lib/galileo-config.js';
|
|
5
|
+
import { BaseEntity } from '../../entities/base-entity.js';
|
|
6
|
+
import { GalileoGenerated } from '../../sdk/sdk.js';
|
|
7
|
+
const TEST_HOST = 'http://localhost:8088';
|
|
8
|
+
const MOCK_API_KEY = 'test-api-key-for-env-auth';
|
|
9
|
+
const MOCK_ACCESS_TOKEN = 'mock-access-token-from-login';
|
|
10
|
+
const MOCK_PROJECT_ID = 'proj-00000000-0000-0000-0000-000000000001';
|
|
11
|
+
/**
|
|
12
|
+
* Captured request data from MSW handlers, used to assert that env vars
|
|
13
|
+
* propagate correctly through the auth and hook chain.
|
|
14
|
+
*/
|
|
15
|
+
let capturedLoginBody = null;
|
|
16
|
+
let capturedTraceHeaders = {};
|
|
17
|
+
let capturedTraceBody = null;
|
|
18
|
+
const loginApiKeyHandler = http.post(`${TEST_HOST}/login/api_key`, async ({ request }) => {
|
|
19
|
+
capturedLoginBody = (await request.json());
|
|
20
|
+
if (capturedLoginBody?.['api_key'] !== MOCK_API_KEY) {
|
|
21
|
+
return HttpResponse.json({ detail: 'Invalid API key' }, { status: 401 });
|
|
22
|
+
}
|
|
23
|
+
return HttpResponse.json({
|
|
24
|
+
access_token: MOCK_ACCESS_TOKEN,
|
|
25
|
+
token_type: 'bearer',
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
const traceIngestionHandler = http.post(`${TEST_HOST}/projects/${MOCK_PROJECT_ID}/traces`, async ({ request }) => {
|
|
29
|
+
capturedTraceHeaders = Object.fromEntries(request.headers.entries());
|
|
30
|
+
capturedTraceBody = (await request.json());
|
|
31
|
+
return HttpResponse.json({
|
|
32
|
+
project_id: MOCK_PROJECT_ID,
|
|
33
|
+
project_name: 'test-project',
|
|
34
|
+
records_count: 1,
|
|
35
|
+
traces_count: 1,
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
const server = setupServer(loginApiKeyHandler, traceIngestionHandler);
|
|
39
|
+
const ENV_KEYS = [
|
|
40
|
+
'GALILEO_API_KEY',
|
|
41
|
+
'GALILEO_CONSOLE_URL',
|
|
42
|
+
'GALILEO_API_URL',
|
|
43
|
+
'GALILEO_USERNAME',
|
|
44
|
+
'GALILEO_PASSWORD',
|
|
45
|
+
'GALILEO_PROJECT',
|
|
46
|
+
'GALILEO_LOG_STREAM',
|
|
47
|
+
];
|
|
48
|
+
function clearGalileoEnv() {
|
|
49
|
+
for (const key of ENV_KEYS) {
|
|
50
|
+
delete process.env[key];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
describe('env vars → auth → trace ingestion', () => {
|
|
54
|
+
beforeAll(() => server.listen({ onUnhandledRequest: 'warn' }));
|
|
55
|
+
afterAll(() => server.close());
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
capturedLoginBody = null;
|
|
58
|
+
capturedTraceHeaders = {};
|
|
59
|
+
capturedTraceBody = null;
|
|
60
|
+
GalileoConfig.reset();
|
|
61
|
+
BaseEntity.resetForTesting();
|
|
62
|
+
});
|
|
63
|
+
afterEach(() => {
|
|
64
|
+
server.resetHandlers();
|
|
65
|
+
clearGalileoEnv();
|
|
66
|
+
});
|
|
67
|
+
test('test GALILEO_API_KEY from env reaches the login endpoint', async () => {
|
|
68
|
+
process.env['GALILEO_CONSOLE_URL'] = TEST_HOST;
|
|
69
|
+
process.env['GALILEO_API_KEY'] = MOCK_API_KEY;
|
|
70
|
+
const token = await BaseEntity.getToken();
|
|
71
|
+
expect(capturedLoginBody).not.toBeNull();
|
|
72
|
+
expect(capturedLoginBody?.['api_key']).toBe(MOCK_API_KEY);
|
|
73
|
+
expect(token).toBe(MOCK_ACCESS_TOKEN);
|
|
74
|
+
});
|
|
75
|
+
test('test auth token is injected into trace ingestion request via hook', async () => {
|
|
76
|
+
process.env['GALILEO_CONSOLE_URL'] = TEST_HOST;
|
|
77
|
+
process.env['GALILEO_API_KEY'] = MOCK_API_KEY;
|
|
78
|
+
// Authenticate — populates BaseEntity.token via the hook chain
|
|
79
|
+
await BaseEntity.getToken();
|
|
80
|
+
// Create a fresh SDK client that reads from GalileoConfig (which got TEST_HOST)
|
|
81
|
+
const client = new GalileoGenerated({ serverURL: TEST_HOST });
|
|
82
|
+
// Call trace ingestion through the SDK
|
|
83
|
+
await client.trace.logTracesProjectsProjectIdTracesPost({}, // security — empty: let the TokenManagementHook inject the Bearer token
|
|
84
|
+
{
|
|
85
|
+
projectId: MOCK_PROJECT_ID,
|
|
86
|
+
body: {
|
|
87
|
+
traces: [{ input: 'hello', output: 'world', name: 'test-trace' }],
|
|
88
|
+
logStreamId: 'ls-test',
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
// The TokenManagementHook should have added the Bearer token
|
|
92
|
+
expect(capturedTraceHeaders['authorization']).toBe(`Bearer ${MOCK_ACCESS_TOKEN}`);
|
|
93
|
+
});
|
|
94
|
+
test('test trace ingestion receives correct payload', async () => {
|
|
95
|
+
process.env['GALILEO_CONSOLE_URL'] = TEST_HOST;
|
|
96
|
+
process.env['GALILEO_API_KEY'] = MOCK_API_KEY;
|
|
97
|
+
await BaseEntity.getToken();
|
|
98
|
+
const client = new GalileoGenerated({ serverURL: TEST_HOST });
|
|
99
|
+
await client.trace.logTracesProjectsProjectIdTracesPost({}, {
|
|
100
|
+
projectId: MOCK_PROJECT_ID,
|
|
101
|
+
body: {
|
|
102
|
+
traces: [{ input: 'test-input', output: 'test-output', name: 'trace-1' }],
|
|
103
|
+
logStreamId: 'ls-abc',
|
|
104
|
+
isComplete: true,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
expect(capturedTraceBody).not.toBeNull();
|
|
108
|
+
expect(capturedTraceBody?.['log_stream_id']).toBe('ls-abc');
|
|
109
|
+
expect(capturedTraceBody?.['is_complete']).toBe(true);
|
|
110
|
+
const traces = capturedTraceBody?.['traces'];
|
|
111
|
+
expect(traces).toHaveLength(1);
|
|
112
|
+
expect(traces[0]?.['input']).toBe('test-input');
|
|
113
|
+
expect(traces[0]?.['output']).toBe('test-output');
|
|
114
|
+
expect(traces[0]?.['name']).toBe('trace-1');
|
|
115
|
+
});
|
|
116
|
+
test('test SDK identifier header is present on trace ingestion', async () => {
|
|
117
|
+
process.env['GALILEO_CONSOLE_URL'] = TEST_HOST;
|
|
118
|
+
process.env['GALILEO_API_KEY'] = MOCK_API_KEY;
|
|
119
|
+
await BaseEntity.getToken();
|
|
120
|
+
const client = new GalileoGenerated({ serverURL: TEST_HOST });
|
|
121
|
+
await client.trace.logTracesProjectsProjectIdTracesPost({}, {
|
|
122
|
+
projectId: MOCK_PROJECT_ID,
|
|
123
|
+
body: {
|
|
124
|
+
traces: [{ input: 'x', output: 'y', name: 'n' }],
|
|
125
|
+
logStreamId: 'ls-test',
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
expect(capturedTraceHeaders['x-galileo-sdk']).toMatch(/^galileo-generated\/\d+\.\d+\.\d+$/);
|
|
129
|
+
});
|
|
130
|
+
test('test wrong GALILEO_API_KEY causes authentication error', async () => {
|
|
131
|
+
process.env['GALILEO_CONSOLE_URL'] = TEST_HOST;
|
|
132
|
+
process.env['GALILEO_API_KEY'] = 'wrong-api-key';
|
|
133
|
+
await expect(BaseEntity.getToken()).rejects.toThrow();
|
|
134
|
+
// Login was attempted with the wrong key
|
|
135
|
+
expect(capturedLoginBody?.['api_key']).toBe('wrong-api-key');
|
|
136
|
+
// No token was cached — trace requests would have no auth header
|
|
137
|
+
BaseEntity.resetForTesting();
|
|
138
|
+
const token = await BaseEntity.getToken().catch(() => null);
|
|
139
|
+
expect(token).toBeNull();
|
|
140
|
+
});
|
|
141
|
+
test('test no credentials in env means no auth header on request', async () => {
|
|
142
|
+
process.env['GALILEO_CONSOLE_URL'] = TEST_HOST;
|
|
143
|
+
// No GALILEO_API_KEY, no USERNAME/PASSWORD
|
|
144
|
+
const token = await BaseEntity.getToken();
|
|
145
|
+
expect(token).toBeNull();
|
|
146
|
+
const client = new GalileoGenerated({ serverURL: TEST_HOST });
|
|
147
|
+
await client.trace.logTracesProjectsProjectIdTracesPost({}, {
|
|
148
|
+
projectId: MOCK_PROJECT_ID,
|
|
149
|
+
body: {
|
|
150
|
+
traces: [{ input: 'a', output: 'b', name: 'c' }],
|
|
151
|
+
logStreamId: 'ls-test',
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
// TokenManagementHook skips injection when token is null
|
|
155
|
+
expect(capturedTraceHeaders['authorization']).toBeUndefined();
|
|
156
|
+
});
|
|
157
|
+
test('test full chain: env var set after config reset is picked up', async () => {
|
|
158
|
+
// Simulate late env loading (e.g. dotenv.config() called after first import)
|
|
159
|
+
const configBefore = GalileoConfig.get();
|
|
160
|
+
expect(configBefore.apiKey).toBeUndefined();
|
|
161
|
+
// Now "load" the env vars (as dotenv would)
|
|
162
|
+
process.env['GALILEO_CONSOLE_URL'] = TEST_HOST;
|
|
163
|
+
process.env['GALILEO_API_KEY'] = MOCK_API_KEY;
|
|
164
|
+
// GalileoConfig.get() re-reads env when instance has no external config
|
|
165
|
+
// (isMissingExternalConfig returns true → singleton is rebuilt)
|
|
166
|
+
const configAfter = GalileoConfig.get();
|
|
167
|
+
expect(configAfter.apiKey).toBe(MOCK_API_KEY);
|
|
168
|
+
// Auth picks up the new config
|
|
169
|
+
const token = await BaseEntity.getToken();
|
|
170
|
+
expect(token).toBe(MOCK_ACCESS_TOKEN);
|
|
171
|
+
// And the token flows through to the request
|
|
172
|
+
const client = new GalileoGenerated({ serverURL: TEST_HOST });
|
|
173
|
+
await client.trace.logTracesProjectsProjectIdTracesPost({}, {
|
|
174
|
+
projectId: MOCK_PROJECT_ID,
|
|
175
|
+
body: {
|
|
176
|
+
traces: [{ input: 'late', output: 'load', name: 'dotenv-test' }],
|
|
177
|
+
logStreamId: 'ls-test',
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
expect(capturedTraceHeaders['authorization']).toBe(`Bearer ${MOCK_ACCESS_TOKEN}`);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
//# sourceMappingURL=env-auth-ingestion.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-auth-ingestion.test.js","sourceRoot":"","sources":["../../../../src/tests/integration/env-auth-ingestion.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -9,9 +9,9 @@ function loadVersion(): string {
|
|
|
9
9
|
|
|
10
10
|
try {
|
|
11
11
|
// NOTES: require is being used for now, using import demands appropriate
|
|
12
|
-
// compiler configuration, which
|
|
13
|
-
//
|
|
14
|
-
//
|
|
12
|
+
// compiler configuration, which is not possible now due to galileo-js
|
|
13
|
+
// being CommonJS only. This point should be revisited when/if galileo-js
|
|
14
|
+
// is migrated to ESM.
|
|
15
15
|
const packageJsonPath = require.resolve("galileo-generated/package.json");
|
|
16
16
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
17
|
const packageJson = require(packageJsonPath);
|
package/src/lib/config.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Code generated by Speakeasy (https://speakeasy.com).
|
|
3
|
-
*
|
|
2
|
+
* Code originally generated by Speakeasy (https://speakeasy.com).
|
|
3
|
+
* 03-11-2026 - Modified by Galileo to add a new source for API URL path.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { Params, pathToFunc } from "./url.js";
|
|
6
7
|
import { HTTPClient } from "./http.js";
|
|
7
8
|
import { Logger } from "./logger.js";
|
|
8
9
|
import { RetryConfig } from "./retries.js";
|
|
9
|
-
import {
|
|
10
|
+
import { GalileoConfig } from "./galileo-config.js";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Contains the list of servers available to the SDK
|
|
@@ -43,7 +44,8 @@ export type SDKOptions = {
|
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
export function serverURLFromOptions(options: SDKOptions): URL | null {
|
|
46
|
-
|
|
47
|
+
const config = GalileoConfig.get();
|
|
48
|
+
let serverURL = options.serverURL ?? config.apiUrl;
|
|
47
49
|
|
|
48
50
|
const params: Params = {};
|
|
49
51
|
|
|
@@ -105,6 +105,9 @@ export type GalileoConfigSnapshot = {
|
|
|
105
105
|
cert?: CertConfig;
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
+
const DEFAULT_CONSOLE_URL = "https://console.galileo.ai";
|
|
109
|
+
const DEFAULT_API_URL = "https://api.galileo.ai";
|
|
110
|
+
|
|
108
111
|
/** Browser global key for auth config (e.g. window.__GALILEO_AUTH__). */
|
|
109
112
|
const DEFAULT_BROWSER_GLOBAL = "__GALILEO_AUTH__";
|
|
110
113
|
/** localStorage key for persisted auth config. */
|
|
@@ -390,7 +393,7 @@ function resolveApiUrl(
|
|
|
390
393
|
): string {
|
|
391
394
|
if (apiUrl) return apiUrl;
|
|
392
395
|
if (!consoleUrl) {
|
|
393
|
-
if (projectType === "gen_ai") return
|
|
396
|
+
if (projectType === "gen_ai") return DEFAULT_API_URL;
|
|
394
397
|
throw new Error("GALILEO_CONSOLE_URL must be set");
|
|
395
398
|
}
|
|
396
399
|
if (
|
|
@@ -432,7 +435,7 @@ export class GalileoConfig {
|
|
|
432
435
|
|
|
433
436
|
private constructor(input: GalileoConfigInput) {
|
|
434
437
|
this.apiUrl = input.apiUrl ?? resolveApiUrl(input.consoleUrl, undefined, "gen_ai");
|
|
435
|
-
this.consoleUrl = input.consoleUrl ||
|
|
438
|
+
this.consoleUrl = input.consoleUrl || DEFAULT_CONSOLE_URL;
|
|
436
439
|
this.apiKey = input.apiKey;
|
|
437
440
|
this.username = input.username;
|
|
438
441
|
this.password = input.password;
|
|
@@ -450,6 +453,22 @@ export class GalileoConfig {
|
|
|
450
453
|
this.rejectUnauthorized = input.rejectUnauthorized;
|
|
451
454
|
}
|
|
452
455
|
|
|
456
|
+
private static readonly URL_KEYS: ReadonlySet<string> = new Set(["consoleUrl", "apiUrl"]);
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Returns true if only consoleUrl and/or apiUrl are configured, with no other
|
|
460
|
+
* meaningful configuration present. Used to detect instances created before
|
|
461
|
+
* environment variables were fully loaded (e.g. late dotenv initialization).
|
|
462
|
+
*/
|
|
463
|
+
private isMissingExternalConfig(): boolean {
|
|
464
|
+
const self = this as unknown as Record<string, unknown>;
|
|
465
|
+
for (const key of Object.keys(self)) {
|
|
466
|
+
if (GalileoConfig.URL_KEYS.has(key) || self[key] == null) continue;
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
return true;
|
|
470
|
+
}
|
|
471
|
+
|
|
453
472
|
/**
|
|
454
473
|
* Returns a snapshot compatible with BaseEntity, including resolved apiUrl, apiKey, login, sso, and cert.
|
|
455
474
|
*
|
|
@@ -497,7 +516,9 @@ export class GalileoConfig {
|
|
|
497
516
|
* 1. Environment variables or browser storage (via resolveFromEnvironment)
|
|
498
517
|
* 2. Constructor overrides (via merge)
|
|
499
518
|
*
|
|
500
|
-
* The instance is cached and reused on subsequent calls unless overrides are provided
|
|
519
|
+
* The instance is cached and reused on subsequent calls unless overrides are provided
|
|
520
|
+
* or the cached instance has only URL defaults (no auth, certs, project, etc.),
|
|
521
|
+
* which indicates environment variables may not have been loaded yet (e.g. late dotenv init).
|
|
501
522
|
* To reset the singleton, call reset().
|
|
502
523
|
*
|
|
503
524
|
* @param overrides - (Optional) Config values to merge over environment and defaults.
|
|
@@ -505,7 +526,7 @@ export class GalileoConfig {
|
|
|
505
526
|
*/
|
|
506
527
|
public static get(overrides: GalileoConfigInput = {}): GalileoConfig {
|
|
507
528
|
const hasOverrides = Object.keys(overrides).length > 0;
|
|
508
|
-
if (!GalileoConfig.instance || hasOverrides) {
|
|
529
|
+
if (!GalileoConfig.instance || hasOverrides || GalileoConfig.instance.isMissingExternalConfig()) {
|
|
509
530
|
const fromEnv = resolveFromEnvironment();
|
|
510
531
|
const merged = merge(fromEnv, overrides);
|
|
511
532
|
GalileoConfig.instance = new GalileoConfig(merged);
|
|
@@ -531,7 +552,7 @@ export class GalileoConfig {
|
|
|
531
552
|
* 1. If apiUrl is set, return it as-is
|
|
532
553
|
* 2. If consoleUrl is set, derive apiUrl by replacing "app.galileo.ai" or "console" with "api"
|
|
533
554
|
* 3. For localhost consoleUrl, return "http://localhost:8088"
|
|
534
|
-
* 4. If neither consoleUrl nor apiUrl is set, use projectType default (e.g., "gen_ai" →
|
|
555
|
+
* 4. If neither consoleUrl nor apiUrl is set, use projectType default (e.g., "gen_ai" → DEFAULT_API_URL)
|
|
535
556
|
* 5. If no projectType and neither URL is set, throw an error
|
|
536
557
|
*
|
|
537
558
|
* @param projectType - (Optional) Default project type for API URL when neither apiUrl nor consoleUrl is set.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Code generated by Speakeasy (https://speakeasy.com).
|
|
3
|
-
*
|
|
2
|
+
* Code originally generated by Speakeasy (https://speakeasy.com).
|
|
3
|
+
* 03-20-2026 - Modified by Galileo to simplify the validation error message.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import * as z from "zod/v4/core";
|
|
@@ -11,12 +11,12 @@ export class ResponseValidationError extends GalileoGeneratedError {
|
|
|
11
11
|
/**
|
|
12
12
|
* The raw value that failed validation.
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
protected readonly rawValue: unknown;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* The raw message that failed validation.
|
|
18
18
|
*/
|
|
19
|
-
|
|
19
|
+
protected readonly rawMessage: unknown;
|
|
20
20
|
|
|
21
21
|
constructor(
|
|
22
22
|
message: string,
|
|
@@ -29,11 +29,19 @@ export class ResponseValidationError extends GalileoGeneratedError {
|
|
|
29
29
|
rawMessage: unknown;
|
|
30
30
|
},
|
|
31
31
|
) {
|
|
32
|
+
const causeString =
|
|
33
|
+
extra.cause instanceof z.$ZodError
|
|
34
|
+
? formatZodError(extra.cause)
|
|
35
|
+
: String(extra.cause);
|
|
36
|
+
|
|
32
37
|
super(message, extra);
|
|
33
38
|
this.name = "ResponseValidationError";
|
|
34
|
-
this.cause =
|
|
39
|
+
this.cause = causeString;
|
|
35
40
|
this.rawValue = extra.rawValue;
|
|
36
41
|
this.rawMessage = extra.rawMessage;
|
|
42
|
+
|
|
43
|
+
Object.defineProperty(this, "rawValue", { value: extra.rawValue, enumerable: false, writable: false, configurable: true });
|
|
44
|
+
Object.defineProperty(this, "rawMessage", { value: extra.rawMessage, enumerable: false, writable: false, configurable: true });
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
/**
|
|
@@ -42,10 +50,6 @@ export class ResponseValidationError extends GalileoGeneratedError {
|
|
|
42
50
|
* default error message.
|
|
43
51
|
*/
|
|
44
52
|
public pretty(): string {
|
|
45
|
-
|
|
46
|
-
return `${this.rawMessage}\n${formatZodError(this.cause)}`;
|
|
47
|
-
} else {
|
|
48
|
-
return this.toString();
|
|
49
|
-
}
|
|
53
|
+
return `${this.rawMessage}\n${this.cause}`;
|
|
50
54
|
}
|
|
51
55
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Code generated by Speakeasy (https://speakeasy.com).
|
|
3
|
-
*
|
|
2
|
+
* Code originally generated by Speakeasy (https://speakeasy.com).
|
|
3
|
+
* 03-20-2026 - Modified by Galileo to simplify the validation error message.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import * as z from "zod/v4/core";
|
|
@@ -9,12 +9,12 @@ export class SDKValidationError extends Error {
|
|
|
9
9
|
/**
|
|
10
10
|
* The raw value that failed validation.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
protected readonly rawValue: unknown;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* The raw message that failed validation.
|
|
16
16
|
*/
|
|
17
|
-
|
|
17
|
+
protected readonly rawMessage: unknown;
|
|
18
18
|
|
|
19
19
|
// Allows for backwards compatibility for `instanceof` checks of `ResponseValidationError`
|
|
20
20
|
static override [Symbol.hasInstance](
|
|
@@ -29,11 +29,24 @@ export class SDKValidationError extends Error {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
constructor(message: string, cause: unknown, rawValue: unknown) {
|
|
32
|
-
|
|
32
|
+
let causeDescription: string;
|
|
33
|
+
if (cause instanceof z.$ZodError) {
|
|
34
|
+
const issuesList = cause.issues;
|
|
35
|
+
const pathArray = issuesList.map((issue: z.$ZodIssue) => issue?.path?.length ? issue.path.join(".") : "").filter((path: string) => path !== "");
|
|
36
|
+
const uniquePaths = [...new Set(pathArray)];
|
|
37
|
+
const paths = uniquePaths?.length ? ` (at ${uniquePaths.join(", ")})` : "";
|
|
38
|
+
causeDescription = `${issuesList[0]?.message ?? "validation failed"}${paths}`;
|
|
39
|
+
} else {
|
|
40
|
+
causeDescription = String(cause);
|
|
41
|
+
}
|
|
42
|
+
super(message);
|
|
33
43
|
this.name = "SDKValidationError";
|
|
34
|
-
this.cause =
|
|
44
|
+
this.cause = causeDescription;
|
|
35
45
|
this.rawValue = rawValue;
|
|
36
46
|
this.rawMessage = message;
|
|
47
|
+
|
|
48
|
+
Object.defineProperty(this, "rawValue", { value: rawValue, enumerable: false, writable: false, configurable: true });
|
|
49
|
+
Object.defineProperty(this, "rawMessage", { value: message, enumerable: false, writable: false, configurable: true });
|
|
37
50
|
}
|
|
38
51
|
|
|
39
52
|
/**
|
|
@@ -42,11 +55,7 @@ export class SDKValidationError extends Error {
|
|
|
42
55
|
* default error message.
|
|
43
56
|
*/
|
|
44
57
|
public pretty(): string {
|
|
45
|
-
|
|
46
|
-
return `${this.rawMessage}\n${formatZodError(this.cause)}`;
|
|
47
|
-
} else {
|
|
48
|
-
return this.toString();
|
|
49
|
-
}
|
|
58
|
+
return `${this.message}: ${this.cause}`;
|
|
50
59
|
}
|
|
51
60
|
}
|
|
52
61
|
|