@forklaunch/universal-sdk 0.5.3 → 0.6.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/lib/index.d.mts CHANGED
@@ -17,7 +17,7 @@ type RegistryOptions = {
17
17
  url: string;
18
18
  static?: boolean;
19
19
  } | {
20
- raw: OpenAPIObject;
20
+ raw: OpenAPIObject | Record<string, OpenAPIObject>;
21
21
  };
22
22
 
23
23
  /**
package/lib/index.d.ts CHANGED
@@ -17,7 +17,7 @@ type RegistryOptions = {
17
17
  url: string;
18
18
  static?: boolean;
19
19
  } | {
20
- raw: OpenAPIObject;
20
+ raw: OpenAPIObject | Record<string, OpenAPIObject>;
21
21
  };
22
22
 
23
23
  /**
package/lib/index.js CHANGED
@@ -170,11 +170,16 @@ function mapContentType(contentType) {
170
170
  }
171
171
  }
172
172
 
173
+ // src/guards/isOpenApiObject.ts
174
+ function isOpenAPIObject(obj) {
175
+ return typeof obj === "object" && obj !== null && "openapi" in obj;
176
+ }
177
+
173
178
  // src/core/openApi.ts
174
179
  function getSdkPathMap(registryOpenApiJson) {
175
180
  const sdkPathMap = {};
176
- Object.entries(registryOpenApiJson?.paths || {}).forEach(
177
- ([path, pathItem]) => {
181
+ Object.entries(registryOpenApiJson).forEach(([version, openApi]) => {
182
+ Object.entries(openApi?.paths || {}).forEach(([path, pathItem]) => {
178
183
  const methods = [
179
184
  "get",
180
185
  "post",
@@ -185,16 +190,18 @@ function getSdkPathMap(registryOpenApiJson) {
185
190
  "head",
186
191
  "trace"
187
192
  ];
193
+ const versionedPath = version === "latest" ? void 0 : version.substring(1);
188
194
  methods.forEach((method) => {
189
195
  if (pathItem[method]?.operationId) {
190
- sdkPathMap[pathItem[method].operationId] = {
196
+ sdkPathMap[`${pathItem[method].operationId}${versionedPath ? `.${versionedPath}` : ""}`] = {
191
197
  method,
192
- path
198
+ path,
199
+ version
193
200
  };
194
201
  }
195
202
  });
196
- }
197
- );
203
+ });
204
+ });
198
205
  return sdkPathMap;
199
206
  }
200
207
  async function refreshOpenApi(host, registryOptions, existingRegistryOpenApiHash) {
@@ -204,11 +211,14 @@ async function refreshOpenApi(host, registryOptions, existingRegistryOpenApiHash
204
211
  };
205
212
  }
206
213
  if ("raw" in registryOptions) {
214
+ const rawVersionedOpenApi = isOpenAPIObject(registryOptions.raw) ? {
215
+ latest: registryOptions.raw
216
+ } : registryOptions.raw;
207
217
  return {
208
218
  updateRequired: true,
209
- registryOpenApiJson: registryOptions.raw,
219
+ registryOpenApiJson: rawVersionedOpenApi,
210
220
  registryOpenApiHash: "static",
211
- sdkPathMap: getSdkPathMap(registryOptions.raw)
221
+ sdkPathMap: getSdkPathMap(rawVersionedOpenApi)
212
222
  };
213
223
  }
214
224
  const registry = "path" in registryOptions ? `${host}/${registryOptions.path}` : "url" in registryOptions ? registryOptions.url : null;
@@ -394,7 +404,12 @@ var UniversalSdk = class _UniversalSdk {
394
404
  this.registryOpenApiHash = refreshResult.registryOpenApiHash;
395
405
  this.sdkPathMap = refreshResult.sdkPathMap;
396
406
  }
397
- return this.execute(path, request?.method ?? "get", request);
407
+ return this.execute(
408
+ path,
409
+ request?.method ?? "get",
410
+ request?.version ? `v${request.version}` : "latest",
411
+ request
412
+ );
398
413
  }
399
414
  async executeSdkCall(sdkPath, request) {
400
415
  if (!this.host) {
@@ -425,8 +440,8 @@ var UniversalSdk = class _UniversalSdk {
425
440
  if (fullSdkPath.length === 0) {
426
441
  throw new Error(`Sdk path not found: ${sdkPath}`);
427
442
  }
428
- const { method, path } = this.sdkPathMap?.[fullSdkPath.join(".")] || {};
429
- return this.execute(path, method, request);
443
+ const { method, path, version } = this.sdkPathMap?.[fullSdkPath.join(".")] || {};
444
+ return this.execute(path, method, version, request);
430
445
  }
431
446
  /**
432
447
  * Executes an HTTP request.
@@ -436,12 +451,14 @@ var UniversalSdk = class _UniversalSdk {
436
451
  * @param {RequestType} [request] - The request object.
437
452
  * @returns {Promise<ResponseType>} - The response object.
438
453
  */
