Skip to content

Commit fd0a093

Browse files
committed
Cleanup sdk factory
1 parent c9de7a8 commit fd0a093

File tree

2 files changed

+75
-44
lines changed

2 files changed

+75
-44
lines changed

src/utils/api.mts

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { messageWithCauses } from 'pony-cause'
2+
13
import { debugDir, debugFn } from '@socketsecurity/registry/lib/debug'
24
import { logger } from '@socketsecurity/registry/lib/logger'
35
import { isNonEmptyString } from '@socketsecurity/registry/lib/strings'
@@ -9,21 +11,24 @@ import { failMsgWithBadge } from './fail-msg-with-badge.mts'
911
import { getDefaultToken } from './sdk.mts'
1012

1113
import type { CResult } from '../types.mts'
14+
import type { Spinner } from '@socketsecurity/registry/lib/spinner'
1215
import type {
1316
SocketSdkErrorResult,
1417
SocketSdkOperations,
1518
SocketSdkResult,
1619
SocketSdkSuccessResult,
1720
} from '@socketsecurity/sdk'
1821

22+
const NO_ERROR_MESSAGE = 'No error message returned'
23+
1924
// TODO: this function is removed after v1.0.0
2025
export function handleUnsuccessfulApiResponse<T extends SocketSdkOperations>(
2126
_name: T,
2227
error: string,
2328
cause: string,
2429
status: number,
2530
): never {
26-
const message = `${error || 'No error message returned'}${cause ? ` (reason: ${cause})` : ''}`
31+
const message = `${error || NO_ERROR_MESSAGE}${cause ? ` (reason: ${cause})` : ''}`
2732
if (status === 401 || status === 403) {
2833
// Lazily access constants.spinner.
2934
const { spinner } = constants
@@ -37,63 +42,82 @@ export function handleUnsuccessfulApiResponse<T extends SocketSdkOperations>(
3742
process.exit(1)
3843
}
3944

45+
export type HandleApiCallOptions = {
46+
desc?: string | undefined
47+
spinner?: Spinner | undefined
48+
}
49+
4050
export async function handleApiCall<T extends SocketSdkOperations>(
4151
value: Promise<SocketSdkResult<T>>,
42-
fetchingDesc: string,
52+
options?: HandleApiCallOptions | undefined,
4353
): Promise<CResult<SocketSdkSuccessResult<T>['data']>> {
44-
// Lazily access constants.spinner.
45-
const { spinner } = constants
54+
const { desc, spinner } = {
55+
__proto__: null,
56+
...options,
57+
} as HandleApiCallOptions
4658

47-
spinner.start(`Requesting ${fetchingDesc} from API...`)
59+
if (desc) {
60+
spinner?.start(`Requesting ${desc} from API...`)
61+
} else {
62+
spinner?.start()
63+
}
4864

49-
let result: SocketSdkResult<T>
65+
let sdkResult: SocketSdkResult<T>
5066
try {
51-
result = await value
52-
53-
// TODO: info, not success (looks weird when response is non-200)
54-
spinner.successAndStop(
55-
`Received API response (after requesting ${fetchingDesc}).`,
56-
)
67+
sdkResult = await value
68+
if (desc) {
69+
// TODO: info, not success (looks weird when response is non-200)
70+
spinner?.successAndStop(
71+
`Received API response (after requesting ${desc}).`,
72+
)
73+
} else {
74+
spinner?.stop()
75+
}
5776
} catch (e) {
58-
spinner.failAndStop(`An error was thrown while requesting ${fetchingDesc}`)
59-
60-
const message = `${e || 'No error message returned'}`
61-
const reason = `${e || 'No error message returned'}`
62-
63-
debugFn('error', `caught: ${fetchingDesc} error`)
77+
if (desc) {
78+
spinner?.failAndStop(`An error was thrown while requesting ${desc}`)
79+
debugFn('error', `caught: ${desc} error`)
80+
} else {
81+
spinner?.stop()
82+
debugFn('error', `caught: error`)
83+
}
6484
debugDir('inspect', { error: e })
6585

6686
return {
6787
ok: false,
6888
message: 'Socket API returned an error',
69-
cause: `${message}${reason ? ` ( Reason: ${reason} )` : ''}`,
89+
cause: messageWithCauses(e as Error),
7090
}
7191
} finally {
72-
spinner.stop()
92+
spinner?.stop()
7393
}
7494

75-
// Note: TS can't narrow down the type of result due to generics
76-
if (result.success === false) {
77-
const error = result as SocketSdkErrorResult<T>
78-
const message = `${error.error || 'No error message returned'}`
79-
const { cause: reason } = error
95+
// Note: TS can't narrow down the type of result due to generics.
96+
if (sdkResult.success === false) {
97+
const errorResult = sdkResult as SocketSdkErrorResult<T>
98+
const message = `${errorResult.error || NO_ERROR_MESSAGE}`
99+
const { cause: reason } = errorResult
80100

81-
debugFn('error', `fail: ${fetchingDesc} bad response`)
82-
debugDir('inspect', { error })
101+
if (desc) {
102+
debugFn('error', `fail: ${desc} bad response`)
103+
} else {
104+
debugFn('error', 'fail: bad response')
105+
}
106+
debugDir('inspect', { sdkResult })
83107

84108
return {
85109
ok: false,
86110
message: 'Socket API returned an error',
87111
cause: `${message}${reason ? ` ( Reason: ${reason} )` : ''}`,
88112
data: {
89-
code: result.status,
113+
code: sdkResult.status,
90114
},
91115
}
92116
} else {
93-
const ok = result as SocketSdkSuccessResult<T>
117+
const { data } = sdkResult as SocketSdkSuccessResult<T>
94118
return {
95119
ok: true,
96-
data: ok.data,
120+
data,
97121
}
98122
}
99123
}
@@ -106,8 +130,8 @@ export async function handleApiCallNoSpinner<T extends SocketSdkOperations>(
106130
try {
107131
result = await value
108132
} catch (e) {
109-
const message = `${e || 'No error message returned'}`
110-
const reason = `${e || 'No error message returned'}`
133+
const message = `${e || NO_ERROR_MESSAGE}`
134+
const reason = `${e || NO_ERROR_MESSAGE}`
111135

112136
debugFn('error', `caught: ${description} error`)
113137
debugDir('inspect', { error: e })
@@ -122,7 +146,7 @@ export async function handleApiCallNoSpinner<T extends SocketSdkOperations>(
122146
// Note: TS can't narrow down the type of result due to generics
123147
if (result.success === false) {
124148
const error = result as SocketSdkErrorResult<T>
125-
const message = `${error.error || 'No error message returned'}`
149+
const message = `${error.error || NO_ERROR_MESSAGE}`
126150

127151
debugFn('error', `fail: ${description} bad response`)
128152
debugDir('inspect', { error })

src/utils/sdk.mts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,41 +79,48 @@ export function getPublicToken(): string {
7979
)
8080
}
8181

82+
export type SetupSdkOptions = {
83+
apiToken?: string | undefined
84+
apiBaseUrl?: string | undefined
85+
apiProxy?: string | undefined
86+
}
87+
8288
export async function setupSdk(
83-
apiToken: string | undefined = getDefaultToken(),
84-
apiBaseUrl: string | undefined = getDefaultApiBaseUrl(),
85-
proxy?: string | undefined,
89+
options?: SetupSdkOptions | undefined,
8690
): Promise<CResult<SocketSdk>> {
91+
const opts = { __proto__: null, ...options } as SetupSdkOptions
92+
let { apiToken = getDefaultToken() } = opts
93+
8794
if (typeof apiToken !== 'string' && isInteractive()) {
8895
apiToken = await password({
8996
message:
9097
'Enter your Socket.dev API key (not saved, use socket login to persist)',
9198
})
9299
_defaultToken = apiToken
93100
}
101+
94102
if (!apiToken) {
95103
return {
96104
ok: false,
97105
message: 'Auth Error',
98106
cause: 'You need to provide an API Token. Run `socket login` first.',
99107
}
100108
}
101-
if (!isUrl(proxy)) {
102-
proxy = getDefaultProxyUrl()
109+
110+
let { apiProxy } = opts
111+
if (!isUrl(apiProxy)) {
112+
apiProxy = getDefaultProxyUrl()
103113
}
104114

105-
const ProxyAgent = proxy?.startsWith('http:')
115+
const { apiBaseUrl = getDefaultApiBaseUrl() } = opts
116+
const ProxyAgent = apiProxy?.startsWith('http:')
106117
? HttpProxyAgent
107118
: HttpsProxyAgent
108119

109120
return {
110121
ok: true,
111122
data: new SocketSdk(apiToken, {
112-
agent: proxy
113-
? new ProxyAgent({
114-
proxy,
115-
})
116-
: undefined,
123+
agent: apiProxy ? new ProxyAgent({ proxy: apiProxy }) : undefined,
117124
baseUrl: apiBaseUrl,
118125
userAgent: createUserAgentFromPkgJson({
119126
// Lazily access constants.ENV.INLINED_SOCKET_CLI_NAME.

0 commit comments

Comments
 (0)