@uveysservetoglu/kobil-core 1.0.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/README.md +21 -0
- package/dist/credentials.d.ts +23 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +23 -0
- package/dist/credentials.js.map +1 -0
- package/dist/error.d.ts +16 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +21 -0
- package/dist/error.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/service-client.d.ts +21 -0
- package/dist/service-client.d.ts.map +1 -0
- package/dist/service-client.js +79 -0
- package/dist/service-client.js.map +1 -0
- package/dist/token-provider.d.ts +19 -0
- package/dist/token-provider.d.ts.map +1 -0
- package/dist/token-provider.js +82 -0
- package/dist/token-provider.js.map +1 -0
- package/package.json +24 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @uveysservetoglu/kobil-core
|
|
2
|
+
|
|
3
|
+
Shared foundation for the KOBIL SDK family (`@uveysservetoglu/kobil-payment`, `@uveysservetoglu/kobil-chat`, `@uveysservetoglu/kobil-sign`, …).
|
|
4
|
+
|
|
5
|
+
You normally don't use this directly — the module packages depend on it. It provides:
|
|
6
|
+
|
|
7
|
+
- **`DefaultTokenProvider`** — OAuth2 `client_credentials` token acquisition with in-memory
|
|
8
|
+
caching (single in-flight request, honours `expires_in`). Modes: `post` (form body,
|
|
9
|
+
default) or `basic` (HTTP Basic header).
|
|
10
|
+
- **`KobilError`** — base error all module errors extend (`statusCode`, `responseBody`).
|
|
11
|
+
- **`KobilServiceClient`** — HTTP base for typed clients (bearer + send + error wrapping,
|
|
12
|
+
JSON / arbitrary-body / binary-download helpers).
|
|
13
|
+
- **`credentialsFromEnv`** — reads `KOBIL_TOKEN_ENDPOINT`, `KOBIL_CLIENT_ID`,
|
|
14
|
+
`KOBIL_CLIENT_SECRET`, `KOBIL_TOKEN_AUTH_MODE`.
|
|
15
|
+
|
|
16
|
+
Works from both TypeScript and JavaScript (ships compiled JS + `.d.ts`). Requires Node 18+
|
|
17
|
+
(global `fetch`).
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** How client credentials are presented to the OAuth2 token endpoint. */
|
|
2
|
+
export type TokenAuthMode = "post" | "basic";
|
|
3
|
+
/**
|
|
4
|
+
* OAuth2 credentials shared by every KOBIL SDK module. The token endpoint and
|
|
5
|
+
* client credentials are the same across modules, so configure them once.
|
|
6
|
+
*/
|
|
7
|
+
export interface KobilCredentials {
|
|
8
|
+
tokenEndpoint: string;
|
|
9
|
+
clientId: string;
|
|
10
|
+
clientSecret: string;
|
|
11
|
+
/** How credentials are sent to the token endpoint. Default: "post". */
|
|
12
|
+
tokenAuthMode?: TokenAuthMode;
|
|
13
|
+
/** Token cache lifetime (seconds) when the endpoint returns no `expires_in`. Default: 280. */
|
|
14
|
+
defaultTokenTtlSeconds?: number;
|
|
15
|
+
/** Safety margin (seconds) subtracted from token lifetime before refresh. Default: 20. */
|
|
16
|
+
tokenExpirySkewSeconds?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Builds credentials from `KOBIL_*` environment variables, with optional overrides
|
|
20
|
+
* (undefined/empty override values are ignored so env still wins for those).
|
|
21
|
+
*/
|
|
22
|
+
export declare function credentialsFromEnv(overrides?: Partial<KobilCredentials>): KobilCredentials;
|
|
23
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC;AAE7C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,8FAA8F;IAC9F,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,0FAA0F;IAC1F,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,GAAE,OAAO,CAAC,gBAAgB,CAAM,GAAG,gBAAgB,CAc9F"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.credentialsFromEnv = credentialsFromEnv;
|
|
4
|
+
/**
|
|
5
|
+
* Builds credentials from `KOBIL_*` environment variables, with optional overrides
|
|
6
|
+
* (undefined/empty override values are ignored so env still wins for those).
|
|
7
|
+
*/
|
|
8
|
+
function credentialsFromEnv(overrides = {}) {
|
|
9
|
+
const mode = process.env.KOBIL_TOKEN_AUTH_MODE?.toLowerCase();
|
|
10
|
+
const base = {
|
|
11
|
+
tokenEndpoint: process.env.KOBIL_TOKEN_ENDPOINT ?? "",
|
|
12
|
+
clientId: process.env.KOBIL_CLIENT_ID ?? "",
|
|
13
|
+
clientSecret: process.env.KOBIL_CLIENT_SECRET ?? "",
|
|
14
|
+
tokenAuthMode: mode === "basic" || mode === "client_secret_basic" ? "basic" : "post",
|
|
15
|
+
};
|
|
16
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
17
|
+
if (value !== undefined && value !== "") {
|
|
18
|
+
base[key] = value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return base;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":";;AAuBA,gDAcC;AAlBD;;;GAGG;AACH,SAAgB,kBAAkB,CAAC,YAAuC,EAAE;IAC1E,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,WAAW,EAAE,CAAC;IAC9D,MAAM,IAAI,GAAqB;QAC7B,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE;QACrD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE;QAC3C,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE;QACnD,aAAa,EAAE,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,qBAAqB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;KACrF,CAAC;IACF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAwC,EAAE,CAAC;QAC5F,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACvC,IAA2C,CAAC,GAAa,CAAC,GAAG,KAAK,CAAC;QACtE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/error.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface KobilErrorOptions {
|
|
2
|
+
statusCode?: number;
|
|
3
|
+
responseBody?: string;
|
|
4
|
+
cause?: unknown;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Base error for all KOBIL SDK modules. Module-specific errors
|
|
8
|
+
* (KobilPaymentError, KobilChatError, …) extend this, so callers can catch
|
|
9
|
+
* `KobilError` to handle any KOBIL failure uniformly.
|
|
10
|
+
*/
|
|
11
|
+
export declare class KobilError extends Error {
|
|
12
|
+
readonly statusCode?: number;
|
|
13
|
+
readonly responseBody?: string;
|
|
14
|
+
constructor(message: string, options?: KobilErrorOptions);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAEnB,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB;CAO7D"}
|
package/dist/error.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KobilError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Base error for all KOBIL SDK modules. Module-specific errors
|
|
6
|
+
* (KobilPaymentError, KobilChatError, …) extend this, so callers can catch
|
|
7
|
+
* `KobilError` to handle any KOBIL failure uniformly.
|
|
8
|
+
*/
|
|
9
|
+
class KobilError extends Error {
|
|
10
|
+
statusCode;
|
|
11
|
+
responseBody;
|
|
12
|
+
constructor(message, options = {}) {
|
|
13
|
+
super(message, options.cause !== undefined ? { cause: options.cause } : undefined);
|
|
14
|
+
this.name = new.target.name;
|
|
15
|
+
this.statusCode = options.statusCode;
|
|
16
|
+
this.responseBody = options.responseBody;
|
|
17
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.KobilError = KobilError;
|
|
21
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":";;;AAMA;;;;GAIG;AACH,MAAa,UAAW,SAAQ,KAAK;IAC1B,UAAU,CAAU;IACpB,YAAY,CAAU;IAE/B,YAAY,OAAe,EAAE,UAA6B,EAAE;QAC1D,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAXD,gCAWC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { KobilError } from "./error";
|
|
2
|
+
export type { KobilErrorOptions } from "./error";
|
|
3
|
+
export { credentialsFromEnv } from "./credentials";
|
|
4
|
+
export type { KobilCredentials, TokenAuthMode } from "./credentials";
|
|
5
|
+
export { DefaultTokenProvider } from "./token-provider";
|
|
6
|
+
export type { TokenProvider } from "./token-provider";
|
|
7
|
+
export { KobilServiceClient } from "./service-client";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KobilServiceClient = exports.DefaultTokenProvider = exports.credentialsFromEnv = exports.KobilError = void 0;
|
|
4
|
+
var error_1 = require("./error");
|
|
5
|
+
Object.defineProperty(exports, "KobilError", { enumerable: true, get: function () { return error_1.KobilError; } });
|
|
6
|
+
var credentials_1 = require("./credentials");
|
|
7
|
+
Object.defineProperty(exports, "credentialsFromEnv", { enumerable: true, get: function () { return credentials_1.credentialsFromEnv; } });
|
|
8
|
+
var token_provider_1 = require("./token-provider");
|
|
9
|
+
Object.defineProperty(exports, "DefaultTokenProvider", { enumerable: true, get: function () { return token_provider_1.DefaultTokenProvider; } });
|
|
10
|
+
var service_client_1 = require("./service-client");
|
|
11
|
+
Object.defineProperty(exports, "KobilServiceClient", { enumerable: true, get: function () { return service_client_1.KobilServiceClient; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AAEnB,6CAAmD;AAA1C,iHAAA,kBAAkB,OAAA;AAE3B,mDAAwD;AAA/C,sHAAA,oBAAoB,OAAA;AAE7B,mDAAsD;AAA7C,oHAAA,kBAAkB,OAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { KobilError } from "./error";
|
|
2
|
+
import { TokenProvider } from "./token-provider";
|
|
3
|
+
/**
|
|
4
|
+
* Base class for typed KOBIL service clients. Attaches the shared bearer token,
|
|
5
|
+
* sends the request, and turns non-2xx/transport failures into an error (override
|
|
6
|
+
* {@link makeError} to produce a module-specific error type).
|
|
7
|
+
*/
|
|
8
|
+
export declare abstract class KobilServiceClient {
|
|
9
|
+
protected readonly tokens: TokenProvider;
|
|
10
|
+
protected constructor(tokens: TokenProvider);
|
|
11
|
+
/** Override to wrap failures in a module-specific error type. */
|
|
12
|
+
protected makeError(message: string, statusCode?: number, responseBody?: string, cause?: unknown): KobilError;
|
|
13
|
+
/** Sends a request with a JSON body (or none) and parses the JSON response. */
|
|
14
|
+
protected sendJson<T>(method: string, url: string, body?: unknown, signal?: AbortSignal): Promise<T>;
|
|
15
|
+
/** Sends a request with an arbitrary body (e.g. FormData) and parses the JSON response. */
|
|
16
|
+
protected send<T>(method: string, url: string, body: string | FormData, signal?: AbortSignal): Promise<T>;
|
|
17
|
+
/** Sends a request and returns the raw response bytes (e.g. a file download). */
|
|
18
|
+
protected sendForBytes(method: string, url: string, signal?: AbortSignal): Promise<Uint8Array>;
|
|
19
|
+
private request;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=service-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-client.d.ts","sourceRoot":"","sources":["../src/service-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;;GAIG;AACH,8BAAsB,kBAAkB;IAChB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa;IAA9D,SAAS,aAAgC,MAAM,EAAE,aAAa;IAE9D,iEAAiE;IACjE,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU;IAI7G,+EAA+E;IAC/E,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAUpG,2FAA2F;IAC3F,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAIzG,iFAAiF;cACjE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;YAetF,OAAO;CAiCtB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KobilServiceClient = void 0;
|
|
4
|
+
const error_1 = require("./error");
|
|
5
|
+
/**
|
|
6
|
+
* Base class for typed KOBIL service clients. Attaches the shared bearer token,
|
|
7
|
+
* sends the request, and turns non-2xx/transport failures into an error (override
|
|
8
|
+
* {@link makeError} to produce a module-specific error type).
|
|
9
|
+
*/
|
|
10
|
+
class KobilServiceClient {
|
|
11
|
+
tokens;
|
|
12
|
+
constructor(tokens) {
|
|
13
|
+
this.tokens = tokens;
|
|
14
|
+
}
|
|
15
|
+
/** Override to wrap failures in a module-specific error type. */
|
|
16
|
+
makeError(message, statusCode, responseBody, cause) {
|
|
17
|
+
return new error_1.KobilError(message, { statusCode, responseBody, cause });
|
|
18
|
+
}
|
|
19
|
+
/** Sends a request with a JSON body (or none) and parses the JSON response. */
|
|
20
|
+
sendJson(method, url, body, signal) {
|
|
21
|
+
const headers = { accept: "application/json" };
|
|
22
|
+
let payload;
|
|
23
|
+
if (body !== undefined && body !== null) {
|
|
24
|
+
headers["content-type"] = "application/json";
|
|
25
|
+
payload = JSON.stringify(body);
|
|
26
|
+
}
|
|
27
|
+
return this.request(method, url, headers, payload, signal);
|
|
28
|
+
}
|
|
29
|
+
/** Sends a request with an arbitrary body (e.g. FormData) and parses the JSON response. */
|
|
30
|
+
send(method, url, body, signal) {
|
|
31
|
+
return this.request(method, url, { accept: "application/json" }, body, signal);
|
|
32
|
+
}
|
|
33
|
+
/** Sends a request and returns the raw response bytes (e.g. a file download). */
|
|
34
|
+
async sendForBytes(method, url, signal) {
|
|
35
|
+
const token = await this.tokens.getToken(signal);
|
|
36
|
+
let response;
|
|
37
|
+
try {
|
|
38
|
+
response = await fetch(url, { method, headers: { authorization: `Bearer ${token}` }, signal });
|
|
39
|
+
}
|
|
40
|
+
catch (cause) {
|
|
41
|
+
throw this.makeError(`An error occurred while calling ${method} ${url}.`, undefined, undefined, cause);
|
|
42
|
+
}
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
const text = await response.text().catch(() => undefined);
|
|
45
|
+
throw this.makeError(`KOBIL API returned ${response.status} for ${method} ${url}.`, response.status, text);
|
|
46
|
+
}
|
|
47
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
48
|
+
}
|
|
49
|
+
async request(method, url, headers, body, signal) {
|
|
50
|
+
const token = await this.tokens.getToken(signal);
|
|
51
|
+
let response;
|
|
52
|
+
try {
|
|
53
|
+
response = await fetch(url, {
|
|
54
|
+
method,
|
|
55
|
+
headers: { ...headers, authorization: `Bearer ${token}` },
|
|
56
|
+
body,
|
|
57
|
+
signal,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
throw this.makeError(`An error occurred while calling ${method} ${url}.`, undefined, undefined, cause);
|
|
62
|
+
}
|
|
63
|
+
const text = await response.text();
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
throw this.makeError(`KOBIL API returned ${response.status} for ${method} ${url}.`, response.status, text);
|
|
66
|
+
}
|
|
67
|
+
if (!text) {
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(text);
|
|
72
|
+
}
|
|
73
|
+
catch (cause) {
|
|
74
|
+
throw this.makeError(`Failed to parse response from ${method} ${url}.`, response.status, text, cause);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.KobilServiceClient = KobilServiceClient;
|
|
79
|
+
//# sourceMappingURL=service-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-client.js","sourceRoot":"","sources":["../src/service-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { KobilCredentials } from "./credentials";
|
|
2
|
+
/** Provides (and caches) OAuth2 access tokens shared across KOBIL SDK modules. */
|
|
3
|
+
export interface TokenProvider {
|
|
4
|
+
getToken(signal?: AbortSignal): Promise<string>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Acquires OAuth2 tokens via the `client_credentials` grant — using either the form
|
|
8
|
+
* body (`post`) or an HTTP Basic header (`basic`) — and caches them in memory until
|
|
9
|
+
* shortly before they expire. A single in-flight request is shared to avoid stampedes.
|
|
10
|
+
*/
|
|
11
|
+
export declare class DefaultTokenProvider implements TokenProvider {
|
|
12
|
+
private readonly credentials;
|
|
13
|
+
private cache?;
|
|
14
|
+
private inflight?;
|
|
15
|
+
constructor(credentials: KobilCredentials);
|
|
16
|
+
getToken(signal?: AbortSignal): Promise<string>;
|
|
17
|
+
private request;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=token-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-provider.d.ts","sourceRoot":"","sources":["../src/token-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACjD;AAOD;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,aAAa;IAI5C,OAAO,CAAC,QAAQ,CAAC,WAAW;IAHxC,OAAO,CAAC,KAAK,CAAC,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAC,CAAkB;gBAEN,WAAW,EAAE,gBAAgB;IAEpD,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;YAavC,OAAO;CAqDtB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultTokenProvider = void 0;
|
|
4
|
+
const error_1 = require("./error");
|
|
5
|
+
/**
|
|
6
|
+
* Acquires OAuth2 tokens via the `client_credentials` grant — using either the form
|
|
7
|
+
* body (`post`) or an HTTP Basic header (`basic`) — and caches them in memory until
|
|
8
|
+
* shortly before they expire. A single in-flight request is shared to avoid stampedes.
|
|
9
|
+
*/
|
|
10
|
+
class DefaultTokenProvider {
|
|
11
|
+
credentials;
|
|
12
|
+
cache;
|
|
13
|
+
inflight;
|
|
14
|
+
constructor(credentials) {
|
|
15
|
+
this.credentials = credentials;
|
|
16
|
+
}
|
|
17
|
+
async getToken(signal) {
|
|
18
|
+
if (this.cache && this.cache.expiresAt > Date.now()) {
|
|
19
|
+
return this.cache.token;
|
|
20
|
+
}
|
|
21
|
+
if (this.inflight) {
|
|
22
|
+
return this.inflight;
|
|
23
|
+
}
|
|
24
|
+
this.inflight = this.request(signal).finally(() => {
|
|
25
|
+
this.inflight = undefined;
|
|
26
|
+
});
|
|
27
|
+
return this.inflight;
|
|
28
|
+
}
|
|
29
|
+
async request(signal) {
|
|
30
|
+
const c = this.credentials;
|
|
31
|
+
if (!c.tokenEndpoint)
|
|
32
|
+
throw new error_1.KobilError("credentials.tokenEndpoint is required.");
|
|
33
|
+
if (!c.clientId)
|
|
34
|
+
throw new error_1.KobilError("credentials.clientId is required.");
|
|
35
|
+
if (!c.clientSecret)
|
|
36
|
+
throw new error_1.KobilError("credentials.clientSecret is required.");
|
|
37
|
+
const body = new URLSearchParams({ grant_type: "client_credentials" });
|
|
38
|
+
const headers = {
|
|
39
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
40
|
+
};
|
|
41
|
+
if ((c.tokenAuthMode ?? "post") === "basic") {
|
|
42
|
+
const basic = Buffer.from(`${c.clientId}:${c.clientSecret}`).toString("base64");
|
|
43
|
+
headers["authorization"] = `Basic ${basic}`;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
body.set("client_id", c.clientId);
|
|
47
|
+
body.set("client_secret", c.clientSecret);
|
|
48
|
+
}
|
|
49
|
+
let response;
|
|
50
|
+
try {
|
|
51
|
+
response = await fetch(c.tokenEndpoint, { method: "POST", headers, body, signal });
|
|
52
|
+
}
|
|
53
|
+
catch (cause) {
|
|
54
|
+
throw new error_1.KobilError("An error occurred while acquiring an access token.", { cause });
|
|
55
|
+
}
|
|
56
|
+
const text = await response.text();
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
throw new error_1.KobilError(`Token endpoint returned ${response.status}.`, {
|
|
59
|
+
statusCode: response.status,
|
|
60
|
+
responseBody: text,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
let json;
|
|
64
|
+
try {
|
|
65
|
+
json = JSON.parse(text);
|
|
66
|
+
}
|
|
67
|
+
catch (cause) {
|
|
68
|
+
throw new error_1.KobilError("Token endpoint returned invalid JSON.", { cause, responseBody: text });
|
|
69
|
+
}
|
|
70
|
+
const token = json.access_token;
|
|
71
|
+
if (!token) {
|
|
72
|
+
throw new error_1.KobilError("Token endpoint response did not contain an access_token.", {
|
|
73
|
+
responseBody: text,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const ttlSeconds = (json.expires_in ?? c.defaultTokenTtlSeconds ?? 280) - (c.tokenExpirySkewSeconds ?? 20);
|
|
77
|
+
this.cache = { token, expiresAt: Date.now() + Math.max(1, ttlSeconds) * 1000 };
|
|
78
|
+
return token;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.DefaultTokenProvider = DefaultTokenProvider;
|
|
82
|
+
//# sourceMappingURL=token-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-provider.js","sourceRoot":"","sources":["../src/token-provider.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uveysservetoglu/kobil-core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared foundation for the KOBIL SDK family: OAuth token acquisition/caching (post & basic), a common error type, and an HTTP base for typed clients.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"keywords": [
|
|
12
|
+
"kobil",
|
|
13
|
+
"sdk",
|
|
14
|
+
"oauth2",
|
|
15
|
+
"core"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/uveysservetoglu/kobil-sdks"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc -b"
|
|
23
|
+
}
|
|
24
|
+
}
|