439
- async execute(path, method, request) {
454
+ async execute(path, method, version, request) {
440
455
  const { params, body, query, headers } = request || {};
441
456
  let url = getSdkPath(this.host + path);
442
457
  if (params) {
443
458
  for (const key in params) {
444
- url = url.replace(`:${key}`, encodeURIComponent(params[key]));
459
+ const paramValue = encodeURIComponent(params[key]);
460
+ url = url.replace(`:${key}`, paramValue);
461
+ url = url.replace(`{${key}}`, paramValue);
445
462
  }
446
463
  }
447
464
  let defaultContentType = "application/json";
@@ -509,7 +526,7 @@ var UniversalSdk = class _UniversalSdk {
509
526
  },
510
527
  body: parsedBody
511
528
  });
512
- const responseOpenApi = path != null && method != null ? this.registryOpenApiJson?.paths?.[(0, import_common2.openApiCompliantPath)(path)]?.[method?.toLowerCase()]?.responses?.[response.status] : null;
529
+ const responseOpenApi = path != null && method != null ? this.registryOpenApiJson?.[version]?.paths?.[(0, import_common2.openApiCompliantPath)(path)]?.[method?.toLowerCase()]?.responses?.[response.status] : null;
513
530
  if (responseOpenApi == null) {
514
531
  throw new Error(
515
532
  `Response ${response.status} not found in OpenAPI spec for ${path} with method ${method}`
package/lib/index.mjs CHANGED
@@ -138,11 +138,16 @@ function mapContentType(contentType) {
138
138
  }
139
139
  }
140
140
 
141
+ // src/guards/isOpenApiObject.ts
142
+ function isOpenAPIObject(obj) {
143
+ return typeof obj === "object" && obj !== null && "openapi" in obj;
144
+ }
145
+
141
146
  // src/core/openApi.ts
142
147
  function getSdkPathMap(registryOpenApiJson) {
143
148
  const sdkPathMap = {};
144
- Object.entries(registryOpenApiJson?.paths || {}).forEach(
145
- ([path, pathItem]) => {
149
+ Object.entries(registryOpenApiJson).forEach(([version, openApi]) => {
150
+ Object.entries(openApi?.paths || {}).forEach(([path, pathItem]) => {
146
151
  const methods = [
147
152
  "get",
148
153
  "post",
@@ -153,16 +158,18 @@ function getSdkPathMap(registryOpenApiJson) {
153
158
  "head",
154
159
  "trace"
155
160
  ];
161
+ const versionedPath = version === "latest" ? void 0 : version.substring(1);
156
162
  methods.forEach((method) => {
157
163
  if (pathItem[method]?.operationId) {
158
- sdkPathMap[pathItem[method].operationId] = {
164
+ sdkPathMap[`${pathItem[method].operationId}${versionedPath ? `.${versionedPath}` : ""}`] = {
159
165
  method,
160
- path
166
+ path,
167
+ version
161
168
  };
162
169
  }
163
170
  });
164
- }
165
- );
171
+ });
172
+ });
166
173
  return sdkPathMap;
167
174
  }
168
175
  async function refreshOpenApi(host, registryOptions, existingRegistryOpenApiHash) {
@@ -172,11 +179,14 @@ async function refreshOpenApi(host, registryOptions, existingRegistryOpenApiHash
172
179
  };
173
180
  }
174
181
  if ("raw" in registryOptions) {
182
+ const rawVersionedOpenApi = isOpenAPIObject(registryOptions.raw) ? {
183
+ latest: registryOptions.raw
184
+ } : registryOptions.raw;
175
185
  return {
176
186
  updateRequired: true,
177
- registryOpenApiJson: registryOptions.raw,
187
+ registryOpenApiJson: rawVersionedOpenApi,
178
188
  registryOpenApiHash: "static",
179
- sdkPathMap: getSdkPathMap(registryOptions.raw)
189
+ sdkPathMap: getSdkPathMap(rawVersionedOpenApi)
180
190
  };
181
191
  }
182
192
  const registry = "path" in registryOptions ? `${host}/${registryOptions.path}` : "url" in registryOptions ? registryOptions.url : null;
@@ -362,7 +372,12 @@ var UniversalSdk = class _UniversalSdk {
362
372
  this.registryOpenApiHash = refreshResult.registryOpenApiHash;
363
373
  this.sdkPathMap = refreshResult.sdkPathMap;
364
374
  }
365
- return this.execute(path, request?.method ?? "get", request);
375
+ return this.execute(
376
+ path,
377
+ request?.method ?? "get",
378
+ request?.version ? `v${request.version}` : "latest",
379
+ request
380
+ );
366
381
  }
367
382
  async executeSdkCall(sdkPath, request) {
368
383
  if (!this.host) {
@@ -393,8 +408,8 @@ var UniversalSdk = class _UniversalSdk {
393
408
  if (fullSdkPath.length === 0) {
394
409
  throw new Error(`Sdk path not found: ${sdkPath}`);
395
410
  }
396
- const { method, path } = this.sdkPathMap?.[fullSdkPath.join(".")] || {};
397
- return this.execute(path, method, request);
411
+ const { method, path, version } = this.sdkPathMap?.[fullSdkPath.join(".")] || {};
412
+ return this.execute(path, method, version, request);
398
413
  }
399
414
  /**
400
415
  * Executes an HTTP request.
@@ -404,12 +419,14 @@ var UniversalSdk = class _UniversalSdk {
404
419
  * @param {RequestType} [request] - The request object.
405
420
  * @returns {Promise<ResponseType>} - The response object.
406
421
  */
407
- async execute(path, method, request) {
422
+ async execute(path, method, version, request) {
408
423
  const { params, body, query, headers } = request || {};
409
424
  let url = getSdkPath(this.host + path);
410
425
  if (params) {
411
426
  for (const key in params) {
412
- url = url.replace(`:${key}`, encodeURIComponent(params[key]));
427
+ const paramValue = encodeURIComponent(params[key]);
428
+ url = url.replace(`:${key}`, paramValue);
429
+ url = url.replace(`{${key}}`, paramValue);
413
430
  }
414
431
  }
415
432
  let defaultContentType = "application/json";
@@ -477,7 +494,7 @@ var UniversalSdk = class _UniversalSdk {
477
494
  },
478
495
  body: parsedBody
479
496
  });
480
- const responseOpenApi = path != null && method != null ? this.registryOpenApiJson?.paths?.[openApiCompliantPath(path)]?.[method?.toLowerCase()]?.responses?.[response.status] : null;
497
+ const responseOpenApi = path != null && method != null ? this.registryOpenApiJson?.[version]?.paths?.[openApiCompliantPath(path)]?.[method?.toLowerCase()]?.responses?.[response.status] : null;
481
498
  if (responseOpenApi == null) {
482
499
  throw new Error(
483
500
  `Response ${response.status} not found in OpenAPI spec for ${path} with method ${method}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forklaunch/universal-sdk",
3
- "version": "0.5.3",
3
+ "version": "0.6.0",
4
4
  "description": "Cross runtime fetch library for forklaunch router sdks",
5
5
  "keywords": [
6
6
  "fetch",
@@ -33,18 +33,18 @@
33
33
  "dependencies": {
34
34
  "ajv": "^8.17.1",
35
35
  "ajv-formats": "^3.0.1",
36
- "@forklaunch/common": "0.4.5"
36
+ "@forklaunch/common": "0.5.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@types/node": "^24.0.13",
40
- "@typescript/native-preview": "7.0.0-dev.20250712.1",
39
+ "@types/node": "^24.3.0",
40
+ "@typescript/native-preview": "7.0.0-dev.20250820.1",
41
41
  "fetch-mock": "^12.5.3",
42
- "jest": "^30.0.4",
42
+ "jest": "^30.0.5",
43
43
  "openapi3-ts": "^4.5.0",
44
44
  "prettier": "^3.6.2",
45
- "ts-jest": "^29.4.0",
45
+ "ts-jest": "^29.4.1",
46
46
  "tsup": "^8.5.0",
47
- "typedoc": "^0.28.7"
47
+ "typedoc": "^0.28.10"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsgo --noEmit && tsup index.ts --format cjs,esm --no-splitting --dts --tsconfig tsconfig.json --out-dir lib --clean",