@corti/sdk 0.0.0-rc.1 → 0.0.0-rc.359

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
@@ -38,29 +38,23 @@ const client = new CortiClient({
38
38
 
39
39
  // Or using a bearer token
40
40
  const client = new CortiClient({
41
- environment: CortiEnvironment.Eu,
42
- tenantName: "YOUR_TENANT_NAME",
43
41
  auth: {
44
- accessToken: "YOUR_ACCESS_TOKEN",
45
- // Optional: refresh token for automatic token refresh
46
- refreshToken: "YOUR_REFRESH_TOKEN",
47
- expiresIn: 3600,
48
- refreshExpiresIn: 86400,
42
+ accessToken: "YOUR_ACCESS_TOKEN"
49
43
  },
50
44
  });
51
45
 
52
46
  // Or using just a refresh function (no initial access token needed)
53
47
  const client = new CortiClient({
54
- environment: CortiEnvironment.Eu,
55
- tenantName: "YOUR_TENANT_NAME",
56
48
  auth: {
49
+ // refreshToken will be undefined for the first call, then it will be the refreshToken returned from the previous token request
57
50
  refreshAccessToken: async (refreshToken?: string) => {
58
51
  // Your custom logic to get a new access token
59
- const response = await fetch("https://your-auth-server/refresh", {
52
+ const response = await fetch("https://your-auth-server/token", {
60
53
  method: "POST",
61
54
  headers: { "Content-Type": "application/json" },
62
- body: JSON.stringify({ refreshToken: refreshToken }),
55
+ body: JSON.stringify({ refreshToken }),
63
56
  });
57
+
64
58
  return response.json();
65
59
  },
66
60
  },
@@ -64,8 +64,8 @@ class CortiClient {
64
64
  "Tenant-Name": _options === null || _options === void 0 ? void 0 : _options.tenantName,
65
65
  "X-Fern-Language": "JavaScript",
66
66
  "X-Fern-SDK-Name": "@corti/sdk",
67
- "X-Fern-SDK-Version": "0.0.0-rc.1",
68
- "User-Agent": "@corti/sdk/0.0.0-rc.1",
67
+ "X-Fern-SDK-Version": "0.0.0-rc.359",
68
+ "User-Agent": "@corti/sdk/0.0.0-rc.359",
69
69
  "X-Fern-Runtime": core.RUNTIME.type,
70
70
  "X-Fern-Runtime-Version": core.RUNTIME.version,
71
71
  }, _options === null || _options === void 0 ? void 0 : _options.headers) });
@@ -27,14 +27,11 @@ import { Agents } from "../api/resources/agents/client/Client.js";
27
27
  */
28
28
  import { Stream } from "./CustomStream.js";
29
29
  import { Transcribe } from "./CustomTranscribe.js";
30
- /**
31
- * Patch: added custom RefreshBearerProvider
32
- */
33
- import { BearerOptions } from "./RefreshBearerProvider.js";
34
30
  import { Environment, CortiInternalEnvironment } from "./utils/getEnvironmentFromString.js";
31
+ import { BearerOptions } from "./RefreshBearerProvider.js";
35
32
  export declare namespace CortiClient {
36
33
  /**
37
- * Patch: added new public interface for `Options` (+ `ClientCredentials` interface)
34
+ * Patch: added new public type for `Options` + internal interfaces to create it
38
35
  */
39
36
  interface ClientCredentials {
40
37
  clientId: core.Supplier<string>;
@@ -44,10 +41,6 @@ export declare namespace CortiClient {
44
41
  /** Additional headers to include in requests. */
45
42
  headers?: Record<string, string | core.Supplier<string | undefined> | undefined>;
46
43
  }
47
- /**
48
- * Options when using Client Credentials authentication
49
- * tenantName and environment are required
50
- */
51
44
  interface OptionsWithClientCredentials extends BaseOptions {
52
45
  /**
53
46
  * Patch: allow to pass a custom string-based environment
@@ -57,12 +50,12 @@ export declare namespace CortiClient {
57
50
  tenantName: core.Supplier<string>;
58
51
  auth: ClientCredentials;
59
52
  }
60
- /**
61
- * Options when using Bearer token authentication
62
- * tenantName and environment are optional (extracted from token if not provided)
63
- */
64
53
  interface OptionsWithBearerToken extends BaseOptions {
54
+ /**
55
+ * Patch: allow to pass a custom string-based environment
56
+ * */
65
57
  environment?: Environment;
58
+ /** Override the Tenant-Name header */
66
59
  tenantName?: core.Supplier<string>;
67
60
  auth: BearerOptions;
68
61
  }
@@ -72,6 +65,7 @@ export declare namespace CortiClient {
72
65
  * - renamed `Options` to `InternalOptions`
73
66
  * - added `token` field to support BearerProvider
74
67
  * - made clientId and clientSecret optional
68
+ * - updated environment type to CortiInternalEnvironment
75
69
  */
76
70
  interface InternalOptions {
77
71
  environment: CortiInternalEnvironment;
@@ -78,21 +78,21 @@ const Client_js_7 = require("../api/resources/agents/client/Client.js");
78
78
  const CustomStream_js_1 = require("./CustomStream.js");
79
79
  const CustomTranscribe_js_1 = require("./CustomTranscribe.js");
80
80
  /**
81
- * Patch: added custom RefreshBearerProvider
82
- */
83
- const RefreshBearerProvider_js_1 = require("./RefreshBearerProvider.js");
84
- /**
85
- * Patch: added SDK_VERSION import
81
+ * Patch: added SDK_VERSION import and custom code imports
86
82
  */
87
83
  const version_js_1 = require("../version.js");
88
84
  const getEnvironmentFromString_js_1 = require("./utils/getEnvironmentFromString.js");
89
85
  const resolveClientOptions_js_1 = require("./utils/resolveClientOptions.js");
86
+ const RefreshBearerProvider_js_1 = require("./RefreshBearerProvider.js");
90
87
  class CortiClient {
91
88
  constructor(_options) {
92
89
  /**
93
90
  * Patch: resolve tenantName and environment from options or token
94
91
  */
95
- const { tenantName, environment } = (0, resolveClientOptions_js_1.resolveClientOptions)(_options);
92
+ const { tenantName, environment, initialTokenResponse } = (0, resolveClientOptions_js_1.resolveClientOptions)(_options);
93
+ /**
94
+ * Patch: redefining options based on new schema
95
+ */
96
96
  this._options = Object.assign(Object.assign({}, _options), { headers: (0, headers_js_1.mergeHeaders)({
97
97
  "Tenant-Name": tenantName,
98
98
  "X-Fern-Language": "JavaScript",
@@ -108,17 +108,16 @@ class CortiClient {
108
108
  /**
109
109
  * Patch: if `clientId` is provided, use OAuthTokenProvider, otherwise use BearerProvider
110
110
  */
111
- this._oauthTokenProvider =
112
- "clientId" in _options.auth
113
- ? new core.OAuthTokenProvider({
114
- clientId: _options.auth.clientId,
115
- clientSecret: _options.auth.clientSecret,
116
- /**
117
- * Patch: provide whole `options` object to the Auth client, since it depends on both tenantName and environment
118
- */
119
- authClient: new CortiAuth_js_1.Auth(this._options),
120
- })
121
- : new RefreshBearerProvider_js_1.RefreshBearerProvider(_options.auth);
111
+ this._oauthTokenProvider = "clientId" in _options.auth ?
112
+ new core.OAuthTokenProvider({
113
+ clientId: _options.auth.clientId,
114
+ clientSecret: _options.auth.clientSecret,
115
+ /**
116
+ * Patch: provide whole `options` object to the Auth client, since it depends on both tenantName and environment
117
+ */
118
+ authClient: new CortiAuth_js_1.Auth(this._options),
119
+ }) :
120
+ new RefreshBearerProvider_js_1.RefreshBearerProvider(Object.assign(Object.assign({}, _options.auth), { initialTokenResponse }));
122
121
  }
123
122
  get interactions() {
124
123
  var _a;
@@ -2,9 +2,9 @@
2
2
  * RefreshBearerProvider used as a replacement of OAuthTokenProvider, in case when accessToken from outside of library was used instead of Client credentials.
3
3
  */
4
4
  import * as api from "../api/index.js";
5
- type ExpectedTokenResponse = Omit<api.GetTokenResponse, 'tokenType' | 'expiresIn'> & {
5
+ export type ExpectedTokenResponse = Omit<api.GetTokenResponse, "tokenType" | "expiresIn"> & {
6
6
  tokenType?: string;
7
- expiresIn?: string;
7
+ expiresIn?: number;
8
8
  };
9
9
  type RefreshAccessTokenFunction = (refreshToken?: string) => Promise<ExpectedTokenResponse> | ExpectedTokenResponse;
10
10
  export type BearerOptions = Partial<Omit<api.GetTokenResponse, 'accessToken'>> & ({
@@ -21,7 +21,10 @@ export declare class RefreshBearerProvider {
21
21
  private _refreshAccessToken;
22
22
  private _expiresAt;
23
23
  private _refreshExpiresAt;
24
- constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn, }: BearerOptions);
24
+ private _initialTokenResponse;
25
+ constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn, initialTokenResponse, }: BearerOptions & {
26
+ initialTokenResponse?: Promise<ExpectedTokenResponse>;
27
+ });
25
28
  getToken(): Promise<string>;
26
29
  private refresh;
27
30
  private getExpiresAt;
@@ -49,54 +49,59 @@ exports.RefreshBearerProvider = void 0;
49
49
  const core = __importStar(require("../core/index.js"));
50
50
  const decodeToken_js_1 = require("./utils/decodeToken.js");
51
51
  class RefreshBearerProvider {
52
- constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn, }) {
52
+ constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn, initialTokenResponse, }) {
53
53
  this.BUFFER_IN_MINUTES = 2;
54
- this._accessToken = accessToken || 'no_token';
54
+ this._accessToken = accessToken || "no_token";
55
55
  this._refreshToken = refreshToken;
56
- this._expiresAt = typeof expiresIn === "number"
57
- ? this.getExpiresAt(expiresIn, this.BUFFER_IN_MINUTES)
58
- : this.parseTokenExpiry(this._accessToken, this.BUFFER_IN_MINUTES) || this.getExpiresAt(0, this.BUFFER_IN_MINUTES);
59
- this._refreshExpiresAt = typeof refreshExpiresIn === "number"
60
- ? this.getExpiresAt(refreshExpiresIn, 0)
61
- : (this._refreshToken && this.parseTokenExpiry(this._refreshToken, 0)) || this.getExpiresAt(0, 0);
56
+ this._initialTokenResponse = initialTokenResponse;
57
+ this._expiresAt = this.getExpiresAt(expiresIn, this._accessToken, this.BUFFER_IN_MINUTES);
58
+ this._refreshExpiresAt = this.getExpiresAt(refreshExpiresIn, this._refreshToken, 0);
62
59
  this._refreshAccessToken = refreshAccessToken;
63
60
  }
64
61
  getToken() {
65
62
  return __awaiter(this, void 0, void 0, function* () {
66
- if (this._accessToken && this._expiresAt > new Date()) {
63
+ if (this._accessToken && this._accessToken !== "no_token" && this._expiresAt > new Date()) {
67
64
  return core.Supplier.get(this._accessToken);
68
65
  }
66
+ if (this._initialTokenResponse) {
67
+ const tokenResponse = yield this._initialTokenResponse;
68
+ this._initialTokenResponse = undefined;
69
+ this._accessToken = tokenResponse.accessToken;
70
+ this._expiresAt = this.getExpiresAt(tokenResponse.expiresIn, tokenResponse.accessToken, this.BUFFER_IN_MINUTES);
71
+ this._refreshToken = tokenResponse.refreshToken;
72
+ this._refreshExpiresAt = this.getExpiresAt(tokenResponse.refreshExpiresIn, this._refreshToken, 0);
73
+ return this.getToken();
74
+ }
69
75
  return this.refresh();
70
76
  });
71
77
  }
72
78
  refresh() {
73
79
  return __awaiter(this, void 0, void 0, function* () {
74
- if (!this._refreshAccessToken || this._refreshToken && this._refreshExpiresAt < new Date()) {
80
+ if (!this._refreshAccessToken || (this._refreshToken && this._refreshExpiresAt < new Date())) {
75
81
  return core.Supplier.get(this._accessToken);
76
82
  }
77
83
  const tokenResponse = yield this._refreshAccessToken(this._refreshToken);
78
84
  this._accessToken = tokenResponse.accessToken;
79
- this._expiresAt = typeof tokenResponse.expiresIn === "number"
80
- ? this.getExpiresAt(tokenResponse.expiresIn, this.BUFFER_IN_MINUTES)
81
- : this.parseTokenExpiry(tokenResponse.accessToken, this.BUFFER_IN_MINUTES) || this.getExpiresAt(0, this.BUFFER_IN_MINUTES);
85
+ this._expiresAt = this.getExpiresAt(tokenResponse.expiresIn, tokenResponse.accessToken, this.BUFFER_IN_MINUTES);
82
86
  this._refreshToken = tokenResponse.refreshToken;
83
- this._refreshExpiresAt = typeof tokenResponse.refreshExpiresIn === "number"
84
- ? this.getExpiresAt(tokenResponse.refreshExpiresIn, 0)
85
- : this.parseTokenExpiry(this._refreshToken, 0) || this.getExpiresAt(0, 0);
87
+ this._refreshExpiresAt = this.getExpiresAt(tokenResponse.refreshExpiresIn, this._refreshToken, 0);
86
88
  return this._accessToken;
87
89
  });
88
90
  }
89
- getExpiresAt(expiresInSeconds = 0, bufferInMinutes = this.BUFFER_IN_MINUTES) {
90
- const now = new Date();
91
- return new Date(now.getTime() + expiresInSeconds * 1000 - bufferInMinutes * 60 * 1000);
91
+ getExpiresAt(expiresIn, token, bufferInMinutes = this.BUFFER_IN_MINUTES) {
92
+ if (typeof expiresIn === "number") {
93
+ const now = new Date();
94
+ return new Date(now.getTime() + expiresIn * 1000 - bufferInMinutes * 60 * 1000);
95
+ }
96
+ return this.parseTokenExpiry(token, bufferInMinutes) || this.getExpiresAt(0, token, bufferInMinutes);
92
97
  }
93
98
  parseTokenExpiry(token, bufferInMinutes) {
94
- if (!token || token === 'no_token') {
99
+ if (!token || token === "no_token") {
95
100
  return;
96
101
  }
97
102
  try {
98
103
  const decoded = (0, decodeToken_js_1.decodeToken)(token);
99
- if (decoded && typeof decoded.expiresAt === 'number') {
104
+ if (decoded && typeof decoded.expiresAt === "number") {
100
105
  const ms = decoded.expiresAt * 1000 - bufferInMinutes * 60 * 1000;
101
106
  return new Date(ms);
102
107
  }
@@ -24,4 +24,4 @@ export declare function decodeToken(token: string): {
24
24
  tenantName: string;
25
25
  accessToken: string;
26
26
  expiresAt: number | undefined;
27
- } | undefined;
27
+ } | null;
@@ -24,9 +24,9 @@ exports.decodeToken = decodeToken;
24
24
  */
25
25
  function decodeToken(token) {
26
26
  // Validate the token structure (should contain at least header and payload parts)
27
- const parts = token.split('.');
27
+ const parts = token ? token.split('.') : '';
28
28
  if (parts.length < 2) {
29
- throw new Error('Invalid token format');
29
+ return null;
30
30
  }
31
31
  // Retrieve the payload (second part) of the JWT token
32
32
  const base64Url = parts[1];
@@ -41,7 +41,7 @@ function decodeToken(token) {
41
41
  .join(''));
42
42
  }
43
43
  catch (error) {
44
- throw new Error('Failed to decode token payload');
44
+ return null;
45
45
  }
46
46
  // Parse the JSON string to obtain token details
47
47
  let tokenDetails;
@@ -49,12 +49,12 @@ function decodeToken(token) {
49
49
  tokenDetails = JSON.parse(jsonPayload);
50
50
  }
51
51
  catch (error) {
52
- throw new Error('Invalid JSON payload in token');
52
+ return null;
53
53
  }
54
54
  // Extract the issuer URL from the token details
55
55
  const issuerUrl = tokenDetails.iss;
56
56
  if (!issuerUrl) {
57
- throw new Error('Token payload does not contain an issuer (iss) field');
57
+ return null;
58
58
  }
59
59
  // Regex to extract environment and tenant from issuer URL:
60
60
  // Expected format: https://keycloak.{environment}.corti.app/realms/{tenant}
@@ -73,4 +73,5 @@ function decodeToken(token) {
73
73
  expiresAt,
74
74
  };
75
75
  }
76
+ return null;
76
77
  }
@@ -1,9 +1,11 @@
1
1
  import * as core from "../../core/index.js";
2
2
  import { CortiClient } from "../CortiClient.js";
3
3
  import { Environment } from "./getEnvironmentFromString.js";
4
+ import { ExpectedTokenResponse } from "../RefreshBearerProvider.js";
4
5
  type ResolvedClientOptions = {
5
6
  environment: Environment;
6
7
  tenantName: core.Supplier<string>;
8
+ initialTokenResponse?: Promise<ExpectedTokenResponse>;
7
9
  };
8
10
  export declare function resolveClientOptions(options: CortiClient.Options): ResolvedClientOptions;
9
11
  export {};
@@ -94,22 +94,16 @@ function resolveClientOptions(options) {
94
94
  ]);
95
95
  }
96
96
  return {
97
+ tokenResponse,
97
98
  tenantName: decoded.tenantName,
98
99
  environment: decoded.environment,
99
100
  };
100
101
  }))();
101
102
  return {
102
103
  tenantName: options.tenantName ||
103
- function () {
104
- return __awaiter(this, void 0, void 0, function* () {
105
- return (yield tokenResponsePromise).tenantName;
106
- });
107
- },
108
- environment: options.environment || function () {
109
- return __awaiter(this, void 0, void 0, function* () {
110
- const environment = (0, getEnvironmentFromString_js_1.getEnvironment)((yield tokenResponsePromise).environment);
111
- return core.Supplier.get(environment);
112
- });
113
- },
104
+ tokenResponsePromise.then(({ tenantName }) => tenantName),
105
+ environment: options.environment ||
106
+ tokenResponsePromise.then(({ environment }) => core.Supplier.get((0, getEnvironmentFromString_js_1.getEnvironment)(environment))),
107
+ initialTokenResponse: tokenResponsePromise.then((result) => result.tokenResponse),
114
108
  };
115
109
  }
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "0.0.0-rc.1";
1
+ export declare const SDK_VERSION = "0.0.0-rc.359";
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = void 0;
4
- exports.SDK_VERSION = "0.0.0-rc.1";
4
+ exports.SDK_VERSION = "0.0.0-rc.359";
@@ -28,8 +28,8 @@ export class CortiClient {
28
28
  "Tenant-Name": _options === null || _options === void 0 ? void 0 : _options.tenantName,
29
29
  "X-Fern-Language": "JavaScript",
30
30
  "X-Fern-SDK-Name": "@corti/sdk",
31
- "X-Fern-SDK-Version": "0.0.0-rc.1",
32
- "User-Agent": "@corti/sdk/0.0.0-rc.1",
31
+ "X-Fern-SDK-Version": "0.0.0-rc.359",
32
+ "User-Agent": "@corti/sdk/0.0.0-rc.359",
33
33
  "X-Fern-Runtime": core.RUNTIME.type,
34
34
  "X-Fern-Runtime-Version": core.RUNTIME.version,
35
35
  }, _options === null || _options === void 0 ? void 0 : _options.headers) });
@@ -27,14 +27,11 @@ import { Agents } from "../api/resources/agents/client/Client.mjs";
27
27
  */
28
28
  import { Stream } from "./CustomStream.mjs";
29
29
  import { Transcribe } from "./CustomTranscribe.mjs";
30
- /**
31
- * Patch: added custom RefreshBearerProvider
32
- */
33
- import { BearerOptions } from "./RefreshBearerProvider.mjs";
34
30
  import { Environment, CortiInternalEnvironment } from "./utils/getEnvironmentFromString.mjs";
31
+ import { BearerOptions } from "./RefreshBearerProvider.mjs";
35
32
  export declare namespace CortiClient {
36
33
  /**
37
- * Patch: added new public interface for `Options` (+ `ClientCredentials` interface)
34
+ * Patch: added new public type for `Options` + internal interfaces to create it
38
35
  */
39
36
  interface ClientCredentials {
40
37
  clientId: core.Supplier<string>;
@@ -44,10 +41,6 @@ export declare namespace CortiClient {
44
41
  /** Additional headers to include in requests. */
45
42
  headers?: Record<string, string | core.Supplier<string | undefined> | undefined>;
46
43
  }
47
- /**
48
- * Options when using Client Credentials authentication
49
- * tenantName and environment are required
50
- */
51
44
  interface OptionsWithClientCredentials extends BaseOptions {
52
45
  /**
53
46
  * Patch: allow to pass a custom string-based environment
@@ -57,12 +50,12 @@ export declare namespace CortiClient {
57
50
  tenantName: core.Supplier<string>;
58
51
  auth: ClientCredentials;
59
52
  }
60
- /**
61
- * Options when using Bearer token authentication
62
- * tenantName and environment are optional (extracted from token if not provided)
63
- */
64
53
  interface OptionsWithBearerToken extends BaseOptions {
54
+ /**
55
+ * Patch: allow to pass a custom string-based environment
56
+ * */
65
57
  environment?: Environment;
58
+ /** Override the Tenant-Name header */
66
59
  tenantName?: core.Supplier<string>;
67
60
  auth: BearerOptions;
68
61
  }
@@ -72,6 +65,7 @@ export declare namespace CortiClient {
72
65
  * - renamed `Options` to `InternalOptions`
73
66
  * - added `token` field to support BearerProvider
74
67
  * - made clientId and clientSecret optional
68
+ * - updated environment type to CortiInternalEnvironment
75
69
  */
76
70
  interface InternalOptions {
77
71
  environment: CortiInternalEnvironment;
@@ -42,21 +42,21 @@ import { Agents } from "../api/resources/agents/client/Client.mjs";
42
42
  import { Stream } from "./CustomStream.mjs";
43
43
  import { Transcribe } from "./CustomTranscribe.mjs";
44
44
  /**
45
- * Patch: added custom RefreshBearerProvider
46
- */
47
- import { RefreshBearerProvider } from "./RefreshBearerProvider.mjs";
48
- /**
49
- * Patch: added SDK_VERSION import
45
+ * Patch: added SDK_VERSION import and custom code imports
50
46
  */
51
47
  import { SDK_VERSION } from "../version.mjs";
52
48
  import { getEnvironment } from "./utils/getEnvironmentFromString.mjs";
53
49
  import { resolveClientOptions } from "./utils/resolveClientOptions.mjs";
50
+ import { RefreshBearerProvider } from "./RefreshBearerProvider.mjs";
54
51
  export class CortiClient {
55
52
  constructor(_options) {
56
53
  /**
57
54
  * Patch: resolve tenantName and environment from options or token
58
55
  */
59
- const { tenantName, environment } = resolveClientOptions(_options);
56
+ const { tenantName, environment, initialTokenResponse } = resolveClientOptions(_options);
57
+ /**
58
+ * Patch: redefining options based on new schema
59
+ */
60
60
  this._options = Object.assign(Object.assign({}, _options), { headers: mergeHeaders({
61
61
  "Tenant-Name": tenantName,
62
62
  "X-Fern-Language": "JavaScript",
@@ -72,17 +72,16 @@ export class CortiClient {
72
72
  /**
73
73
  * Patch: if `clientId` is provided, use OAuthTokenProvider, otherwise use BearerProvider
74
74
  */
75
- this._oauthTokenProvider =
76
- "clientId" in _options.auth
77
- ? new core.OAuthTokenProvider({
78
- clientId: _options.auth.clientId,
79
- clientSecret: _options.auth.clientSecret,
80
- /**
81
- * Patch: provide whole `options` object to the Auth client, since it depends on both tenantName and environment
82
- */
83
- authClient: new Auth(this._options),
84
- })
85
- : new RefreshBearerProvider(_options.auth);
75
+ this._oauthTokenProvider = "clientId" in _options.auth ?
76
+ new core.OAuthTokenProvider({
77
+ clientId: _options.auth.clientId,
78
+ clientSecret: _options.auth.clientSecret,
79
+ /**
80
+ * Patch: provide whole `options` object to the Auth client, since it depends on both tenantName and environment
81
+ */
82
+ authClient: new Auth(this._options),
83
+ }) :
84
+ new RefreshBearerProvider(Object.assign(Object.assign({}, _options.auth), { initialTokenResponse }));
86
85
  }
87
86
  get interactions() {
88
87
  var _a;
@@ -2,9 +2,9 @@
2
2
  * RefreshBearerProvider used as a replacement of OAuthTokenProvider, in case when accessToken from outside of library was used instead of Client credentials.
3
3
  */
4
4
  import * as api from "../api/index.mjs";
5
- type ExpectedTokenResponse = Omit<api.GetTokenResponse, 'tokenType' | 'expiresIn'> & {
5
+ export type ExpectedTokenResponse = Omit<api.GetTokenResponse, "tokenType" | "expiresIn"> & {
6
6
  tokenType?: string;
7
- expiresIn?: string;
7
+ expiresIn?: number;
8
8
  };
9
9
  type RefreshAccessTokenFunction = (refreshToken?: string) => Promise<ExpectedTokenResponse> | ExpectedTokenResponse;
10
10
  export type BearerOptions = Partial<Omit<api.GetTokenResponse, 'accessToken'>> & ({
@@ -21,7 +21,10 @@ export declare class RefreshBearerProvider {
21
21
  private _refreshAccessToken;
22
22
  private _expiresAt;
23
23
  private _refreshExpiresAt;
24
- constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn, }: BearerOptions);
24
+ private _initialTokenResponse;
25
+ constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn, initialTokenResponse, }: BearerOptions & {
26
+ initialTokenResponse?: Promise<ExpectedTokenResponse>;
27
+ });
25
28
  getToken(): Promise<string>;
26
29
  private refresh;
27
30
  private getExpiresAt;
@@ -13,54 +13,59 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
13
13
  import * as core from "../core/index.mjs";
14
14
  import { decodeToken } from "./utils/decodeToken.mjs";
15
15
  export class RefreshBearerProvider {
16
- constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn, }) {
16
+ constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn, initialTokenResponse, }) {
17
17
  this.BUFFER_IN_MINUTES = 2;
18
- this._accessToken = accessToken || 'no_token';
18
+ this._accessToken = accessToken || "no_token";
19
19
  this._refreshToken = refreshToken;
20
- this._expiresAt = typeof expiresIn === "number"
21
- ? this.getExpiresAt(expiresIn, this.BUFFER_IN_MINUTES)
22
- : this.parseTokenExpiry(this._accessToken, this.BUFFER_IN_MINUTES) || this.getExpiresAt(0, this.BUFFER_IN_MINUTES);
23
- this._refreshExpiresAt = typeof refreshExpiresIn === "number"
24
- ? this.getExpiresAt(refreshExpiresIn, 0)
25
- : (this._refreshToken && this.parseTokenExpiry(this._refreshToken, 0)) || this.getExpiresAt(0, 0);
20
+ this._initialTokenResponse = initialTokenResponse;
21
+ this._expiresAt = this.getExpiresAt(expiresIn, this._accessToken, this.BUFFER_IN_MINUTES);
22
+ this._refreshExpiresAt = this.getExpiresAt(refreshExpiresIn, this._refreshToken, 0);
26
23
  this._refreshAccessToken = refreshAccessToken;
27
24
  }
28
25
  getToken() {
29
26
  return __awaiter(this, void 0, void 0, function* () {
30
- if (this._accessToken && this._expiresAt > new Date()) {
27
+ if (this._accessToken && this._accessToken !== "no_token" && this._expiresAt > new Date()) {
31
28
  return core.Supplier.get(this._accessToken);
32
29
  }
30
+ if (this._initialTokenResponse) {
31
+ const tokenResponse = yield this._initialTokenResponse;
32
+ this._initialTokenResponse = undefined;
33
+ this._accessToken = tokenResponse.accessToken;
34
+ this._expiresAt = this.getExpiresAt(tokenResponse.expiresIn, tokenResponse.accessToken, this.BUFFER_IN_MINUTES);
35
+ this._refreshToken = tokenResponse.refreshToken;
36
+ this._refreshExpiresAt = this.getExpiresAt(tokenResponse.refreshExpiresIn, this._refreshToken, 0);
37
+ return this.getToken();
38
+ }
33
39
  return this.refresh();
34
40
  });
35
41
  }
36
42
  refresh() {
37
43
  return __awaiter(this, void 0, void 0, function* () {
38
- if (!this._refreshAccessToken || this._refreshToken && this._refreshExpiresAt < new Date()) {
44
+ if (!this._refreshAccessToken || (this._refreshToken && this._refreshExpiresAt < new Date())) {
39
45
  return core.Supplier.get(this._accessToken);
40
46
  }
41
47
  const tokenResponse = yield this._refreshAccessToken(this._refreshToken);
42
48
  this._accessToken = tokenResponse.accessToken;
43
- this._expiresAt = typeof tokenResponse.expiresIn === "number"
44
- ? this.getExpiresAt(tokenResponse.expiresIn, this.BUFFER_IN_MINUTES)
45
- : this.parseTokenExpiry(tokenResponse.accessToken, this.BUFFER_IN_MINUTES) || this.getExpiresAt(0, this.BUFFER_IN_MINUTES);
49
+ this._expiresAt = this.getExpiresAt(tokenResponse.expiresIn, tokenResponse.accessToken, this.BUFFER_IN_MINUTES);
46
50
  this._refreshToken = tokenResponse.refreshToken;
47
- this._refreshExpiresAt = typeof tokenResponse.refreshExpiresIn === "number"
48
- ? this.getExpiresAt(tokenResponse.refreshExpiresIn, 0)
49
- : this.parseTokenExpiry(this._refreshToken, 0) || this.getExpiresAt(0, 0);
51
+ this._refreshExpiresAt = this.getExpiresAt(tokenResponse.refreshExpiresIn, this._refreshToken, 0);
50
52
  return this._accessToken;
51
53
  });
52
54
  }
53
- getExpiresAt(expiresInSeconds = 0, bufferInMinutes = this.BUFFER_IN_MINUTES) {
54
- const now = new Date();
55
- return new Date(now.getTime() + expiresInSeconds * 1000 - bufferInMinutes * 60 * 1000);
55
+ getExpiresAt(expiresIn, token, bufferInMinutes = this.BUFFER_IN_MINUTES) {
56
+ if (typeof expiresIn === "number") {
57
+ const now = new Date();
58
+ return new Date(now.getTime() + expiresIn * 1000 - bufferInMinutes * 60 * 1000);
59
+ }
60
+ return this.parseTokenExpiry(token, bufferInMinutes) || this.getExpiresAt(0, token, bufferInMinutes);
56
61
  }
57
62
  parseTokenExpiry(token, bufferInMinutes) {
58
- if (!token || token === 'no_token') {
63
+ if (!token || token === "no_token") {
59
64
  return;
60
65
  }
61
66
  try {
62
67
  const decoded = decodeToken(token);
63
- if (decoded && typeof decoded.expiresAt === 'number') {
68
+ if (decoded && typeof decoded.expiresAt === "number") {
64
69
  const ms = decoded.expiresAt * 1000 - bufferInMinutes * 60 * 1000;
65
70
  return new Date(ms);
66
71
  }
@@ -24,4 +24,4 @@ export declare function decodeToken(token: string): {
24
24
  tenantName: string;
25
25
  accessToken: string;
26
26
  expiresAt: number | undefined;
27
- } | undefined;
27
+ } | null;
@@ -21,9 +21,9 @@
21
21
  */
22
22
  export function decodeToken(token) {
23
23
  // Validate the token structure (should contain at least header and payload parts)
24
- const parts = token.split('.');
24
+ const parts = token ? token.split('.') : '';
25
25
  if (parts.length < 2) {
26
- throw new Error('Invalid token format');
26
+ return null;
27
27
  }
28
28
  // Retrieve the payload (second part) of the JWT token
29
29
  const base64Url = parts[1];
@@ -38,7 +38,7 @@ export function decodeToken(token) {
38
38
  .join(''));
39
39
  }
40
40
  catch (error) {
41
- throw new Error('Failed to decode token payload');
41
+ return null;
42
42
  }
43
43
  // Parse the JSON string to obtain token details
44
44
  let tokenDetails;
@@ -46,12 +46,12 @@ export function decodeToken(token) {
46
46
  tokenDetails = JSON.parse(jsonPayload);
47
47
  }
48
48
  catch (error) {
49
- throw new Error('Invalid JSON payload in token');
49
+ return null;
50
50
  }
51
51
  // Extract the issuer URL from the token details
52
52
  const issuerUrl = tokenDetails.iss;
53
53
  if (!issuerUrl) {
54
- throw new Error('Token payload does not contain an issuer (iss) field');
54
+ return null;
55
55
  }
56
56
  // Regex to extract environment and tenant from issuer URL:
57
57
  // Expected format: https://keycloak.{environment}.corti.app/realms/{tenant}
@@ -70,4 +70,5 @@ export function decodeToken(token) {
70
70
  expiresAt,
71
71
  };
72
72
  }
73
+ return null;
73
74
  }
@@ -1,9 +1,11 @@
1
1
  import * as core from "../../core/index.mjs";
2
2
  import { CortiClient } from "../CortiClient.mjs";
3
3
  import { Environment } from "./getEnvironmentFromString.mjs";
4
+ import { ExpectedTokenResponse } from "../RefreshBearerProvider.mjs";
4
5
  type ResolvedClientOptions = {
5
6
  environment: Environment;
6
7
  tenantName: core.Supplier<string>;
8
+ initialTokenResponse?: Promise<ExpectedTokenResponse>;
7
9
  };
8
10
  export declare function resolveClientOptions(options: CortiClient.Options): ResolvedClientOptions;
9
11
  export {};
@@ -58,22 +58,16 @@ export function resolveClientOptions(options) {
58
58
  ]);
59
59
  }
60
60
  return {
61
+ tokenResponse,
61
62
  tenantName: decoded.tenantName,
62
63
  environment: decoded.environment,
63
64
  };
64
65
  }))();
65
66
  return {
66
67
  tenantName: options.tenantName ||
67
- function () {
68
- return __awaiter(this, void 0, void 0, function* () {
69
- return (yield tokenResponsePromise).tenantName;
70
- });
71
- },
72
- environment: options.environment || function () {
73
- return __awaiter(this, void 0, void 0, function* () {
74
- const environment = getEnvironment((yield tokenResponsePromise).environment);
75
- return core.Supplier.get(environment);
76
- });
77
- },
68
+ tokenResponsePromise.then(({ tenantName }) => tenantName),
69
+ environment: options.environment ||
70
+ tokenResponsePromise.then(({ environment }) => core.Supplier.get(getEnvironment(environment))),
71
+ initialTokenResponse: tokenResponsePromise.then((result) => result.tokenResponse),
78
72
  };
79
73
  }
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "0.0.0-rc.1";
1
+ export declare const SDK_VERSION = "0.0.0-rc.359";
@@ -1 +1 @@
1
- export const SDK_VERSION = "0.0.0-rc.1";
1
+ export const SDK_VERSION = "0.0.0-rc.359";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corti/sdk",
3
- "version": "0.0.0-rc.1",
3
+ "version": "0.0.0-rc.359",
4
4
  "private": false,
5
5
  "repository": "github:corticph/corti-sdk-javascript",
6
6
  "license": "MIT",