@socketsecurity/sdk 1.10.1 → 1.11.0

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/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.11.0](https://github.com/SocketDev/socket-sdk-js/releases/tag/v1.11.0) - 2025-10-04
8
+
9
+ ### Added
10
+ - Optional TTL caching for API responses with configurable cache duration
11
+ - New `cache` option (default: false) to enable response caching
12
+ - New `cacheTtl` option (default: 5 minutes) to customize cache duration
13
+
7
14
  ## [1.10.1](https://github.com/SocketDev/socket-sdk-js/releases/tag/v1.10.1) - 2025-10-04
8
15
 
9
16
  ### Added
package/README.md CHANGED
@@ -20,8 +20,8 @@ pnpm add @socketsecurity/sdk
20
20
  import { SocketSdk } from '@socketsecurity/sdk'
21
21
 
22
22
  const client = new SocketSdk('yourApiKeyHere', {
23
- retries: 3, // Retry failed requests up to 3 times (default: 3)
24
- retryDelay: 1000, // Start with 1s delay, exponential backoff (default: 1000ms)
23
+ retries: 3, // Retry failed requests up to 3 times (default: 0, disabled)
24
+ retryDelay: 1000, // Start with 1s delay, exponential backoff (default: 100ms)
25
25
  timeout: 30000, // Request timeout in milliseconds (optional)
26
26
  })
27
27
 
@@ -41,18 +41,19 @@ The SDK constructor accepts the following options:
41
41
  interface SocketSdkOptions {
42
42
  baseUrl?: string // API base URL (default: 'https://api.socket.dev/v0/')
43
43
  timeout?: number // Request timeout in milliseconds
44
- retries?: number // Number of retry attempts for failed requests (default: 3)
45
- retryDelay?: number // Initial retry delay in ms, with exponential backoff (default: 1000)
44
+ retries?: number // Number of retry attempts for failed requests (default: 0, disabled)
45
+ retryDelay?: number // Initial retry delay in ms, with exponential backoff (default: 100)
46
46
  userAgent?: string // Custom user agent string
47
47
  agent?: Agent // Custom HTTP agent for advanced networking
48
48
  }
49
49
  ```
50
50
 
51
51
  **Retry Logic:**
52
- - Automatically retries transient network errors and 5xx server responses
53
- - Uses exponential backoff: 1s, 2s, 4s, 8s... (configurable via `retryDelay`)
52
+ - **Disabled by default** (opt-in pattern following Node.js fs.rm() convention)
53
+ - Set `retries: 3` (recommended for production) to enable automatic retries
54
+ - Retries transient network errors and 5xx server responses
55
+ - Uses exponential backoff: 100ms, 200ms, 400ms, 800ms... (configurable via `retryDelay`)
54
56
  - Does NOT retry 401/403 authentication errors (immediate failure)
55
- - Set `retries: 0` to disable retry logic entirely
56
57
 
57
58
  ### Quota Management Example
58
59
 
@@ -81,8 +81,8 @@ export declare function reshapeArtifactForPublicPolicy<T extends Record<string,
81
81
  * Wraps any async HTTP function and retries on failure.
82
82
  *
83
83
  * @param fn - Async function to retry
84
- * @param retries - Number of retry attempts (default: 3)
85
- * @param retryDelay - Initial delay in ms (default: 1000)
84
+ * @param retries - Number of retry attempts (default: 0, retries disabled)
85
+ * @param retryDelay - Initial delay in ms (default: 100)
86
86
  * @returns Result of the function call
87
87
  * @throws {Error} Last error if all retries exhausted
88
88
  */
@@ -91,23 +91,23 @@ export declare function withRetry<T>(fn: () => Promise<T>, retries?: number, ret
91
91
  * Create GET request with automatic retry logic.
92
92
  * Retries on network errors and 5xx responses.
93
93
  *
94
- * @param retries - Number of retry attempts (default: 3)
95
- * @param retryDelay - Initial delay in ms (default: 1000)
94
+ * @param retries - Number of retry attempts (default: 0, retries disabled)
95
+ * @param retryDelay - Initial delay in ms (default: 100)
96
96
  */
97
97
  export declare function createGetRequestWithRetry(baseUrl: string, urlPath: string, options: RequestOptions, retries?: number, retryDelay?: number): Promise<IncomingMessage>;
98
98
  /**
99
99
  * Create DELETE request with automatic retry logic.
100
100
  * Retries on network errors and 5xx responses.
101
101
  *
102
- * @param retries - Number of retry attempts (default: 3)
103
- * @param retryDelay - Initial delay in ms (default: 1000)
102
+ * @param retries - Number of retry attempts (default: 0, retries disabled)
103
+ * @param retryDelay - Initial delay in ms (default: 100)
104
104
  */
105
105
  export declare function createDeleteRequestWithRetry(baseUrl: string, urlPath: string, options: RequestOptions, retries?: number, retryDelay?: number): Promise<IncomingMessage>;
106
106
  /**
107
107
  * Create request with JSON payload and automatic retry logic.
108
108
  * Retries on network errors and 5xx responses.
109
109
  *
110
- * @param retries - Number of retry attempts (default: 3)
111
- * @param retryDelay - Initial delay in ms (default: 1000)
110
+ * @param retries - Number of retry attempts (default: 0, retries disabled)
111
+ * @param retryDelay - Initial delay in ms (default: 100)
112
112
  */
113
113
  export declare function createRequestWithJsonAndRetry(method: SendMethod, baseUrl: string, urlPath: string, json: unknown, options: RequestOptions, retries?: number, retryDelay?: number): Promise<IncomingMessage>;
@@ -273,12 +273,12 @@ function reshapeArtifactForPublicPolicy(data, isAuthenticated, actions) {
273
273
  * Wraps any async HTTP function and retries on failure.
274
274
  *
275
275
  * @param fn - Async function to retry
276
- * @param retries - Number of retry attempts (default: 3)
277
- * @param retryDelay - Initial delay in ms (default: 1000)
276
+ * @param retries - Number of retry attempts (default: 0, retries disabled)
277
+ * @param retryDelay - Initial delay in ms (default: 100)
278
278
  * @returns Result of the function call
279
279
  * @throws {Error} Last error if all retries exhausted
280
280
  */
281
- async function withRetry(fn, retries = 3, retryDelay = 1000) {
281
+ async function withRetry(fn, retries = 0, retryDelay = 100) {
282
282
  let lastError;
283
283
  for (let attempt = 0; attempt <= retries; attempt++) {
284
284
  try {
@@ -319,29 +319,29 @@ async function withRetry(fn, retries = 3, retryDelay = 1000) {
319
319
  * Create GET request with automatic retry logic.
320
320
  * Retries on network errors and 5xx responses.
321
321
  *
322
- * @param retries - Number of retry attempts (default: 3)
323
- * @param retryDelay - Initial delay in ms (default: 1000)
322
+ * @param retries - Number of retry attempts (default: 0, retries disabled)
323
+ * @param retryDelay - Initial delay in ms (default: 100)
324
324
  */
325
- async function createGetRequestWithRetry(baseUrl, urlPath, options, retries = 3, retryDelay = 1000) {
325
+ async function createGetRequestWithRetry(baseUrl, urlPath, options, retries = 0, retryDelay = 100) {
326
326
  return await withRetry(() => createGetRequest(baseUrl, urlPath, options), retries, retryDelay);
327
327
  }
328
328
  /**
329
329
  * Create DELETE request with automatic retry logic.
330
330
  * Retries on network errors and 5xx responses.
331
331
  *
332
- * @param retries - Number of retry attempts (default: 3)
333
- * @param retryDelay - Initial delay in ms (default: 1000)
332
+ * @param retries - Number of retry attempts (default: 0, retries disabled)
333
+ * @param retryDelay - Initial delay in ms (default: 100)
334
334
  */
335
- async function createDeleteRequestWithRetry(baseUrl, urlPath, options, retries = 3, retryDelay = 1000) {
335
+ async function createDeleteRequestWithRetry(baseUrl, urlPath, options, retries = 0, retryDelay = 100) {
336
336
  return await withRetry(() => createDeleteRequest(baseUrl, urlPath, options), retries, retryDelay);
337
337
  }
338
338
  /**
339
339
  * Create request with JSON payload and automatic retry logic.
340
340
  * Retries on network errors and 5xx responses.
341
341
  *
342
- * @param retries - Number of retry attempts (default: 3)
343
- * @param retryDelay - Initial delay in ms (default: 1000)
342
+ * @param retries - Number of retry attempts (default: 0, retries disabled)
343
+ * @param retryDelay - Initial delay in ms (default: 100)
344
344
  */
345
- async function createRequestWithJsonAndRetry(method, baseUrl, urlPath, json, options, retries = 3, retryDelay = 1000) {
345
+ async function createRequestWithJsonAndRetry(method, baseUrl, urlPath, json, options, retries = 0, retryDelay = 100) {
346
346
  return await withRetry(() => createRequestWithJson(method, baseUrl, urlPath, json, options), retries, retryDelay);
347
347
  }
@@ -8,7 +8,7 @@ export declare class SocketSdk {
8
8
  #private;
9
9
  /**
10
10
  * Initialize Socket SDK with API token and configuration options.
11
- * Sets up authentication, base URL, HTTP client options, and retry behavior.
11
+ * Sets up authentication, base URL, HTTP client options, retry behavior, and caching.
12
12
  */
13
13
  constructor(apiToken: string, options?: SocketSdkOptions | undefined);
14
14
  /**
@@ -11,6 +11,7 @@ exports.SocketSdk = void 0;
11
11
  const node_events_1 = __importDefault(require("node:events"));
12
12
  const node_fs_1 = require("node:fs");
13
13
  const node_readline_1 = __importDefault(require("node:readline"));
14
+ const cache_with_ttl_1 = require("@socketsecurity/registry/lib/cache-with-ttl");
14
15
  const SOCKET_PUBLIC_API_TOKEN_1 = __importDefault(require("@socketsecurity/registry/lib/constants/SOCKET_PUBLIC_API_TOKEN"));
15
16
  const UNKNOWN_ERROR_1 = __importDefault(require("@socketsecurity/registry/lib/constants/UNKNOWN_ERROR"));
16
17
  const abort_signal_1 = __importDefault(require("@socketsecurity/registry/lib/constants/abort-signal"));
@@ -30,15 +31,16 @@ const utils_1 = require("./utils");
30
31
  class SocketSdk {
31
32
  #apiToken;
32
33
  #baseUrl;
34
+ #cache;
33
35
  #reqOptions;
34
36
  #retries;
35
37
  #retryDelay;
36
38
  /**
37
39
  * Initialize Socket SDK with API token and configuration options.
38
- * Sets up authentication, base URL, HTTP client options, and retry behavior.
40
+ * Sets up authentication, base URL, HTTP client options, retry behavior, and caching.
39
41
  */
40
42
  constructor(apiToken, options) {
41
- const { agent: agentOrObj, baseUrl = 'https://api.socket.dev/v0/', retries = 3, retryDelay = 1000, timeout, userAgent, } = { __proto__: null, ...options };
43
+ const { agent: agentOrObj, baseUrl = 'https://api.socket.dev/v0/', cache = false, cacheTtl = 5 * 60 * 1000, retries = 0, retryDelay = 100, timeout, userAgent, } = { __proto__: null, ...options };
42
44
  const agentKeys = agentOrObj ? Object.keys(agentOrObj) : [];
43
45
  const agentAsGotOptions = agentOrObj;
44
46
  const agent = (agentKeys.length && agentKeys.every(k => constants_1.httpAgentNames.has(k))
@@ -49,6 +51,13 @@ class SocketSdk {
49
51
  : agentOrObj);
50
52
  this.#apiToken = apiToken;
51
53
  this.#baseUrl = (0, utils_1.normalizeBaseUrl)(baseUrl);
54
+ this.#cache = cache
55
+ ? (0, cache_with_ttl_1.createTtlCache)({
56
+ memoize: true,
57
+ prefix: 'socket-sdk',
58
+ ttl: cacheTtl,
59
+ })
60
+ : undefined;
52
61
  this.#retries = retries;
53
62
  this.#retryDelay = retryDelay;
54
63
  this.#reqOptions = {
@@ -88,6 +97,20 @@ class SocketSdk {
88
97
  }
89
98
  return result;
90
99
  }
100
+ /**
101
+ * Execute a GET request with optional caching.
102
+ * Internal method for handling cached GET requests with retry logic.
103
+ */
104
+ async #getCached(cacheKey, fetcher) {
105
+ // If caching is disabled, just execute the request.
106
+ if (!this.#cache) {
107
+ return await this.#executeWithRetry(fetcher);
108
+ }
109
+ // Use cache with retry logic.
110
+ return await this.#cache.getOrFetch(cacheKey, async () => {
111
+ return await this.#executeWithRetry(fetcher);
112
+ });
113
+ }
91
114
  /**
92
115
  * Create async generator for streaming batch package URL processing.
93
116
  * Internal method for handling chunked PURL responses with error handling.
@@ -812,7 +835,7 @@ class SocketSdk {
812
835
  */
813
836
  async getOrganizations() {
814
837
  try {
815
- const data = await this.#executeWithRetry(async () => await (0, http_client_1.getResponseJson)(await (0, http_client_1.createGetRequest)(this.#baseUrl, 'organizations', this.#reqOptions)));
838
+ const data = await this.#getCached('organizations', async () => await (0, http_client_1.getResponseJson)(await (0, http_client_1.createGetRequest)(this.#baseUrl, 'organizations', this.#reqOptions)));
816
839
  return this.#handleApiSuccess(data);
817
840
  }
818
841
  catch (e) {
@@ -977,7 +1000,7 @@ class SocketSdk {
977
1000
  */
978
1001
  async getQuota() {
979
1002
  try {
980
- const data = await this.#executeWithRetry(async () => await (0, http_client_1.getResponseJson)(await (0, http_client_1.createGetRequest)(this.#baseUrl, 'quota', this.#reqOptions)));
1003
+ const data = await this.#getCached('quota', async () => await (0, http_client_1.getResponseJson)(await (0, http_client_1.createGetRequest)(this.#baseUrl, 'quota', this.#reqOptions)));
981
1004
  return this.#handleApiSuccess(data);
982
1005
  }
983
1006
  catch (e) {
package/dist/types.d.ts CHANGED
@@ -129,12 +129,38 @@ export type SocketSdkGenericResult<T> = {
129
129
  status: number;
130
130
  success: false;
131
131
  };
132
+ /**
133
+ * Configuration options for SocketSdk.
134
+ */
132
135
  export interface SocketSdkOptions {
136
+ /** HTTP agent for connection pooling and proxy support */
133
137
  agent?: Agent | GotOptions | undefined;
138
+ /** Base URL for Socket API (default: 'https://api.socket.dev/v0/') */
134
139
  baseUrl?: string | undefined;
140
+ /**
141
+ * Enable TTL caching for API responses (default: false).
142
+ * When enabled, GET requests are cached with a 5-minute TTL.
143
+ */
144
+ cache?: boolean | undefined;
145
+ /**
146
+ * Cache TTL in milliseconds (default: 300000 = 5 minutes).
147
+ * Only used when cache is enabled.
148
+ */
149
+ cacheTtl?: number | undefined;
150
+ /**
151
+ * Number of retry attempts on failure (default: 0, retries disabled).
152
+ * Retries are opt-in following Node.js fs.rm() pattern.
153
+ * Recommended: 3 for production, 0 for testing.
154
+ */
135
155
  retries?: number | undefined;
156
+ /**
157
+ * Initial delay in milliseconds between retries (default: 100).
158
+ * Uses exponential backoff: 100ms, 200ms, 400ms, etc.
159
+ */
136
160
  retryDelay?: number | undefined;
161
+ /** Request timeout in milliseconds */
137
162
  timeout?: number | undefined;
163
+ /** Custom User-Agent header */
138
164
  userAgent?: string | undefined;
139
165
  }
140
166
  export type UploadManifestFilesResponse = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@socketsecurity/sdk",
3
- "version": "1.10.1",
3
+ "version": "1.11.0",
4
4
  "license": "MIT",
5
5
  "description": "SDK for the Socket API client",
6
6
  "author": {
@@ -75,7 +75,7 @@
75
75
  "update:socket": "pnpm -r update '@socketsecurity/*' --latest"
76
76
  },
77
77
  "dependencies": {
78
- "@socketsecurity/registry": "1.4.1"
78
+ "@socketsecurity/registry": "1.4.2"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@biomejs/biome": "2.2.4",