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.
Files changed (50) hide show
  1. package/README.md +1 -1
  2. package/dist/commonjs/hooks/sdk-identifier.js +3 -3
  3. package/dist/commonjs/hooks/sdk-identifier.js.map +1 -1
  4. package/dist/commonjs/lib/config.d.ts.map +1 -1
  5. package/dist/commonjs/lib/config.js +5 -3
  6. package/dist/commonjs/lib/config.js.map +1 -1
  7. package/dist/commonjs/lib/galileo-config.d.ts +11 -2
  8. package/dist/commonjs/lib/galileo-config.d.ts.map +1 -1
  9. package/dist/commonjs/lib/galileo-config.js +24 -5
  10. package/dist/commonjs/lib/galileo-config.js.map +1 -1
  11. package/dist/commonjs/models/errors/responsevalidationerror.d.ts +2 -2
  12. package/dist/commonjs/models/errors/responsevalidationerror.d.ts.map +1 -1
  13. package/dist/commonjs/models/errors/responsevalidationerror.js +9 -9
  14. package/dist/commonjs/models/errors/responsevalidationerror.js.map +1 -1
  15. package/dist/commonjs/models/errors/sdkvalidationerror.d.ts +2 -2
  16. package/dist/commonjs/models/errors/sdkvalidationerror.d.ts.map +1 -1
  17. package/dist/commonjs/models/errors/sdkvalidationerror.js +18 -10
  18. package/dist/commonjs/models/errors/sdkvalidationerror.js.map +1 -1
  19. package/dist/commonjs/tests/integration/env-auth-ingestion.test.d.ts +2 -0
  20. package/dist/commonjs/tests/integration/env-auth-ingestion.test.d.ts.map +1 -0
  21. package/dist/commonjs/tests/integration/env-auth-ingestion.test.js +185 -0
  22. package/dist/commonjs/tests/integration/env-auth-ingestion.test.js.map +1 -0
  23. package/dist/esm/hooks/sdk-identifier.js +3 -3
  24. package/dist/esm/hooks/sdk-identifier.js.map +1 -1
  25. package/dist/esm/lib/config.d.ts.map +1 -1
  26. package/dist/esm/lib/config.js +5 -3
  27. package/dist/esm/lib/config.js.map +1 -1
  28. package/dist/esm/lib/galileo-config.d.ts +11 -2
  29. package/dist/esm/lib/galileo-config.d.ts.map +1 -1
  30. package/dist/esm/lib/galileo-config.js +24 -5
  31. package/dist/esm/lib/galileo-config.js.map +1 -1
  32. package/dist/esm/models/errors/responsevalidationerror.d.ts +2 -2
  33. package/dist/esm/models/errors/responsevalidationerror.d.ts.map +1 -1
  34. package/dist/esm/models/errors/responsevalidationerror.js +9 -9
  35. package/dist/esm/models/errors/responsevalidationerror.js.map +1 -1
  36. package/dist/esm/models/errors/sdkvalidationerror.d.ts +2 -2
  37. package/dist/esm/models/errors/sdkvalidationerror.d.ts.map +1 -1
  38. package/dist/esm/models/errors/sdkvalidationerror.js +18 -10
  39. package/dist/esm/models/errors/sdkvalidationerror.js.map +1 -1
  40. package/dist/esm/tests/integration/env-auth-ingestion.test.d.ts +2 -0
  41. package/dist/esm/tests/integration/env-auth-ingestion.test.d.ts.map +1 -0
  42. package/dist/esm/tests/integration/env-auth-ingestion.test.js +183 -0
  43. package/dist/esm/tests/integration/env-auth-ingestion.test.js.map +1 -0
  44. package/package.json +1 -1
  45. package/src/hooks/sdk-identifier.ts +3 -3
  46. package/src/lib/config.ts +6 -4
  47. package/src/lib/galileo-config.ts +26 -5
  48. package/src/models/errors/responsevalidationerror.ts +14 -10
  49. package/src/models/errors/sdkvalidationerror.ts +20 -11
  50. package/src/tests/integration/env-auth-ingestion.test.ts +254 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=env-auth-ingestion.test.d.ts.map
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "galileo-generated",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "author": "Galileo/Speakeasy",
5
5
  "repository": {
6
6
  "type": "git",
@@ -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 won't be enabled yet due to Speakeasy's
13
- // particular way of enabling persistent edits conflicting with workflow.
14
- // Ticket sc-56960 created for this investigation.
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). DO NOT EDIT.
3
- * @generated-id: 320761608fb3
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 { Params, pathToFunc } from "./url.js";
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
- let serverURL = options.serverURL;
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 "https://api.galileo.ai";
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 || "https://console.galileo.ai";
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" → "https://api.galileo.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). DO NOT EDIT.
3
- * @generated-id: 88ff98a41be9
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
- public readonly rawValue: unknown;
14
+ protected readonly rawValue: unknown;
15
15
 
16
16
  /**
17
17
  * The raw message that failed validation.
18
18
  */
19
- public readonly rawMessage: unknown;
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 = extra.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
- if (this.cause instanceof z.$ZodError) {
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). DO NOT EDIT.
3
- * @generated-id: fb6b2b49c445
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
- public readonly rawValue: unknown;
12
+ protected readonly rawValue: unknown;
13
13
 
14
14
  /**
15
15
  * The raw message that failed validation.
16
16
  */
17
- public readonly rawMessage: unknown;
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
- super(`${message}: ${cause}`);
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 = 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
- if (this.cause instanceof z.$ZodError) {
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