@oapiex/sdk-kit 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -65,6 +65,17 @@ const sdk = new ExampleCore({
65
65
  clientId: process.env.CLIENT_ID!,
66
66
  clientSecret: process.env.CLIENT_SECRET!,
67
67
  environment: 'sandbox',
68
+ urls: {
69
+ sandbox: 'https://sandbox-api.example.com',
70
+ },
71
+ headers: {
72
+ 'X-SDK-Version': '1.0.0',
73
+ },
74
+ timeout: 10000,
75
+ auth: {
76
+ type: 'bearer',
77
+ token: process.env.ACCESS_TOKEN!,
78
+ },
68
79
  });
69
80
 
70
81
  await sdk.api.examples.list();
@@ -108,16 +119,234 @@ const sdk = createSdk(bundle, {
108
119
  clientId: process.env.CLIENT_ID!,
109
120
  clientSecret: process.env.CLIENT_SECRET!,
110
121
  environment: 'sandbox',
122
+ auth: {
123
+ type: 'apiKey',
124
+ name: 'X-API-Key',
125
+ value: process.env.API_KEY!,
126
+ in: 'header',
127
+ },
128
+ });
129
+
130
+ await sdk.api.examples.list();
131
+ ```
132
+
133
+ ## Init Options
134
+
135
+ `Core` and `createSdk()` both accept the same `InitOptions` object.
136
+
137
+ - `clientId`: required API client identifier
138
+ - `clientSecret`: required API client secret
139
+ - `environment`: selects `sandbox` or `live`
140
+ - `urls`: optional base URL overrides per environment
141
+ - `headers`: optional default headers added to every request
142
+ - `timeout`: optional Axios timeout in milliseconds
143
+ - `encryptionKey`: optional runtime encryption key override
144
+ - `auth`: one auth strategy or an array of strategies applied to outgoing requests
145
+
146
+ ```ts
147
+ const sdk = new Core({
148
+ clientId: process.env.CLIENT_ID!,
149
+ clientSecret: process.env.CLIENT_SECRET!,
150
+ environment: 'sandbox',
151
+ urls: {
152
+ sandbox: 'https://sandbox-api.example.com',
153
+ live: 'https://api.example.com',
154
+ },
155
+ headers: {
156
+ 'X-Trace-Source': 'example-sdk',
157
+ },
158
+ timeout: 15000,
159
+ });
160
+ ```
161
+
162
+ ## Auth Shapes
163
+
164
+ The `auth` option accepts any `AuthConfig` supported by the transport layer.
165
+
166
+ ### Bearer
167
+
168
+ ```ts
169
+ auth: {
170
+ type: 'bearer',
171
+ token: process.env.ACCESS_TOKEN!,
172
+ }
173
+ ```
174
+
175
+ ### Basic
176
+
177
+ ```ts
178
+ auth: {
179
+ type: 'basic',
180
+ username: process.env.API_USERNAME!,
181
+ password: process.env.API_PASSWORD!,
182
+ }
183
+ ```
184
+
185
+ ### API Key
186
+
187
+ ```ts
188
+ auth: {
189
+ type: 'apiKey',
190
+ name: 'X-API-Key',
191
+ value: process.env.API_KEY!,
192
+ in: 'header',
193
+ }
194
+ ```
195
+
196
+ ### OAuth2 Token
197
+
198
+ ```ts
199
+ auth: {
200
+ type: 'oauth2',
201
+ accessToken: process.env.ACCESS_TOKEN!,
202
+ tokenType: 'Bearer',
203
+ }
204
+ ```
205
+
206
+ ### Multiple Strategies
207
+
208
+ ```ts
209
+ auth: [
210
+ {
211
+ type: 'apiKey',
212
+ name: 'X-Partner-Key',
213
+ value: process.env.PARTNER_KEY!,
214
+ in: 'header',
215
+ },
216
+ {
217
+ type: 'apiKey',
218
+ name: 'api_key',
219
+ value: process.env.QUERY_KEY!,
220
+ in: 'query',
221
+ },
222
+ ];
223
+ ```
224
+
225
+ ### Custom
226
+
227
+ ```ts
228
+ auth: {
229
+ type: 'custom',
230
+ apply: async (request) => ({
231
+ ...request,
232
+ headers: {
233
+ ...request.headers,
234
+ Authorization: `Token ${process.env.CUSTOM_TOKEN!}`,
235
+ },
236
+ }),
237
+ }
238
+ ```
239
+
240
+ Generated SDK packages can now expose auth helper functions derived from OpenAPI `securitySchemes`, plus `securitySchemes` and `security` metadata exports for inspection.
241
+
242
+ ## Access Validator Auth Refresh
243
+
244
+ `setAccessValidator()` can be used to replace auth before the actual SDK request is sent. This is useful for APIs like Flutterwave where you first exchange API keys for a bearer token.
245
+
246
+ The validator can:
247
+
248
+ - return `true` to allow the request as-is
249
+ - return a string to fail validation with a custom message
250
+ - return an `AuthConfig` or `AuthConfig[]` to replace auth for the pending request
251
+ - return a partial config object such as `{ auth, headers, timeout }`
252
+ - call `core.setAuth(...)` or `core.configure(...)` directly
253
+
254
+ ```ts
255
+ import axios from 'axios';
256
+ import { Core } from '@oapiex/sdk-kit';
257
+
258
+ const sdk = new Core({
259
+ clientId: process.env.CLIENT_ID!,
260
+ clientSecret: process.env.CLIENT_SECRET!,
261
+ environment: 'sandbox',
262
+ urls: {
263
+ sandbox: 'https://developersandbox-api.example.com',
264
+ },
265
+ });
266
+
267
+ sdk.setAccessValidator(async (core) => {
268
+ const response = await axios.post(
269
+ 'https://developersandbox-api.example.com/auth/token',
270
+ {
271
+ client_id: core.getClientId(),
272
+ client_secret: core.getClientSecret(),
273
+ },
274
+ );
275
+
276
+ return {
277
+ type: 'bearer',
278
+ token: response.data.access_token,
279
+ };
111
280
  });
