@idealyst/oauth-client 1.2.9 → 1.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,25 +1,45 @@
1
- interface OAuthConfig {
2
- oauthUrl: string;
3
- redirectUrl: string;
4
- additionalParameters?: Record<string, string>;
5
- }
1
+ /**
2
+ * Raw callback parameters from OAuth redirect
3
+ * Contains all query parameters returned by the OAuth provider
4
+ */
5
+ type OAuthCallbackParams = Record<string, string | undefined>;
6
+ /**
7
+ * Default OAuth result with standard code and state
8
+ */
6
9
  interface OAuthResult {
7
10
  code: string;
8
11
  state?: string;
9
12
  }
10
- interface OAuthClient {
11
- authorize(): Promise<OAuthResult>;
13
+ /**
14
+ * OAuth configuration options
15
+ */
16
+ interface OAuthConfig<T = OAuthResult> {
17
+ oauthUrl: string;
18
+ redirectUrl: string;
19
+ additionalParameters?: Record<string, string>;
20
+ /**
21
+ * Optional transformer to convert raw callback params to desired type
22
+ * If not provided, returns all callback params as-is (typed as T)
23
+ */
24
+ transformCallback?: (params: OAuthCallbackParams) => T;
25
+ }
26
+ /**
27
+ * OAuth client interface with generic result type
28
+ * @template T - The type returned from authorize(), defaults to OAuthResult
29
+ */
30
+ interface OAuthClient<T = OAuthResult> {
31
+ authorize(): Promise<T>;
12
32
  }
13
33
 
14
- declare class WebOAuthClient implements OAuthClient {
34
+ declare class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {
15
35
  private config;
16
- constructor(config: OAuthConfig);
17
- authorize(): Promise<OAuthResult>;
36
+ constructor(config: OAuthConfig<T>);
37
+ authorize(): Promise<T>;
18
38
  private checkForCallback;
19
39
  private buildOAuthUrl;
20
40
  private generateState;
21
41
  }
22
42
 
23
- declare function createOAuthClient(config: OAuthConfig): OAuthClient;
43
+ declare function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T>;
24
44
 
25
- export { type OAuthClient, type OAuthConfig, type OAuthResult, WebOAuthClient, createOAuthClient };
45
+ export { type OAuthCallbackParams, type OAuthClient, type OAuthConfig, type OAuthResult, WebOAuthClient, createOAuthClient };
package/dist/index.d.ts CHANGED
@@ -1,25 +1,45 @@
1
- interface OAuthConfig {
2
- oauthUrl: string;
3
- redirectUrl: string;
4
- additionalParameters?: Record<string, string>;
5
- }
1
+ /**
2
+ * Raw callback parameters from OAuth redirect
3
+ * Contains all query parameters returned by the OAuth provider
4
+ */
5
+ type OAuthCallbackParams = Record<string, string | undefined>;
6
+ /**
7
+ * Default OAuth result with standard code and state
8
+ */
6
9
  interface OAuthResult {
7
10
  code: string;
8
11
  state?: string;
9
12
  }
10
- interface OAuthClient {
11
- authorize(): Promise<OAuthResult>;
13
+ /**
14
+ * OAuth configuration options
15
+ */
16
+ interface OAuthConfig<T = OAuthResult> {
17
+ oauthUrl: string;
18
+ redirectUrl: string;
19
+ additionalParameters?: Record<string, string>;
20
+ /**
21
+ * Optional transformer to convert raw callback params to desired type
22
+ * If not provided, returns all callback params as-is (typed as T)
23
+ */
24
+ transformCallback?: (params: OAuthCallbackParams) => T;
25
+ }
26
+ /**
27
+ * OAuth client interface with generic result type
28
+ * @template T - The type returned from authorize(), defaults to OAuthResult
29
+ */
30
+ interface OAuthClient<T = OAuthResult> {
31
+ authorize(): Promise<T>;
12
32
  }
13
33
 
14
- declare class WebOAuthClient implements OAuthClient {
34
+ declare class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {
15
35
  private config;
16
- constructor(config: OAuthConfig);
17
- authorize(): Promise<OAuthResult>;
36
+ constructor(config: OAuthConfig<T>);
37
+ authorize(): Promise<T>;
18
38
  private checkForCallback;
19
39
  private buildOAuthUrl;
20
40
  private generateState;
21
41
  }
22
42
 
23
- declare function createOAuthClient(config: OAuthConfig): OAuthClient;
43
+ declare function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T>;
24
44
 
25
- export { type OAuthClient, type OAuthConfig, type OAuthResult, WebOAuthClient, createOAuthClient };
45
+ export { type OAuthCallbackParams, type OAuthClient, type OAuthConfig, type OAuthResult, WebOAuthClient, createOAuthClient };
package/dist/index.js CHANGED
@@ -32,19 +32,16 @@ var WebOAuthClient = class {
32
32
  }
33
33
  async authorize() {
34
34
  const state = this.generateState();
35
- const callbackData = this.checkForCallback();
36
- if (callbackData) {
37
- const { code, error, returnedState } = callbackData;
38
- if (error) {
39
- throw new Error(`OAuth error: ${error}`);
35
+ const callbackParams = this.checkForCallback();
36
+ if (callbackParams) {
37
+ if (callbackParams.error) {
38
+ throw new Error(`OAuth error: ${callbackParams.error}`);
40
39
  }
41
- if (code) {
42
- window.history.replaceState({}, document.title, window.location.pathname);
43
- return {
44
- code,
45
- state: returnedState || void 0
46
- };
40
+ window.history.replaceState({}, document.title, window.location.pathname);
41
+ if (this.config.transformCallback) {
42
+ return this.config.transformCallback(callbackParams);
47
43
  }
44
+ return callbackParams;
48
45
  }
49
46
  const oauthUrl = this.buildOAuthUrl(state);
50
47
  window.location.href = oauthUrl;
@@ -52,17 +49,14 @@ var WebOAuthClient = class {
52
49
  }
53
50
  checkForCallback() {
54
51
  const urlParams = new URLSearchParams(window.location.search);
55
- const code = urlParams.get("code");
56
- const error = urlParams.get("error");
57
- const state = urlParams.get("state");
58
- if (code || error) {
59
- return {
60
- code: code || void 0,
61
- error: error || void 0,
62
- returnedState: state || void 0
63
- };
52
+ const params = {};
53
+ urlParams.forEach((value, key) => {
54
+ params[key] = value;
55
+ });
56
+ if (Object.keys(params).length === 0) {
57
+ return null;
64
58
  }
65
- return null;
59
+ return params;
66
60
  }
67
61
  buildOAuthUrl(state) {
68
62
  const url = new URL(this.config.oauthUrl);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/oauth-client.web.ts","../src/index.web.ts"],"sourcesContent":["export * from './index.web'","import type { OAuthClient, OAuthConfig, OAuthResult } from './types'\n\nexport class WebOAuthClient implements OAuthClient {\n private config: OAuthConfig\n\n constructor(config: OAuthConfig) {\n this.config = config\n }\n\n async authorize(): Promise<OAuthResult> {\n const state = this.generateState()\n\n // Check if we're already in a callback\n const callbackData = this.checkForCallback()\n \n if (callbackData) {\n const { code, error, returnedState } = callbackData\n \n if (error) {\n throw new Error(`OAuth error: ${error}`)\n }\n\n if (code) {\n // Clean up URL\n window.history.replaceState({}, document.title, window.location.pathname)\n \n return { \n code,\n state: returnedState || undefined\n }\n }\n }\n\n // Build OAuth URL and redirect\n const oauthUrl = this.buildOAuthUrl(state)\n window.location.href = oauthUrl\n \n // This won't be reached due to redirect\n throw new Error('Authorization flow initiated')\n }\n\n private checkForCallback(): { code?: string; error?: string; returnedState?: string } | null {\n const urlParams = new URLSearchParams(window.location.search)\n const code = urlParams.get('code')\n const error = urlParams.get('error')\n const state = urlParams.get('state')\n \n if (code || error) {\n return {\n code: code || undefined,\n error: error || undefined,\n returnedState: state || undefined,\n }\n }\n \n return null\n }\n\n private buildOAuthUrl(state: string): string {\n const url = new URL(this.config.oauthUrl)\n \n url.searchParams.set('redirect_uri', this.config.redirectUrl)\n url.searchParams.set('state', state)\n\n // Add additional parameters\n if (this.config.additionalParameters) {\n Object.entries(this.config.additionalParameters).forEach(([key, value]) => {\n url.searchParams.set(key, value)\n })\n }\n\n return url.toString()\n }\n\n private generateState(): string {\n // Generate random state for CSRF protection\n let result = ''\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'\n for (let i = 0; i < 32; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length))\n }\n return result\n }\n}","export * from './types'\n\nimport type { OAuthConfig, OAuthClient } from './types'\nimport { WebOAuthClient } from './oauth-client.web'\n\nexport function createOAuthClient(config: OAuthConfig): OAuthClient {\n return new WebOAuthClient(config)\n}\n\nexport { WebOAuthClient }"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,iBAAN,MAA4C;AAAA,EAGjD,YAAY,QAAqB;AAC/B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,YAAkC;AACtC,UAAM,QAAQ,KAAK,cAAc;AAGjC,UAAM,eAAe,KAAK,iBAAiB;AAE3C,QAAI,cAAc;AAChB,YAAM,EAAE,MAAM,OAAO,cAAc,IAAI;AAEvC,UAAI,OAAO;AACT,cAAM,IAAI,MAAM,gBAAgB,KAAK,EAAE;AAAA,MACzC;AAEA,UAAI,MAAM;AAER,eAAO,QAAQ,aAAa,CAAC,GAAG,SAAS,OAAO,OAAO,SAAS,QAAQ;AAExE,eAAO;AAAA,UACL;AAAA,UACA,OAAO,iBAAiB;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAW,KAAK,cAAc,KAAK;AACzC,WAAO,SAAS,OAAO;AAGvB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AAAA,EAEQ,mBAAqF;AAC3F,UAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,UAAM,OAAO,UAAU,IAAI,MAAM;AACjC,UAAM,QAAQ,UAAU,IAAI,OAAO;AACnC,UAAM,QAAQ,UAAU,IAAI,OAAO;AAEnC,QAAI,QAAQ,OAAO;AACjB,aAAO;AAAA,QACL,MAAM,QAAQ;AAAA,QACd,OAAO,SAAS;AAAA,QAChB,eAAe,SAAS;AAAA,MAC1B;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,OAAuB;AAC3C,UAAM,MAAM,IAAI,IAAI,KAAK,OAAO,QAAQ;AAExC,QAAI,aAAa,IAAI,gBAAgB,KAAK,OAAO,WAAW;AAC5D,QAAI,aAAa,IAAI,SAAS,KAAK;AAGnC,QAAI,KAAK,OAAO,sBAAsB;AACpC,aAAO,QAAQ,KAAK,OAAO,oBAAoB,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACzE,YAAI,aAAa,IAAI,KAAK,KAAK;AAAA,MACjC,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEQ,gBAAwB;AAE9B,QAAI,SAAS;AACb,UAAM,QAAQ;AACd,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,gBAAU,MAAM,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACF;;;AC9EO,SAAS,kBAAkB,QAAkC;AAClE,SAAO,IAAI,eAAe,MAAM;AAClC;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/oauth-client.web.ts","../src/index.web.ts"],"sourcesContent":["export * from './index.web'","import type { OAuthClient, OAuthConfig, OAuthResult, OAuthCallbackParams } from './types'\n\nexport class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {\n private config: OAuthConfig<T>\n\n constructor(config: OAuthConfig<T>) {\n this.config = config\n }\n\n async authorize(): Promise<T> {\n const state = this.generateState()\n\n // Check if we're already in a callback\n const callbackParams = this.checkForCallback()\n\n if (callbackParams) {\n if (callbackParams.error) {\n throw new Error(`OAuth error: ${callbackParams.error}`)\n }\n\n // Clean up URL\n window.history.replaceState({}, document.title, window.location.pathname)\n\n // Transform callback params if transformer provided, otherwise return as-is\n if (this.config.transformCallback) {\n return this.config.transformCallback(callbackParams)\n }\n\n // Default behavior: return all callback params as T\n return callbackParams as T\n }\n\n // Build OAuth URL and redirect\n const oauthUrl = this.buildOAuthUrl(state)\n window.location.href = oauthUrl\n\n // This won't be reached due to redirect\n throw new Error('Authorization flow initiated')\n }\n\n private checkForCallback(): OAuthCallbackParams | null {\n const urlParams = new URLSearchParams(window.location.search)\n const params: OAuthCallbackParams = {}\n\n // Collect all query parameters\n urlParams.forEach((value, key) => {\n params[key] = value\n })\n\n // Return null if no parameters found\n if (Object.keys(params).length === 0) {\n return null\n }\n\n return params\n }\n\n private buildOAuthUrl(state: string): string {\n const url = new URL(this.config.oauthUrl)\n \n url.searchParams.set('redirect_uri', this.config.redirectUrl)\n url.searchParams.set('state', state)\n\n // Add additional parameters\n if (this.config.additionalParameters) {\n Object.entries(this.config.additionalParameters).forEach(([key, value]) => {\n url.searchParams.set(key, value)\n })\n }\n\n return url.toString()\n }\n\n private generateState(): string {\n // Generate random state for CSRF protection\n let result = ''\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'\n for (let i = 0; i < 32; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length))\n }\n return result\n }\n}","export * from './types'\n\nimport type { OAuthConfig, OAuthClient, OAuthResult } from './types'\nimport { WebOAuthClient } from './oauth-client.web'\n\nexport function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T> {\n return new WebOAuthClient<T>(config)\n}\n\nexport { WebOAuthClient }"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,iBAAN,MAAgE;AAAA,EAGrE,YAAY,QAAwB;AAClC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,YAAwB;AAC5B,UAAM,QAAQ,KAAK,cAAc;AAGjC,UAAM,iBAAiB,KAAK,iBAAiB;AAE7C,QAAI,gBAAgB;AAClB,UAAI,eAAe,OAAO;AACxB,cAAM,IAAI,MAAM,gBAAgB,eAAe,KAAK,EAAE;AAAA,MACxD;AAGA,aAAO,QAAQ,aAAa,CAAC,GAAG,SAAS,OAAO,OAAO,SAAS,QAAQ;AAGxE,UAAI,KAAK,OAAO,mBAAmB;AACjC,eAAO,KAAK,OAAO,kBAAkB,cAAc;AAAA,MACrD;AAGA,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,KAAK,cAAc,KAAK;AACzC,WAAO,SAAS,OAAO;AAGvB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AAAA,EAEQ,mBAA+C;AACrD,UAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,UAAM,SAA8B,CAAC;AAGrC,cAAU,QAAQ,CAAC,OAAO,QAAQ;AAChC,aAAO,GAAG,IAAI;AAAA,IAChB,CAAC;AAGD,QAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AACpC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,OAAuB;AAC3C,UAAM,MAAM,IAAI,IAAI,KAAK,OAAO,QAAQ;AAExC,QAAI,aAAa,IAAI,gBAAgB,KAAK,OAAO,WAAW;AAC5D,QAAI,aAAa,IAAI,SAAS,KAAK;AAGnC,QAAI,KAAK,OAAO,sBAAsB;AACpC,aAAO,QAAQ,KAAK,OAAO,oBAAoB,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACzE,YAAI,aAAa,IAAI,KAAK,KAAK;AAAA,MACjC,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEQ,gBAAwB;AAE9B,QAAI,SAAS;AACb,UAAM,QAAQ;AACd,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,gBAAU,MAAM,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACF;;;AC7EO,SAAS,kBAAmC,QAAwC;AACzF,SAAO,IAAI,eAAkB,MAAM;AACrC;","names":[]}
package/dist/index.mjs CHANGED
@@ -5,19 +5,16 @@ var WebOAuthClient = class {
5
5
  }
6
6
  async authorize() {
7
7
  const state = this.generateState();
8
- const callbackData = this.checkForCallback();
9
- if (callbackData) {
10
- const { code, error, returnedState } = callbackData;
11
- if (error) {
12
- throw new Error(`OAuth error: ${error}`);
8
+ const callbackParams = this.checkForCallback();
9
+ if (callbackParams) {
10
+ if (callbackParams.error) {
11
+ throw new Error(`OAuth error: ${callbackParams.error}`);
13
12
  }
14
- if (code) {
15
- window.history.replaceState({}, document.title, window.location.pathname);
16
- return {
17
- code,
18
- state: returnedState || void 0
19
- };
13
+ window.history.replaceState({}, document.title, window.location.pathname);
14
+ if (this.config.transformCallback) {
15
+ return this.config.transformCallback(callbackParams);
20
16
  }
17
+ return callbackParams;
21
18
  }
22
19
  const oauthUrl = this.buildOAuthUrl(state);
23
20
  window.location.href = oauthUrl;
@@ -25,17 +22,14 @@ var WebOAuthClient = class {
25
22
  }
26
23
  checkForCallback() {
27
24
  const urlParams = new URLSearchParams(window.location.search);
28
- const code = urlParams.get("code");
29
- const error = urlParams.get("error");
30
- const state = urlParams.get("state");
31
- if (code || error) {
32
- return {
33
- code: code || void 0,
34
- error: error || void 0,
35
- returnedState: state || void 0
36
- };
25
+ const params = {};
26
+ urlParams.forEach((value, key) => {
27
+ params[key] = value;
28
+ });
29
+ if (Object.keys(params).length === 0) {
30
+ return null;
37
31
  }
38
- return null;
32
+ return params;
39
33
  }
40
34
  buildOAuthUrl(state) {
41
35
  const url = new URL(this.config.oauthUrl);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/oauth-client.web.ts","../src/index.web.ts"],"sourcesContent":["import type { OAuthClient, OAuthConfig, OAuthResult } from './types'\n\nexport class WebOAuthClient implements OAuthClient {\n private config: OAuthConfig\n\n constructor(config: OAuthConfig) {\n this.config = config\n }\n\n async authorize(): Promise<OAuthResult> {\n const state = this.generateState()\n\n // Check if we're already in a callback\n const callbackData = this.checkForCallback()\n \n if (callbackData) {\n const { code, error, returnedState } = callbackData\n \n if (error) {\n throw new Error(`OAuth error: ${error}`)\n }\n\n if (code) {\n // Clean up URL\n window.history.replaceState({}, document.title, window.location.pathname)\n \n return { \n code,\n state: returnedState || undefined\n }\n }\n }\n\n // Build OAuth URL and redirect\n const oauthUrl = this.buildOAuthUrl(state)\n window.location.href = oauthUrl\n \n // This won't be reached due to redirect\n throw new Error('Authorization flow initiated')\n }\n\n private checkForCallback(): { code?: string; error?: string; returnedState?: string } | null {\n const urlParams = new URLSearchParams(window.location.search)\n const code = urlParams.get('code')\n const error = urlParams.get('error')\n const state = urlParams.get('state')\n \n if (code || error) {\n return {\n code: code || undefined,\n error: error || undefined,\n returnedState: state || undefined,\n }\n }\n \n return null\n }\n\n private buildOAuthUrl(state: string): string {\n const url = new URL(this.config.oauthUrl)\n \n url.searchParams.set('redirect_uri', this.config.redirectUrl)\n url.searchParams.set('state', state)\n\n // Add additional parameters\n if (this.config.additionalParameters) {\n Object.entries(this.config.additionalParameters).forEach(([key, value]) => {\n url.searchParams.set(key, value)\n })\n }\n\n return url.toString()\n }\n\n private generateState(): string {\n // Generate random state for CSRF protection\n let result = ''\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'\n for (let i = 0; i < 32; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length))\n }\n return result\n }\n}","export * from './types'\n\nimport type { OAuthConfig, OAuthClient } from './types'\nimport { WebOAuthClient } from './oauth-client.web'\n\nexport function createOAuthClient(config: OAuthConfig): OAuthClient {\n return new WebOAuthClient(config)\n}\n\nexport { WebOAuthClient }"],"mappings":";AAEO,IAAM,iBAAN,MAA4C;AAAA,EAGjD,YAAY,QAAqB;AAC/B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,YAAkC;AACtC,UAAM,QAAQ,KAAK,cAAc;AAGjC,UAAM,eAAe,KAAK,iBAAiB;AAE3C,QAAI,cAAc;AAChB,YAAM,EAAE,MAAM,OAAO,cAAc,IAAI;AAEvC,UAAI,OAAO;AACT,cAAM,IAAI,MAAM,gBAAgB,KAAK,EAAE;AAAA,MACzC;AAEA,UAAI,MAAM;AAER,eAAO,QAAQ,aAAa,CAAC,GAAG,SAAS,OAAO,OAAO,SAAS,QAAQ;AAExE,eAAO;AAAA,UACL;AAAA,UACA,OAAO,iBAAiB;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAW,KAAK,cAAc,KAAK;AACzC,WAAO,SAAS,OAAO;AAGvB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AAAA,EAEQ,mBAAqF;AAC3F,UAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,UAAM,OAAO,UAAU,IAAI,MAAM;AACjC,UAAM,QAAQ,UAAU,IAAI,OAAO;AACnC,UAAM,QAAQ,UAAU,IAAI,OAAO;AAEnC,QAAI,QAAQ,OAAO;AACjB,aAAO;AAAA,QACL,MAAM,QAAQ;AAAA,QACd,OAAO,SAAS;AAAA,QAChB,eAAe,SAAS;AAAA,MAC1B;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,OAAuB;AAC3C,UAAM,MAAM,IAAI,IAAI,KAAK,OAAO,QAAQ;AAExC,QAAI,aAAa,IAAI,gBAAgB,KAAK,OAAO,WAAW;AAC5D,QAAI,aAAa,IAAI,SAAS,KAAK;AAGnC,QAAI,KAAK,OAAO,sBAAsB;AACpC,aAAO,QAAQ,KAAK,OAAO,oBAAoB,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACzE,YAAI,aAAa,IAAI,KAAK,KAAK;AAAA,MACjC,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEQ,gBAAwB;AAE9B,QAAI,SAAS;AACb,UAAM,QAAQ;AACd,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,gBAAU,MAAM,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACF;;;AC9EO,SAAS,kBAAkB,QAAkC;AAClE,SAAO,IAAI,eAAe,MAAM;AAClC;","names":[]}
1
+ {"version":3,"sources":["../src/oauth-client.web.ts","../src/index.web.ts"],"sourcesContent":["import type { OAuthClient, OAuthConfig, OAuthResult, OAuthCallbackParams } from './types'\n\nexport class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {\n private config: OAuthConfig<T>\n\n constructor(config: OAuthConfig<T>) {\n this.config = config\n }\n\n async authorize(): Promise<T> {\n const state = this.generateState()\n\n // Check if we're already in a callback\n const callbackParams = this.checkForCallback()\n\n if (callbackParams) {\n if (callbackParams.error) {\n throw new Error(`OAuth error: ${callbackParams.error}`)\n }\n\n // Clean up URL\n window.history.replaceState({}, document.title, window.location.pathname)\n\n // Transform callback params if transformer provided, otherwise return as-is\n if (this.config.transformCallback) {\n return this.config.transformCallback(callbackParams)\n }\n\n // Default behavior: return all callback params as T\n return callbackParams as T\n }\n\n // Build OAuth URL and redirect\n const oauthUrl = this.buildOAuthUrl(state)\n window.location.href = oauthUrl\n\n // This won't be reached due to redirect\n throw new Error('Authorization flow initiated')\n }\n\n private checkForCallback(): OAuthCallbackParams | null {\n const urlParams = new URLSearchParams(window.location.search)\n const params: OAuthCallbackParams = {}\n\n // Collect all query parameters\n urlParams.forEach((value, key) => {\n params[key] = value\n })\n\n // Return null if no parameters found\n if (Object.keys(params).length === 0) {\n return null\n }\n\n return params\n }\n\n private buildOAuthUrl(state: string): string {\n const url = new URL(this.config.oauthUrl)\n \n url.searchParams.set('redirect_uri', this.config.redirectUrl)\n url.searchParams.set('state', state)\n\n // Add additional parameters\n if (this.config.additionalParameters) {\n Object.entries(this.config.additionalParameters).forEach(([key, value]) => {\n url.searchParams.set(key, value)\n })\n }\n\n return url.toString()\n }\n\n private generateState(): string {\n // Generate random state for CSRF protection\n let result = ''\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'\n for (let i = 0; i < 32; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length))\n }\n return result\n }\n}","export * from './types'\n\nimport type { OAuthConfig, OAuthClient, OAuthResult } from './types'\nimport { WebOAuthClient } from './oauth-client.web'\n\nexport function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T> {\n return new WebOAuthClient<T>(config)\n}\n\nexport { WebOAuthClient }"],"mappings":";AAEO,IAAM,iBAAN,MAAgE;AAAA,EAGrE,YAAY,QAAwB;AAClC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,YAAwB;AAC5B,UAAM,QAAQ,KAAK,cAAc;AAGjC,UAAM,iBAAiB,KAAK,iBAAiB;AAE7C,QAAI,gBAAgB;AAClB,UAAI,eAAe,OAAO;AACxB,cAAM,IAAI,MAAM,gBAAgB,eAAe,KAAK,EAAE;AAAA,MACxD;AAGA,aAAO,QAAQ,aAAa,CAAC,GAAG,SAAS,OAAO,OAAO,SAAS,QAAQ;AAGxE,UAAI,KAAK,OAAO,mBAAmB;AACjC,eAAO,KAAK,OAAO,kBAAkB,cAAc;AAAA,MACrD;AAGA,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,KAAK,cAAc,KAAK;AACzC,WAAO,SAAS,OAAO;AAGvB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AAAA,EAEQ,mBAA+C;AACrD,UAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,UAAM,SAA8B,CAAC;AAGrC,cAAU,QAAQ,CAAC,OAAO,QAAQ;AAChC,aAAO,GAAG,IAAI;AAAA,IAChB,CAAC;AAGD,QAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AACpC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,OAAuB;AAC3C,UAAM,MAAM,IAAI,IAAI,KAAK,OAAO,QAAQ;AAExC,QAAI,aAAa,IAAI,gBAAgB,KAAK,OAAO,WAAW;AAC5D,QAAI,aAAa,IAAI,SAAS,KAAK;AAGnC,QAAI,KAAK,OAAO,sBAAsB;AACpC,aAAO,QAAQ,KAAK,OAAO,oBAAoB,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACzE,YAAI,aAAa,IAAI,KAAK,KAAK;AAAA,MACjC,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEQ,gBAAwB;AAE9B,QAAI,SAAS;AACb,UAAM,QAAQ;AACd,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,gBAAU,MAAM,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACF;;;AC7EO,SAAS,kBAAmC,QAAwC;AACzF,SAAO,IAAI,eAAkB,MAAM;AACrC;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idealyst/oauth-client",
3
- "version": "1.2.9",
3
+ "version": "1.2.12",
4
4
  "description": "Universal OAuth2 client for web and React Native",
5
5
  "main": "src/index.ts",
6
6
  "module": "src/index.ts",
@@ -1,10 +1,10 @@
1
1
  export * from './types'
2
2
 
3
- import type { OAuthConfig, OAuthClient } from './types'
3
+ import type { OAuthConfig, OAuthClient, OAuthResult } from './types'
4
4
  import { NativeOAuthClient } from './oauth-client.native'
5
5
 
6
- export function createOAuthClient(config: OAuthConfig): OAuthClient {
7
- return new NativeOAuthClient(config)
6
+ export function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T> {
7
+ return new NativeOAuthClient<T>(config)
8
8
  }
9
9
 
10
10
  export { NativeOAuthClient }
package/src/index.web.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  export * from './types'
2
2
 
3
- import type { OAuthConfig, OAuthClient } from './types'
3
+ import type { OAuthConfig, OAuthClient, OAuthResult } from './types'
4
4
  import { WebOAuthClient } from './oauth-client.web'
5
5
 
6
- export function createOAuthClient(config: OAuthConfig): OAuthClient {
7
- return new WebOAuthClient(config)
6
+ export function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T> {
7
+ return new WebOAuthClient<T>(config)
8
8
  }
9
9
 
10
10
  export { WebOAuthClient }
@@ -1,38 +1,37 @@
1
- import type { OAuthClient, OAuthConfig, OAuthResult } from './types'
1
+ import type { OAuthClient, OAuthConfig, OAuthResult, OAuthCallbackParams } from './types'
2
2
  import { Linking } from 'react-native'
3
3
 
4
- export class NativeOAuthClient implements OAuthClient {
5
- private config: OAuthConfig
4
+ export class NativeOAuthClient<T = OAuthResult> implements OAuthClient<T> {
5
+ private config: OAuthConfig<T>
6
6
 
7
- constructor(config: OAuthConfig) {
7
+ constructor(config: OAuthConfig<T>) {
8
8
  this.config = config
9
9
  }
10
10
 
11
- async authorize(): Promise<OAuthResult> {
11
+ async authorize(): Promise<T> {
12
12
  const state = this.generateState()
13
13
  const oauthUrl = this.buildOAuthUrl(state)
14
-
14
+
15
15
  // Open OAuth URL in system browser
16
16
  await Linking.openURL(oauthUrl)
17
-
17
+
18
18
  // Wait for deep link callback
19
- const callbackData = await this.waitForDeepLinkCallback()
20
-
21
- if (callbackData.error) {
22
- throw new Error(`OAuth error: ${callbackData.error}`)
19
+ const callbackParams = await this.waitForDeepLinkCallback()
20
+
21
+ if (callbackParams.error) {
22
+ throw new Error(`OAuth error: ${callbackParams.error}`)
23
23
  }
24
-
25
- if (callbackData.code) {
26
- return {
27
- code: callbackData.code,
28
- state: callbackData.state
29
- }
24
+
25
+ // Transform callback params if transformer provided, otherwise return as-is
26
+ if (this.config.transformCallback) {
27
+ return this.config.transformCallback(callbackParams)
30
28
  }
31
-
32
- throw new Error('No authorization code received')
29
+
30
+ // Default behavior: return all callback params as T
31
+ return callbackParams as T
33
32
  }
34
33
 
35
- private async waitForDeepLinkCallback(): Promise<{ code?: string; error?: string; state?: string }> {
34
+ private async waitForDeepLinkCallback(): Promise<OAuthCallbackParams> {
36
35
  return new Promise((resolve, reject) => {
37
36
  let subscription: any
38
37
  let timeoutId: NodeJS.Timeout | null = null
@@ -82,47 +81,39 @@ export class NativeOAuthClient implements OAuthClient {
82
81
  })
83
82
  }
84
83
 
85
- private parseDeepLink(url: string): { code?: string; error?: string; state?: string } | null {
84
+ private parseDeepLink(url: string): OAuthCallbackParams | null {
86
85
  try {
87
86
  // Handle custom scheme URLs (e.g., com.myapp://oauth/callback?code=123)
88
87
  const parsedUrl = new URL(url)
89
-
88
+
90
89
  // Check if this is our OAuth callback
91
90
  const expectedScheme = new URL(this.config.redirectUrl).protocol.slice(0, -1)
92
91
  if (parsedUrl.protocol.slice(0, -1) !== expectedScheme) {
93
92
  return null
94
93
  }
95
94
 
96
- // For custom schemes, parameters are in the query string
97
- const code = parsedUrl.searchParams.get('code')
98
- const error = parsedUrl.searchParams.get('error')
99
- const state = parsedUrl.searchParams.get('state')
95
+ // Collect all query parameters
96
+ const params: OAuthCallbackParams = {}
97
+
98
+ // Get all parameters from query string
99
+ parsedUrl.searchParams.forEach((value, key) => {
100
+ params[key] = value
101
+ })
100
102
 
101
103
  // Also check the hash fragment for parameters (some OAuth providers use this)
102
- if (!code && !error && parsedUrl.hash) {
104
+ if (Object.keys(params).length === 0 && parsedUrl.hash) {
103
105
  const hashParams = new URLSearchParams(parsedUrl.hash.substring(1))
104
- const hashCode = hashParams.get('code')
105
- const hashError = hashParams.get('error')
106
- const hashState = hashParams.get('state')
107
-
108
- if (hashCode || hashError) {
109
- return {
110
- code: hashCode || undefined,
111
- error: hashError || undefined,
112
- state: hashState || undefined
113
- }
114
- }
106
+ hashParams.forEach((value, key) => {
107
+ params[key] = value
108
+ })
115
109
  }
116
110
 
117
- if (!code && !error) {
111
+ // Return null if no parameters found
112
+ if (Object.keys(params).length === 0) {
118
113
  return null
119
114
  }
120
115
 
121
- return {
122
- code: code || undefined,
123
- error: error || undefined,
124
- state: state || undefined
125
- }
116
+ return params
126
117
  } catch (error) {
127
118
  console.warn('Failed to parse deep link URL:', url, error)
128
119
  return null
@@ -1,59 +1,58 @@
1
- import type { OAuthClient, OAuthConfig, OAuthResult } from './types'
1
+ import type { OAuthClient, OAuthConfig, OAuthResult, OAuthCallbackParams } from './types'
2
2
 
3
- export class WebOAuthClient implements OAuthClient {
4
- private config: OAuthConfig
3
+ export class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {
4
+ private config: OAuthConfig<T>
5
5
 
6
- constructor(config: OAuthConfig) {
6
+ constructor(config: OAuthConfig<T>) {
7
7
  this.config = config
8
8
  }
9
9
 
10
- async authorize(): Promise<OAuthResult> {
10
+ async authorize(): Promise<T> {
11
11
  const state = this.generateState()
12
12
 
13
13
  // Check if we're already in a callback
14
- const callbackData = this.checkForCallback()
15
-
16
- if (callbackData) {
17
- const { code, error, returnedState } = callbackData
18
-
19
- if (error) {
20
- throw new Error(`OAuth error: ${error}`)
14
+ const callbackParams = this.checkForCallback()
15
+
16
+ if (callbackParams) {
17
+ if (callbackParams.error) {
18
+ throw new Error(`OAuth error: ${callbackParams.error}`)
21
19
  }
22
20
 
23
- if (code) {
24
- // Clean up URL
25
- window.history.replaceState({}, document.title, window.location.pathname)
26
-
27
- return {
28
- code,
29
- state: returnedState || undefined
30
- }
21
+ // Clean up URL
22
+ window.history.replaceState({}, document.title, window.location.pathname)
23
+
24
+ // Transform callback params if transformer provided, otherwise return as-is
25
+ if (this.config.transformCallback) {
26
+ return this.config.transformCallback(callbackParams)
31
27
  }
28
+
29
+ // Default behavior: return all callback params as T
30
+ return callbackParams as T
32
31
  }
33
32
 
34
33
  // Build OAuth URL and redirect
35
34
  const oauthUrl = this.buildOAuthUrl(state)
36
35
  window.location.href = oauthUrl
37
-
36
+
38
37
  // This won't be reached due to redirect
39
38
  throw new Error('Authorization flow initiated')
40
39
  }
41
40
 
42
- private checkForCallback(): { code?: string; error?: string; returnedState?: string } | null {
41
+ private checkForCallback(): OAuthCallbackParams | null {
43
42
  const urlParams = new URLSearchParams(window.location.search)
44
- const code = urlParams.get('code')
45
- const error = urlParams.get('error')
46
- const state = urlParams.get('state')
47
-
48
- if (code || error) {
49
- return {
50
- code: code || undefined,
51
- error: error || undefined,
52
- returnedState: state || undefined,
53
- }
43
+ const params: OAuthCallbackParams = {}
44
+
45
+ // Collect all query parameters
46
+ urlParams.forEach((value, key) => {
47
+ params[key] = value
48
+ })
49
+
50
+ // Return null if no parameters found
51
+ if (Object.keys(params).length === 0) {
52
+ return null
54
53
  }
55
-
56
- return null
54
+
55
+ return params
57
56
  }
58
57
 
59
58
  private buildOAuthUrl(state: string): string {
package/src/types.ts CHANGED
@@ -1,19 +1,41 @@
1
- export interface OAuthConfig {
1
+ /**
2
+ * Raw callback parameters from OAuth redirect
3
+ * Contains all query parameters returned by the OAuth provider
4
+ */
5
+ export type OAuthCallbackParams = Record<string, string | undefined>
6
+
7
+ /**
8
+ * Default OAuth result with standard code and state
9
+ */
10
+ export interface OAuthResult {
11
+ code: string
12
+ state?: string
13
+ }
14
+
15
+ /**
16
+ * OAuth configuration options
17
+ */
18
+ export interface OAuthConfig<T = OAuthResult> {
2
19
  // OAuth endpoint URL (e.g., "https://api.yourapp.com/auth/google")
3
20
  oauthUrl: string
4
-
21
+
5
22
  // Redirect URL for the client app (e.g., "com.yourapp://oauth/callback")
6
23
  redirectUrl: string
7
-
24
+
8
25
  // Optional additional parameters to send to OAuth endpoint
9
26
  additionalParameters?: Record<string, string>
10
- }
11
27
 
12
- export interface OAuthResult {
13
- code: string
14
- state?: string
28
+ /**
29
+ * Optional transformer to convert raw callback params to desired type
30
+ * If not provided, returns all callback params as-is (typed as T)
31
+ */
32
+ transformCallback?: (params: OAuthCallbackParams) => T
15
33
  }
16
34
 
17
- export interface OAuthClient {
18
- authorize(): Promise<OAuthResult>
35
+ /**
36
+ * OAuth client interface with generic result type
37
+ * @template T - The type returned from authorize(), defaults to OAuthResult
38
+ */
39
+ export interface OAuthClient<T = OAuthResult> {
40
+ authorize(): Promise<T>
19
41
  }