@corti/sdk 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +14 -2
  2. package/dist/cjs/Client.d.ts +1 -1
  3. package/dist/cjs/Client.js +2 -2
  4. package/dist/cjs/api/resources/auth/client/Client.d.ts +2 -2
  5. package/dist/cjs/api/resources/auth/client/Client.js +2 -2
  6. package/dist/cjs/api/resources/auth/client/requests/AuthGetTokenRequest.d.ts +4 -3
  7. package/dist/cjs/core/auth/OAuthTokenProvider.d.ts +1 -1
  8. package/dist/cjs/custom/CortiAuth.d.ts +48 -5
  9. package/dist/cjs/custom/CortiAuth.js +55 -20
  10. package/dist/cjs/custom/CortiSDKError.d.ts +12 -0
  11. package/dist/cjs/custom/CortiSDKError.js +19 -0
  12. package/dist/cjs/custom/utils/localStorage.d.ts +4 -0
  13. package/dist/cjs/custom/utils/localStorage.js +38 -0
  14. package/dist/cjs/custom/utils/pkce.d.ts +2 -0
  15. package/dist/cjs/custom/utils/pkce.js +32 -0
  16. package/dist/cjs/custom/utils/tokenRequest.d.ts +11 -0
  17. package/dist/cjs/custom/utils/tokenRequest.js +76 -0
  18. package/dist/cjs/index.d.ts +4 -0
  19. package/dist/cjs/index.js +6 -1
  20. package/dist/cjs/serialization/resources/auth/client/requests/AuthGetTokenRequest.d.ts +1 -1
  21. package/dist/cjs/serialization/resources/auth/client/requests/AuthGetTokenRequest.js +1 -1
  22. package/dist/cjs/version.d.ts +1 -1
  23. package/dist/cjs/version.js +1 -1
  24. package/dist/esm/Client.d.mts +1 -1
  25. package/dist/esm/Client.mjs +2 -2
  26. package/dist/esm/api/resources/auth/client/Client.d.mts +2 -2
  27. package/dist/esm/api/resources/auth/client/Client.mjs +2 -2
  28. package/dist/esm/api/resources/auth/client/requests/AuthGetTokenRequest.d.mts +4 -3
  29. package/dist/esm/core/auth/OAuthTokenProvider.d.mts +1 -1
  30. package/dist/esm/custom/CortiAuth.d.mts +48 -5
  31. package/dist/esm/custom/CortiAuth.mjs +55 -20
  32. package/dist/esm/custom/CortiSDKError.d.mts +12 -0
  33. package/dist/esm/custom/CortiSDKError.mjs +15 -0
  34. package/dist/esm/custom/utils/localStorage.d.mts +4 -0
  35. package/dist/esm/custom/utils/localStorage.mjs +32 -0
  36. package/dist/esm/custom/utils/pkce.d.mts +2 -0
  37. package/dist/esm/custom/utils/pkce.mjs +27 -0
  38. package/dist/esm/custom/utils/tokenRequest.d.mts +11 -0
  39. package/dist/esm/custom/utils/tokenRequest.mjs +39 -0
  40. package/dist/esm/index.d.mts +4 -0
  41. package/dist/esm/index.mjs +4 -0
  42. package/dist/esm/serialization/resources/auth/client/requests/AuthGetTokenRequest.d.mts +1 -1
  43. package/dist/esm/serialization/resources/auth/client/requests/AuthGetTokenRequest.mjs +1 -1
  44. package/dist/esm/version.d.mts +1 -1
  45. package/dist/esm/version.mjs +1 -1
  46. package/package.json +1 -1
package/README.md CHANGED
@@ -60,7 +60,10 @@ const client = new CortiClient({
60
60
  },
61
61
  });
62
62
 
63
- // For user authentication, you can also use Authorization Code Flow
63
+ // For user authentication, you can use:
64
+ // - Authorization Code Flow
65
+ // - Authorization Code Flow with PKCE
66
+ // - Resource Owner Password Credentials (ROPC) flow
64
67
  // See the Authentication Guide for detailed instructions
65
68
 