112
281
 
113
282
  await sdk.api.examples.list();
114
283
  ```
115
284
 
285
+ If you need to update more than auth, return a config object instead:
286
+
287
+ ```ts
288
+ sdk.setAccessValidator(async (core) => {
289
+ const response = await axios.post(
290
+ 'https://developersandbox-api.example.com/auth/token',
291
+ {
292
+ client_id: core.getClientId(),
293
+ client_secret: core.getClientSecret(),
294
+ },
295
+ );
296
+
297
+ return {
298
+ auth: {
299
+ type: 'bearer',
300
+ token: response.data.access_token,
301
+ },
302
+ headers: {
303
+ 'X-Token-Source': 'access-validator',
304
+ },
305
+ };
306
+ });
307
+ ```
308
+
309
+ If the token endpoint returns an expiry value, use `createAccessTokenCache()` so the validator does not fetch a new token on every request.
310
+
311
+ ```ts
312
+ import axios from 'axios';
313
+ import { Core, createAccessTokenCache } from '@oapiex/sdk-kit';
314
+
315
+ const sdk = new Core({
316
+ clientId: process.env.CLIENT_ID!,
317
+ clientSecret: process.env.CLIENT_SECRET!,
318
+ environment: 'sandbox',
319
+ urls: {
320
+ sandbox: 'https://developersandbox-api.example.com',
321
+ },
322
+ });
323
+
324
+ const tokenCache = createAccessTokenCache(async (core) => {
325
+ const response = await axios.post(
326
+ 'https://developersandbox-api.example.com/auth/token',
327
+ {
328
+ client_id: core.getClientId(),
329
+ client_secret: core.getClientSecret(),
330
+ },
331
+ );
332
+
333
+ return {
334
+ token: response.data.access_token,
335
+ expiresInSeconds: Math.max((response.data.expires_in ?? 60) - 30, 1),
336
+ };
337
+ });
338
+
339
+ sdk.setAccessValidator(tokenCache);
340
+ ```
341
+
116
342
  ## Main Exports
117
343
 
118
344
  - `Core`: base SDK client with environment setup, access validation, and runtime bundle support
119
345
  - `BaseApi`: base class for SDK-specific API binders and API classes
120
346
  - `createSdk()`: helper for creating a runtime SDK from a manifest bundle
347
+ - `AuthConfig`: shared auth strategy union used by `InitOptions.auth`
348
+ - `createAccessTokenCache()`: helper for caching validator-fetched tokens until expiry
349
+ - `setAccessValidator()`: hook for readiness checks, auth refresh, and config replacement before requests
121
350
  - `Http`, `Builder`, and exceptions: lower-level request and error primitives
122
351
  - `InitOptions`, `UnifiedResponse`, and runtime manifest types: shared contracts for generated SDKs
123
352
 
@@ -1,2 +1,2 @@
1
- import { _ as CountryCodeRestricted, a as InitOptions, c as Response, d as UnifiedResponse, f as UserConfig, g as CountryCode, h as XGenericObject, i as ErrorResponse, l as ResponseStatus, m as ValidationErrorResponse, n as AuthResponse, o as NormalPagination, p as ValidationError, r as CursorPagination, s as PageInfoMeta, t as AuthErrorResponse, u as SuccessResponse, v as CurrencyCode } from "./index-BYtse_Mh.cjs";
2
- export { AuthErrorResponse, AuthResponse, CountryCode, CountryCodeRestricted, CurrencyCode, CursorPagination, ErrorResponse, InitOptions, NormalPagination, PageInfoMeta, Response, ResponseStatus, SuccessResponse, UnifiedResponse, UserConfig, ValidationError, ValidationErrorResponse, XGenericObject };
1
+ import { A as CurrencyCode, C as UserConfig, D as XGenericObject, E as ValidationErrorResponse, O as CountryCode, S as UnifiedResponse, T as ValidationError, _ as OAuth2AuthConfig, a as AuthErrorResponse, b as ResponseStatus, c as BasicAuthConfig, d as CustomAuthConfig, f as Environment, g as NormalPagination, h as InitOptions, i as AuthConfig, k as CountryCodeRestricted, l as BearerAuthConfig, m as HttpMethod, n as AccessValidationResult, o as AuthRequestConfig, p as ErrorResponse, r as ApiKeyAuthConfig, s as AuthResponse, t as AccessValidationConfigUpdate, u as CursorPagination, v as PageInfoMeta, w as UserUrls, x as SuccessResponse, y as Response } from "./index-JjhthUpt.cjs";
2
+ export { AccessValidationConfigUpdate, AccessValidationResult, ApiKeyAuthConfig, AuthConfig, AuthErrorResponse, AuthRequestConfig, AuthResponse, BasicAuthConfig, BearerAuthConfig, CountryCode, CountryCodeRestricted, CurrencyCode, CursorPagination, CustomAuthConfig, Environment, ErrorResponse, HttpMethod, InitOptions, NormalPagination, OAuth2AuthConfig, PageInfoMeta, Response, ResponseStatus, SuccessResponse, UnifiedResponse, UserConfig, UserUrls, ValidationError, ValidationErrorResponse, XGenericObject };
@@ -1,2 +1,2 @@
1
- import { _ as CountryCodeRestricted, a as InitOptions, c as Response, d as UnifiedResponse, f as UserConfig, g as CountryCode, h as XGenericObject, i as ErrorResponse, l as ResponseStatus, m as ValidationErrorResponse, n as AuthResponse, o as NormalPagination, p as ValidationError, r as CursorPagination, s as PageInfoMeta, t as AuthErrorResponse, u as SuccessResponse, v as CurrencyCode } from "./index-sMTTpEJS.js";
2
- export { AuthErrorResponse, AuthResponse, CountryCode, CountryCodeRestricted, CurrencyCode, CursorPagination, ErrorResponse, InitOptions, NormalPagination, PageInfoMeta, Response, ResponseStatus, SuccessResponse, UnifiedResponse, UserConfig, ValidationError, ValidationErrorResponse, XGenericObject };
1
+ import { A as CurrencyCode, C as UserConfig, D as XGenericObject, E as ValidationErrorResponse, O as CountryCode, S as UnifiedResponse, T as ValidationError, _ as OAuth2AuthConfig, a as AuthErrorResponse, b as ResponseStatus, c as BasicAuthConfig, d as CustomAuthConfig, f as Environment, g as NormalPagination, h as InitOptions, i as AuthConfig, k as CountryCodeRestricted, l as BearerAuthConfig, m as HttpMethod, n as AccessValidationResult, o as AuthRequestConfig, p as ErrorResponse, r as ApiKeyAuthConfig, s as AuthResponse, t as AccessValidationConfigUpdate, u as CursorPagination, v as PageInfoMeta, w as UserUrls, x as SuccessResponse, y as Response } from "./index-DUI9uPJQ.js";
2
+ export { AccessValidationConfigUpdate, AccessValidationResult, ApiKeyAuthConfig, AuthConfig, AuthErrorResponse, AuthRequestConfig, AuthResponse, BasicAuthConfig, BearerAuthConfig, CountryCode, CountryCodeRestricted, CurrencyCode, CursorPagination, CustomAuthConfig, Environment, ErrorResponse, HttpMethod, InitOptions, NormalPagination, OAuth2AuthConfig, PageInfoMeta, Response, ResponseStatus, SuccessResponse, UnifiedResponse, UserConfig, UserUrls, ValidationError, ValidationErrorResponse, XGenericObject };
@@ -9,6 +9,8 @@ interface XGenericObject {
9
9
  }
10
10
  //#endregion
11
11
  //#region src/Contracts/Core.d.ts
12
+ type Environment = 'sandbox' | 'live';
13
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
12
14
  type ResponseStatus = 'failed' | 'success';
13
15
  interface ValidationError {
14
16
  'field_name': string;
@@ -78,30 +80,87 @@ interface NormalPagination {
78
80
  interface PageInfoMeta {
79
81
  page_info: NormalPagination;
80
82
  }
83
+ interface UserUrls {
84
+ live?: string;
85
+ sandbox?: string;
86
+ }
87
+ interface BearerAuthConfig {
88
+ type: 'bearer';
89
+ token: string;
90
+ prefix?: string;
91
+ }
92
+ interface OAuth2AuthConfig {
93
+ type: 'oauth2';
94
+ accessToken: string;
95
+ tokenType?: string;
96
+ }
97
+ interface BasicAuthConfig {
98
+ type: 'basic';
99
+ username: string;
100
+ password: string;
101
+ }
102
+ interface ApiKeyAuthConfig {
103
+ type: 'apiKey';
104
+ name: string;
105
+ value: string;
106
+ in?: 'header' | 'query' | 'cookie';
107
+ prefix?: string;
108
+ }
109
+ interface AuthRequestConfig {
110
+ url: string;
111
+ method: HttpMethod;
112
+ headers: Record<string, string>;
113
+ params: XGenericObject;
114
+ body?: unknown;
115
+ }
116
+ interface CustomAuthConfig {
117
+ type: 'custom';
118
+ apply: (request: AuthRequestConfig) => AuthRequestConfig | Promise<AuthRequestConfig>;
119
+ }
120
+ type AuthConfig = BearerAuthConfig | OAuth2AuthConfig | BasicAuthConfig | ApiKeyAuthConfig | CustomAuthConfig;
121
+ type AccessValidationConfigUpdate = Partial<UserConfig> | AuthConfig | AuthConfig[];
122
+ type AccessValidationResult = boolean | string | void | AccessValidationConfigUpdate;
81
123
  interface InitOptions {
82
124
  /**
83
- * Your Flutterwave Public Key
125
+ * Your API Public Key
84
126
  */
85
127
  clientId: string;
86
128
  /**
87
- * Your Flutterwave Secret Key
129
+ * Your API Secret Key
88
130
  */
89
131
  clientSecret: string;
90
132
  /**
91
- * Your Flutterwave Encryption Key
133
+ * Your API Encryption Key
92
134
  */
93
135
  encryptionKey?: string;
94
136
  /**
95
137
  * Environment to use
96
138
  */
97
- environment?: 'sandbox' | 'live';
139
+ environment?: Environment;
140
+ /**
141
+ * Override environment base URLs.
142
+ */
143
+ urls?: UserUrls;
144
+ /**
145
+ * Default headers applied to every request.
146
+ */
147
+ headers?: Record<string, string>;
148
+ /**
149
+ * Request timeout in milliseconds.
150
+ */
151
+ timeout?: number;
152
+ /**
153
+ * Request authentication strategy or strategies.
154
+ */
155
+ auth?: AuthConfig | AuthConfig[];
98
156
  }
99
157
  interface UserConfig {
100
- environment?: 'sandbox' | 'live';
101
- urls: {
102
- live: string;
103
- sandbox: string;
104
- };
158
+ environment?: Environment;
159
+ urls?: UserUrls;
160
+ headers?: Record<string, string>;
161
+ timeout?: number;
162
+ encryptionKey?: string;
163
+ auth?: AuthConfig | AuthConfig[];
105
164
  }
106
165
  //#endregion
107
- export { CountryCodeRestricted as _, InitOptions as a, Response as c, UnifiedResponse as d, UserConfig as f, CountryCode as g, XGenericObject as h, ErrorResponse as i, ResponseStatus as l, ValidationErrorResponse as m, AuthResponse as n, NormalPagination as o, ValidationError as p, CursorPagination as r, PageInfoMeta as s, AuthErrorResponse as t, SuccessResponse as u, CurrencyCode as v };
166
+ export { CurrencyCode as A, UserConfig as C, XGenericObject as D, ValidationErrorResponse as E, CountryCode as O, UnifiedResponse as S, ValidationError as T, OAuth2AuthConfig as _, AuthErrorResponse as a, ResponseStatus as b, BasicAuthConfig as c, CustomAuthConfig as d, Environment as f, NormalPagination as g, InitOptions as h, AuthConfig as i, CountryCodeRestricted as k, BearerAuthConfig as l, HttpMethod as m, AccessValidationResult as n, AuthRequestConfig as o, ErrorResponse as p, ApiKeyAuthConfig as r, AuthResponse as s, AccessValidationConfigUpdate as t, CursorPagination as u, PageInfoMeta as v, UserUrls as w, SuccessResponse as x, Response as y };
@@ -9,6 +9,8 @@ interface XGenericObject {
9
9
  }
10
10
  //#endregion
11
11
  //#region src/Contracts/Core.d.ts
12
+ type Environment = 'sandbox' | 'live';
13
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
12
14
  type ResponseStatus = 'failed' | 'success';
13
15
  interface ValidationError {
14
16
  'field_name': string;
@@ -78,30 +80,87 @@ interface NormalPagination {
78
80
  interface PageInfoMeta {
79
81
  page_info: NormalPagination;
80
82
  }
83
+ interface UserUrls {
84
+ live?: string;
85
+ sandbox?: string;
86
+ }
87
+ interface BearerAuthConfig {
88
+ type: 'bearer';
89
+ token: string;
90
+ prefix?: string;
91
+ }
92
+ interface OAuth2AuthConfig {
93
+ type: 'oauth2';
94
+ accessToken: string;
95
+ tokenType?: string;
96
+ }
97
+ interface BasicAuthConfig {
98
+ type: 'basic';
99
+ username: string;
100
+ password: string;
101
+ }
102
+ interface ApiKeyAuthConfig {
103
+ type: 'apiKey';
104
+ name: string;
105
+ value: string;
106
+ in?: 'header' | 'query' | 'cookie';
107
+ prefix?: string;
108
+ }
109
+ interface AuthRequestConfig {
110
+ url: string;
111
+ method: HttpMethod;
112
+ headers: Record<string, string>;
113
+ params: XGenericObject;
114
+ body?: unknown;
115
+ }
116
+ interface CustomAuthConfig {
117
+ type: 'custom';
118
+ apply: (request: AuthRequestConfig) => AuthRequestConfig | Promise<AuthRequestConfig>;
119
+ }
120
+ type AuthConfig = BearerAuthConfig | OAuth2AuthConfig | BasicAuthConfig | ApiKeyAuthConfig | CustomAuthConfig;
121
+ type AccessValidationConfigUpdate = Partial<UserConfig> | AuthConfig | AuthConfig[];
122
+ type AccessValidationResult = boolean | string | void | AccessValidationConfigUpdate;
81
123
  interface InitOptions {
82
124
  /**
83
- * Your Flutterwave Public Key
125
+ * Your API Public Key
84
126
  */
85
127
  clientId: string;
86
128
  /**
87
- * Your Flutterwave Secret Key
129
+ * Your API Secret Key
88
130
  */
89
131
  clientSecret: string;
90
132
  /**
91
- * Your Flutterwave Encryption Key
133
+ * Your API Encryption Key
92
134
  */
93
135
  encryptionKey?: string;
94
136
  /**
95
137
  * Environment to use
96
138
  */
97
- environment?: 'sandbox' | 'live';
139
+ environment?: Environment;
140
+ /**
141
+ * Override environment base URLs.
142
+ */
143
+ urls?: UserUrls;
144
+ /**
145
+ * Default headers applied to every request.
146
+ */
147
+ headers?: Record<string, string>;
148
+ /**
149
+ * Request timeout in milliseconds.
150
+ */
151
+ timeout?: number;
152
+ /**
153
+ * Request authentication strategy or strategies.
154
+ */
155
+ auth?: AuthConfig | AuthConfig[];
98
156
  }
99
157
  interface UserConfig {
100
- environment?: 'sandbox' | 'live';
101
- urls: {
102
- live: string;
103
- sandbox: string;
104
- };
158
+ environment?: Environment;
159
+ urls?: UserUrls;
160
+ headers?: Record<string, string>;
161
+ timeout?: number;
162
+ encryptionKey?: string;
163
+ auth?: AuthConfig | AuthConfig[];
105
164
  }
106
165
  //#endregion
107
- export { CountryCodeRestricted as _, InitOptions as a, Response as c, UnifiedResponse as d, UserConfig as f, CountryCode as g, XGenericObject as h, ErrorResponse as i, ResponseStatus as l, ValidationErrorResponse as m, AuthResponse as n, NormalPagination as o, ValidationError as p, CursorPagination as r, PageInfoMeta as s, AuthErrorResponse as t, SuccessResponse as u, CurrencyCode as v };
166
+ export { CurrencyCode as A, UserConfig as C, XGenericObject as D, ValidationErrorResponse as E, CountryCode as O, UnifiedResponse as S, ValidationError as T, OAuth2AuthConfig as _, AuthErrorResponse as a, ResponseStatus as b, BasicAuthConfig as c, CustomAuthConfig as d, Environment as f, NormalPagination as g, InitOptions as h, AuthConfig as i, CountryCodeRestricted as k, BearerAuthConfig as l, HttpMethod as m, AccessValidationResult as n, AuthRequestConfig as o, ErrorResponse as p, ApiKeyAuthConfig as r, AuthResponse as s, AccessValidationConfigUpdate as t, CursorPagination as u, PageInfoMeta as v, UserUrls as w, SuccessResponse as x, Response as y };