@oapiex/sdk-kit 0.1.11 → 0.1.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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { A as CountryCodeRestricted, C as UnifiedResponse, D as ValidationErrorResponse, E as ValidationError, O as XGenericObject, S as SuccessResponse, T as UserUrls, _ as NormalPagination, a as AuthErrorResponse, b as Response, c as BasicAuthConfig, d as CustomAuthConfig, f as DebugLevel, g as InitOptions, h as HttpMethod, i as AuthConfig, j as CurrencyCode, k as CountryCode, l as BearerAuthConfig, m as ErrorResponse, n as AccessValidationResult, o as AuthRequestConfig, p as Environment, r as ApiKeyAuthConfig, s as AuthResponse, t as AccessValidationConfigUpdate, u as CursorPagination, v as OAuth2AuthConfig, w as UserConfig, x as ResponseStatus, y as PageInfoMeta } from "./index-CZOi0v1m.js";
2
+ import "dotenv/config";
2
3
  import * as axios0 from "axios";
3
4
  import { RawAxiosRequestHeaders } from "axios";
4
5
 
@@ -320,7 +321,7 @@ declare class HttpException extends Error {
320
321
  * @param code
321
322
  * @param data
322
323
  */
323
- static fromCode(code: number, data: Required<UnifiedResponse>, parent?: Error): BadRequestException | HttpException | UnauthorizedRequestException | ForbiddenRequestException;
324
+ static fromCode(code: number, data: Required<UnifiedResponse>, parent?: Error): BadRequestException | ForbiddenRequestException | HttpException | UnauthorizedRequestException;
324
325
  }
325
326
  //#endregion
326
327
  //#region src/Apis/BaseApi.d.ts
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@oapiex/sdk-kit",
3
3
  "type": "module",
4
- "version": "0.1.11",
4
+ "version": "0.1.12",
5
5
  "description": "A TypeScript Base for building SDKs using OpenAPI specifications extracted by OAPIEX.",
6
- "main": "./dist/index.cjs",
6
+ "main": "./dist/index.js",
7
7
  "private": false,