66
69
  await client.interactions.create({
@@ -92,11 +95,12 @@ Depending on the type of error, the SDK will throw one of the following:
92
95
  - **CortiError**: Thrown when the API returns a non-success status code (4xx or 5xx response). This is the base error for API-related issues.
93
96
  - **ParseError**: Thrown when parsing input data fails schema validation. This typically occurs when the data you provide does not match the expected schema.
94
97
  - **JsonError**: Thrown when serializing data to JSON fails schema validation. This typically occurs when converting parsed data to JSON for transmission or storage fails validation.
98
+ - **CortiSDKError**: Base class for SDK-specific runtime issues (e.g., internal helpers, environment detection). Provides an optional `code` and `cause` for debugging.
95
99
 
96
100
  Example usage:
97
101
 
98
102
  ```typescript
99
- import { CortiError, ParseError, JsonError } from "@corti/sdk";
103
+ import { CortiError, ParseError, JsonError, CortiSDKError } from "@corti/sdk";
100
104
 
101
105
  try {
102
106
  await client.interactions.create(...);
@@ -116,6 +120,14 @@ try {
116
120
  // Handle schema validation errors during serialization
117
121
  console.error("JSON validation error details:", err.errors);
118
122
  }
123
+ if (err instanceof CortiSDKError) {
124
+ // Handle other SDK-level errors that expose extra context
125
+ console.error("SDK error code:", err.code);
126
+ console.error("SDK error cause:", err.cause);
127
+ if (err.code === "local_storage_error") {
128
+ console.error("LocalStorage operation failed:", err.message);
129
+ }
130
+ }
119
131
  }
120
132
  ```
121
133
 
@@ -19,7 +19,7 @@ export declare namespace CortiClient {
19
19
  /** Specify a custom URL to connect the client to. */
20
20
  baseUrl?: core.Supplier<string>;
21
21
  clientId: core.Supplier<string>;
22
- clientSecret: core.Supplier<string>;
22
+ clientSecret: core.Supplier<string | undefined>;
23
23
  /** Override the Tenant-Name header */
24
24
  tenantName: core.Supplier<string>;
25
25
  /** Additional headers to include in requests. */
@@ -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.5.0",
68
- "User-Agent": "@corti/sdk/0.5.0",
67
+ "X-Fern-SDK-Version": "0.6.0",
68
+ "User-Agent": "@corti/sdk/0.6.0",
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) });
@@ -39,8 +39,8 @@ export declare class Auth {
39
39
  *
40
40
  * @example
41
41
  * await client.auth.getToken({
42
- * clientId: "client_id",
43
- * clientSecret: "client_secret"
42
+ * clientId: "client_id_123",
43
+ * clientSecret: "my_secret_value"
44
44
  * })
45
45
  */
46
46
  getToken(request: Corti.AuthGetTokenRequest, requestOptions?: Auth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
@@ -62,8 +62,8 @@ class Auth {
62
62
  *
63
63
  * @example
64
64
  * await client.auth.getToken({
65
- * clientId: "client_id",
66
- * clientSecret: "client_secret"
65
+ * clientId: "client_id_123",
66
+ * clientSecret: "my_secret_value"
67
67
  * })
68
68
  */
69
69
  getToken(request, requestOptions) {
@@ -4,11 +4,12 @@
4
4
  /**
5
5
  * @example
6
6
  * {
7
- * clientId: "client_id",
8
- * clientSecret: "client_secret"
7
+ * clientId: "client_id_123",
8
+ * clientSecret: "my_secret_value"
9
9
  * }
10
10
  */
11
11
  export interface AuthGetTokenRequest {
12
12
  clientId: string;
13
- clientSecret: string;
13
+ /** Optional secret for confidential clients and Authorization code flow */
14
+ clientSecret?: string;
14
15
  }
@@ -16,7 +16,7 @@ export declare class OAuthTokenProvider {
16
16
  private _expiresAt;
17
17
  constructor({ clientId, clientSecret, authClient, }: {
18
18
  clientId: core.Supplier<string>;
19
- clientSecret: core.Supplier<string>;
19
+ clientSecret: core.Supplier<string | undefined>;
20
20
  authClient: Auth;
21
21
  });
22
22
  getToken(): Promise<string>;
@@ -15,20 +15,47 @@ import { Auth as FernAuth } from "../api/resources/auth/client/Client.js";
15
15
  import * as core from "../core/index.js";
16
16
  import * as Corti from "../api/index.js";
17
17
  import * as environments from "../environments.js";
18
+ /**
19
+ * Patch: added codeChallenge to the AuthorizationCodeClient interface to support PKCE flow
20
+ */
18
21
  interface AuthorizationCodeClient {
19
22
  clientId: string;
20
23
  redirectUri: string;
24
+ codeChallenge?: string;
21
25
  }
22
- interface AuthorizationCodeServer {
26
+ /**
27
+ * Patch: renamed AuthorizationCodeClient to AuthorizationCode as it can be used for both(server and client) flows
28
+ */
29
+ interface AuthorizationCode {
23
30
  clientId: string;
24
31
  clientSecret: string;
25
32
  redirectUri: string;
26
33
  code: string;
27
34
  }
35
+ /**
36
+ * Patch: added type for AuthorizationPkce request
37
+ */
38
+ interface AuthorizationPkce {
39
+ clientId: string;
40
+ redirectUri: string;
41
+ code: string;
42
+ codeVerifier?: string;
43
+ }
44
+ /**
45
+ * Patch: added type for AuthorizationRopc request
46
+ */
47
+ interface AuthorizationRopcServer {
48
+ clientId: string;
49
+ username: string;
50
+ password: string;
51
+ }
28
52
  interface AuthorizationRefreshServer {
29
53
  clientId: string;
30
54
  clientSecret: string;
31
- refreshToken: string;
55
+ /**
56
+ * Patch: added optional refreshToken for ROPC and PKCE flow
57
+ */
58
+ refreshToken?: string;
32
59
  }
33
60
  interface Options {
34
61
  skipRedirect?: boolean;
@@ -41,18 +68,34 @@ export declare class Auth extends FernAuth {
41
68
  * Patch: use custom AuthOptions type to support string-based environment
42
69
  */
43
70
  constructor(_options: AuthOptions);
71
+ /**
72
+ * Patch: Generate PKCE authorization URL with automatic code verifier generation
73
+ */
74
+ authorizePkceUrl({ clientId, redirectUri, }: AuthorizationCodeClient, options?: Options): Promise<string>;
75
+ /**
76
+ * Patch: Get the stored PKCE code verifier
77
+ */
78
+ getCodeVerifier(): string | null;
44
79
  /**
45
80
  * Patch: called custom implementation this.__getToken_custom instead of this.__getToken
46
81
  */
47
82
  getToken(request: Corti.AuthGetTokenRequest, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
48
83
  /**
49
- * Patch: added method to get Authorization URL for Authorization code flow
84
+ * Patch: added method to get Authorization URL for Authorization code flow and PKCE flow
50
85
  */
51
- authorizeURL({ clientId, redirectUri, }: AuthorizationCodeClient, options?: Options): Promise<string>;
86
+ authorizeURL({ clientId, redirectUri, codeChallenge, }: AuthorizationCodeClient, options?: Options): Promise<string>;
52
87
  /**
53
88
  * Patch: calls __getToken_custom with additional fields to support Authorization code flow
54
89
  */
55
- getCodeFlowToken(request: AuthorizationCodeServer, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
90
+ getCodeFlowToken(request: AuthorizationCode, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
91
+ /**
92
+ * Patch: PKCE-specific method
93
+ */
94
+ getPkceFlowToken(request: AuthorizationPkce, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
95
+ /**
96
+ * Patch: ROPC-specific method
97
+ */
98
+ getRopcFlowToken(request: AuthorizationRopcServer, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
56
99
  /**
57
100
  * Patch: copy of this.__getToken with patches
58
101
  */
@@ -62,6 +62,11 @@ const headers_js_1 = require("../core/headers.js");
62
62
  const serializers = __importStar(require("../serialization/index.js"));
63
63
  const errors = __importStar(require("../errors/index.js"));
64
64
  const getEnvironmentFromString_js_1 = require("./utils/getEnvironmentFromString.js");
65
+ const ParseError_js_1 = require("../core/schemas/builders/schema-utils/ParseError.js");
66
+ const localStorage_js_1 = require("./utils/localStorage.js");
67
+ const pkce_js_1 = require("./utils/pkce.js");
68
+ const tokenRequest_js_1 = require("./utils/tokenRequest.js");
69
+ const CODE_VERIFIER_KEY = "corti_js_sdk_code_verifier";
65
70
  class Auth extends Client_js_1.Auth {
66
71
  /**
67
72
  * Patch: use custom AuthOptions type to support string-based environment
@@ -69,6 +74,27 @@ class Auth extends Client_js_1.Auth {
69
74
  constructor(_options) {
70
75
  super(Object.assign(Object.assign({}, _options), { environment: (0, getEnvironmentFromString_js_1.getEnvironment)(_options.environment) }));
71
76
  }
77
+ /**
78
+ * Patch: Generate PKCE authorization URL with automatic code verifier generation
79
+ */
80
+ authorizePkceUrl(_a, options_1) {
81
+ return __awaiter(this, arguments, void 0, function* ({ clientId, redirectUri, }, options) {
82
+ const codeVerifier = (0, pkce_js_1.generateCodeVerifier)();
83
+ (0, localStorage_js_1.setLocalStorageItem)(CODE_VERIFIER_KEY, codeVerifier);
84
+ const codeChallenge = yield (0, pkce_js_1.generateCodeChallenge)(codeVerifier);
85
+ return this.authorizeURL({
86
+ clientId,
87
+ redirectUri,
88
+ codeChallenge,
89
+ }, options);
90
+ });
91
+ }
92
+ /**
93
+ * Patch: Get the stored PKCE code verifier
94
+ */
95
+ getCodeVerifier() {
96
+ return (0, localStorage_js_1.getLocalStorageItem)(CODE_VERIFIER_KEY);
97
+ }
72
98
  /**
73
99
  * Patch: called custom implementation this.__getToken_custom instead of this.__getToken
74
100
  */
@@ -76,10 +102,10 @@ class Auth extends Client_js_1.Auth {
76
102
  return core.HttpResponsePromise.fromPromise(this.__getToken_custom(request, requestOptions));
77
103
  }
78
104
  /**
79
- * Patch: added method to get Authorization URL for Authorization code flow
105
+ * Patch: added method to get Authorization URL for Authorization code flow and PKCE flow
80
106
  */
81
107
  authorizeURL(_a, options_1) {
82
- return __awaiter(this, arguments, void 0, function* ({ clientId, redirectUri, }, options) {
108
+ return __awaiter(this, arguments, void 0, function* ({ clientId, redirectUri, codeChallenge, }, options) {
83
109
  var _b;
84
110
  const authUrl = new URL(core.url.join((_b = (yield core.Supplier.get(this._options.baseUrl))) !== null && _b !== void 0 ? _b : (yield core.Supplier.get(this._options.environment)).login, yield core.Supplier.get(this._options.tenantName), "protocol/openid-connect/auth"));
85
111
  authUrl.searchParams.set('response_type', 'code');
@@ -90,6 +116,10 @@ class Auth extends Client_js_1.Auth {
90
116
  if (redirectUri !== undefined) {
91
117
  authUrl.searchParams.set('redirect_uri', redirectUri);
92
118
  }
119
+ if (codeChallenge !== undefined) {
120
+ authUrl.searchParams.set('code_challenge', codeChallenge);
121
+ authUrl.searchParams.set('code_challenge_method', 'S256');
122
+ }
93
123
  const authUrlString = authUrl.toString();
94
124
  if (typeof window !== "undefined" && !(options === null || options === void 0 ? void 0 : options.skipRedirect)) {
95
125
  window.location.href = authUrlString;
@@ -104,12 +134,33 @@ class Auth extends Client_js_1.Auth {
104
134
  getCodeFlowToken(request, requestOptions) {
105
135
  return core.HttpResponsePromise.fromPromise(this.__getToken_custom(Object.assign(Object.assign({}, request), { grantType: "authorization_code" }), requestOptions));
106
136
  }
137
+ /**
138
+ * Patch: PKCE-specific method
139
+ */
140
+ getPkceFlowToken(request, requestOptions) {
141
+ const codeVerifier = request.codeVerifier || this.getCodeVerifier();
142
+ if (!codeVerifier) {
143
+ throw new ParseError_js_1.ParseError([
144
+ {
145
+ path: ['codeVerifier'],
146
+ message: 'Code verifier was not provided and not found in localStorage.',
147
+ },
148
+ ]);
149
+ }
150
+ return core.HttpResponsePromise.fromPromise(this.__getToken_custom(Object.assign(Object.assign({}, request), { codeVerifier: codeVerifier, grantType: "authorization_code" }), requestOptions));
151
+ }
152
+ /**
153
+ * Patch: ROPC-specific method
154
+ */
155
+ getRopcFlowToken(request, requestOptions) {
156
+ return core.HttpResponsePromise.fromPromise(this.__getToken_custom(Object.assign(Object.assign({}, request), { grantType: "password" }), requestOptions));
157
+ }
107
158
  /**
108
159
  * Patch: copy of this.__getToken with patches
109
160
  */
110
161
  __getToken_custom(
111
162
  /**
112
- * Patch: added additional fields to request to support Authorization code flow
163
+ * Patch: added additional fields to request to support Authorization PKCE and ROPC flow
113
164
  */
114
165
  request, requestOptions) {
115
166
  return __awaiter(this, void 0, void 0, function* () {
@@ -132,23 +183,7 @@ class Auth extends Client_js_1.Auth {
132
183
  /**
133
184
  * Patch: removed `requestType: "json"`, made body a URLSearchParams object
134
185
  */
135
- body: new URLSearchParams(Object.assign(Object.assign(Object.assign(Object.assign({}, serializers.AuthGetTokenRequest.jsonOrThrow(request, {
136
- unrecognizedObjectKeys: "strip",
137
- omitUndefined: true,
138
- })), { scope: "openid",
139
- /**
140
- * Patch: `grant_type` uses values from request or defaults to "client_credentials"
141
- */
142
- grant_type: request.grantType || "client_credentials" }), (request.grantType === "authorization_code"
143
- ? {
144
- code: request.code,
145
- redirect_uri: request.redirectUri
146
- }
147
- : {})), (request.grantType === "refresh_token"
148
- ? {
149
- refresh_token: request.refreshToken,
150
- }
151
- : {}))),
186
+ body: (0, tokenRequest_js_1.buildTokenRequestBody)(request),
152
187
  timeoutMs: (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.timeoutInSeconds) != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
153
188
  maxRetries: requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.maxRetries,
154
189
  abortSignal: requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.abortSignal,
@@ -0,0 +1,12 @@
1
+ export interface CortiSDKErrorOptions {
2
+ code: CortiSDKErrorCodes;
3
+ cause?: unknown;
4
+ }
5
+ export declare enum CortiSDKErrorCodes {
6
+ LOCAL_STORAGE_ERROR = "local_storage_error"
7
+ }
8
+ export declare class CortiSDKError extends Error {
9
+ readonly code: CortiSDKErrorCodes;
10
+ readonly cause?: unknown;
11
+ constructor(message?: string, options?: CortiSDKErrorOptions);
12
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CortiSDKError = exports.CortiSDKErrorCodes = void 0;
4
+ var CortiSDKErrorCodes;
5
+ (function (CortiSDKErrorCodes) {
6
+ CortiSDKErrorCodes["LOCAL_STORAGE_ERROR"] = "local_storage_error";
7
+ })(CortiSDKErrorCodes || (exports.CortiSDKErrorCodes = CortiSDKErrorCodes = {}));
8
+ class CortiSDKError extends Error {
9
+ constructor(message = "An unexpected error occurred in the Corti SDK.", options = { code: CortiSDKErrorCodes.LOCAL_STORAGE_ERROR }) {
10
+ super(message);
11
+ this.name = "CortiSDKError";
12
+ this.code = options.code;
13
+ if ("cause" in options) {
14
+ this.cause = options.cause;
15
+ }
16
+ Object.setPrototypeOf(this, CortiSDKError.prototype);
17
+ }
18
+ }
19
+ exports.CortiSDKError = CortiSDKError;
@@ -0,0 +1,4 @@
1
+ export declare const LOCAL_STORAGE_ERROR_CODE: "local_storage_error";
2
+ export declare const requireLocalStorage: () => Storage;
3
+ export declare const setLocalStorageItem: (key: string, value: string) => void;
4
+ export declare const getLocalStorageItem: (key: string) => string | null;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getLocalStorageItem = exports.setLocalStorageItem = exports.requireLocalStorage = exports.LOCAL_STORAGE_ERROR_CODE = void 0;
4
+ const CortiSDKError_js_1 = require("../CortiSDKError.js");
5
+ exports.LOCAL_STORAGE_ERROR_CODE = "local_storage_error";
6
+ const requireLocalStorage = () => {
7
+ if (typeof window === "undefined" || !window.localStorage) {
8
+ throw new CortiSDKError_js_1.CortiSDKError("LocalStorage operation failed: storage is not available in this environment.", { code: CortiSDKError_js_1.CortiSDKErrorCodes.LOCAL_STORAGE_ERROR });
9
+ }
10
+ return window.localStorage;
11
+ };
12
+ exports.requireLocalStorage = requireLocalStorage;
13
+ const setLocalStorageItem = (key, value) => {
14
+ const storage = (0, exports.requireLocalStorage)();
15
+ try {
16
+ storage.setItem(key, value);
17
+ }
18
+ catch (error) {
19
+ throw new CortiSDKError_js_1.CortiSDKError("LocalStorage set operation failed.", {
20
+ code: CortiSDKError_js_1.CortiSDKErrorCodes.LOCAL_STORAGE_ERROR,
21
+ cause: error,
22
+ });
23
+ }
24
+ };
25
+ exports.setLocalStorageItem = setLocalStorageItem;
26
+ const getLocalStorageItem = (key) => {
27
+ const storage = (0, exports.requireLocalStorage)();
28
+ try {
29
+ return storage.getItem(key);
30
+ }
31
+ catch (error) {
32
+ throw new CortiSDKError_js_1.CortiSDKError("LocalStorage get operation failed.", {
33
+ code: CortiSDKError_js_1.CortiSDKErrorCodes.LOCAL_STORAGE_ERROR,
34
+ cause: error,
35
+ });
36
+ }
37
+ };
38
+ exports.getLocalStorageItem = getLocalStorageItem;
@@ -0,0 +1,2 @@
1
+ export declare const generateCodeVerifier: () => string;
2
+ export declare const generateCodeChallenge: (verifier: string) => Promise<string>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.generateCodeChallenge = exports.generateCodeVerifier = void 0;
13
+ const base64URLEncode = (buffer) => {
14
+ const base64 = btoa(String.fromCharCode(...buffer));
15
+ return base64
16
+ .replace(/\+/g, '-')
17
+ .replace(/\//g, '_')
18
+ .replace(/=/g, '');
19
+ };
20
+ const generateCodeVerifier = () => {
21
+ const array = new Uint8Array(32);
22
+ crypto.getRandomValues(array);
23
+ return base64URLEncode(array);
24
+ };
25
+ exports.generateCodeVerifier = generateCodeVerifier;
26
+ const generateCodeChallenge = (verifier) => __awaiter(void 0, void 0, void 0, function* () {
27
+ const encoder = new TextEncoder();
28
+ const data = encoder.encode(verifier);
29
+ const hash = yield crypto.subtle.digest('SHA-256', data);
30
+ return base64URLEncode(new Uint8Array(hash));
31
+ });
32
+ exports.generateCodeChallenge = generateCodeChallenge;
@@ -0,0 +1,11 @@
1
+ import * as Corti from "../../api/index.js";
2
+ export type TokenRequest = Corti.AuthGetTokenRequest & Partial<{
3
+ grantType: "client_credentials" | "authorization_code" | "refresh_token" | "password";
4
+ code: string;
5
+ redirectUri: string;
6
+ refreshToken: string;
7
+ codeVerifier: string;
8
+ username: string;
9
+ password: string;
10
+ }>;
11
+ export declare const buildTokenRequestBody: (request: TokenRequest) => URLSearchParams;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.buildTokenRequestBody = void 0;
37
+ const serializers = __importStar(require("../../serialization/index.js"));
38
+ const buildTokenRequestBody = (request) => {
39
+ const serializedRequest = serializers.AuthGetTokenRequest.jsonOrThrow(request, {
40
+ unrecognizedObjectKeys: "strip",
41
+ omitUndefined: true,
42
+ });
43
+ const tokenRequestBody = {
44
+ scope: "openid",
45
+ grant_type: request.grantType || "client_credentials",
46
+ };
47
+ Object.entries(serializedRequest).forEach(([key, value]) => {
48
+ if (value != null) {
49
+ tokenRequestBody[key] = String(value);
50
+ }
51
+ });
52
+ if (request.grantType === "authorization_code") {
53
+ if (request.code != null) {
54
+ tokenRequestBody.code = request.code;
55
+ }
56
+ if (request.redirectUri != null) {
57
+ tokenRequestBody.redirect_uri = request.redirectUri;
58
+ }
59
+ if (request.codeVerifier != null) {
60
+ tokenRequestBody.code_verifier = request.codeVerifier;
61
+ }
62
+ }
63
+ if (request.grantType === "refresh_token" && request.refreshToken != null) {
64
+ tokenRequestBody.refresh_token = request.refreshToken;
65
+ }
66
+ if (request.grantType === "password") {
67
+ if (request.username != null) {
68
+ tokenRequestBody.username = request.username;
69
+ }
70
+ if (request.password != null) {
71
+ tokenRequestBody.password = request.password;
72
+ }
73
+ }
74
+ return new URLSearchParams(tokenRequestBody);
75
+ };
76
+ exports.buildTokenRequestBody = buildTokenRequestBody;
@@ -15,3 +15,7 @@ export { Auth as CortiAuth } from "./custom/CortiAuth.js";
15
15
  */
16
16
  export { JsonError } from "./core/schemas/builders/schema-utils/JsonError.js";
17
17
  export { ParseError } from "./core/schemas/builders/schema-utils/ParseError.js";
18
+ /**
19
+ * Patch: added new export to provide SDK-level error handling.
20
+ */
21
+ export { CortiSDKError } from "./custom/CortiSDKError.js";
package/dist/cjs/index.js CHANGED
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ParseError = exports.JsonError = exports.CortiAuth = exports.CortiEnvironment = exports.CortiClient = exports.serialization = exports.CortiTimeoutError = exports.CortiError = exports.Corti = void 0;
36
+ exports.CortiSDKError = exports.ParseError = exports.JsonError = exports.CortiAuth = exports.CortiEnvironment = exports.CortiClient = exports.serialization = exports.CortiTimeoutError = exports.CortiError = exports.Corti = void 0;
37
37
  exports.Corti = __importStar(require("./api/index.js"));
38
38
  var index_js_1 = require("./errors/index.js");
39
39
  Object.defineProperty(exports, "CortiError", { enumerable: true, get: function () { return index_js_1.CortiError; } });
@@ -58,3 +58,8 @@ var JsonError_js_1 = require("./core/schemas/builders/schema-utils/JsonError.js"
58
58
  Object.defineProperty(exports, "JsonError", { enumerable: true, get: function () { return JsonError_js_1.JsonError; } });
59
59
  var ParseError_js_1 = require("./core/schemas/builders/schema-utils/ParseError.js");
60
60
  Object.defineProperty(exports, "ParseError", { enumerable: true, get: function () { return ParseError_js_1.ParseError; } });
61
+ /**
62
+ * Patch: added new export to provide SDK-level error handling.
63
+ */
64
+ var CortiSDKError_js_1 = require("./custom/CortiSDKError.js");
65
+ Object.defineProperty(exports, "CortiSDKError", { enumerable: true, get: function () { return CortiSDKError_js_1.CortiSDKError; } });
@@ -8,6 +8,6 @@ export declare const AuthGetTokenRequest: core.serialization.Schema<serializers.
8
8
  export declare namespace AuthGetTokenRequest {
9
9
  interface Raw {
10
10
  client_id: string;
11
- client_secret: string;
11
+ client_secret?: string | null;
12
12
  }
13
13
  }
@@ -40,5 +40,5 @@ exports.AuthGetTokenRequest = void 0;
40
40
  const core = __importStar(require("../../../../../core/index.js"));
41
41
  exports.AuthGetTokenRequest = core.serialization.object({
42
42
  clientId: core.serialization.property("client_id", core.serialization.string()),
43
- clientSecret: core.serialization.property("client_secret", core.serialization.string()),
43
+ clientSecret: core.serialization.property("client_secret", core.serialization.string().optional()),
44
44
  });
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "0.5.0";
1
+ export declare const SDK_VERSION = "0.6.0";
@@ -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.5.0";
4
+ exports.SDK_VERSION = "0.6.0";
@@ -19,7 +19,7 @@ export declare namespace CortiClient {
19
19
  /** Specify a custom URL to connect the client to. */
20
20
  baseUrl?: core.Supplier<string>;
21
21
  clientId: core.Supplier<string>;
22
- clientSecret: core.Supplier<string>;
22
+ clientSecret: core.Supplier<string | undefined>;
23
23
  /** Override the Tenant-Name header */
24
24
  tenantName: core.Supplier<string>;
25
25
  /** Additional headers to include in requests. */
@@ -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.5.0",
32
- "User-Agent": "@corti/sdk/0.5.0",
31
+ "X-Fern-SDK-Version": "0.6.0",
32
+ "User-Agent": "@corti/sdk/0.6.0",
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) });
@@ -39,8 +39,8 @@ export declare class Auth {
39
39
  *
40
40
  * @example
41
41
  * await client.auth.getToken({
42
- * clientId: "client_id",
43
- * clientSecret: "client_secret"
42
+ * clientId: "client_id_123",
43
+ * clientSecret: "my_secret_value"
44
44
  * })
45
45
  */
46
46
  getToken(request: Corti.AuthGetTokenRequest, requestOptions?: Auth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
@@ -26,8 +26,8 @@ export class Auth {
26
26
  *
27
27
  * @example
28
28
  * await client.auth.getToken({
29
- * clientId: "client_id",
30
- * clientSecret: "client_secret"
29
+ * clientId: "client_id_123",
30
+ * clientSecret: "my_secret_value"
31
31
  * })
32
32
  */
33
33
  getToken(request, requestOptions) {
@@ -4,11 +4,12 @@
4
4
  /**
5
5
  * @example
6
6
  * {
7
- * clientId: "client_id",
8
- * clientSecret: "client_secret"
7
+ * clientId: "client_id_123",
8
+ * clientSecret: "my_secret_value"
9
9
  * }
10
10
  */
11
11
  export interface AuthGetTokenRequest {
12
12
  clientId: string;
13
- clientSecret: string;
13
+ /** Optional secret for confidential clients and Authorization code flow */
14
+ clientSecret?: string;
14
15
  }
@@ -16,7 +16,7 @@ export declare class OAuthTokenProvider {
16
16
  private _expiresAt;
17
17
  constructor({ clientId, clientSecret, authClient, }: {
18
18
  clientId: core.Supplier<string>;
19
- clientSecret: core.Supplier<string>;
19
+ clientSecret: core.Supplier<string | undefined>;
20
20
  authClient: Auth;
21
21
  });
22
22
  getToken(): Promise<string>;
@@ -15,20 +15,47 @@ import { Auth as FernAuth } from "../api/resources/auth/client/Client.mjs";
15
15
  import * as core from "../core/index.mjs";
16
16
  import * as Corti from "../api/index.mjs";
17
17
  import * as environments from "../environments.mjs";
18
+ /**
19
+ * Patch: added codeChallenge to the AuthorizationCodeClient interface to support PKCE flow
20
+ */
18
21
  interface AuthorizationCodeClient {
19
22
  clientId: string;
20
23
  redirectUri: string;
24
+ codeChallenge?: string;
21
25
  }
22
- interface AuthorizationCodeServer {
26
+ /**
27
+ * Patch: renamed AuthorizationCodeClient to AuthorizationCode as it can be used for both(server and client) flows
28
+ */
29
+ interface AuthorizationCode {
23
30
  clientId: string;
24
31
  clientSecret: string;
25
32
  redirectUri: string;
26
33
  code: string;
27
34
  }
35
+ /**
36
+ * Patch: added type for AuthorizationPkce request
37
+ */
38
+ interface AuthorizationPkce {
39
+ clientId: string;
40
+ redirectUri: string;
41
+ code: string;
42
+ codeVerifier?: string;
43
+ }
44
+ /**
45
+ * Patch: added type for AuthorizationRopc request
46
+ */
47
+ interface AuthorizationRopcServer {
48
+ clientId: string;
49
+ username: string;
50
+ password: string;
51
+ }
28
52
  interface AuthorizationRefreshServer {
29
53
  clientId: string;
30
54
  clientSecret: string;
31
- refreshToken: string;
55
+ /**
56
+ * Patch: added optional refreshToken for ROPC and PKCE flow
57
+ */
58
+ refreshToken?: string;
32
59
  }
33
60
  interface Options {
34
61
  skipRedirect?: boolean;
@@ -41,18 +68,34 @@ export declare class Auth extends FernAuth {
41
68
  * Patch: use custom AuthOptions type to support string-based environment
42
69
  */
43
70
  constructor(_options: AuthOptions);
71
+ /**
72
+ * Patch: Generate PKCE authorization URL with automatic code verifier generation
73
+ */
74
+ authorizePkceUrl({ clientId, redirectUri, }: AuthorizationCodeClient, options?: Options): Promise<string>;
75
+ /**
76
+ * Patch: Get the stored PKCE code verifier
77
+ */
78
+ getCodeVerifier(): string | null;
44
79
  /**
45
80
  * Patch: called custom implementation this.__getToken_custom instead of this.__getToken
46
81
  */
47
82
  getToken(request: Corti.AuthGetTokenRequest, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
48
83
  /**
49
- * Patch: added method to get Authorization URL for Authorization code flow
84
+ * Patch: added method to get Authorization URL for Authorization code flow and PKCE flow
50
85
  */
51
- authorizeURL({ clientId, redirectUri, }: AuthorizationCodeClient, options?: Options): Promise<string>;
86
+ authorizeURL({ clientId, redirectUri, codeChallenge, }: AuthorizationCodeClient, options?: Options): Promise<string>;
52
87
  /**
53
88
  * Patch: calls __getToken_custom with additional fields to support Authorization code flow
54
89
  */
55
- getCodeFlowToken(request: AuthorizationCodeServer, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
90
+ getCodeFlowToken(request: AuthorizationCode, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
91
+ /**
92
+ * Patch: PKCE-specific method
93
+ */
94
+ getPkceFlowToken(request: AuthorizationPkce, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
95
+ /**
96
+ * Patch: ROPC-specific method
97
+ */
98
+ getRopcFlowToken(request: AuthorizationRopcServer, requestOptions?: FernAuth.RequestOptions): core.HttpResponsePromise<Corti.GetTokenResponse>;
56
99
  /**
57
100
  * Patch: copy of this.__getToken with patches
58
101
  */
@@ -26,6 +26,11 @@ import { mergeHeaders, mergeOnlyDefinedHeaders } from "../core/headers.mjs";
26
26
  import * as serializers from "../serialization/index.mjs";
27
27
  import * as errors from "../errors/index.mjs";
28
28
  import { getEnvironment } from "./utils/getEnvironmentFromString.mjs";
29
+ import { ParseError } from "../core/schemas/builders/schema-utils/ParseError.mjs";
30
+ import { getLocalStorageItem, setLocalStorageItem } from "./utils/localStorage.mjs";
31
+ import { generateCodeChallenge, generateCodeVerifier } from "./utils/pkce.mjs";
32
+ import { buildTokenRequestBody } from "./utils/tokenRequest.mjs";
33
+ const CODE_VERIFIER_KEY = "corti_js_sdk_code_verifier";
29
34
  export class Auth extends FernAuth {
30
35
  /**
31
36
  * Patch: use custom AuthOptions type to support string-based environment
@@ -33,6 +38,27 @@ export class Auth extends FernAuth {
33
38
  constructor(_options) {
34
39
  super(Object.assign(Object.assign({}, _options), { environment: getEnvironment(_options.environment) }));
35
40
  }
41
+ /**
42
+ * Patch: Generate PKCE authorization URL with automatic code verifier generation
43
+ */
44
+ authorizePkceUrl(_a, options_1) {
45
+ return __awaiter(this, arguments, void 0, function* ({ clientId, redirectUri, }, options) {
46
+ const codeVerifier = generateCodeVerifier();
47
+ setLocalStorageItem(CODE_VERIFIER_KEY, codeVerifier);
48
+ const codeChallenge = yield generateCodeChallenge(codeVerifier);
49
+ return this.authorizeURL({
50
+ clientId,
51
+ redirectUri,
52
+ codeChallenge,
53
+ }, options);
54
+ });
55
+ }
56
+ /**
57
+ * Patch: Get the stored PKCE code verifier
58
+ */
59
+ getCodeVerifier() {
60
+ return getLocalStorageItem(CODE_VERIFIER_KEY);
61
+ }
36
62
  /**
37
63
  * Patch: called custom implementation this.__getToken_custom instead of this.__getToken
38
64
  */
@@ -40,10 +66,10 @@ export class Auth extends FernAuth {
40
66
  return core.HttpResponsePromise.fromPromise(this.__getToken_custom(request, requestOptions));
41
67
  }
42
68
  /**
43
- * Patch: added method to get Authorization URL for Authorization code flow
69
+ * Patch: added method to get Authorization URL for Authorization code flow and PKCE flow
44
70
  */
45
71
  authorizeURL(_a, options_1) {
46
- return __awaiter(this, arguments, void 0, function* ({ clientId, redirectUri, }, options) {
72
+ return __awaiter(this, arguments, void 0, function* ({ clientId, redirectUri, codeChallenge, }, options) {
47
73
  var _b;
48
74
  const authUrl = new URL(core.url.join((_b = (yield core.Supplier.get(this._options.baseUrl))) !== null && _b !== void 0 ? _b : (yield core.Supplier.get(this._options.environment)).login, yield core.Supplier.get(this._options.tenantName), "protocol/openid-connect/auth"));
49
75
  authUrl.searchParams.set('response_type', 'code');
@@ -54,6 +80,10 @@ export class Auth extends FernAuth {
54
80
  if (redirectUri !== undefined) {
55
81
  authUrl.searchParams.set('redirect_uri', redirectUri);
56
82
  }
83
+ if (codeChallenge !== undefined) {
84
+ authUrl.searchParams.set('code_challenge', codeChallenge);
85
+ authUrl.searchParams.set('code_challenge_method', 'S256');
86
+ }
57
87
  const authUrlString = authUrl.toString();
58
88
  if (typeof window !== "undefined" && !(options === null || options === void 0 ? void 0 : options.skipRedirect)) {
59
89
  window.location.href = authUrlString;
@@ -68,12 +98,33 @@ export class Auth extends FernAuth {
68
98
  getCodeFlowToken(request, requestOptions) {
69
99
  return core.HttpResponsePromise.fromPromise(this.__getToken_custom(Object.assign(Object.assign({}, request), { grantType: "authorization_code" }), requestOptions));
70
100
  }
101
+ /**
102
+ * Patch: PKCE-specific method
103
+ */
104
+ getPkceFlowToken(request, requestOptions) {
105
+ const codeVerifier = request.codeVerifier || this.getCodeVerifier();
106
+ if (!codeVerifier) {
107
+ throw new ParseError([
108
+ {
109
+ path: ['codeVerifier'],
110
+ message: 'Code verifier was not provided and not found in localStorage.',
111
+ },
112
+ ]);
113
+ }
114
+ return core.HttpResponsePromise.fromPromise(this.__getToken_custom(Object.assign(Object.assign({}, request), { codeVerifier: codeVerifier, grantType: "authorization_code" }), requestOptions));
115
+ }
116
+ /**
117
+ * Patch: ROPC-specific method
118
+ */
119
+ getRopcFlowToken(request, requestOptions) {
120
+ return core.HttpResponsePromise.fromPromise(this.__getToken_custom(Object.assign(Object.assign({}, request), { grantType: "password" }), requestOptions));
121
+ }
71
122
  /**
72
123
  * Patch: copy of this.__getToken with patches
73
124
  */
74
125
  __getToken_custom(
75
126
  /**
76
- * Patch: added additional fields to request to support Authorization code flow
127
+ * Patch: added additional fields to request to support Authorization PKCE and ROPC flow
77
128
  */
78
129
  request, requestOptions) {
79
130
  return __awaiter(this, void 0, void 0, function* () {
@@ -96,23 +147,7 @@ export class Auth extends FernAuth {
96
147
  /**
97
148
  * Patch: removed `requestType: "json"`, made body a URLSearchParams object
98
149
  */
99
- body: new URLSearchParams(Object.assign(Object.assign(Object.assign(Object.assign({}, serializers.AuthGetTokenRequest.jsonOrThrow(request, {
100
- unrecognizedObjectKeys: "strip",
101
- omitUndefined: true,
102
- })), { scope: "openid",
103
- /**
104
- * Patch: `grant_type` uses values from request or defaults to "client_credentials"
105
- */
106
- grant_type: request.grantType || "client_credentials" }), (request.grantType === "authorization_code"
107
- ? {
108
- code: request.code,
109
- redirect_uri: request.redirectUri
110
- }
111
- : {})), (request.grantType === "refresh_token"
112
- ? {
113
- refresh_token: request.refreshToken,
114
- }
115
- : {}))),
150
+ body: buildTokenRequestBody(request),
116
151
  timeoutMs: (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.timeoutInSeconds) != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
117
152
  maxRetries: requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.maxRetries,
118
153
  abortSignal: requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.abortSignal,
@@ -0,0 +1,12 @@
1
+ export interface CortiSDKErrorOptions {
2
+ code: CortiSDKErrorCodes;
3
+ cause?: unknown;
4
+ }
5
+ export declare enum CortiSDKErrorCodes {
6
+ LOCAL_STORAGE_ERROR = "local_storage_error"
7
+ }
8
+ export declare class CortiSDKError extends Error {
9
+ readonly code: CortiSDKErrorCodes;
10
+ readonly cause?: unknown;
11
+ constructor(message?: string, options?: CortiSDKErrorOptions);
12
+ }
@@ -0,0 +1,15 @@
1
+ export var CortiSDKErrorCodes;
2
+ (function (CortiSDKErrorCodes) {
3
+ CortiSDKErrorCodes["LOCAL_STORAGE_ERROR"] = "local_storage_error";
4
+ })(CortiSDKErrorCodes || (CortiSDKErrorCodes = {}));
5
+ export class CortiSDKError extends Error {
6
+ constructor(message = "An unexpected error occurred in the Corti SDK.", options = { code: CortiSDKErrorCodes.LOCAL_STORAGE_ERROR }) {
7
+ super(message);
8
+ this.name = "CortiSDKError";
9
+ this.code = options.code;
10
+ if ("cause" in options) {
11
+ this.cause = options.cause;
12
+ }
13
+ Object.setPrototypeOf(this, CortiSDKError.prototype);
14
+ }
15
+ }
@@ -0,0 +1,4 @@
1
+ export declare const LOCAL_STORAGE_ERROR_CODE: "local_storage_error";
2
+ export declare const requireLocalStorage: () => Storage;
3
+ export declare const setLocalStorageItem: (key: string, value: string) => void;
4
+ export declare const getLocalStorageItem: (key: string) => string | null;
@@ -0,0 +1,32 @@
1
+ import { CortiSDKError, CortiSDKErrorCodes } from "../CortiSDKError.mjs";
2
+ export const LOCAL_STORAGE_ERROR_CODE = "local_storage_error";
3
+ export const requireLocalStorage = () => {
4
+ if (typeof window === "undefined" || !window.localStorage) {
5
+ throw new CortiSDKError("LocalStorage operation failed: storage is not available in this environment.", { code: CortiSDKErrorCodes.LOCAL_STORAGE_ERROR });
6
+ }
7
+ return window.localStorage;
8
+ };
9
+ export const setLocalStorageItem = (key, value) => {
10
+ const storage = requireLocalStorage();
11
+ try {
12
+ storage.setItem(key, value);
13
+ }
14
+ catch (error) {
15
+ throw new CortiSDKError("LocalStorage set operation failed.", {
16
+ code: CortiSDKErrorCodes.LOCAL_STORAGE_ERROR,
17
+ cause: error,
18
+ });
19
+ }
20
+ };
21
+ export const getLocalStorageItem = (key) => {
22
+ const storage = requireLocalStorage();
23
+ try {
24
+ return storage.getItem(key);
25
+ }
26
+ catch (error) {
27
+ throw new CortiSDKError("LocalStorage get operation failed.", {
28
+ code: CortiSDKErrorCodes.LOCAL_STORAGE_ERROR,
29
+ cause: error,
30
+ });
31
+ }
32
+ };
@@ -0,0 +1,2 @@
1
+ export declare const generateCodeVerifier: () => string;
2
+ export declare const generateCodeChallenge: (verifier: string) => Promise<string>;
@@ -0,0 +1,27 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ const base64URLEncode = (buffer) => {
11
+ const base64 = btoa(String.fromCharCode(...buffer));
12
+ return base64
13
+ .replace(/\+/g, '-')
14
+ .replace(/\//g, '_')
15
+ .replace(/=/g, '');
16
+ };
17
+ export const generateCodeVerifier = () => {
18
+ const array = new Uint8Array(32);
19
+ crypto.getRandomValues(array);
20
+ return base64URLEncode(array);
21
+ };
22
+ export const generateCodeChallenge = (verifier) => __awaiter(void 0, void 0, void 0, function* () {
23
+ const encoder = new TextEncoder();
24
+ const data = encoder.encode(verifier);
25
+ const hash = yield crypto.subtle.digest('SHA-256', data);
26
+ return base64URLEncode(new Uint8Array(hash));
27
+ });
@@ -0,0 +1,11 @@
1
+ import * as Corti from "../../api/index.mjs";
2
+ export type TokenRequest = Corti.AuthGetTokenRequest & Partial<{
3
+ grantType: "client_credentials" | "authorization_code" | "refresh_token" | "password";
4
+ code: string;
5
+ redirectUri: string;
6
+ refreshToken: string;
7
+ codeVerifier: string;
8
+ username: string;
9
+ password: string;
10
+ }>;
11
+ export declare const buildTokenRequestBody: (request: TokenRequest) => URLSearchParams;
@@ -0,0 +1,39 @@
1
+ import * as serializers from "../../serialization/index.mjs";
2
+ export const buildTokenRequestBody = (request) => {
3
+ const serializedRequest = serializers.AuthGetTokenRequest.jsonOrThrow(request, {
4
+ unrecognizedObjectKeys: "strip",
5
+ omitUndefined: true,
6
+ });
7
+ const tokenRequestBody = {
8
+ scope: "openid",
9
+ grant_type: request.grantType || "client_credentials",
10
+ };
11
+ Object.entries(serializedRequest).forEach(([key, value]) => {
12
+ if (value != null) {
13
+ tokenRequestBody[key] = String(value);
14
+ }
15
+ });
16
+ if (request.grantType === "authorization_code") {
17
+ if (request.code != null) {
18
+ tokenRequestBody.code = request.code;
19
+ }
20
+ if (request.redirectUri != null) {
21
+ tokenRequestBody.redirect_uri = request.redirectUri;
22
+ }
23
+ if (request.codeVerifier != null) {
24
+ tokenRequestBody.code_verifier = request.codeVerifier;
25
+ }
26
+ }
27
+ if (request.grantType === "refresh_token" && request.refreshToken != null) {
28
+ tokenRequestBody.refresh_token = request.refreshToken;
29
+ }
30
+ if (request.grantType === "password") {
31
+ if (request.username != null) {
32
+ tokenRequestBody.username = request.username;
33
+ }
34
+ if (request.password != null) {
35
+ tokenRequestBody.password = request.password;
36
+ }
37
+ }
38
+ return new URLSearchParams(tokenRequestBody);
39
+ };
@@ -15,3 +15,7 @@ export { Auth as CortiAuth } from "./custom/CortiAuth.mjs";
15
15
  */
16
16
  export { JsonError } from "./core/schemas/builders/schema-utils/JsonError.mjs";
17
17
  export { ParseError } from "./core/schemas/builders/schema-utils/ParseError.mjs";
18
+ /**
19
+ * Patch: added new export to provide SDK-level error handling.
20
+ */
21
+ export { CortiSDKError } from "./custom/CortiSDKError.mjs";
@@ -15,3 +15,7 @@ export { Auth as CortiAuth } from "./custom/CortiAuth.mjs";
15
15
  */
16
16
  export { JsonError } from "./core/schemas/builders/schema-utils/JsonError.mjs";
17
17
  export { ParseError } from "./core/schemas/builders/schema-utils/ParseError.mjs";
18
+ /**
19
+ * Patch: added new export to provide SDK-level error handling.
20
+ */
21
+ export { CortiSDKError } from "./custom/CortiSDKError.mjs";
@@ -8,6 +8,6 @@ export declare const AuthGetTokenRequest: core.serialization.Schema<serializers.
8
8
  export declare namespace AuthGetTokenRequest {
9
9
  interface Raw {
10
10
  client_id: string;
11
- client_secret: string;
11
+ client_secret?: string | null;
12
12
  }
13
13
  }
@@ -4,5 +4,5 @@
4
4
  import * as core from "../../../../../core/index.mjs";
5
5
  export const AuthGetTokenRequest = core.serialization.object({
6
6
  clientId: core.serialization.property("client_id", core.serialization.string()),
7
- clientSecret: core.serialization.property("client_secret", core.serialization.string()),
7
+ clientSecret: core.serialization.property("client_secret", core.serialization.string().optional()),
8
8
  });
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "0.5.0";
1
+ export declare const SDK_VERSION = "0.6.0";
@@ -1 +1 @@
1
- export const SDK_VERSION = "0.5.0";
1
+ export const SDK_VERSION = "0.6.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corti/sdk",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "private": false,
5
5
  "repository": "github:corticph/corti-sdk-javascript",
6
6
  "license": "MIT",