@superfan-app/spotify-auth 0.1.61 → 0.1.63

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
@@ -228,7 +228,18 @@ npx expo run:ios
228
228
 
229
229
  ## Requirements
230
230
 
231
- - Expo SDK 47+
232
- - iOS 13.0+
233
- - Node.js 14.0+
231
+ - Expo SDK 53+
232
+ - iOS 15.1+
233
+ - Swift 5.9 (Xcode 15+)
234
+ - Node.js 20.0+
234
235
  - Expo Development Client
236
+
237
+ ## iOS Native Notes
238
+
239
+ - The Spotify SDK is bundled as a vendored `SpotifyiOS.xcframework`. CocoaPods configures header and framework search paths automatically. You do not need to add manual `HEADER_SEARCH_PATHS` or `FRAMEWORK_SEARCH_PATHS`.
240
+ - If you hit CocoaPods build issues after installing, try:
241
+ ```bash
242
+ cd ios
243
+ pod deintegrate
244
+ pod install --repo-update
245
+ ```
@@ -1,10 +1,10 @@
1
1
  import { NativeModule } from "expo-modules-core";
2
2
  import type { AuthorizeConfig, SpotifyAuthEvent } from "./SpotifyAuth.types";
3
- type SpotifyAuthEvents = {
3
+ export type SpotifyAuthEvents = {
4
4
  onSpotifyAuth(event: SpotifyAuthEvent): void;
5
5
  };
6
6
  export declare class SpotifyAuthModule extends NativeModule<SpotifyAuthEvents> {
7
- readonly AuthEventName: string;
7
+ readonly AuthEventName: 'onSpotifyAuth';
8
8
  readonly authorize: (config: AuthorizeConfig) => Promise<void>;
9
9
  }
10
10
  declare const _default: SpotifyAuthModule;
@@ -1 +1 @@
1
- {"version":3,"file":"SpotifyAuthModule.d.ts","sourceRoot":"","sources":["../src/SpotifyAuthModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE7E,KAAK,iBAAiB,GAAG;IACvB,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC9C,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IAC5E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;wBAGoD,iBAAiB;AAAtE,wBAAuE;AAEvE,eAAO,MAAM,aAAa,EAAG,eAAwB,CAAC"}
1
+ {"version":3,"file":"SpotifyAuthModule.d.ts","sourceRoot":"","sources":["../src/SpotifyAuthModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC9C,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IAC5E,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;;AAGD,wBAAuE;AAEvE,eAAO,MAAM,aAAa,iBAA2B,CAAC"}
@@ -1,5 +1,5 @@
1
1
  // src/SpotifyAuthModule.ts
2
- import { requireNativeModule } from "expo-modules-core";
2
+ import { requireNativeModule, NativeModule } from "expo-modules-core";
3
3
  // This call loads the native module object from the JSI.
4
4
  export default requireNativeModule("SpotifyAuth");
5
5
  export const AuthEventName = "onSpotifyAuth";
@@ -1 +1 @@
1
- {"version":3,"file":"SpotifyAuthModule.js","sourceRoot":"","sources":["../src/SpotifyAuthModule.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,OAAO,EAAE,mBAAmB,EAAgB,MAAM,mBAAmB,CAAC;AAYtE,yDAAyD;AACzD,eAAe,mBAAmB,CAAC,aAAa,CAAsB,CAAC;AAEvE,MAAM,CAAC,MAAM,aAAa,GAAG,eAAwB,CAAC","sourcesContent":["// src/SpotifyAuthModule.ts\n\nimport { requireNativeModule, NativeModule } from \"expo-modules-core\";\nimport type { AuthorizeConfig, SpotifyAuthEvent } from \"./SpotifyAuth.types\";\n\ntype SpotifyAuthEvents = {\n onSpotifyAuth(event: SpotifyAuthEvent): void;\n};\n\nexport declare class SpotifyAuthModule extends NativeModule<SpotifyAuthEvents> {\n readonly AuthEventName: string;\n readonly authorize: (config: AuthorizeConfig) => Promise<void>;\n}\n\n// This call loads the native module object from the JSI.\nexport default requireNativeModule(\"SpotifyAuth\") as SpotifyAuthModule;\n\nexport const AuthEventName = \"onSpotifyAuth\" as const;\n"]}
1
+ {"version":3,"file":"SpotifyAuthModule.js","sourceRoot":"","sources":["../src/SpotifyAuthModule.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAYtE,yDAAyD;AACzD,eAAe,mBAAmB,CAAC,aAAa,CAAsB,CAAC;AAEvE,MAAM,CAAC,MAAM,aAAa,GAAG,eAAwB,CAAC","sourcesContent":["// src/SpotifyAuthModule.ts\n\nimport { requireNativeModule, NativeModule } from \"expo-modules-core\";\nimport type { AuthorizeConfig, SpotifyAuthEvent } from \"./SpotifyAuth.types\";\n\nexport type SpotifyAuthEvents = {\n onSpotifyAuth(event: SpotifyAuthEvent): void;\n};\n\nexport declare class SpotifyAuthModule extends NativeModule<SpotifyAuthEvents> {\n readonly AuthEventName: 'onSpotifyAuth';\n readonly authorize: (config: AuthorizeConfig) => Promise<void>;\n}\n\n// This call loads the native module object from the JSI.\nexport default requireNativeModule(\"SpotifyAuth\") as SpotifyAuthModule;\n\nexport const AuthEventName = \"onSpotifyAuth\" as const;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAE5E,OAAO,EAEL,kBAAkB,EAGlB,KAAK,eAAe,EAErB,MAAM,qBAAqB,CAAC;AAe7B;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAGvD;AAED,UAAU,wBAAwB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,GACT,EAAE,wBAAwB,GAAG,GAAG,CAAC,OAAO,CAwFxC;AAED,wBAAgB,cAAc,IAAI,kBAAkB,CAMnD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAE5E,OAAO,EACL,kBAAkB,EAGlB,KAAK,eAAe,EAGrB,MAAM,qBAAqB,CAAC;AAQ7B;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAGvD;AAED,UAAU,wBAAwB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,GACT,EAAE,wBAAwB,GAAG,GAAG,CAAC,OAAO,CAwFxC;AAED,wBAAgB,cAAc,IAAI,kBAAkB,CAMnD"}
package/build/index.js CHANGED
@@ -1,14 +1,10 @@
1
1
  // src/index.tsx
2
- import { EventEmitter } from "expo-modules-core";
3
2
  import React, { useContext, useEffect, useState, useCallback } from "react";
4
3
  import { SpotifyAuthContextInstance, } from "./SpotifyAuth.types";
5
4
  import SpotifyAuthModule from "./SpotifyAuthModule";
6
- // Create a properly typed emitter
7
- const emitter = new EventEmitter(SpotifyAuthModule);
8
5
  function addAuthListener(listener) {
9
- // Assert the event name is of the correct type
10
6
  const eventName = SpotifyAuthModule.AuthEventName;
11
- return emitter.addListener(eventName, listener);
7
+ return SpotifyAuthModule.addListener(eventName, listener);
12
8
  }
13
9
  /**
14
10
  * Prompts the user to log in to Spotify and authorize your application.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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","sourcesContent":["// src/index.tsx\n\nimport { EventEmitter } from \"expo-modules-core\";\nimport React, { useContext, useEffect, useState, useCallback } from \"react\";\n\nimport {\n SpotifyAuthorizationData,\n SpotifyAuthContext,\n SpotifyAuthContextInstance,\n SpotifyAuthState,\n type AuthorizeConfig,\n type SpotifyAuthError,\n} from \"./SpotifyAuth.types\";\nimport SpotifyAuthModule from \"./SpotifyAuthModule\";\n\n// First define the event name as a string literal type\ntype SpotifyAuthEventName = \"onSpotifyAuth\"; // This should match SpotifyAuthModule.AuthEventName\n\n// Create a properly typed emitter\nconst emitter = new EventEmitter(SpotifyAuthModule);\n\nfunction addAuthListener(listener: (data: SpotifyAuthorizationData) => void) {\n // Assert the event name is of the correct type\n const eventName = SpotifyAuthModule.AuthEventName as SpotifyAuthEventName;\n return emitter.addListener(eventName, listener);\n}\n\n/**\n * Prompts the user to log in to Spotify and authorize your application.\n */\nexport function authorize(config: AuthorizeConfig): void {\n console.log('[SpotifyAuth] Initiating authorization request');\n SpotifyAuthModule.authorize(config);\n}\n\ninterface SpotifyAuthProviderProps {\n children: React.ReactNode;\n}\n\nexport function SpotifyAuthProvider({\n children,\n}: SpotifyAuthProviderProps): JSX.Element {\n const [authState, setAuthState] = useState<SpotifyAuthState>({\n accessToken: null,\n refreshToken: null,\n expiresIn: null,\n tokenType: null,\n scope: null,\n });\n const [isAuthenticating, setIsAuthenticating] = useState(false);\n const [error, setError] = useState<SpotifyAuthError | null>(null);\n\n const authorize = useCallback(\n async (config: AuthorizeConfig): Promise<void> => {\n try {\n console.log('[SpotifyAuth] Starting authorization process in provider');\n console.log('[SpotifyAuth] Authorization config:', JSON.stringify(config));\n setIsAuthenticating(true);\n setError(null);\n await SpotifyAuthModule.authorize(config);\n } catch (err) {\n console.error('[SpotifyAuth] Authorization error:', err);\n // Handle structured errors from the native layer\n if (err && typeof err === 'object' && 'type' in err) {\n setError(err as SpotifyAuthError);\n } else {\n // Create a generic error structure for unknown errors\n setError({\n type: 'unknown_error',\n message: err instanceof Error ? err.message : 'Authorization failed',\n details: {\n error_code: 'unknown',\n recoverable: false\n }\n });\n }\n throw err;\n }\n },\n [],\n );\n\n useEffect(() => {\n console.log('[SpotifyAuth] Setting up auth listener');\n const subscription = addAuthListener((data) => {\n console.log('[SpotifyAuth] Received auth event:', JSON.stringify(data));\n\n // Only update state if we receive a token\n if (data.token) {\n setAuthState({\n accessToken: data.token,\n refreshToken: data.refreshToken,\n expiresIn: data.expiresIn,\n tokenType: data.tokenType,\n scope: data.scope,\n });\n setIsAuthenticating(false);\n setError(null);\n }\n\n // Only set error if we have no token and there's an error\n if (!data.token && data.error) {\n console.error('[SpotifyAuth] Auth event error:', data.error);\n setAuthState({\n accessToken: null,\n refreshToken: null,\n expiresIn: null,\n tokenType: null,\n scope: null,\n });\n setError(data.error);\n setIsAuthenticating(false);\n }\n });\n return () => subscription.remove();\n }, []);\n\n return (\n <SpotifyAuthContextInstance.Provider\n value={{\n authState,\n authorize,\n isAuthenticating,\n error\n }}\n >\n {children}\n </SpotifyAuthContextInstance.Provider>\n );\n}\n\nexport function useSpotifyAuth(): SpotifyAuthContext {\n const context = useContext(SpotifyAuthContextInstance);\n if (!context) {\n throw new Error(\"useSpotifyAuth must be used within a SpotifyAuthProvider\");\n }\n return context;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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","sourcesContent":["// src/index.tsx\n\nimport React, { useContext, useEffect, useState, useCallback } from \"react\";\n\nimport {\n SpotifyAuthContext,\n SpotifyAuthContextInstance,\n SpotifyAuthState,\n type AuthorizeConfig,\n type SpotifyAuthError,\n type SpotifyAuthEvent,\n} from \"./SpotifyAuth.types\";\nimport SpotifyAuthModule from \"./SpotifyAuthModule\";\n\nfunction addAuthListener(listener: (event: SpotifyAuthEvent) => void) {\n const eventName = SpotifyAuthModule.AuthEventName;\n return SpotifyAuthModule.addListener(eventName, listener);\n}\n\n/**\n * Prompts the user to log in to Spotify and authorize your application.\n */\nexport function authorize(config: AuthorizeConfig): void {\n console.log('[SpotifyAuth] Initiating authorization request');\n SpotifyAuthModule.authorize(config);\n}\n\ninterface SpotifyAuthProviderProps {\n children: React.ReactNode;\n}\n\nexport function SpotifyAuthProvider({\n children,\n}: SpotifyAuthProviderProps): JSX.Element {\n const [authState, setAuthState] = useState<SpotifyAuthState>({\n accessToken: null,\n refreshToken: null,\n expiresIn: null,\n tokenType: null,\n scope: null,\n });\n const [isAuthenticating, setIsAuthenticating] = useState(false);\n const [error, setError] = useState<SpotifyAuthError | null>(null);\n\n const authorize = useCallback(\n async (config: AuthorizeConfig): Promise<void> => {\n try {\n console.log('[SpotifyAuth] Starting authorization process in provider');\n console.log('[SpotifyAuth] Authorization config:', JSON.stringify(config));\n setIsAuthenticating(true);\n setError(null);\n await SpotifyAuthModule.authorize(config);\n } catch (err) {\n console.error('[SpotifyAuth] Authorization error:', err);\n // Handle structured errors from the native layer\n if (err && typeof err === 'object' && 'type' in err) {\n setError(err as SpotifyAuthError);\n } else {\n // Create a generic error structure for unknown errors\n setError({\n type: 'unknown_error',\n message: err instanceof Error ? err.message : 'Authorization failed',\n details: {\n error_code: 'unknown',\n recoverable: false\n }\n });\n }\n throw err;\n }\n },\n [],\n );\n\n useEffect(() => {\n console.log('[SpotifyAuth] Setting up auth listener');\n const subscription = addAuthListener((data) => {\n console.log('[SpotifyAuth] Received auth event:', JSON.stringify(data));\n\n // Only update state if we receive a token\n if (data.token) {\n setAuthState({\n accessToken: data.token,\n refreshToken: data.refreshToken,\n expiresIn: data.expiresIn,\n tokenType: data.tokenType,\n scope: data.scope,\n });\n setIsAuthenticating(false);\n setError(null);\n }\n\n // Only set error if we have no token and there's an error\n if (!data.token && data.error) {\n console.error('[SpotifyAuth] Auth event error:', data.error);\n setAuthState({\n accessToken: null,\n refreshToken: null,\n expiresIn: null,\n tokenType: null,\n scope: null,\n });\n setError(data.error);\n setIsAuthenticating(false);\n }\n });\n return () => subscription.remove();\n }, []);\n\n return (\n <SpotifyAuthContextInstance.Provider\n value={{\n authState,\n authorize,\n isAuthenticating,\n error\n }}\n >\n {children}\n </SpotifyAuthContextInstance.Provider>\n );\n}\n\nexport function useSpotifyAuth(): SpotifyAuthContext {\n const context = useContext(SpotifyAuthContextInstance);\n if (!context) {\n throw new Error(\"useSpotifyAuth must be used within a SpotifyAuthProvider\");\n }\n return context;\n}\n"]}
@@ -0,0 +1,33 @@
1
+ import react from 'eslint-plugin-react';
2
+ import reactHooks from 'eslint-plugin-react-hooks';
3
+ import eslint from '@eslint/js';
4
+ import { defineConfig } from 'eslint/config';
5
+ import tseslint from 'typescript-eslint';
6
+
7
+ export default defineConfig([
8
+ { ignores: ['build/**', 'node_modules/**', 'ios/Frameworks/**'] },
9
+ eslint.configs.recommended,
10
+ tseslint.configs.recommended,
11
+ {
12
+ languageOptions: {
13
+ ecmaVersion: 'latest',
14
+ sourceType: 'module',
15
+ parserOptions: {
16
+ ecmaFeatures: { jsx: true },
17
+ },
18
+ },
19
+ plugins: {
20
+ react,
21
+ 'react-hooks': reactHooks,
22
+ },
23
+ settings: {
24
+ react: { version: 'detect' },
25
+ },
26
+ rules: {
27
+ 'react/react-in-jsx-scope': 'off',
28
+ 'react/jsx-uses-react': 'off',
29
+ 'react-hooks/rules-of-hooks': 'error',
30
+ 'react-hooks/exhaustive-deps': 'warn',
31
+ },
32
+ }
33
+ ]);
@@ -13,8 +13,8 @@ Pod::Spec.new do |s|
13
13
  s.license = package['license']
14
14
  s.author = package['author']
15
15
  s.homepage = package['homepage']
16
- s.platform = :ios, '13.0'
17
- s.swift_version = '5.4'
16
+ s.platform = :ios, '15.1'
17
+ s.swift_version = '5.9'
18
18
 
19
19
  s.source = {
20
20
  git: 'https://github.com/superfan-app/spotify-auth.git',
@@ -31,14 +31,12 @@ Pod::Spec.new do |s|
31
31
  'DEFINES_MODULE' => 'YES',
32
32
  'SWIFT_COMPILATION_MODE' => 'wholemodule',
33
33
  'ENABLE_BITCODE' => 'NO',
34
- 'IPHONEOS_DEPLOYMENT_TARGET' => '13.0',
35
- 'FRAMEWORK_SEARCH_PATHS' => '$(PODS_TARGET_SRCROOT)/Frameworks',
36
- 'HEADER_SEARCH_PATHS' => '$(PODS_TARGET_SRCROOT)/Frameworks/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers'
34
+ 'IPHONEOS_DEPLOYMENT_TARGET' => '15.1'
37
35
  }
38
36
 
39
37
  s.user_target_xcconfig = {
40
38
  'ENABLE_BITCODE' => 'NO',
41
- 'IPHONEOS_DEPLOYMENT_TARGET' => '13.0',
39
+ 'IPHONEOS_DEPLOYMENT_TARGET' => '15.1',
42
40
  'OTHER_LDFLAGS' => '-ObjC'
43
41
  }
44
42
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superfan-app/spotify-auth",
3
- "version": "0.1.61",
3
+ "version": "0.1.63",
4
4
  "description": "Spotify OAuth module for Expo",
5
5
  "main": "src/index.tsx",
6
6
  "types": "build/index.d.ts",
@@ -33,19 +33,27 @@
33
33
  "author": "Superfan App",
34
34
  "license": "MIT",
35
35
  "dependencies": {
36
- "@expo/config-plugins": "^7.0.0"
36
+ "@expo/config-plugins": "^10.1.2"
37
37
  },
38
38
  "devDependencies": {
39
- "@expo/config-types": "^49.0.0",
40
- "@types/react": "^18.0.0",
41
- "@types/react-native": "^0.70.0",
42
- "expo-module-scripts": "^3.0.0",
43
- "expo-modules-core": "^1.5.0",
44
- "typescript": "^5.0.0"
39
+ "@eslint/js": "^9.35.0",
40
+ "@expo/config-types": "^53.0.5",
41
+ "@types/react": "18.3.24",
42
+ "eslint": "^9.35.0",
43
+ "eslint-plugin-react": "^7.37.5",
44
+ "eslint-plugin-react-hooks": "^5.2.0",
45
+ "expo": "^53.0.22",
46
+ "expo-module-scripts": "^5.0.7",
47
+ "expo-modules-core": "^3.0.15",
48
+ "typescript": "5.4",
49
+ "typescript-eslint": "^8.43.0"
45
50
  },
46
51
  "peerDependencies": {
47
52
  "expo": "*",
48
53
  "react": "*",
49
54
  "react-native": "*"
55
+ },
56
+ "overrides": {
57
+ "@types/react": "18.3.24"
50
58
  }
51
59
  }
@@ -3,12 +3,12 @@
3
3
  import { requireNativeModule, NativeModule } from "expo-modules-core";
4
4
  import type { AuthorizeConfig, SpotifyAuthEvent } from "./SpotifyAuth.types";
5
5
 
6
- type SpotifyAuthEvents = {
6
+ export type SpotifyAuthEvents = {
7
7
  onSpotifyAuth(event: SpotifyAuthEvent): void;
8
8
  };
9
9
 
10
10
  export declare class SpotifyAuthModule extends NativeModule<SpotifyAuthEvents> {
11
- readonly AuthEventName: string;
11
+ readonly AuthEventName: 'onSpotifyAuth';
12
12
  readonly authorize: (config: AuthorizeConfig) => Promise<void>;
13
13
  }
14
14
 
package/src/index.tsx CHANGED
@@ -1,28 +1,20 @@
1
1
  // src/index.tsx
2
2
 
3
- import { EventEmitter } from "expo-modules-core";
4
3
  import React, { useContext, useEffect, useState, useCallback } from "react";
5
4
 
6
5
  import {
7
- SpotifyAuthorizationData,
8
6
  SpotifyAuthContext,
9
7
  SpotifyAuthContextInstance,
10
8
  SpotifyAuthState,
11
9
  type AuthorizeConfig,
12
10
  type SpotifyAuthError,
11
+ type SpotifyAuthEvent,
13
12
  } from "./SpotifyAuth.types";
14
13
  import SpotifyAuthModule from "./SpotifyAuthModule";
15
14
 
16
- // First define the event name as a string literal type
17
- type SpotifyAuthEventName = "onSpotifyAuth"; // This should match SpotifyAuthModule.AuthEventName
18
-
19
- // Create a properly typed emitter
20
- const emitter = new EventEmitter(SpotifyAuthModule);
21
-
22
- function addAuthListener(listener: (data: SpotifyAuthorizationData) => void) {
23
- // Assert the event name is of the correct type
24
- const eventName = SpotifyAuthModule.AuthEventName as SpotifyAuthEventName;
25
- return emitter.addListener(eventName, listener);
15
+ function addAuthListener(listener: (event: SpotifyAuthEvent) => void) {
16
+ const eventName = SpotifyAuthModule.AuthEventName;
17
+ return SpotifyAuthModule.addListener(eventName, listener);
26
18
  }
27
19
 
28
20
  /**
package/tsconfig.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "outDir": "./build"
6
6
  },
7
7
  "include": ["./src"],
8
- "exclude": ["**/__mocks__/*", "**/__tests__/*"]
8
+ "exclude": ["**/__mocks__/*", "**/__tests__/*", "**/__rsc_tests__/*"]
9
9
  }