Skip to content

Commit 037f18d

Browse files
committed
Improve result type consistency and compatibility
- Replace CResult with SocketSdkGenericResult for getApi/sendApi - Add symmetric properties (data, error, cause) to all result types - Use HTTP status codes consistently across result types - Improve TypeScript narrowing with explicit undefined types
1 parent fe8bd75 commit 037f18d

2 files changed

Lines changed: 92 additions & 52 deletions

File tree

src/socket-sdk-class.ts

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ import type {
4646
ArtifactPatches,
4747
BatchPackageFetchResultType,
4848
BatchPackageStreamOptions,
49-
CResult,
5049
CompactSocketArtifact,
5150
CustomResponseType,
5251
Entitlement,
@@ -59,6 +58,7 @@ import type {
5958
SendOptions,
6059
SocketArtifact,
6160
SocketSdkErrorResult,
61+
SocketSdkGenericResult,
6262
SocketSdkOperations,
6363
SocketSdkOptions,
6464
SocketSdkResult,
@@ -254,6 +254,7 @@ export class SocketSdk {
254254
}
255255
return {
256256
cause: body,
257+
data: undefined,
257258
error: errorMessage,
258259
/* c8 ignore next - fallback for missing status code in edge cases. */
259260
status: statusCode ?? 0,
@@ -269,7 +270,9 @@ export class SocketSdk {
269270
data: unknown,
270271
): SocketSdkSuccessResult<T> {
271272
return {
273+
cause: undefined,
272274
data: data as SocketSdkSuccessResult<T>['data'],
275+
error: undefined,
273276
// Use generic 200 OK status for all successful API responses.
274277
status: 200,
275278
success: true,
@@ -1833,7 +1836,7 @@ export class SocketSdk {
18331836
* Create standardized error result from query operation exceptions.
18341837
* Internal error handling for non-throwing query API methods.
18351838
*/
1836-
#createQueryErrorResult<T>(e: unknown): CResult<T> {
1839+
#createQueryErrorResult<T>(e: unknown): SocketSdkGenericResult<T> {
18371840
if (e instanceof SyntaxError) {
18381841
// Try to get response text from enhanced error, fall back to regex pattern for compatibility.
18391842
const enhancedError = e as SyntaxError & { originalResponse?: string }
@@ -1849,29 +1852,37 @@ export class SocketSdk {
18491852
/* c8 ignore next - Defensive empty string fallback when slice returns empty. */
18501853
const preview = responseText.slice(0, 100) || ''
18511854
return {
1852-
ok: false,
1853-
message: 'Server returned invalid JSON',
18541855
cause: `Please report this. JSON.parse threw an error over the following response: \`${preview.trim()}${responseText.length > 100 ? '...' : ''}\``,
1855-
} as CResult<T>
1856+
data: undefined,
1857+
error: 'Server returned invalid JSON',
1858+
status: 0,
1859+
success: false,
1860+
}
18561861
}
18571862

18581863
/* c8 ignore start - Defensive error stringification fallback branches for edge cases. */
18591864
const errStr = e ? String(e).trim() : ''
18601865
return {
1861-
ok: false,
1862-
message: 'API request failed',
18631866
cause: errStr || UNKNOWN_ERROR,
1864-
} as CResult<T>
1867+
data: undefined,
1868+
error: 'API request failed',
1869+
status: 0,
1870+
success: false,
1871+
}
18651872
/* c8 ignore stop */
18661873
}
18671874

18681875
/**
18691876
* Execute a raw GET request to any API endpoint with configurable response type.
1877+
* Supports both throwing (default) and non-throwing modes.
1878+
* @param urlPath - API endpoint path (e.g., 'organizations')
1879+
* @param options - Request options including responseType and throws behavior
1880+
* @returns Raw response, parsed data, or SocketSdkGenericResult based on options
18701881
*/
18711882
async getApi<T = IncomingMessage>(
18721883
urlPath: string,
18731884
options?: GetOptions | undefined,
1874-
): Promise<T | CResult<T>> {
1885+
): Promise<T | SocketSdkGenericResult<T>> {
18751886
const { responseType = 'response', throws = true } = {
18761887
__proto__: null,
18771888
...options,
@@ -1892,12 +1903,12 @@ export class SocketSdk {
18921903
new ResponseError(response),
18931904
)
18941905
return {
1895-
ok: false,
1896-
code: errorResult.status,
1897-
message: 'Socket API error',
1898-
cause: errorResult.cause || errorResult.error,
1899-
data: { code: errorResult.status },
1900-
} as CResult<T>
1906+
cause: errorResult.cause,
1907+
data: undefined,
1908+
error: errorResult.error,
1909+
status: errorResult.status,
1910+
success: false,
1911+
}
19011912
}
19021913

19031914
const data = await this.#handleQueryResponseData<T>(
@@ -1910,25 +1921,29 @@ export class SocketSdk {
19101921
}
19111922

19121923
return {
1913-
ok: true,
1924+
cause: undefined,
19141925
data,
1915-
} as CResult<T>
1926+
error: undefined,
1927+
/* c8 ignore next - Defensive fallback: response.statusCode is always defined in Node.js http/https */
1928+
status: response.statusCode ?? 200,
1929+
success: true,
1930+
}
19161931
} catch (e) {
19171932
if (throws) {
19181933
throw e
19191934
}
19201935

19211936
if (e instanceof ResponseError) {
1922-
/* c8 ignore start - ResponseError handling in sendApi non-throwing mode */
1937+
/* c8 ignore start - ResponseError handling in getApi non-throwing mode covered by other tests */
19231938
// Re-use existing error handling logic from the SDK
19241939
const errorResult = await this.#handleApiError<any>(e)
19251940
return {
1926-
ok: false,
1927-
code: errorResult.status,
1928-
message: 'Socket API error',
1929-
cause: errorResult.cause || errorResult.error,
1930-
data: { code: errorResult.status },
1931-
} as CResult<T>
1941+
cause: errorResult.cause,
1942+
data: undefined,
1943+
error: errorResult.error,
1944+
status: errorResult.status,
1945+
success: false,
1946+
}
19321947
/* c8 ignore stop */
19331948
} /* c8 ignore next - Closing brace of error result handling. */
19341949

@@ -1939,11 +1954,15 @@ export class SocketSdk {
19391954

19401955
/**
19411956
* Send POST or PUT request with JSON body and return parsed JSON response.
1957+
* Supports both throwing (default) and non-throwing modes.
1958+
* @param urlPath - API endpoint path (e.g., 'organizations')
1959+
* @param options - Request options including method, body, and throws behavior
1960+
* @returns Parsed JSON response or SocketSdkGenericResult based on options
19421961
*/
19431962
async sendApi<T>(
19441963
urlPath: string,
19451964
options?: SendOptions | undefined,
1946-
): Promise<T | CResult<T>> {
1965+
): Promise<T | SocketSdkGenericResult<T>> {
19471966
const {
19481967
body,
19491968
// Default to POST method for JSON API requests.
@@ -1961,9 +1980,19 @@ export class SocketSdk {
19611980
this.#reqOptions,
19621981
)
19631982

1983+
const data = (await getResponseJson(response)) as T
1984+
1985+
if (throws) {
1986+
return data
1987+
}
1988+
19641989
return {
1965-
ok: true,
1966-
data: (await getResponseJson(response)) as T,
1990+
cause: undefined,
1991+
data,
1992+
error: undefined,
1993+
/* c8 ignore next - Defensive fallback: response.statusCode is always defined in Node.js http/https */
1994+
status: response.statusCode ?? 200,
1995+
success: true,
19671996
}
19681997
} catch (e) {
19691998
if (throws) {
@@ -1974,20 +2003,22 @@ export class SocketSdk {
19742003
// Re-use existing error handling logic from the SDK
19752004
const errorResult = await this.#handleApiError<any>(e)
19762005
return {
1977-
ok: false,
1978-
code: errorResult.status,
1979-
message: 'Socket API error',
1980-
cause: errorResult.cause || errorResult.error,
1981-
data: { code: errorResult.status },
2006+
cause: errorResult.cause,
2007+
data: undefined,
2008+
error: errorResult.error,
2009+
status: errorResult.status,
2010+
success: false,
19822011
}
19832012
}
19842013

19852014
/* c8 ignore start - Defensive error stringification fallback branches for sendApi edge cases. */
19862015
const errStr = e ? String(e).trim() : ''
19872016
return {
1988-
ok: false,
1989-
message: 'API request failed',
19902017
cause: errStr || UNKNOWN_ERROR,
2018+
data: undefined,
2019+
error: 'API request failed',
2020+
status: 0,
2021+
success: false,
19912022
}
19922023
/* c8 ignore stop */
19932024
}

src/types.ts

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -163,20 +163,41 @@ export type SocketArtifactAlert = Remap<
163163
export type SocketSdkOperations = keyof operations
164164

165165
export type SocketSdkSuccessResult<T extends SocketSdkOperations> =
166-
OpReturnType<operations[T]>
166+
OpReturnType<operations[T]> & {
167+
cause?: undefined
168+
error?: undefined
169+
}
167170

168171
export type SocketSdkErrorResult<T extends SocketSdkOperations> = Omit<
169172
OpErrorType<operations[T]>,
170173
'error'
171174
> & {
172-
error: string
173175
cause?: string | undefined
176+
data?: undefined
177+
error: string
174178
}
175179

176180
export type SocketSdkResult<T extends SocketSdkOperations> =
177181
| SocketSdkSuccessResult<T>
178182
| SocketSdkErrorResult<T>
179183

184+
// Generic result type for methods not mapped to specific operations
185+
export type SocketSdkGenericResult<T> =
186+
| {
187+
cause?: undefined
188+
data: T
189+
error?: undefined
190+
status: number
191+
success: true
192+
}
193+
| {
194+
cause?: string | undefined
195+
data?: undefined
196+
error: string
197+
status: number
198+
success: false
199+
}
200+
180201
export interface SocketSdkOptions {
181202
agent?: Agent | GotOptions | undefined
182203
baseUrl?: string | undefined
@@ -190,33 +211,21 @@ export type UploadManifestFilesResponse = {
190211
}
191212

192213
export type UploadManifestFilesReturnType = {
214+
cause?: undefined
193215
data: UploadManifestFilesResponse
216+
error?: undefined
194217
status: 200
195218
success: true
196219
}
197220

198221
export type UploadManifestFilesError = {
222+
cause?: string | undefined
223+
data?: undefined
199224
error: string
200225
status: number
201226
success: false
202-
cause: string | undefined
203227
}
204228

205-
// CResult pattern for non-throwing API operations
206-
export type CResult<T> =
207-
| {
208-
data: T
209-
ok: true
210-
message?: string | undefined
211-
}
212-
| {
213-
message: string
214-
ok: false
215-
cause?: string | undefined
216-
code?: number | undefined
217-
data?: unknown | undefined
218-
}
219-
220229
// Derived types that depend on SocketSdkOperations
221230
export type BatchPackageFetchResultType = SocketSdkResult<'batchPackageFetch'>
222231

0 commit comments

Comments
 (0)