8
- "homepage": "https://toneflix.github.io/oapiex/sdk-kit",
8
+ "homepage": "https://toneflix.github.io/oapiex/reference/sdk-kit",
9
9
  "repository": {
10
10
  "url": "https://github.com/toneflix/oapiex.git",
11
11
  "type": "git",
@@ -14,17 +14,11 @@
14
14
  "publishConfig": {
15
15
  "access": "public"
16
16
  },
17
- "module": "./dist/index.mjs",
17
+ "module": "./dist/index.js",
18
18
  "types": "./dist/index.d.ts",
19
19
  "exports": {
20
- ".": {
21
- "import": "./dist/index.mjs",
22
- "require": "./dist/index.cjs"
23
- },
24
- "./contracts": {
25
- "import": "./dist/contracts.mjs",
26
- "require": "./dist/contracts.cjs"
27
- },
20
+ ".": "./dist/index.js",
21
+ "./contracts": "./dist/contracts.js",
28
22
  "./package.json": "./package.json"
29
23
  },
30
24
  "files": [
package/dist/index.cjs DELETED
@@ -1,1216 +0,0 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
- key = keys[i];
11
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
- get: ((k) => from[k]).bind(null, key),
13
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
- });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
- value: mod,
20
- enumerable: true
21
- }) : target, mod));
22
-
23
- //#endregion
24
- require("dotenv/config");
25
- let axios = require("axios");
26
- axios = __toESM(axios);
27
- let path = require("path");
28
- path = __toESM(path);
29
- let jiti = require("jiti");
30
- jiti = __toESM(jiti);
31
- let node_path = require("node:path");
32
- node_path = __toESM(node_path);
33
- let crypto = require("crypto");
34
- crypto = __toESM(crypto);
35
- let __h3ravel_shared = require("@h3ravel/shared");
36
- __h3ravel_shared = __toESM(__h3ravel_shared);
37
-
38
- //#region src/utilities/global.ts
39
- String.prototype.toKebabCase = function() {
40
- return this.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
41
- };
42
- String.prototype.toCamelCase = function() {
43
- return this.replace(/[-_ ]+([a-zA-Z0-9])/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase());
44
- };
45
- String.prototype.toPascalCase = function() {
46
- return this.replace(/(^\w|[-_ ]+\w)/g, (match) => match.replace(/[-_ ]+/, "").toUpperCase());
47
- };
48
- String.prototype.toSnakeCase = function() {
49
- return this.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toLowerCase();
50
- };
51
- String.prototype.toSlug = function(separator = "-") {
52
- return this.toSnakeCase().replace(/[/__:]+/g, "_").replace(/_/g, separator);
53
- };
54
- String.prototype.toTitleCase = function() {
55
- return this.toLowerCase().replace(/(^|\s)\w/g, (match) => match.toUpperCase());
56
- };
57
- String.prototype.toCleanCase = function() {
58
- return this.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").replace(/\s+/g, " ").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ").trim().replace(/\b\w{1,3}\b/g, (match) => match.toUpperCase());
59
- };
60
- String.prototype.truncate = function(n, suffix = "…") {
61
- return this.length > n ? this.slice(0, n - 1) + suffix : this.toString();
62
- };
63
-
64
- //#endregion
65
- //#region src/utilities/helpers.ts
66
- /**
67
- * Takes a value like the one prodvided in a destructuring assignment where for instance
68
- * a single value might have been provided as opposed to an array of values and
69
- * normalizes it.
70
- *
71
- * Examples:
72
- * Definition:
73
- * (...value: string[]) => normalizeValue(value)
74
- *
75
- * Usage:
76
- * normalizeValue('singleValue') // returns ['singleValue']
77
- * normalizeValue('value1', 'value2') // returns ['value1', 'value2']
78
- * normalizeValue(['value1', 'value2']) // returns ['value1', 'value2']
79
- *
80
- * @param value
81
- * @returns
82
- */
83
- const normalizeValue = (value) => {
84
- if (Array.isArray(value)) return value;
85
- return [value];
86
- };
87
- /**
88
- * Builds a full url based on endpoint provided
89
- *
90
- * @param baseUrl
91
- * @param endpoint
92
- *
93
- * @returns
94
- */
95
- const buildUrl = (baseUrl, ...endpoint) => {
96
- return (baseUrl + path.default.normalize(path.default.join(...normalizeValue(endpoint)))).replace(/([^:]\/)\/+/g, "$1");
97
- };
98
-
99
- //#endregion
100
- //#region src/config.ts
101
- const defaultConfig = {
102
- environment: "sandbox",
103
- urls: {
104
- live: "",
105
- sandbox: ""
106
- },
107
- headers: {},
108
- debugLevel: 0
109
- };
110
- const createDefaultConfig = () => ({
111
- ...defaultConfig,
112
- urls: { ...defaultConfig.urls ?? {} },
113
- headers: { ...defaultConfig.headers ?? {} }
114
- });
115
- const mergeConfig = (baseConfig, config) => ({
116
- ...baseConfig,
117
- ...config,
118
- urls: config.urls ? {
119
- ...baseConfig.urls ?? defaultConfig.urls,
120
- ...config.urls
121
- } : baseConfig.urls,
122
- headers: config.headers ? {
123
- ...baseConfig.headers ?? defaultConfig.headers,
124
- ...config.headers
125
- } : baseConfig.headers
126
- });
127
- const defineConfig = (config) => config;
128
-
129
- //#endregion
130
- //#region src/utilities/Manager.ts
131
- const CONFIG_BASENAMES = [
132
- "oapiex.config.ts",
133
- "oapiex.config.js",
134
- "oapiex.config.cjs"
135
- ];
136
- let globalConfig = createDefaultConfig();
137
- let loadedConfigRoot = null;
138
- const pickInitOptions = (value) => {
139
- if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
140
- const config = value;
141
- const scoped = config.sdkKit ?? config.sdk;
142
- if (scoped && typeof scoped === "object" && !Array.isArray(scoped)) return pickInitOptions(scoped);
143
- const nextConfig = [
144
- "clientId",
145
- "clientSecret",
146
- "encryptionKey",
147
- "environment",
148
- "urls",
149
- "headers",
150
- "timeout",
151
- "auth",
152
- "debugLevel"
153
- ].reduce((result, key) => {
154
- if (config[key] !== void 0) result[key] = config[key];
155
- return result;
156
- }, {});
157
- return Object.keys(nextConfig).length > 0 ? nextConfig : null;
158
- };
159
- const loadUserConfig = (rootDir = process.cwd()) => {
160
- const syncLoad = (0, jiti.createJiti)(require("url").pathToFileURL(__filename).href, {
161
- interopDefault: true,
162
- moduleCache: false,
163
- fsCache: false
164
- });
165
- for (const basename of CONFIG_BASENAMES) {
166
- const configPath = node_path.default.join(rootDir, basename);
167
- try {
168
- const loaded = syncLoad(configPath);
169
- const loadedModule = typeof loaded === "object" && loaded !== null ? loaded : null;
170
- const sdkConfig = pickInitOptions(loadedModule?.default ?? loadedModule?.config ?? loaded);
171
- if (sdkConfig) return sdkConfig;
172
- } catch {
173
- continue;
174
- }
175
- }
176
- return null;
177
- };
178
- const ensureConfigLoaded = (rootDir = process.cwd()) => {
179
- if (loadedConfigRoot === rootDir) return globalConfig;
180
- globalConfig = createDefaultConfig();
181
- loadedConfigRoot = rootDir;
182
- const userConfig = loadUserConfig(rootDir);
183
- if (userConfig) globalConfig = mergeConfig(globalConfig, userConfig);
184
- return globalConfig;
185
- };
186
- const updateConfig = (config) => {
187
- const userConfig = mergeConfig(ensureConfigLoaded(), config);
188
- globalConfig = userConfig;
189
- return userConfig;
190
- };
191
- const getConfig = () => ensureConfigLoaded();
192
- const resetConfig = () => {
193
- loadedConfigRoot = null;
194
- globalConfig = createDefaultConfig();
195
- return globalConfig;
196
- };
197
-
198
- //#endregion
199
- //#region src/Builder.ts
200
- var Builder = class {
201
- static baseUrls = {
202
- live: "",
203
- sandbox: ""
204
- };
205
- /**
206
- * API Environment
207
- */
208
- static environment;
209
- constructor() {}
210
- /**
211
- * Sets the environment for the builder
212
- *
213
- * @param env
214
- */
215
- static setEnvironment(env) {
216
- this.environment = env;
217
- }
218
- /**
219
- * Gets the base url based on environment
220
- *
221
- * @returns
222
- */
223
- static baseUrl() {
224
- const config = getConfig();
225
- const env = this.environment ?? config.environment ?? this.normalizeEnvironment(process.env.ENVIRONMENT) ?? "sandbox";
226
- const configuredUrl = config.urls?.[env];
227
- if (configuredUrl) return this.normalizeBaseUrl(configuredUrl);
228
- return this.normalizeBaseUrl(this.baseUrls[env]);
229
- }
230
- /**
231
- * Builds a full url based on endpoint provided
232
- *
233
- * @param endpoint
234
- * @returns
235
- */
236
- static buildUrl(...endpoint) {
237
- return buildUrl(this.baseUrl(), ...endpoint);
238
- }
239
- /**
240
- * Builds parameters for query or path
241
- *
242
- * @param params
243
- * @param type
244
- * @returns
245
- */
246
- static buildParams(params, type = "path") {
247
- let built = "";
248
- if (type === "path") built = Object.values(params).join("/");
249
- else {
250
- const queryParams = [];
251
- for (const [key, value] of Object.entries(params)) queryParams.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
252
- built = queryParams.join("&");
253
- }
254
- return built;
255
- }
256
- /**
257
- * Assigns parameters to url {placeholders} based on type
258
- *
259
- * @param url
260
- * @param params
261
- * @param type
262
- *
263
- * @returns
264
- */
265
- static assignParamsToUrl(url, params, type = "path") {
266
- let builtUrl = url;
267
- if (type === "path") for (const [key, value] of Object.entries(params)) {
268
- builtUrl = builtUrl.replace(`{${key}}`, encodeURIComponent(String(value)));
269
- builtUrl = builtUrl.replace(`:${key}`, encodeURIComponent(String(value)));
270
- }
271
- else {
272
- if (Object.keys(params).length === 0) return builtUrl;
273
- const queryString = this.buildParams(params, "query");
274
- const separator = builtUrl.includes("?") ? "&" : "?";
275
- builtUrl += `${separator}${queryString}`;
276
- }
277
- return builtUrl;
278
- }
279
- /**
280
- * Builds the target url by assigning both path and query parameters
281
- *
282
- * @param path
283
- * @param params
284
- * @param queryParams
285
- * @returns
286
- */
287
- static buildTargetUrl(path$3, params = {}, queryParams = {}) {
288
- const url = this.buildUrl(path$3);
289
- let builtUrl = this.assignParamsToUrl(url, params, "path");
290
- builtUrl = this.assignParamsToUrl(builtUrl, queryParams, "query");
291
- return builtUrl;
292
- }
293
- /**
294
- * Encrypts specified keys in the input object and returns a new object with
295
- * encrypted values.
296
- *
297
- * @param input The input object containing the data to be encrypted.
298
- * @param keysToEncrypt The keys in the input object that should be encrypted.
299
- * @param outputMapping A mapping of input keys to output keys for the encrypted values.
300
- * @returns A new object with the specified keys encrypted.
301
- */
302
- static async encryptDetails(input, keysToEncrypt = [], outputMapping = {}) {
303
- const encryptionKey = getConfig().encryptionKey ?? process.env.ENCRYPTION_KEY;
304
- if (!encryptionKey) throw new Error("Encryption key is required to encrypt details");
305
- const nonce = crypto.default.randomBytes(12).toString("base64").slice(0, 12);
306
- const encryptableKeys = keysToEncrypt.length > 0 ? keysToEncrypt : Object.keys(input);
307
- const encrypted = Object.fromEntries(Object.entries(input).map(([key, value]) => {
308
- if (encryptableKeys.includes(key) && typeof value === "string") return [outputMapping?.[key] || key, this.encryptAES(value, encryptionKey, nonce)];
309
- return [key, value];
310
- }));
311
- for (const key of encryptableKeys) delete input[key];
312
- return encrypted;
313
- }
314
- /**
315
- * Encrypts data using AES-GCM encryption
316
- * @param data
317
- * @param token
318
- * @param nonce
319
- * @returns
320
- */
321
- static async encryptAES(data, token, nonce) {
322
- if (nonce.length !== 12) throw new Error("Nonce must be exactly 12 characters long");
323
- const cryptoSubtle = globalThis.crypto?.subtle || crypto.default.webcrypto?.subtle;
324
- if (!cryptoSubtle) throw new Error("Crypto API is not available in this environment.");
325
- const decodedKeyBytes = Uint8Array.from(atob(token), (c) => c.charCodeAt(0));
326
- const key = await cryptoSubtle.importKey("raw", decodedKeyBytes, { name: "AES-GCM" }, false, ["encrypt"]);
327
- const iv = new TextEncoder().encode(nonce);
328
- const encryptedData = await cryptoSubtle.encrypt({
329
- name: "AES-GCM",
330
- iv
331
- }, key, new TextEncoder().encode(data));
332
- return btoa(String.fromCharCode(...new Uint8Array(encryptedData)));
333
- }
334
- static normalizeBaseUrl = (url) => url.endsWith("/") ? url : `${url}/`;
335
- static normalizeEnvironment = (value) => {
336
- if (value === "live" || value === "sandbox") return value;
337
- };
338
- };
339
-
340
- //#endregion
341
- //#region src/Exceptions/BadRequestException.ts
342
- var BadRequestException = class extends Error {
343
- statusCode = 400;
344
- type = "INVALID_REQUEST";
345
- code = "400";
346
- data;
347
- constructor(data) {
348
- super(data?.error.message ?? data?.message ?? "Bad request. The server could not understand the request due to invalid syntax.");
349
- if (data?.error.code) this.type = data.error.type;
350
- if (data?.error.code) this.code = data.error.code;
351
- this.data = data ?? {
352
- status: "failed",
353
- error: {
354
- type: this.type,
355
- code: this.code,
356
- message: this.message,
357
- validation_errors: []
358
- }
359
- };
360
- this.name = "BadRequestException";
361
- }
362
- };
363
-
364
- //#endregion
365
- //#region src/Exceptions/ForbiddenRequestException.ts
366
- var ForbiddenRequestException = class extends Error {
367
- statusCode = 403;
368
- type = "FORBIDDEN";
369
- code = "403";
370
- data;
371
- constructor(data) {
372
- super(data?.error.message ?? data?.message ?? "Forbidden request. You do not have permission to access this resource.");
373
- if (data?.error.code) this.type = data.error.type;
374
- if (data?.error.code) this.code = data.error.code;
375
- this.data = data ?? {
376
- status: "failed",
377
- error: {
378
- type: this.type,
379
- code: this.code,
380
- message: this.message
381
- }
382
- };
383
- this.name = "ForbiddenRequestException";
384
- }
385
- };
386
-
387
- //#endregion
388
- //#region src/Exceptions/UnauthorizedRequestException.ts
389
- var UnauthorizedRequestException = class extends Error {
390
- statusCode = 401;
391
- type = "UNAUTHORIZED";
392
- code = "401";
393
- data;
394
- constructor(data) {
395
- super(data?.error.message ?? data?.message ?? "Forbidden request. You do not have permission to access this resource.");
396
- if (data?.error.code) this.type = data.error.type;
397
- if (data?.error.code) this.code = data.error.code;
398
- this.data = data ?? {
399
- status: "failed",
400
- error: {
401
- type: this.type,
402
- code: this.code,
403
- message: this.message
404
- }
405
- };
406
- this.name = "UnauthorizedRequestException";
407
- }
408
- };
409
-
410
- //#endregion
411
- //#region src/Exceptions/HttpException.ts
412
- var HttpException = class HttpException extends Error {
413
- statusCode = 500;
414
- parent;
415
- constructor(data, statusCode, parent) {
416
- super(data.message);
417
- this.data = data;
418
- this.name = "HttpException";
419
- this.parent = parent;
420
- if (statusCode) this.statusCode = statusCode;
421
- }
422
- /**
423
- * Create an exception from status code
424
- *
425
- * @param code
426
- * @param data
427
- */
428
- static fromCode(code, data, parent) {
429
- switch (code) {
430
- case 400: return new BadRequestException(data);
431
- case 401: return new UnauthorizedRequestException(data);
432
- case 403: return new ForbiddenRequestException(data);
433
- default: return new HttpException(data, code, parent);
434
- }
435
- }
436
- };
437
-
438
- //#endregion
439
- //#region src/utilities/Log.ts
440
- var Logger = class Logger {
441
- /**
442
- * Render a log message with colors based on the type of each value
443
- *
444
- * @param message
445
- */
446
- static run(...message) {
447
- console.log(message.map((m) => typeof m === "object" ? new Logger().build(m, message.length === 1 ? 0 : 2) : m).join("\n"));
448
- }
449
- /**
450
- * Recursively build a log string with colors based on the type of each value
451
- *
452
- * @param obj
453
- * @param indent
454
- * @returns
455
- */
456
- build = (obj, indent = 0) => {
457
- const indentation = " ".repeat(indent);
458
- let str = "";
459
- for (const key in obj) {
460
- const value = obj[key];
461
- if (typeof value === "object" && value !== null) {
462
- str += `${indentation}${this.stringFormatter(key)}:`;
463
- str += `\n${this.build(value, indent + 2)}\n`;
464
- } else {
465
- let coloredValue;
466
- switch (typeof value) {
467
- case "string":
468
- coloredValue = __h3ravel_shared.Logger.log(value, "green", false);
469
- break;
470
- case "number":
471
- coloredValue = __h3ravel_shared.Logger.log(String(value), "yellow", false);
472
- break;
473
- case "boolean":
474
- coloredValue = __h3ravel_shared.Logger.log(String(value), "blue", false);
475
- break;
476
- case "object":
477
- if (value === null) coloredValue = __h3ravel_shared.Logger.log("null", "gray", false);
478
- else coloredValue = __h3ravel_shared.Logger.log(JSON.stringify(value), "cyan", false);
479
- break;
480
- default: coloredValue = value;
481
- }
482
- str += `${indentation}${this.stringFormatter(key)}: ${coloredValue}\n`;
483
- }
484
- }
485
- return str;
486
- };
487
- /**
488
- * Format a string to be more human-readable.
489
- *
490
- * @param str
491
- * @returns
492
- */
493
- stringFormatter = (str) => {
494
- return str.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").replace(/\s+/g, " ").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ").trim().replace(/^(\w{2})$/, (_, p1) => p1.toUpperCase());
495
- };
496
- };
497
-
498
- //#endregion
499
- //#region src/Http.ts
500
- var Http = class Http {
501
- /**
502
- * Bearer token
503
- */
504
- static bearerToken;
505
- /**
506
- * Debug level
507
- */
508
- static debugLevel = 0;
509
- static apiInstance;
510
- /**
511
- * Creates an instance of Http.
512
- *
513
- * @param method
514
- * @param url
515
- * @param headers
516
- * @param body
517
- */
518
- constructor(headers = {}, body) {
519
- this.headers = headers;
520
- this.body = body;
521
- }
522
- /**
523
- * Set the debug level
524
- *
525
- * @param debug
526
- */
527
- static setDebugLevel(level = 0) {
528
- this.debugLevel = level ?? 0;
529
- }
530
- /**
531
- * Set the API instance
532
- *
533
- * @param api
534
- */
535
- static setApiInstance(api) {
536
- this.apiInstance = api;
537
- }
538
- /**
539
- * Set the bearer token
540
- *
541
- * @param token
542
- */
543
- static setBearerToken(token) {
544
- this.bearerToken = token;
545
- updateConfig({ auth: {
546
- type: "bearer",
547
- token
548
- } });
549
- }
550
- static setAuth(auth) {
551
- updateConfig({ auth });
552
- }
553
- static setBasicAuth(username, password) {
554
- this.setAuth({
555
- type: "basic",
556
- username,
557
- password
558
- });
559
- }
560
- static setApiKey(name, value, location = "header", prefix) {
561
- this.setAuth({
562
- type: "apiKey",
563
- name,
564
- value,
565
- in: location,
566
- prefix
567
- });
568
- }
569
- static clearAuth() {
570
- this.bearerToken = void 0;
571
- updateConfig({ auth: void 0 });
572
- }
573
- setDefaultHeaders(defaults) {
574
- const config = getConfig();
575
- this.headers = {
576
- ...defaults,
577
- ...config.headers ?? {},
578
- ...this.headers
579
- };
580
- }
581
- getHeaders() {
582
- return this.headers;
583
- }
584
- getBody() {
585
- return this.body;
586
- }
587
- axiosApi() {
588
- const config = getConfig();
589
- this.setDefaultHeaders({
590
- "Accept": "application/json",
591
- "Content-Type": "application/json"
592
- });
593
- const instance = axios.default.create({
594
- baseURL: Builder.baseUrl(),
595
- headers: this.getHeaders(),
596
- timeout: config.timeout
597
- });
598
- if (Http.debugLevel > 0) {
599
- instance.interceptors.request.use((request) => {
600
- Logger.run("Starting Request:", {
601
- url: request.url,
602
- method: request.method,
603
- headers: Http.debugLevel < 3 ? Object.fromEntries(Object.entries(request.headers || {}).filter(([key]) => key.toLowerCase() !== "authorization")) : request.headers,
604
- params: request.params,
605
- data: request.data
606
- });
607
- return request;
608
- }, (error) => {
609
- Logger.run("Request Error:", error);
610
- return Promise.reject(error);
611
- });
612
- instance.interceptors.response.use((response) => {
613
- Logger.run("Response:", {
614
- status: response.status,
615
- data: Http.debugLevel < 3 ? Object.fromEntries(Object.entries(response.data || {}).filter(([key]) => key.toLowerCase() !== "access_token")) : response.data
616
- });
617
- return response;
618
- }, (error) => {
619
- Logger.run("Response Error:", {
620
- status: error.response?.status,
621
- data: Object.fromEntries(Object.entries(error.response?.data || {}).filter(([key]) => key.toLowerCase() !== "access_token"))
622
- });
623
- return Promise.reject(error);
624
- });
625
- }
626
- return instance;
627
- }
628
- /**
629
- * Makes a GET request
630
- *
631
- * @param url
632
- * @param headers
633
- * @param params
634
- * @returns
635
- */
636
- static async get(url, params, headers = {}) {
637
- return this.send(url, "GET", void 0, headers, params);
638
- }
639
- /**
640
- *
641
- *
642
- * @param url
643
- * @param headers
644
- * @param params
645
- * @returns
646
- */
647
- static async send(url, method, body, headers = {}, params) {
648
- try {
649
- const request = await this.prepareRequest({
650
- url,
651
- method,
652
- body,
653
- headers: this.toHeaderRecord(headers),
654
- params: { ...params ?? {} }
655
- });
656
- const { data } = await new Http(request.headers, request.body).axiosApi()({
657
- url: request.url,
658
- method: request.method,
659
- data: request.body,
660
- params: request.params
661
- });
662
- return {
663
- success: true,
664
- message: data.message || "Request successful",
665
- data: data.data ?? data,
666
- meta: data.meta
667
- };
668
- } catch (e) {
669
- const error = e.response?.data ?? {};
670
- throw this.exception(e.response?.status ?? 500, error || e, e);
671
- }
672
- }
673
- static async prepareRequest(request) {
674
- let prepared = {
675
- ...request,
676
- headers: { ...request.headers },
677
- params: { ...request.params ?? {} }
678
- };
679
- for (const auth of this.getConfiguredAuth()) prepared = await this.applyAuth(prepared, auth);
680
- return prepared;
681
- }
682
- static getConfiguredAuth() {
683
- const configuredAuth = getConfig().auth;
684
- if (configuredAuth) return Array.isArray(configuredAuth) ? configuredAuth : [configuredAuth];
685
- if (this.bearerToken) return [{
686
- type: "bearer",
687
- token: this.bearerToken
688
- }];
689
- return [];
690
- }
691
- static async applyAuth(request, auth) {
692
- switch (auth.type) {
693
- case "bearer":
694
- this.setHeaderIfMissing(request.headers, "Authorization", `${auth.prefix ?? "Bearer"} ${auth.token}`.trim());
695
- return request;
696
- case "oauth2":
697
- this.setHeaderIfMissing(request.headers, "Authorization", `${auth.tokenType ?? "Bearer"} ${auth.accessToken}`.trim());
698
- return request;
699
- case "basic": {
700
- const encoded = Buffer.from(`${auth.username}:${auth.password}`).toString("base64");
701
- this.setHeaderIfMissing(request.headers, "Authorization", `Basic ${encoded}`);
702
- return request;
703
- }
704
- case "apiKey": {
705
- const value = auth.prefix ? `${auth.prefix} ${auth.value}`.trim() : auth.value;
706
- const location = auth.in ?? "header";
707
- if (location === "query") {
708
- if (request.params[auth.name] === void 0) request.params[auth.name] = value;
709
- return request;
710
- }
711
- if (location === "cookie") {
712
- this.appendCookie(request.headers, auth.name, value);
713
- return request;
714
- }
715
- this.setHeaderIfMissing(request.headers, auth.name, value);
716
- return request;
717
- }
718
- case "custom": return await auth.apply({
719
- ...request,
720
- headers: { ...request.headers },
721
- params: { ...request.params }
722
- });
723
- }
724
- }
725
- static setHeaderIfMissing(headers, name, value) {
726
- if (!Object.keys(headers).find((header) => header.toLowerCase() === name.toLowerCase())) headers[name] = value;
727
- }
728
- static appendCookie(headers, name, value) {
729
- const headerName = Object.keys(headers).find((header) => header.toLowerCase() === "cookie") ?? "Cookie";
730
- const existingCookie = headers[headerName];
731
- const cookieEntry = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
732
- if (!existingCookie) {
733
- headers[headerName] = cookieEntry;
734
- return;
735
- }
736
- if (!existingCookie.split(";").map((part) => part.trim()).some((part) => part.startsWith(`${encodeURIComponent(name)}=`))) headers[headerName] = `${existingCookie}; ${cookieEntry}`;
737
- }
738
- /**
739
- * Create an HttpException from status and error
740
- *
741
- * @param status
742
- * @param error
743
- * @returns
744
- */
745
- static exception(status, error, originalError) {
746
- const exception = HttpException.fromCode(status, {
747
- success: false,
748
- message: `Request failed: ${error.error?.message || "An error occurred"}`,
749
- status: "failed",
750
- data: void 0,
751
- meta: {},
752
- error: {
753
- type: ((typeof error.error === "string" ? error.error : error.error?.type) ?? "UNKNOWN_ERROR").toUpperCase(),
754
- code: error.error?.code ?? "000000",
755
- message: error.error?.message ?? error.error_description ?? error.message,
756
- validation_errors: error.error?.validation_errors ?? []
757
- }
758
- }, originalError);
759
- if (this.apiInstance) this.apiInstance.setLastException(exception);
760
- return exception;
761
- }
762
- static toHeaderRecord = (headers) => {
763
- return Object.fromEntries(Object.entries(headers).map(([key, value]) => [key, String(value)]));
764
- };
765
- };
766
-
767
- //#endregion
768
- //#region src/Apis/BaseApi.ts
769
- var BaseApi = class {
770
- /**
771
- * API Core instance for API bootstrapping and shared utilities
772
- */
773
- #core;
774
- lastException;
775
- /**
776
- * Create a BaseApi instance
777
- *
778
- * @param coreInstance Core instance
779
- */
780
- constructor(coreInstance) {
781
- this.#core = coreInstance;
782
- }
783
- /**
784
- * Get the owning core instance for SDK-specific API bootstrapping.
785
- */
786
- get core() {
787
- return this.#core;
788
- }
789
- /**
790
- * Hook for SDK-specific API registration.
791
- */
792
- boot() {}
793
- /**
794
- * Set access validator function
795
- *
796
- * @param validator
797
- */
798
- setAccessValidator(validator) {
799
- this.#core.setAccessValidator(validator);
800
- }
801
- /**
802
- * Get the last exception
803
- *
804
- * @returns
805
- */
806
- getLastException() {
807
- return this.lastException;
808
- }
809
- /**
810
- * Set the last exception
811
- *
812
- * @param exception
813
- */
814
- setLastException(exception) {
815
- this.lastException = exception;
816
- }
817
- /**
818
- * Initialize BaseApi and its sub-APIs
819
- *
820
- * @param coreInstance Core instance
821
- * @returns
822
- */
823
- static initialize(coreInstance) {
824
- Http.setDebugLevel(coreInstance.debugLevel);
825
- const baseApi = new this(coreInstance);
826
- Http.setApiInstance(baseApi);
827
- baseApi.boot();
828
- return baseApi;
829
- }
830
- };
831
-
832
- //#endregion
833
- //#region src/RuntimeSdk.ts
834
- const createRuntimeApi = (core, bundle) => {
835
- const api = BaseApi.initialize(core);
836
- for (const group of bundle.manifest.groups) {
837
- const namespace = {};
838
- for (const operation of group.operations) namespace[operation.methodName] = async (...args) => {
839
- await core.validateAccess();
840
- const [pathParams, queryParams, body, headers] = normalizeRuntimeArguments(operation, args);
841
- validateRequiredArguments(operation.pathParams, pathParams, "path");
842
- validateRequiredArguments(operation.queryParams, queryParams, "query");
843
- validateRequiredArguments(operation.headerParams, headers, "header");
844
- if (operation.hasBody && operation.bodyRequired && body == null) throw new Error(`Missing required request body for ${operation.method} ${operation.path}`);
845
- const { data } = await Http.send(core.builder.buildTargetUrl(operation.path, pathParams, queryParams), operation.method, body ?? {}, headers);
846
- return data;
847
- };
848
- api[group.propertyName] = namespace;
849
- }
850
- return api;
851
- };
852
- const createSdk = (bundle, options) => {
853
- return new Core(options).useDocument(bundle);
854
- };
855
- const normalizeRuntimeArguments = (operation, args) => {
856
- let cursor = 0;
857
- return [
858
- operation.pathParams.length > 0 ? toRecord(args[cursor++]) : {},
859
- operation.queryParams.length > 0 ? toRecord(args[cursor++]) : {},
860
- operation.hasBody ? args[cursor++] : void 0,
861
- operation.headerParams.length > 0 ? toRecord(args[cursor++]) : {}
862
- ];
863
- };
864
- const validateRequiredArguments = (parameters, values, location) => {
865
- for (const parameter of parameters) {
866
- if (!parameter.required) continue;
867
- if (values[parameter.name] === void 0 && values[parameter.accessor] === void 0) throw new Error(`Missing required ${location} parameter: ${parameter.name}`);
868
- }
869
- };
870
- const toRecord = (value) => {
871
- if (typeof value === "object" && value !== null && !Array.isArray(value)) return value;
872
- return {};
873
- };
874
-
875
- //#endregion
876
- //#region src/Core.ts
877
- var Core = class Core {
878
- static apiClass = BaseApi;
879
- debugLevel = 0;
880
- /**
881
- * Client ID
882
- */
883
- clientId;
884
- /**
885
- * Client Secret
886
- */
887
- clientSecret;
888
- /**
889
- * API Environment
890
- */
891
- environment = "live";
892
- accessValidator;
893
- /**
894
- * API Instance
895
- */
896
- api;
897
- /**
898
- * Builder Instance
899
- */
900
- builder = Builder;
901
- constructor(clientId, clientSecret, encryptionKey, env, config) {
902
- const currentConfig = getConfig();
903
- const resolvedConfig = clientId && typeof clientId === "object" ? this.resolveInitOptionsFromObject(clientId, currentConfig) : this.resolveInitOptionsFromArgs(clientId, clientSecret, encryptionKey, env, config, currentConfig);
904
- this.clientId = Core.normalizeCredential(resolvedConfig.clientId);
905
- this.clientSecret = Core.normalizeCredential(resolvedConfig.clientSecret);
906
- this.environment = resolvedConfig.environment ?? Core.normalizeEnvironment(process.env.ENVIRONMENT) ?? "live";
907
- this.configure({
908
- ...resolvedConfig,
909
- environment: this.environment
910
- });
911
- this.debug(resolvedConfig.debugLevel ?? 0);
912
- if (!this.clientSecret && !this.hasConfiguredAuth()) throw new Error("Client Secret is required to initialize API instance when auth is not provided");
913
- this.api = this.createApi();
914
- }
915
- createApi() {
916
- return (this.constructor.apiClass ?? BaseApi).initialize(this);
917
- }
918
- init(clientId, clientSecret, encryptionKey, env, config) {
919
- return new this.constructor(clientId, clientSecret, encryptionKey, env, config);
920
- }
921
- configure(config) {
922
- const nextConfig = updateConfig(config);
923
- if (nextConfig.environment) {
924
- this.environment = nextConfig.environment;
925
- this.builder.setEnvironment(nextConfig.environment);
926
- }
927
- if ("clientId" in config) this.clientId = Core.normalizeCredential(nextConfig.clientId);
928
- if ("clientSecret" in config) this.clientSecret = Core.normalizeCredential(nextConfig.clientSecret);
929
- if (nextConfig.debugLevel !== void 0) this.debug(nextConfig.debugLevel);
930
- return this;
931
- }
932
- /**
933
- * Set the debug level
934
- *
935
- * @param level
936
- * @returns
937
- */
938
- debug(level = 0) {
939
- this.debugLevel = level;
940
- Http.setDebugLevel(level);
941
- return this;
942
- }
943
- /**
944
- * Get the current environment
945
- *
946
- * @returns
947
- */
948
- getEnvironment() {
949
- return this.environment;
950
- }
951
- /**
952
- * Get the configured client identifier.
953
- */
954
- getClientId() {
955
- return this.clientId;
956
- }
957
- /**
958
- * Get the configured client secret.
959
- */
960
- getClientSecret() {
961
- return this.clientSecret;
962
- }
963
- /**
964
- * Get the current shared SDK config.
965
- */
966
- getConfig() {
967
- return getConfig();
968
- }
969
- /**
970
- * Replace the active auth strategy.
971
- */
972
- setAuth(auth) {
973
- return this.configure({ auth });
974
- }
975
- /**
976
- * Clear any configured auth strategy.
977
- */
978
- clearAuth() {
979
- Http.clearAuth();
980
- return this;
981
- }
982
- /**
983
- * Set access validator function
984
- *
985
- * @param validator Function to validate access
986
- */
987
- setAccessValidator(validator) {
988
- this.accessValidator = validator;
989
- return this;
990
- }
991
- /**
992
- * Validates access using the provided access validator function
993
- *
994
- * @throws Error if validation fails
995
- */
996
- async validateAccess() {
997
- const check = this.accessValidator ? await this.accessValidator(this) : true;
998
- if (check === true || check == null) return;
999
- if (this.isAuthConfigOrArray(check)) {
1000
- this.setAuth(check);
1001
- return;
1002
- }
1003
- if (this.isConfigUpdate(check)) {
1004
- this.configure(check);
1005
- return;
1006
- }
1007
- throw new Error(typeof check === "string" ? check : "Access validation failed");
1008
- }
1009
- /**
1010
- * Use a manifest bundle to create the API instance
1011
- *
1012
- * @param bundle
1013
- * @returns
1014
- */
1015
- useDocument(bundle) {
1016
- this.api = createRuntimeApi(this, bundle);
1017
- return this;
1018
- }
1019
- /**
1020
- * Use a manifest bundle to create the API instance (alias for useDocument).
1021
- *
1022
- * @param bundle
1023
- * @returns
1024
- */
1025
- useSdk(bundle) {
1026
- return this.useDocument(bundle);
1027
- }
1028
- static normalizeEnvironment = (value) => {
1029
- if (value === "live" || value === "sandbox") return value;
1030
- };
1031
- static normalizeCredential(value) {
1032
- if (typeof value !== "string") return;
1033
- const normalized = value.trim();
1034
- return normalized ? normalized : void 0;
1035
- }
1036
- resolveInitOptionsFromObject(config, currentConfig) {
1037
- return {
1038
- ...currentConfig,
1039
- ...config,
1040
- clientId: Core.normalizeCredential(config.clientId) ?? Core.normalizeCredential(currentConfig.clientId) ?? Core.normalizeCredential(process.env.CLIENT_ID),
1041
- clientSecret: Core.normalizeCredential(config.clientSecret) ?? Core.normalizeCredential(currentConfig.clientSecret) ?? Core.normalizeCredential(process.env.CLIENT_SECRET),
1042
- environment: config.environment ?? currentConfig.environment ?? Core.normalizeEnvironment(process.env.ENVIRONMENT) ?? "live",
1043
- encryptionKey: config.encryptionKey ?? currentConfig.encryptionKey,
1044
- urls: config.urls ?? currentConfig.urls,
1045
- headers: config.headers ?? currentConfig.headers,
1046
- timeout: config.timeout ?? currentConfig.timeout,
1047
- auth: config.auth ?? currentConfig.auth,
1048
- debugLevel: config.debugLevel ?? currentConfig.debugLevel ?? 0
1049
- };
1050
- }
1051
- resolveInitOptionsFromArgs(clientId, clientSecret, encryptionKey, env, config, currentConfig) {
1052
- return {
1053
- ...currentConfig,
1054
- ...config ?? {},
1055
- clientId: Core.normalizeCredential(clientId) ?? Core.normalizeCredential(currentConfig.clientId) ?? Core.normalizeCredential(process.env.CLIENT_ID),
1056
- clientSecret: Core.normalizeCredential(clientSecret) ?? Core.normalizeCredential(currentConfig.clientSecret) ?? Core.normalizeCredential(process.env.CLIENT_SECRET),
1057
- environment: env ?? config?.environment ?? currentConfig.environment ?? Core.normalizeEnvironment(process.env.ENVIRONMENT) ?? "live",
1058
- encryptionKey: encryptionKey ?? config?.encryptionKey ?? currentConfig.encryptionKey,
1059
- urls: config?.urls ?? currentConfig.urls,
1060
- headers: config?.headers ?? currentConfig.headers,
1061
- timeout: config?.timeout ?? currentConfig.timeout,
1062
- auth: config?.auth ?? currentConfig.auth,
1063
- debugLevel: config?.debugLevel ?? currentConfig.debugLevel ?? 0
1064
- };
1065
- }
1066
- hasConfiguredAuth() {
1067
- const auth = getConfig().auth;
1068
- if (Array.isArray(auth)) return auth.length > 0;
1069
- return auth != null;
1070
- }
1071
- isAuthConfigOrArray(value) {
1072
- if (Array.isArray(value)) return value.every((entry) => this.isAuthConfig(entry));
1073
- return this.isAuthConfig(value);
1074
- }
1075
- isAuthConfig(value) {
1076
- return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
1077
- }
1078
- isConfigUpdate(value) {
1079
- if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1080
- return [
1081
- "auth",
1082
- "clientId",
1083
- "clientSecret",
1084
- "debugLevel",
1085
- "environment",
1086
- "headers",
1087
- "timeout",
1088
- "urls",
1089
- "encryptionKey"
1090
- ].some((key) => key in value);
1091
- }
1092
- };
1093
-
1094
- //#endregion
1095
- //#region src/utilities/AuthCache.ts
1096
- /**
1097
- * Cache any auth payload returned from a loader until it expires.
1098
- */
1099
- const createAuthCache = (loader) => {
1100
- let cached;
1101
- return async (core) => {
1102
- if (cached && !isExpired(cached.expiresAt)) return cached.auth;
1103
- cached = await loader(core);
1104
- return cached.auth;
1105
- };
1106
- };
1107
- /**
1108
- * Cache bearer or oauth-style access tokens returned from a loader until expiry.
1109
- */
1110
- const createAccessTokenCache = (loader) => {
1111
- return createAuthCache(async (core) => {
1112
- const token = await loader(core);
1113
- const expiresAt = token.expiresAt ?? (typeof token.expiresInMs === "number" ? Date.now() + token.expiresInMs : typeof token.expiresInSeconds === "number" ? Date.now() + token.expiresInSeconds * 1e3 : void 0);
1114
- return {
1115
- auth: {
1116
- type: "oauth2",
1117
- accessToken: token.token,
1118
- tokenType: token.tokenType ?? "Bearer"
1119
- },
1120
- expiresAt
1121
- };
1122
- });
1123
- };
1124
- const isExpired = (expiresAt) => {
1125
- return typeof expiresAt === "number" && expiresAt <= Date.now();
1126
- };
1127
-
1128
- //#endregion
1129
- //#region src/utilities/WebhookValidator.ts
1130
- var WebhookValidator = class {
1131
- algorithm = "sha256";
1132
- encoding = "base64";
1133
- /**
1134
- * @param secretHash
1135
- * @param options
1136
- */
1137
- constructor(secretHash, options) {
1138
- this.secretHash = secretHash;
1139
- this.algorithm = options?.hashAlgorithm || "sha256";
1140
- this.encoding = options?.encoding || "base64";
1141
- if (!this.secretHash || this.secretHash.length === 0) this.secretHash = process.env.SECRET_HASH;
1142
- }
1143
- /**
1144
- * Validate webhook signature
1145
- * @param rawBody - Raw request body as string
1146
- * @param signature - Signature from request header
1147
- * @returns {boolean} - True if signature is valid
1148
- */
1149
- validate(rawBody, signature) {
1150
- if (!this.secretHash) throw new Error("Secret hash is required for validation");
1151
- return crypto.default.createHmac(this.algorithm, this.secretHash).update(rawBody).digest(this.encoding) === signature;
1152
- }
1153
- /**
1154
- * Generate signature for testing/verification
1155
- * @param rawBody - Raw request body as string
1156
- * @returns {string} - Generated signature
1157
- */
1158
- generateSignature(rawBody) {
1159
- if (!this.secretHash) throw new Error("Secret hash is required to generate signature");
1160
- return crypto.default.createHmac(this.algorithm, this.secretHash).update(rawBody).digest(this.encoding);
1161
- }
1162
- /**
1163
- * Async version of validate (for large payloads)
1164
- *
1165
- * @param rawBody
1166
- * @param signature
1167
- * @returns {Promise<boolean>}
1168
- */
1169
- validateAsync(rawBody, signature) {
1170
- if (!this.secretHash) throw new Error("Secret hash is required for validation");
1171
- const hmac = crypto.default.createHmac(this.algorithm, this.secretHash);
1172
- hmac.update(rawBody);
1173
- return hmac.digest(this.encoding) === signature;
1174
- }
1175
- /**
1176
- * Get current configuration
1177
- */
1178
- getConfig() {
1179
- return {
1180
- algorithm: this.algorithm,
1181
- encoding: this.encoding,
1182
- secretHashLength: this.secretHash?.length
1183
- };
1184
- }
1185
- };
1186
-
1187
- //#endregion
1188
- exports.BadRequestException = BadRequestException;
1189
- exports.BaseApi = BaseApi;
1190
- exports.Builder = Builder;
1191
- exports.Core = Core;
1192
- exports.ForbiddenRequestException = ForbiddenRequestException;
1193
- exports.Http = Http;
1194
- exports.HttpException = HttpException;
1195
- exports.UnauthorizedRequestException = UnauthorizedRequestException;
1196
- exports.WebhookValidator = WebhookValidator;
1197
- exports.buildUrl = buildUrl;
1198
- exports.createAccessTokenCache = createAccessTokenCache;
1199
- exports.createAuthCache = createAuthCache;
1200
- exports.createDefaultConfig = createDefaultConfig;
1201
- exports.createRuntimeApi = createRuntimeApi;
1202
- exports.createSdk = createSdk;
1203
- exports.defaultConfig = defaultConfig;
1204
- exports.defineConfig = defineConfig;
1205
- exports.getConfig = getConfig;
1206
- Object.defineProperty(exports, 'globalConfig', {
1207
- enumerable: true,
1208
- get: function () {
1209
- return globalConfig;
1210
- }
1211
- });
1212
- exports.loadUserConfig = loadUserConfig;
1213
- exports.mergeConfig = mergeConfig;
1214
- exports.normalizeValue = normalizeValue;
1215
- exports.resetConfig = resetConfig;
1216
- exports.updateConfig = updateConfig;
File without changes
File without changes